@@ -268,61 +268,96 @@ function signextend(x1, x2, x3, x4, y1, y2, y3, y4) -> z1, z2, z3, z4 {
268
268
// TODO implement
269
269
unreachable()
270
270
}
271
+
272
+ function u256_to_i64(x1, x2, x3, x4) -> v {
273
+ if i64.ne(0, i64.or(i64.or(x1, x2), x3)) { invalid() }
274
+ v := x4
275
+ }
276
+
277
+ function u256_to_i32(x1, x2, x3, x4) -> v {
278
+ if i64.ne(0, i64.or(i64.or(x1, x2), x3)) { invalid() }
279
+ if i64.ne(0, i64.shr_u(x4, 32)) { invalid() }
280
+ v := x4
281
+ }
282
+
283
+ function u256_to_i32ptr(x1, x2, x3, x4) -> v {
284
+ v := u256_to_i32(x1, x2, x3, x4)
285
+ }
286
+
271
287
function keccak256(x1, x2, x3, x4, y1, y2, y3, y4) -> z1, z2, z3, z4 {
272
288
// TODO implement
273
289
unreachable()
274
290
}
275
291
276
292
function address() -> z1, z2, z3, z4 {
277
- // TODO implement
278
- unreachable()
293
+ let t1, t2, t3, t4 := save_temp_mem_32()
294
+ eth.getAddress(0)
295
+ z1, z2, z3, z4 := mload(0, 0, 0, 0)
296
+ restore_temp_mem_32(t1, t2, t3, t4)
279
297
}
280
298
function balance(x1, x2, x3, x4) -> z1, z2, z3, z4 {
281
299
// TODO implement
282
300
unreachable()
283
301
}
284
302
function origin() -> z1, z2, z3, z4 {
285
- // TODO implement
286
- unreachable()
303
+ let t1, t2, t3, t4 := save_temp_mem_32()
304
+ eth.getTxOrigin(0)
305
+ z1, z2, z3, z4 := mload(0, 0, 0, 0)
306
+ restore_temp_mem_32(t1, t2, t3, t4)
287
307
}
288
308
function caller() -> z1, z2, z3, z4 {
289
- // TODO implement
290
- unreachable()
309
+ let t1, t2, t3, t4 := save_temp_mem_32()
310
+ eth.getCaller(0)
311
+ z1, z2, z3, z4 := mload(0, 0, 0, 0)
312
+ restore_temp_mem_32(t1, t2, t3, t4)
291
313
}
292
314
function callvalue() -> z1, z2, z3, z4 {
293
- // TODO implement
294
- unreachable()
315
+ let t1, t2, t3, t4 := save_temp_mem_32()
316
+ eth.getCallValue(0)
317
+ z1, z2, z3, z4 := mload(0, 0, 0, 0)
318
+ restore_temp_mem_32(t1, t2, t3, t4)
295
319
}
296
320
function calldataload(x1, x2, x3, x4) -> z1, z2, z3, z4 {
297
- // TODO implement
298
- unreachable()
321
+ let t1, t2, t3, t4 := save_temp_mem_32()
322
+ eth.callDataCopy(0, u256_to_i32(x1, x2, x3, x4), 32)
323
+ z1, z2, z3, z4 := mload(0, 0, 0, 0)
324
+ restore_temp_mem_32(t1, t2, t3, t4)
299
325
}
300
326
function calldatasize() -> z1, z2, z3, z4 {
301
- // TODO implement
302
- unreachable()
327
+ z4 := eth.getCallDataSize()
303
328
}
304
329
function calldatacopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4) {
305
- // TODO implement
306
- unreachable()
330
+ eth.callDataCopy(
331
+ u256_to_i32ptr(x1, x2, x3, x4),
332
+ u256_to_i32(y1, y2, y3, y4),
333
+ u256_to_i32(z1, z2, z3, z4)
334
+ )
307
335
}
308
336
309
337
// Needed?
310
338
function codesize() -> z1, z2, z3, z4 {
311
- // TODO implement
312
- unreachable()
339
+ let t1, t2, t3, t4 := save_temp_mem_32()
340
+ eth.getCodeSize(0)
341
+ z1, z2, z3, z4 := mload(0, 0, 0, 0)
342
+ restore_temp_mem_32(t1, t2, t3, t4)
313
343
}
314
344
function codecopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4) {
315
- // TODO implement
316
- unreachable()
345
+ eth.codeCopy(
346
+ u256_to_i32ptr(x1, x2, x3, x4),
347
+ u256_to_i32(y1, y2, y3, y4),
348
+ u256_to_i32(z1, z2, z3, z4)
349
+ )
317
350
}
318
351
function datacopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4) {
319
- // TODO implement
320
- unreachable( )
352
+ // TODO correct?
353
+ codecopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4 )
321
354
}
322
355
323
356
function gasprice() -> z1, z2, z3, z4 {
324
- // TODO implement
325
- unreachable()
357
+ let t1, t2, t3, t4 := save_temp_mem_32()
358
+ eth.getTxGasPrice(0)
359
+ z1, z2, z3, z4 := mload(0, 0, 0, 0)
360
+ restore_temp_mem_32(t1, t2, t3, t4)
326
361
}
327
362
function extcodesize(x1, x2, x3, x4) -> z1, z2, z3, z4 {
328
363
// TODO implement
@@ -338,12 +373,14 @@ function extcodecopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4) {
338
373
}
339
374
340
375
function returndatasize() -> z1, z2, z3, z4 {
341
- // TODO implement
342
- unreachable()
376
+ z4 := eth.getReturnDataSize()
343
377
}
344
378
function returndatacopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4) {
345
- // TODO implement
346
- unreachable()
379
+ eth.returnDataCopy(
380
+ u256_to_i32ptr(x1, x2, x3, x4),
381
+ u256_to_i32(y1, y2, y3, y4),
382
+ u256_to_i32(z1, z2, z3, z4)
383
+ )
347
384
}
348
385
349
386
function blockhash(x1, x2, x3, x4) -> z1, z2, z3, z4 {
@@ -355,34 +392,87 @@ function coinbase() -> z1, z2, z3, z4 {
355
392
unreachable()
356
393
}
357
394
function timestamp() -> z1, z2, z3, z4 {
358
- // TODO implement
359
- unreachable()
395
+ z4 := eth.getBlockTimestamp()
360
396
}
361
397
function number() -> z1, z2, z3, z4 {
362
- // TODO implement
363
- unreachable()
398
+ z4 := eth.getBlockNumber()
364
399
}
365
400
function difficulty() -> z1, z2, z3, z4 {
366
- // TODO implement
367
- unreachable()
401
+ let t1, t2, t3, t4 := save_temp_mem_32()
402
+ eth.getBlockDifficulty(0)
403
+ z1, z2, z3, z4 := mload(0, 0, 0, 0)
404
+ restore_temp_mem_32(t1, t2, t3, t4)
368
405
}
369
406
function gaslimit() -> z1, z2, z3, z4 {
370
- // TODO implement
371
- unreachable()
407
+ z4 := eth.getBlockGasLimit()
372
408
}
373
409
374
410
function pop(x1, x2, x3, x4) {
375
- // TODO implement
376
- unreachable()
377
411
}
378
412
413
+
414
+ function endian_swap_16(x) -> y {
415
+ let hi := i64.and(i64.shl(x, 8), 0xff00)
416
+ let lo := i64.and(i64.shr_u(x, 8), 0xff)
417
+ y := i64.or(hi, lo)
418
+ }
419
+
420
+ function endian_swap_32(x) -> y {
421
+ let hi := i64.shl(endian_swap_16(x), 16)
422
+ let lo := endian_swap_16(i64.shr_u(x, 16))
423
+ y := i64.or(hi, lo)
424
+ }
425
+
426
+ function endian_swap(x) -> y {
427
+ let hi := i64.shl(endian_swap_32(x), 32)
428
+ let lo := endian_swap_32(i64.shr_u(x, 32))
429
+ y := i64.or(hi, lo)
430
+ }
431
+ function save_temp_mem_32() -> t1, t2, t3, t4 {
432
+ t1 := i64.load(0)
433
+ t2 := i64.load(8)
434
+ t3 := i64.load(16)
435
+ t4 := i64.load(24)
436
+ }
437
+ function restore_temp_mem_32(t1, t2, t3, t4) {
438
+ i64.store(0, t1)
439
+ i64.store(8, t2)
440
+ i64.store(16, t3)
441
+ i64.store(24, t4)
442
+ }
443
+ function save_temp_mem_64() -> t1, t2, t3, t4, t5, t6, t7, t8 {
444
+ t1 := i64.load(0)
445
+ t2 := i64.load(8)
446
+ t3 := i64.load(16)
447
+ t4 := i64.load(24)
448
+ t5 := i64.load(32)
449
+ t6 := i64.load(40)
450
+ t7 := i64.load(48)
451
+ t8 := i64.load(54)
452
+ }
453
+ function restore_temp_mem_64(t1, t2, t3, t4, t5, t6, t7, t8) {
454
+ i64.store(0, t1)
455
+ i64.store(8, t2)
456
+ i64.store(16, t3)
457
+ i64.store(24, t4)
458
+ i64.store(32, t5)
459
+ i64.store(40, t6)
460
+ i64.store(48, t7)
461
+ i64.store(54, t8)
462
+ }
379
463
function mload(x1, x2, x3, x4) -> z1, z2, z3, z4 {
380
- // TODO implement
381
- unreachable()
464
+ let pos := u256_to_i32ptr(x1, x2, x3, x4)
465
+ z1 := endian_swap(i64.load(pos))
466
+ z2 := endian_swap(i64.load(i64.add(pos, 8)))
467
+ z3 := endian_swap(i64.load(i64.add(pos, 16)))
468
+ z4 := endian_swap(i64.load(i64.add(pos, 24)))
382
469
}
383
470
function mstore(x1, x2, x3, x4, y1, y2, y3, y4) {
384
- // TODO implement
385
- unreachable()
471
+ let pos := u256_to_i32ptr(x1, x2, x3, x4)
472
+ i64.store(pos, endian_swap(x1))
473
+ i64.store(i64.add(pos, 8), endian_swap(x2))
474
+ i64.store(i64.add(pos, 16), endian_swap(x3))
475
+ i64.store(i64.add(pos, 24), endian_swap(x4))
386
476
}
387
477
function mstore8(x1, x2, x3, x4, y1, y2, y3, y4) {
388
478
// TODO implement
@@ -394,12 +484,19 @@ function msize() -> z1, z2, z3, z4 {
394
484
unreachable()
395
485
}
396
486
function sload(x1, x2, x3, x4) -> z1, z2, z3, z4 {
397
- // TODO implement
398
- unreachable()
487
+ let t1, t2, t3, t4, t5, t6, t7, t8 := save_temp_mem_64()
488
+ mstore(0, 0, 0, 0, x1, x2, x3, x4)
489
+ eth.storageLoad(0, 16)
490
+ z1, z2, z3, z4 := mload(0, 0, 0, 16)
491
+ restore_temp_mem_64(t1, t2, t3, t4, t5, t6, t7, t8)
399
492
}
493
+
400
494
function sstore(x1, x2, x3, x4, y1, y2, y3, y4) {
401
- // TODO implement
402
- unreachable()
495
+ let t1, t2, t3, t4, t5, t6, t7, t8 := save_temp_mem_64()
496
+ mstore(0, 0, 0, 0, x1, x2, x3, x4)
497
+ mstore(0, 0, 0, 32, y1, y2, y3, y4)
498
+ eth.storageStore(0, 32)
499
+ restore_temp_mem_64(t1, t2, t3, t4, t5, t6, t7, t8)
403
500
}
404
501
405
502
// Needed?
@@ -408,8 +505,7 @@ function pc() -> z1, z2, z3, z4 {
408
505
unreachable()
409
506
}
410
507
function gas() -> z1, z2, z3, z4 {
411
- // TODO implement
412
- unreachable()
508
+ z4 := eth.getGasLeft()
413
509
}
414
510
415
511
function log0(p1, p2, p3, p4, s1, s2, s3, s4) {
@@ -511,17 +607,22 @@ function create2(
511
607
unreachable()
512
608
}
513
609
function selfdestruct(a1, a2, a3, a4) {
514
- // TODO implement
515
- unreachable()
610
+ mstore(0, 0, 0, 0, a1, a2, a3, a4)
611
+ // In EVM, addresses are padded to 32 bytes, so discard the first 12.
612
+ eth.selfDestruct(12)
516
613
}
517
614
518
615
function return(x1, x2, x3, x4, y1, y2, y3, y4) {
519
- // TODO implement
520
- unreachable()
616
+ eth.finish(
617
+ u256_to_i32ptr(x1, x2, x3, x4),
618
+ u256_to_i32(y1, y2, y3, y4)
619
+ )
521
620
}
522
621
function revert(x1, x2, x3, x4, y1, y2, y3, y4) {
523
- // TODO implement
524
- unreachable()
622
+ eth.revert(
623
+ u256_to_i32ptr(x1, x2, x3, x4),
624
+ u256_to_i32(y1, y2, y3, y4)
625
+ )
525
626
}
526
627
function invalid() {
527
628
unreachable()
0 commit comments