Commit 4af15d02 authored by Inphi's avatar Inphi Committed by GitHub

cannon: Refactor ALU execution (#6868)

* cannon: Refactor ALU execution

Reduce cyclomatic complexity of Go and Solidity MIPS VMs.
This has minimal effect on runtime. Though better gas savings in
Solidity.

* Make Go and Solidity MIPS VMs more similar
parent 875bac3c
...@@ -395,87 +395,110 @@ func (m *InstrumentedState) mipsStep() error { ...@@ -395,87 +395,110 @@ func (m *InstrumentedState) mipsStep() error {
func execute(insn uint32, rs uint32, rt uint32, mem uint32) uint32 { func execute(insn uint32, rs uint32, rt uint32, mem uint32) uint32 {
opcode := insn >> 26 // 6-bits opcode := insn >> 26 // 6-bits
fun := insn & 0x3f // 6-bits
if opcode == 0 || (opcode >= 8 && opcode < 0xF) {
if opcode < 0x20 { fun := insn & 0x3f // 6-bits
// transform ArithLogI // transform ArithLogI to SPECIAL
// TODO(CLI-4136): replace with table switch opcode {
if opcode >= 8 && opcode < 0xF { case 8:
switch opcode { fun = 0x20 // addi
case 8: case 9:
fun = 0x20 // addi fun = 0x21 // addiu
case 9: case 0xA:
fun = 0x21 // addiu fun = 0x2A // slti
case 0xA: case 0xB:
fun = 0x2A // slti fun = 0x2B // sltiu
case 0xB: case 0xC:
fun = 0x2B // sltiu fun = 0x24 // andi
case 0xC: case 0xD:
fun = 0x24 // andi fun = 0x25 // ori
case 0xD: case 0xE:
fun = 0x25 // ori fun = 0x26 // xori
case 0xE:
fun = 0x26 // xori
}
opcode = 0
} }
// 0 is opcode SPECIAL switch fun {
if opcode == 0 { case 0x00: // sll
return rt << ((insn >> 6) & 0x1F)
case 0x02: // srl
return rt >> ((insn >> 6) & 0x1F)
case 0x03: // sra
shamt := (insn >> 6) & 0x1F shamt := (insn >> 6) & 0x1F
if fun < 0x20 { return SE(rt>>shamt, 32-shamt)
switch { case 0x04: // sllv
case fun >= 0x08: return rt << (rs & 0x1F)
return rs // jr/jalr/div + others case 0x06: // srlv
case fun == 0x00: return rt >> (rs & 0x1F)
return rt << shamt // sll case 0x07: // srav
case fun == 0x02: return SE(rt>>rs, 32-rs)
return rt >> shamt // srl // functs in range [0x8, 0x1b] are handled specially by other functions
case fun == 0x03: case 0x08: // jr
return SE(rt>>shamt, 32-shamt) // sra return rs
case fun == 0x04: case 0x09: // jalr
return rt << (rs & 0x1F) // sllv return rs
case fun == 0x06: case 0x0a: // movz
return rt >> (rs & 0x1F) // srlv return rs
case fun == 0x07: case 0x0b: // movn
return SE(rt>>rs, 32-rs) // srav return rs
} case 0x0c: // syscall
return rs
// 0x0d - break not supported
case 0x0f: // sync
return rs
case 0x10: // mfhi
return rs
case 0x11: // mthi
return rs
case 0x12: // mflo
return rs
case 0x13: // mtlo
return rs
case 0x18: // mult
return rs
case 0x19: // multu
return rs
case 0x1a: // div
return rs
case 0x1b: // divu
return rs
// The rest includes transformed R-type arith imm instructions
case 0x20: // add
return rs + rt
case 0x21: // addu
return rs + rt
case 0x22: // sub
return rs - rt
case 0x23: // subu
return rs - rt
case 0x24: // and
return rs & rt
case 0x25: // or
return rs | rt
case 0x26: // xor
return rs ^ rt
case 0x27: // nor
return ^(rs | rt)
case 0x2a: // slti
if int32(rs) < int32(rt) {
return 1
} }
// 0x10-0x13 = mfhi, mthi, mflo, mtlo return 0
// R-type (ArithLog) case 0x2b: // sltiu
switch fun { if rs < rt {
case 0x20, 0x21: return 1
return rs + rt // add or addu
case 0x22, 0x23:
return rs - rt // sub or subu
case 0x24:
return rs & rt // and
case 0x25:
return rs | rt // or
case 0x26:
return rs ^ rt // xor
case 0x27:
return ^(rs | rt) // nor
case 0x2A:
if int32(rs) < int32(rt) {
return 1 // slt
} else {
return 0
}
case 0x2B:
if rs < rt {
return 1 // sltu
} else {
return 0
}
} }
} else if opcode == 0xF { return 0
return rt << 16 // lui default:
} else if opcode == 0x1C { // SPECIAL2 panic("invalid instruction")
if fun == 2 { // mul }
} else {
switch opcode {
// SPECIAL2
case 0x1C:
fun := insn & 0x3f // 6-bits
switch fun {
case 0x2: // mul
return uint32(int32(rs) * int32(rt)) return uint32(int32(rs) * int32(rt))
} case 0x20, 0x21: // clo
if fun == 0x20 || fun == 0x21 { // clo
if fun == 0x20 { if fun == 0x20 {
rs = ^rs rs = ^rs
} }
...@@ -485,9 +508,8 @@ func execute(insn uint32, rs uint32, rt uint32, mem uint32) uint32 { ...@@ -485,9 +508,8 @@ func execute(insn uint32, rs uint32, rt uint32, mem uint32) uint32 {
} }
return i return i
} }
} case 0x0F: // lui
} else if opcode < 0x28 { return rt << 16
switch opcode {
case 0x20: // lb case 0x20: // lb
return SE((mem>>(24-(rs&3)*8))&0xFF, 8) return SE((mem>>(24-(rs&3)*8))&0xFF, 8)
case 0x21: // lh case 0x21: // lh
...@@ -500,37 +522,38 @@ func execute(insn uint32, rs uint32, rt uint32, mem uint32) uint32 { ...@@ -500,37 +522,38 @@ func execute(insn uint32, rs uint32, rt uint32, mem uint32) uint32 {
return mem return mem
case 0x24: // lbu case 0x24: // lbu
return (mem >> (24 - (rs&3)*8)) & 0xFF return (mem >> (24 - (rs&3)*8)) & 0xFF
case 0x25: // lhu case 0x25: // lhu
return (mem >> (16 - (rs&2)*8)) & 0xFFFF return (mem >> (16 - (rs&2)*8)) & 0xFFFF
case 0x26: // lwr case 0x26: // lwr
val := mem >> (24 - (rs&3)*8) val := mem >> (24 - (rs&3)*8)
mask := uint32(0xFFFFFFFF) >> (24 - (rs&3)*8) mask := uint32(0xFFFFFFFF) >> (24 - (rs&3)*8)
return (rt & ^mask) | val return (rt & ^mask) | val
case 0x28: // sb
val := (rt & 0xFF) << (24 - (rs&3)*8)
mask := 0xFFFFFFFF ^ uint32(0xFF<<(24-(rs&3)*8))
return (mem & mask) | val
case 0x29: // sh
val := (rt & 0xFFFF) << (16 - (rs&2)*8)
mask := 0xFFFFFFFF ^ uint32(0xFFFF<<(16-(rs&2)*8))
return (mem & mask) | val
case 0x2a: // swl
val := rt >> ((rs & 3) * 8)
mask := uint32(0xFFFFFFFF) >> ((rs & 3) * 8)
return (mem & ^mask) | val
case 0x2b: // sw
return rt
case 0x2e: // swr
val := rt << (24 - (rs&3)*8)
mask := uint32(0xFFFFFFFF) << (24 - (rs&3)*8)
return (mem & ^mask) | val
case 0x30: // ll
return mem
case 0x38: // sc
return rt
default:
panic("invalid instruction")
} }
} else if opcode == 0x28 { // sb
val := (rt & 0xFF) << (24 - (rs&3)*8)
mask := 0xFFFFFFFF ^ uint32(0xFF<<(24-(rs&3)*8))
return (mem & mask) | val
} else if opcode == 0x29 { // sh
val := (rt & 0xFFFF) << (16 - (rs&2)*8)
mask := 0xFFFFFFFF ^ uint32(0xFFFF<<(16-(rs&2)*8))
return (mem & mask) | val
} else if opcode == 0x2a { // swl
val := rt >> ((rs & 3) * 8)
mask := uint32(0xFFFFFFFF) >> ((rs & 3) * 8)
return (mem & ^mask) | val
} else if opcode == 0x2b { // sw
return rt
} else if opcode == 0x2e { // swr
val := rt << (24 - (rs&3)*8)
mask := uint32(0xFFFFFFFF) << (24 - (rs&3)*8)
return (mem & ^mask) | val
} else if opcode == 0x30 {
return mem // ll
} else if opcode == 0x38 {
return rt // sc
} }
panic("invalid instruction") panic("invalid instruction")
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -298,12 +298,13 @@ LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12957) ...@@ -298,12 +298,13 @@ LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12957)
LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10755) LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10755)
LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34524) LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34524)
LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689) LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689)
MIPS_Test:test_add_succeeds() (gas: 121593) MIPS_Test:test_add_succeeds() (gas: 122197)
MIPS_Test:test_addi_succeeds() (gas: 121918) MIPS_Test:test_addiSign_succeeds() (gas: 122188)
MIPS_Test:test_addu_succeeds() (gas: 121601) MIPS_Test:test_addi_succeeds() (gas: 122385)
MIPS_Test:test_addui_succeeds() (gas: 121975) MIPS_Test:test_addu_succeeds() (gas: 122239)
MIPS_Test:test_and_succeeds() (gas: 121650) MIPS_Test:test_addui_succeeds() (gas: 122447)
MIPS_Test:test_andi_succeeds() (gas: 121792) MIPS_Test:test_and_succeeds() (gas: 122258)
MIPS_Test:test_andi_succeeds() (gas: 122191)
MIPS_Test:test_beq_succeeds() (gas: 202355) MIPS_Test:test_beq_succeeds() (gas: 202355)
MIPS_Test:test_bgez_succeeds() (gas: 121484) MIPS_Test:test_bgez_succeeds() (gas: 121484)
MIPS_Test:test_bgtz_succeeds() (gas: 121405) MIPS_Test:test_bgtz_succeeds() (gas: 121405)
...@@ -311,67 +312,67 @@ MIPS_Test:test_blez_succeeds() (gas: 121361) ...@@ -311,67 +312,67 @@ MIPS_Test:test_blez_succeeds() (gas: 121361)
MIPS_Test:test_bltz_succeeds() (gas: 121504) MIPS_Test:test_bltz_succeeds() (gas: 121504)
MIPS_Test:test_bne_succeeds() (gas: 121570) MIPS_Test:test_bne_succeeds() (gas: 121570)
MIPS_Test:test_branch_inDelaySlot_fails() (gas: 85999) MIPS_Test:test_branch_inDelaySlot_fails() (gas: 85999)
MIPS_Test:test_brk_succeeds() (gas: 121531) MIPS_Test:test_brk_succeeds() (gas: 121869)
MIPS_Test:test_clo_succeeds() (gas: 121991) MIPS_Test:test_clo_succeeds() (gas: 121926)
MIPS_Test:test_clone_succeeds() (gas: 121484) MIPS_Test:test_clone_succeeds() (gas: 121822)
MIPS_Test:test_clz_succeeds() (gas: 122462) MIPS_Test:test_clz_succeeds() (gas: 122397)
MIPS_Test:test_div_succeeds() (gas: 121806) MIPS_Test:test_div_succeeds() (gas: 122376)
MIPS_Test:test_divu_succeeds() (gas: 121762) MIPS_Test:test_divu_succeeds() (gas: 122361)
MIPS_Test:test_exit_succeeds() (gas: 121408) MIPS_Test:test_exit_succeeds() (gas: 121746)
MIPS_Test:test_fcntl_succeeds() (gas: 203129) MIPS_Test:test_fcntl_succeeds() (gas: 203827)
MIPS_Test:test_illegal_instruction_fails() (gas: 91175) MIPS_Test:test_illegal_instruction_fails() (gas: 91462)
MIPS_Test:test_invalid_root_fails() (gas: 435678) MIPS_Test:test_invalid_root_fails() (gas: 435636)
MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 120492) MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 120514)
MIPS_Test:test_jal_succeeds() (gas: 120481) MIPS_Test:test_jal_succeeds() (gas: 120503)
MIPS_Test:test_jalr_succeeds() (gas: 121349) MIPS_Test:test_jalr_succeeds() (gas: 121622)
MIPS_Test:test_jr_succeeds() (gas: 121094) MIPS_Test:test_jr_succeeds() (gas: 121316)
MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85345) MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85367)
MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120236) MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120258)
MIPS_Test:test_jump_succeeds() (gas: 120188) MIPS_Test:test_jump_succeeds() (gas: 120188)
MIPS_Test:test_lb_succeeds() (gas: 127346) MIPS_Test:test_lb_succeeds() (gas: 127429)
MIPS_Test:test_lbu_succeeds() (gas: 127222) MIPS_Test:test_lbu_succeeds() (gas: 127327)
MIPS_Test:test_lh_succeeds() (gas: 127367) MIPS_Test:test_lh_succeeds() (gas: 127450)
MIPS_Test:test_lhu_succeeds() (gas: 127284) MIPS_Test:test_lhu_succeeds() (gas: 127367)
MIPS_Test:test_ll_succeeds() (gas: 127304) MIPS_Test:test_ll_succeeds() (gas: 127589)
MIPS_Test:test_lui_succeeds() (gas: 121488) MIPS_Test:test_lui_succeeds() (gas: 121470)
MIPS_Test:test_lw_succeeds() (gas: 127158) MIPS_Test:test_lw_succeeds() (gas: 127218)
MIPS_Test:test_lwl_succeeds() (gas: 241434) MIPS_Test:test_lwl_succeeds() (gas: 241600)
MIPS_Test:test_lwr_succeeds() (gas: 241722) MIPS_Test:test_lwr_succeeds() (gas: 241888)
MIPS_Test:test_mfhi_succeeds() (gas: 121458) MIPS_Test:test_mfhi_succeeds() (gas: 121831)
MIPS_Test:test_mflo_succeeds() (gas: 121484) MIPS_Test:test_mflo_succeeds() (gas: 121960)
MIPS_Test:test_mmap_succeeds() (gas: 118451) MIPS_Test:test_mmap_succeeds() (gas: 118789)
MIPS_Test:test_movn_succeeds() (gas: 202409) MIPS_Test:test_movn_succeeds() (gas: 203027)
MIPS_Test:test_movz_succeeds() (gas: 202313) MIPS_Test:test_movz_succeeds() (gas: 202895)
MIPS_Test:test_mthi_succeeds() (gas: 121450) MIPS_Test:test_mthi_succeeds() (gas: 121875)
MIPS_Test:test_mtlo_succeeds() (gas: 121478) MIPS_Test:test_mtlo_succeeds() (gas: 121983)
MIPS_Test:test_mul_succeeds() (gas: 121563) MIPS_Test:test_mul_succeeds() (gas: 121475)
MIPS_Test:test_mult_succeeds() (gas: 121667) MIPS_Test:test_mult_succeeds() (gas: 122179)
MIPS_Test:test_multu_succeeds() (gas: 121675) MIPS_Test:test_multu_succeeds() (gas: 122216)
MIPS_Test:test_nor_succeeds() (gas: 121697) MIPS_Test:test_nor_succeeds() (gas: 122308)
MIPS_Test:test_or_succeeds() (gas: 121657) MIPS_Test:test_or_succeeds() (gas: 122265)
MIPS_Test:test_ori_succeeds() (gas: 121865) MIPS_Test:test_ori_succeeds() (gas: 122268)
MIPS_Test:test_preimage_read_succeeds() (gas: 233847) MIPS_Test:test_preimage_read_succeeds() (gas: 234185)
MIPS_Test:test_preimage_write_succeeds() (gas: 126473) MIPS_Test:test_preimage_write_succeeds() (gas: 126811)
MIPS_Test:test_prestate_exited_succeeds() (gas: 112992) MIPS_Test:test_prestate_exited_succeeds() (gas: 112992)
MIPS_Test:test_sb_succeeds() (gas: 159993) MIPS_Test:test_sb_succeeds() (gas: 160300)
MIPS_Test:test_sc_succeeds() (gas: 160187) MIPS_Test:test_sc_succeeds() (gas: 160494)
MIPS_Test:test_sh_succeeds() (gas: 160052) MIPS_Test:test_sh_succeeds() (gas: 160337)
MIPS_Test:test_sll_succeeds() (gas: 121456) MIPS_Test:test_sll_succeeds() (gas: 121436)
MIPS_Test:test_sllv_succeeds() (gas: 121646) MIPS_Test:test_sllv_succeeds() (gas: 121665)
MIPS_Test:test_slt_succeeds() (gas: 203266) MIPS_Test:test_slt_succeeds() (gas: 204222)
MIPS_Test:test_sltu_succeeds() (gas: 121871) MIPS_Test:test_sltu_succeeds() (gas: 122482)
MIPS_Test:test_sra_succeeds() (gas: 121763) MIPS_Test:test_sra_succeeds() (gas: 121687)
MIPS_Test:test_srav_succeeds() (gas: 121959) MIPS_Test:test_srav_succeeds() (gas: 121955)
MIPS_Test:test_srl_succeeds() (gas: 121514) MIPS_Test:test_srl_succeeds() (gas: 121518)
MIPS_Test:test_srlv_succeeds() (gas: 121707) MIPS_Test:test_srlv_succeeds() (gas: 121683)
MIPS_Test:test_step_abi_succeeds() (gas: 57876) MIPS_Test:test_step_abi_succeeds() (gas: 58312)
MIPS_Test:test_sub_succeeds() (gas: 121696) MIPS_Test:test_sub_succeeds() (gas: 122292)
MIPS_Test:test_subu_succeeds() (gas: 121659) MIPS_Test:test_subu_succeeds() (gas: 122289)
MIPS_Test:test_sw_succeeds() (gas: 160027) MIPS_Test:test_sw_succeeds() (gas: 160312)
MIPS_Test:test_swl_succeeds() (gas: 160088) MIPS_Test:test_swl_succeeds() (gas: 160373)
MIPS_Test:test_swr_succeeds() (gas: 160163) MIPS_Test:test_swr_succeeds() (gas: 160448)
MIPS_Test:test_xor_succeeds() (gas: 121685) MIPS_Test:test_xor_succeeds() (gas: 122293)
MIPS_Test:test_xori_succeeds() (gas: 121916) MIPS_Test:test_xori_succeeds() (gas: 122345)
MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5733) MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5733)
MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889) MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889)
MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35845) MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35845)
......
...@@ -102,6 +102,26 @@ contract MIPS_Test is CommonTest { ...@@ -102,6 +102,26 @@ contract MIPS_Test is CommonTest {
assertEq(postState, outputState(expect), "unexpected post state"); assertEq(postState, outputState(expect), "unexpected post state");
} }
function test_addiSign_succeeds() external {
uint16 imm = 0xfffe; // -2
uint32 insn = encodeitype(0x8, 17, 8, imm); // addi t0, s1, 40
(MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
state.registers[8] = 1; // t0
state.registers[17] = 2; // s1
bytes memory encodedState = encodeState(state);
MIPS.State memory expect;
expect.memRoot = state.memRoot;
expect.pc = state.nextPC;
expect.nextPC = state.nextPC + 4;
expect.step = state.step + 1;
expect.registers[8] = 0;
expect.registers[17] = state.registers[17];
bytes32 postState = mips.step(encodedState, proof);
assertEq(postState, outputState(expect), "unexpected post state");
}
function test_addui_succeeds() external { function test_addui_succeeds() external {
uint16 imm = 40; uint16 imm = 40;
uint32 insn = encodeitype(0x9, 17, 8, imm); // addui t0, s1, 40 uint32 insn = encodeitype(0x9, 17, 8, imm); // addui t0, s1, 40
...@@ -305,15 +325,15 @@ contract MIPS_Test is CommonTest { ...@@ -305,15 +325,15 @@ contract MIPS_Test is CommonTest {
function test_slt_succeeds() external { function test_slt_succeeds() external {
uint32 insn = encodespec(17, 18, 8, 0x2a); // slt t0, s1, s2 uint32 insn = encodespec(17, 18, 8, 0x2a); // slt t0, s1, s2
(MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0); (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
state.registers[17] = 1200; state.registers[17] = 0xFF_FF_FF_FE; // -2
state.registers[18] = 490; state.registers[18] = 5;
MIPS.State memory expect; MIPS.State memory expect;
expect.memRoot = state.memRoot; expect.memRoot = state.memRoot;
expect.pc = state.nextPC; expect.pc = state.nextPC;
expect.nextPC = state.nextPC + 4; expect.nextPC = state.nextPC + 4;
expect.step = state.step + 1; expect.step = state.step + 1;
expect.registers[8] = state.registers[17] < state.registers[18] ? 1 : 0; // t0 expect.registers[8] = 1; // t0
expect.registers[17] = state.registers[17]; expect.registers[17] = state.registers[17];
expect.registers[18] = state.registers[18]; expect.registers[18] = state.registers[18];
...@@ -326,7 +346,7 @@ contract MIPS_Test is CommonTest { ...@@ -326,7 +346,7 @@ contract MIPS_Test is CommonTest {
state.registers[18] = tmp; state.registers[18] = tmp;
expect.registers[17] = state.registers[17]; expect.registers[17] = state.registers[17];
expect.registers[18] = state.registers[18]; expect.registers[18] = state.registers[18];
expect.registers[8] = state.registers[17] < state.registers[18] ? 1 : 0; // t0 expect.registers[8] = 0; // t0
postState = mips.step(encodeState(state), proof); postState = mips.step(encodeState(state), proof);
assertEq(postState, outputState(expect), "unexpected post state"); assertEq(postState, outputState(expect), "unexpected post state");
} }
...@@ -1127,14 +1147,14 @@ contract MIPS_Test is CommonTest { ...@@ -1127,14 +1147,14 @@ contract MIPS_Test is CommonTest {
uint8 shiftamt = 4; uint8 shiftamt = 4;
uint32 insn = encodespec(0x0, 0x9, 0x8, uint16(shiftamt) << 6 | 3); // sra t0, t1, 3 uint32 insn = encodespec(0x0, 0x9, 0x8, uint16(shiftamt) << 6 | 3); // sra t0, t1, 3
(MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0); (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
state.registers[9] = 0x20; // t1 state.registers[9] = 0x80_00_00_20; // t1
MIPS.State memory expect; MIPS.State memory expect;
expect.memRoot = state.memRoot; expect.memRoot = state.memRoot;
expect.pc = state.nextPC; expect.pc = state.nextPC;
expect.nextPC = state.nextPC + 4; expect.nextPC = state.nextPC + 4;
expect.step = state.step + 1; expect.step = state.step + 1;
expect.registers[8] = state.registers[9] >> shiftamt; expect.registers[8] = 0xF8_00_00_02; // 4 shifts while preserving sign bit
expect.registers[9] = state.registers[9]; expect.registers[9] = state.registers[9];
bytes memory enc = encodeState(state); bytes memory enc = encodeState(state);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment