github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/test/cannon/MIPS.t.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  import { CommonTest } from "test/setup/CommonTest.sol";
     5  import { MIPS } from "src/cannon/MIPS.sol";
     6  import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
     7  import "src/libraries/DisputeTypes.sol";
     8  
     9  contract MIPS_Test is CommonTest {
    10      MIPS internal mips;
    11      PreimageOracle internal oracle;
    12  
    13      function setUp() public virtual override {
    14          super.setUp();
    15          oracle = new PreimageOracle(0, 0);
    16          mips = new MIPS(oracle);
    17          vm.store(address(mips), 0x0, bytes32(abi.encode(address(oracle))));
    18          vm.label(address(oracle), "PreimageOracle");
    19          vm.label(address(mips), "MIPS");
    20      }
    21  
    22      function test_step_abi_succeeds() external {
    23          uint32[32] memory registers;
    24          registers[16] = 0xbfff0000;
    25          MIPS.State memory state = MIPS.State({
    26              memRoot: hex"30be14bdf94d7a93989a6263f1e116943dc052d584730cae844bf330dfddce2f",
    27              preimageKey: bytes32(0),
    28              preimageOffset: 0,
    29              pc: 4,
    30              nextPC: 8,
    31              lo: 0,
    32              hi: 0,
    33              heap: 0,
    34              exitCode: 0,
    35              exited: false,
    36              step: 1,
    37              registers: registers
    38          });
    39          bytes memory proof =
    40              hex"3c10bfff3610fff0341100013c08ffff3508fffd34090003010950202d420001ae020008ae11000403e000080000000000000000000000000000000000000000ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3021ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a193440eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f839867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756afcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8923490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99cc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8beccda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d22733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd95a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3774df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618db8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
    41  
    42          bytes32 postState = mips.step(encodeState(state), proof, 0);
    43          assertNotEq(postState, bytes32(0));
    44      }
    45  
    46      function test_add_succeeds() external {
    47          uint32 insn = encodespec(17, 18, 8, 0x20); // add t0, s1, s2
    48          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
    49          state.registers[17] = 12;
    50          state.registers[18] = 20;
    51          bytes memory encodedState = encodeState(state);
    52  
    53          MIPS.State memory expect;
    54          expect.memRoot = state.memRoot;
    55          expect.pc = state.nextPC;
    56          expect.nextPC = state.nextPC + 4;
    57          expect.step = state.step + 1;
    58          expect.registers[8] = state.registers[17] + state.registers[18]; // t0
    59          expect.registers[17] = state.registers[17];
    60          expect.registers[18] = state.registers[18];
    61  
    62          bytes32 postState = mips.step(encodedState, proof, 0);
    63          assertEq(postState, outputState(expect), "unexpected post state");
    64      }
    65  
    66      function test_addu_succeeds() external {
    67          uint32 insn = encodespec(17, 18, 8, 0x21); // addu t0, s1, s2
    68          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
    69          state.registers[17] = 12;
    70          state.registers[18] = 20;
    71          bytes memory encodedState = encodeState(state);
    72  
    73          MIPS.State memory expect;
    74          expect.memRoot = state.memRoot;
    75          expect.pc = state.nextPC;
    76          expect.nextPC = state.nextPC + 4;
    77          expect.step = state.step + 1;
    78          expect.registers[8] = state.registers[17] + state.registers[18]; // t0
    79          expect.registers[17] = state.registers[17];
    80          expect.registers[18] = state.registers[18];
    81  
    82          bytes32 postState = mips.step(encodedState, proof, 0);
    83          assertEq(postState, outputState(expect), "unexpected post state");
    84      }
    85  
    86      function test_addi_succeeds() external {
    87          uint16 imm = 40;
    88          uint32 insn = encodeitype(0x8, 17, 8, imm); // addi t0, s1, 40
    89          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
    90          state.registers[8] = 1; // t0
    91          state.registers[17] = 4; // s1
    92          bytes memory encodedState = encodeState(state);
    93  
    94          MIPS.State memory expect;
    95          expect.memRoot = state.memRoot;
    96          expect.pc = state.nextPC;
    97          expect.nextPC = state.nextPC + 4;
    98          expect.step = state.step + 1;
    99          expect.registers[8] = state.registers[17] + imm;
   100          expect.registers[17] = state.registers[17];
   101  
   102          bytes32 postState = mips.step(encodedState, proof, 0);
   103          assertEq(postState, outputState(expect), "unexpected post state");
   104      }
   105  
   106      function test_addiSign_succeeds() external {
   107          uint16 imm = 0xfffe; // -2
   108          uint32 insn = encodeitype(0x8, 17, 8, imm); // addi t0, s1, 40
   109          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   110          state.registers[8] = 1; // t0
   111          state.registers[17] = 2; // s1
   112          bytes memory encodedState = encodeState(state);
   113  
   114          MIPS.State memory expect;
   115          expect.memRoot = state.memRoot;
   116          expect.pc = state.nextPC;
   117          expect.nextPC = state.nextPC + 4;
   118          expect.step = state.step + 1;
   119          expect.registers[8] = 0;
   120          expect.registers[17] = state.registers[17];
   121  
   122          bytes32 postState = mips.step(encodedState, proof, 0);
   123          assertEq(postState, outputState(expect), "unexpected post state");
   124      }
   125  
   126      function test_addui_succeeds() external {
   127          uint16 imm = 40;
   128          uint32 insn = encodeitype(0x9, 17, 8, imm); // addui t0, s1, 40
   129          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   130          state.registers[8] = 1; // t0
   131          state.registers[17] = 4; // s1
   132          bytes memory encodedState = encodeState(state);
   133  
   134          MIPS.State memory expect;
   135          expect.memRoot = state.memRoot;
   136          expect.pc = state.nextPC;
   137          expect.nextPC = state.nextPC + 4;
   138          expect.step = state.step + 1;
   139          expect.registers[8] = state.registers[17] + imm;
   140          expect.registers[17] = state.registers[17];
   141  
   142          bytes32 postState = mips.step(encodedState, proof, 0);
   143          assertEq(postState, outputState(expect), "unexpected post state");
   144      }
   145  
   146      function test_sub_succeeds() external {
   147          uint32 insn = encodespec(17, 18, 8, 0x22); // sub t0, s1, s2
   148          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   149          state.registers[17] = 20;
   150          state.registers[18] = 12;
   151          bytes memory encodedState = encodeState(state);
   152  
   153          MIPS.State memory expect;
   154          expect.memRoot = state.memRoot;
   155          expect.pc = state.nextPC;
   156          expect.nextPC = state.nextPC + 4;
   157          expect.step = state.step + 1;
   158          expect.registers[8] = state.registers[17] - state.registers[18]; // t0
   159          expect.registers[17] = state.registers[17];
   160          expect.registers[18] = state.registers[18];
   161  
   162          bytes32 postState = mips.step(encodedState, proof, 0);
   163          assertEq(postState, outputState(expect), "unexpected post state");
   164      }
   165  
   166      function test_subu_succeeds() external {
   167          uint32 insn = encodespec(17, 18, 8, 0x23); // subu t0, s1, s2
   168          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   169          state.registers[17] = 20;
   170          state.registers[18] = 12;
   171          bytes memory encodedState = encodeState(state);
   172  
   173          MIPS.State memory expect;
   174          expect.memRoot = state.memRoot;
   175          expect.pc = state.nextPC;
   176          expect.nextPC = state.nextPC + 4;
   177          expect.step = state.step + 1;
   178          expect.registers[8] = state.registers[17] - state.registers[18]; // t0
   179          expect.registers[17] = state.registers[17];
   180          expect.registers[18] = state.registers[18];
   181  
   182          bytes32 postState = mips.step(encodedState, proof, 0);
   183          assertEq(postState, outputState(expect), "unexpected post state");
   184      }
   185  
   186      function test_and_succeeds() external {
   187          uint32 insn = encodespec(17, 18, 8, 0x24); // and t0, s1, s2
   188          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   189          state.registers[17] = 1200;
   190          state.registers[18] = 490;
   191          bytes memory encodedState = encodeState(state);
   192  
   193          MIPS.State memory expect;
   194          expect.memRoot = state.memRoot;
   195          expect.pc = state.nextPC;
   196          expect.nextPC = state.nextPC + 4;
   197          expect.step = state.step + 1;
   198          expect.registers[8] = state.registers[17] & state.registers[18]; // t0
   199          expect.registers[17] = state.registers[17];
   200          expect.registers[18] = state.registers[18];
   201  
   202          bytes32 postState = mips.step(encodedState, proof, 0);
   203          assertEq(postState, outputState(expect), "unexpected post state");
   204      }
   205  
   206      function test_andi_succeeds() external {
   207          uint16 imm = 40;
   208          uint32 insn = encodeitype(0xc, 17, 8, imm); // andi t0, s1, 40
   209          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   210          state.registers[8] = 1; // t0
   211          state.registers[17] = 4; // s1
   212          bytes memory encodedState = encodeState(state);
   213  
   214          MIPS.State memory expect;
   215          expect.memRoot = state.memRoot;
   216          expect.pc = state.nextPC;
   217          expect.nextPC = state.nextPC + 4;
   218          expect.step = state.step + 1;
   219          expect.registers[8] = state.registers[17] & imm;
   220          expect.registers[17] = state.registers[17];
   221  
   222          bytes32 postState = mips.step(encodedState, proof, 0);
   223          assertEq(postState, outputState(expect), "unexpected post state");
   224      }
   225  
   226      function test_or_succeeds() external {
   227          uint32 insn = encodespec(17, 18, 8, 0x25); // or t0, s1, s2
   228          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   229          state.registers[17] = 1200;
   230          state.registers[18] = 490;
   231          bytes memory encodedState = encodeState(state);
   232  
   233          MIPS.State memory expect;
   234          expect.memRoot = state.memRoot;
   235          expect.pc = state.nextPC;
   236          expect.nextPC = state.nextPC + 4;
   237          expect.step = state.step + 1;
   238          expect.registers[8] = state.registers[17] | state.registers[18]; // t0
   239          expect.registers[17] = state.registers[17];
   240          expect.registers[18] = state.registers[18];
   241  
   242          bytes32 postState = mips.step(encodedState, proof, 0);
   243          assertEq(postState, outputState(expect), "unexpected post state");
   244      }
   245  
   246      function test_ori_succeeds() external {
   247          uint16 imm = 40;
   248          uint32 insn = encodeitype(0xd, 17, 8, imm); // ori t0, s1, 40
   249          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   250          state.registers[8] = 1; // t0
   251          state.registers[17] = 4; // s1
   252          bytes memory encodedState = encodeState(state);
   253  
   254          MIPS.State memory expect;
   255          expect.memRoot = state.memRoot;
   256          expect.pc = state.nextPC;
   257          expect.nextPC = state.nextPC + 4;
   258          expect.step = state.step + 1;
   259          expect.registers[8] = state.registers[17] | imm;
   260          expect.registers[17] = state.registers[17];
   261  
   262          bytes32 postState = mips.step(encodedState, proof, 0);
   263          assertEq(postState, outputState(expect), "unexpected post state");
   264      }
   265  
   266      function test_xor_succeeds() external {
   267          uint32 insn = encodespec(17, 18, 8, 0x26); // xor t0, s1, s2
   268          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   269          state.registers[17] = 1200;
   270          state.registers[18] = 490;
   271          bytes memory encodedState = encodeState(state);
   272  
   273          MIPS.State memory expect;
   274          expect.memRoot = state.memRoot;
   275          expect.pc = state.nextPC;
   276          expect.nextPC = state.nextPC + 4;
   277          expect.step = state.step + 1;
   278          expect.registers[8] = state.registers[17] ^ state.registers[18]; // t0
   279          expect.registers[17] = state.registers[17];
   280          expect.registers[18] = state.registers[18];
   281  
   282          bytes32 postState = mips.step(encodedState, proof, 0);
   283          assertEq(postState, outputState(expect), "unexpected post state");
   284      }
   285  
   286      function test_xori_succeeds() external {
   287          uint16 imm = 40;
   288          uint32 insn = encodeitype(0xe, 17, 8, imm); // xori t0, s1, 40
   289          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   290          state.registers[8] = 1; // t0
   291          state.registers[17] = 4; // s1
   292          bytes memory encodedState = encodeState(state);
   293  
   294          MIPS.State memory expect;
   295          expect.memRoot = state.memRoot;
   296          expect.pc = state.nextPC;
   297          expect.nextPC = state.nextPC + 4;
   298          expect.step = state.step + 1;
   299          expect.registers[8] = state.registers[17] ^ imm;
   300          expect.registers[17] = state.registers[17];
   301  
   302          bytes32 postState = mips.step(encodedState, proof, 0);
   303          assertEq(postState, outputState(expect), "unexpected post state");
   304      }
   305  
   306      function test_nor_succeeds() external {
   307          uint32 insn = encodespec(17, 18, 8, 0x27); // nor t0, s1, s2
   308          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   309          state.registers[17] = 1200;
   310          state.registers[18] = 490;
   311          bytes memory encodedState = encodeState(state);
   312  
   313          MIPS.State memory expect;
   314          expect.memRoot = state.memRoot;
   315          expect.pc = state.nextPC;
   316          expect.nextPC = state.nextPC + 4;
   317          expect.step = state.step + 1;
   318          expect.registers[8] = ~(state.registers[17] | state.registers[18]); // t0
   319          expect.registers[17] = state.registers[17];
   320          expect.registers[18] = state.registers[18];
   321  
   322          bytes32 postState = mips.step(encodedState, proof, 0);
   323          assertEq(postState, outputState(expect), "unexpected post state");
   324      }
   325  
   326      function test_slt_succeeds() external {
   327          uint32 insn = encodespec(17, 18, 8, 0x2a); // slt t0, s1, s2
   328          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   329          state.registers[17] = 0xFF_FF_FF_FE; // -2
   330          state.registers[18] = 5;
   331  
   332          MIPS.State memory expect;
   333          expect.memRoot = state.memRoot;
   334          expect.pc = state.nextPC;
   335          expect.nextPC = state.nextPC + 4;
   336          expect.step = state.step + 1;
   337          expect.registers[8] = 1; // t0
   338          expect.registers[17] = state.registers[17];
   339          expect.registers[18] = state.registers[18];
   340  
   341          bytes32 postState = mips.step(encodeState(state), proof, 0);
   342          assertEq(postState, outputState(expect), "unexpected post state");
   343  
   344          // swap and check again
   345          uint32 tmp = state.registers[17];
   346          state.registers[17] = state.registers[18];
   347          state.registers[18] = tmp;
   348          expect.registers[17] = state.registers[17];
   349          expect.registers[18] = state.registers[18];
   350          expect.registers[8] = 0; // t0
   351          postState = mips.step(encodeState(state), proof, 0);
   352          assertEq(postState, outputState(expect), "unexpected post state");
   353      }
   354  
   355      function test_sltu_succeeds() external {
   356          uint32 insn = encodespec(17, 18, 8, 0x2b); // sltu t0, s1, s2
   357          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   358          state.registers[17] = 1200;
   359          state.registers[18] = 490;
   360          bytes memory encodedState = encodeState(state);
   361  
   362          MIPS.State memory expect;
   363          expect.memRoot = state.memRoot;
   364          expect.pc = state.nextPC;
   365          expect.nextPC = state.nextPC + 4;
   366          expect.step = state.step + 1;
   367          expect.registers[8] = state.registers[17] < state.registers[18] ? 1 : 0; // t0
   368          expect.registers[17] = state.registers[17];
   369          expect.registers[18] = state.registers[18];
   370  
   371          bytes32 postState = mips.step(encodedState, proof, 0);
   372          assertEq(postState, outputState(expect), "unexpected post state");
   373      }
   374  
   375      function test_lb_succeeds() external {
   376          uint32 t1 = 0x100;
   377          uint32 insn = encodeitype(0x20, 0x9, 0x8, 0x4); // lb $t0, 4($t1)
   378          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0x12_00_00_00);
   379          state.registers[8] = 0; // t0
   380          state.registers[9] = t1;
   381          bytes memory encodedState = encodeState(state);
   382  
   383          MIPS.State memory expect;
   384          expect.memRoot = state.memRoot;
   385          expect.pc = state.nextPC;
   386          expect.nextPC = state.nextPC + 4;
   387          expect.step = state.step + 1;
   388          expect.registers[8] = 0x12; // t0
   389          expect.registers[9] = t1;
   390  
   391          bytes32 postState = mips.step(encodedState, proof, 0);
   392          assertEq(postState, outputState(expect), "unexpected post state");
   393      }
   394  
   395      function test_lh_succeeds() external {
   396          uint32 t1 = 0x100;
   397          uint32 val = 0x12_23_00_00;
   398          uint32 insn = encodeitype(0x21, 0x9, 0x8, 0x4); // lh $t0, 4($t1)
   399  
   400          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, val);
   401          state.registers[8] = 0; // t0
   402          state.registers[9] = t1;
   403          bytes memory encodedState = encodeState(state);
   404  
   405          MIPS.State memory expect;
   406          expect.memRoot = state.memRoot;
   407          expect.pc = state.nextPC;
   408          expect.nextPC = state.nextPC + 4;
   409          expect.step = state.step + 1;
   410          expect.registers[8] = 0x12_23; // t0
   411          expect.registers[9] = t1;
   412  
   413          bytes32 postState = mips.step(encodedState, proof, 0);
   414          assertEq(postState, outputState(expect), "unexpected post state");
   415      }
   416  
   417      function test_lw_succeeds() external {
   418          uint32 t1 = 0x100;
   419          uint32 val = 0x12_23_45_67;
   420          uint32 insn = encodeitype(0x23, 0x9, 0x8, 0x4); // lw $t0, 4($t1)
   421  
   422          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, val);
   423          state.registers[8] = 0; // t0
   424          state.registers[9] = t1;
   425          bytes memory encodedState = encodeState(state);
   426  
   427          MIPS.State memory expect;
   428          expect.memRoot = state.memRoot;
   429          expect.pc = state.nextPC;
   430          expect.nextPC = state.nextPC + 4;
   431          expect.step = state.step + 1;
   432          expect.registers[8] = val; // t0
   433          expect.registers[9] = t1;
   434  
   435          bytes32 postState = mips.step(encodedState, proof, 0);
   436          assertEq(postState, outputState(expect), "unexpected post state");
   437      }
   438  
   439      function test_lbu_succeeds() external {
   440          uint32 t1 = 0x100;
   441          uint32 insn = encodeitype(0x24, 0x9, 0x8, 0x4); // lbu $t0, 4($t1)
   442          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0x12_23_00_00);
   443          state.registers[8] = 0; // t0
   444          state.registers[9] = t1;
   445          bytes memory encodedState = encodeState(state);
   446  
   447          MIPS.State memory expect;
   448          expect.memRoot = state.memRoot;
   449          expect.pc = state.nextPC;
   450          expect.nextPC = state.nextPC + 4;
   451          expect.step = state.step + 1;
   452          expect.registers[8] = 0x12; // t0
   453          expect.registers[9] = t1;
   454  
   455          bytes32 postState = mips.step(encodedState, proof, 0);
   456          assertEq(postState, outputState(expect), "unexpected post state");
   457      }
   458  
   459      function test_lhu_succeeds() external {
   460          uint32 t1 = 0x100;
   461          uint32 insn = encodeitype(0x25, 0x9, 0x8, 0x4); // lhu $t0, 4($t1)
   462          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0x12_23_00_00);
   463          state.registers[8] = 0; // t0
   464          state.registers[9] = t1;
   465          bytes memory encodedState = encodeState(state);
   466  
   467          MIPS.State memory expect;
   468          expect.memRoot = state.memRoot;
   469          expect.pc = state.nextPC;
   470          expect.nextPC = state.nextPC + 4;
   471          expect.step = state.step + 1;
   472          expect.registers[8] = 0x12_23; // t0
   473          expect.registers[9] = t1;
   474  
   475          bytes32 postState = mips.step(encodedState, proof, 0);
   476          assertEq(postState, outputState(expect), "unexpected post state");
   477      }
   478  
   479      function test_lwl_succeeds() external {
   480          uint32 t1 = 0x100;
   481          uint32 insn = encodeitype(0x22, 0x9, 0x8, 0x4); // lwl $t0, 4($t1)
   482          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0x12_34_56_78);
   483          state.registers[8] = 0xaa_bb_cc_dd; // t0
   484          state.registers[9] = t1;
   485  
   486          MIPS.State memory expect;
   487          expect.memRoot = state.memRoot;
   488          expect.pc = state.nextPC;
   489          expect.nextPC = state.nextPC + 4;
   490          expect.step = state.step + 1;
   491          expect.registers[8] = 0x12_34_56_78; // t0
   492          expect.registers[9] = t1;
   493  
   494          bytes32 postState = mips.step(encodeState(state), proof, 0);
   495          assertEq(postState, outputState(expect), "unexpected post state");
   496  
   497          // test unaligned address
   498          insn = encodeitype(0x22, 0x9, 0x8, 0x5); // lwl $t0, 5($t1)
   499          (state.memRoot, proof) = ffi.getCannonMemoryProof(0, insn, t1 + 4, 0x12_34_56_78);
   500          expect.memRoot = state.memRoot;
   501          expect.registers[8] = 0x34_56_78_dd; // t0
   502          postState = mips.step(encodeState(state), proof, 0);
   503          assertEq(postState, outputState(expect), "unexpected post state");
   504      }
   505  
   506      function test_lwr_succeeds() external {
   507          uint32 t1 = 0x100;
   508          uint32 insn = encodeitype(0x26, 0x9, 0x8, 0x4); // lwr $t0, 4($t1)
   509          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0x12_34_56_78);
   510          state.registers[8] = 0xaa_bb_cc_dd; // t0
   511          state.registers[9] = t1;
   512  
   513          MIPS.State memory expect;
   514          expect.memRoot = state.memRoot;
   515          expect.pc = state.nextPC;
   516          expect.nextPC = state.nextPC + 4;
   517          expect.step = state.step + 1;
   518          expect.registers[8] = 0xaa_bb_cc_12; // t0
   519          expect.registers[9] = t1;
   520  
   521          bytes32 postState = mips.step(encodeState(state), proof, 0);
   522          assertEq(postState, outputState(expect), "unexpected post state");
   523  
   524          // test unaligned address
   525          insn = encodeitype(0x26, 0x9, 0x8, 0x5); // lwr $t0, 5($t1)
   526          (state.memRoot, proof) = ffi.getCannonMemoryProof(0, insn, t1 + 4, 0x12_34_56_78);
   527          expect.memRoot = state.memRoot;
   528          expect.registers[8] = 0xaa_bb_12_34; // t0
   529          postState = mips.step(encodeState(state), proof, 0);
   530          assertEq(postState, outputState(expect), "unexpected post state");
   531      }
   532  
   533      function test_sb_succeeds() external {
   534          uint32 t1 = 0x100;
   535          uint32 insn = encodeitype(0x28, 0x9, 0x8, 0x4); // sb $t0, 4($t1)
   536          // note. cannon memory is zero-initalized. mem[t+4] = 0 is a no-op
   537          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0);
   538          state.registers[8] = 0xaa_bb_cc_dd; // t0
   539          state.registers[9] = t1;
   540  
   541          MIPS.State memory expect;
   542          (expect.memRoot,) = ffi.getCannonMemoryProof(0, insn, t1 + 4, 0xdd_00_00_00);
   543          expect.pc = state.nextPC;
   544          expect.nextPC = state.nextPC + 4;
   545          expect.step = state.step + 1;
   546          expect.registers[8] = state.registers[8];
   547          expect.registers[9] = state.registers[9];
   548  
   549          bytes32 postState = mips.step(encodeState(state), proof, 0);
   550          assertEq(postState, outputState(expect), "unexpected post state");
   551      }
   552  
   553      function test_sh_succeeds() external {
   554          uint32 t1 = 0x100;
   555          uint32 insn = encodeitype(0x29, 0x9, 0x8, 0x4); // sh $t0, 4($t1)
   556          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0);
   557          state.registers[8] = 0xaa_bb_cc_dd; // t0
   558          state.registers[9] = t1;
   559  
   560          MIPS.State memory expect;
   561          (expect.memRoot,) = ffi.getCannonMemoryProof(0, insn, t1 + 4, 0xcc_dd_00_00);
   562          expect.pc = state.nextPC;
   563          expect.nextPC = state.nextPC + 4;
   564          expect.step = state.step + 1;
   565          expect.registers[8] = state.registers[8];
   566          expect.registers[9] = state.registers[9];
   567  
   568          bytes32 postState = mips.step(encodeState(state), proof, 0);
   569          assertEq(postState, outputState(expect), "unexpected post state");
   570      }
   571  
   572      function test_swl_succeeds() external {
   573          uint32 t1 = 0x100;
   574          uint32 insn = encodeitype(0x2a, 0x9, 0x8, 0x4); // swl $t0, 4($t1)
   575          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0);
   576          state.registers[8] = 0xaa_bb_cc_dd; // t0
   577          state.registers[9] = t1;
   578  
   579          MIPS.State memory expect;
   580          (expect.memRoot,) = ffi.getCannonMemoryProof(0, insn, t1 + 4, 0xaa_bb_cc_dd);
   581          expect.pc = state.nextPC;
   582          expect.nextPC = state.nextPC + 4;
   583          expect.step = state.step + 1;
   584          expect.registers[8] = state.registers[8];
   585          expect.registers[9] = state.registers[9];
   586  
   587          bytes32 postState = mips.step(encodeState(state), proof, 0);
   588          assertEq(postState, outputState(expect), "unexpected post state");
   589      }
   590  
   591      function test_sw_succeeds() external {
   592          uint32 t1 = 0x100;
   593          uint32 insn = encodeitype(0x2b, 0x9, 0x8, 0x4); // sw $t0, 4($t1)
   594          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0);
   595          state.registers[8] = 0xaa_bb_cc_dd; // t0
   596          state.registers[9] = t1;
   597  
   598          MIPS.State memory expect;
   599          (expect.memRoot,) = ffi.getCannonMemoryProof(0, insn, t1 + 4, 0xaa_bb_cc_dd);
   600          expect.pc = state.nextPC;
   601          expect.nextPC = state.nextPC + 4;
   602          expect.step = state.step + 1;
   603          expect.registers[8] = state.registers[8];
   604          expect.registers[9] = state.registers[9];
   605  
   606          bytes32 postState = mips.step(encodeState(state), proof, 0);
   607          assertEq(postState, outputState(expect), "unexpected post state");
   608      }
   609  
   610      function test_swr_succeeds() external {
   611          uint32 t1 = 0x100;
   612          uint32 insn = encodeitype(0x2e, 0x9, 0x8, 0x5); // swr $t0, 5($t1)
   613          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0);
   614          state.registers[8] = 0xaa_bb_cc_dd; // t0
   615          state.registers[9] = t1;
   616  
   617          MIPS.State memory expect;
   618          (expect.memRoot,) = ffi.getCannonMemoryProof(0, insn, t1 + 4, 0xcc_dd_00_00);
   619          expect.pc = state.nextPC;
   620          expect.nextPC = state.nextPC + 4;
   621          expect.step = state.step + 1;
   622          expect.registers[8] = state.registers[8];
   623          expect.registers[9] = state.registers[9];
   624  
   625          bytes32 postState = mips.step(encodeState(state), proof, 0);
   626          assertEq(postState, outputState(expect), "unexpected post state");
   627      }
   628  
   629      function test_ll_succeeds() external {
   630          uint32 t1 = 0x100;
   631          uint32 val = 0x12_23_45_67;
   632          uint32 insn = encodeitype(0x30, 0x9, 0x8, 0x4); // ll $t0, 4($t1)
   633  
   634          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, val);
   635          state.registers[8] = 0; // t0
   636          state.registers[9] = t1;
   637          bytes memory encodedState = encodeState(state);
   638  
   639          MIPS.State memory expect;
   640          expect.memRoot = state.memRoot;
   641          expect.pc = state.nextPC;
   642          expect.nextPC = state.nextPC + 4;
   643          expect.step = state.step + 1;
   644          expect.registers[8] = val; // t0
   645          expect.registers[9] = t1;
   646  
   647          bytes32 postState = mips.step(encodedState, proof, 0);
   648          assertEq(postState, outputState(expect), "unexpected post state");
   649      }
   650  
   651      function test_sc_succeeds() external {
   652          uint32 t1 = 0x100;
   653          uint32 insn = encodeitype(0x38, 0x9, 0x8, 0x4); // sc $t0, 4($t1)
   654          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, t1 + 4, 0);
   655          state.registers[8] = 0xaa_bb_cc_dd; // t0
   656          state.registers[9] = t1;
   657  
   658          MIPS.State memory expect;
   659          (expect.memRoot,) = ffi.getCannonMemoryProof(0, insn, t1 + 4, 0xaa_bb_cc_dd);
   660          expect.pc = state.nextPC;
   661          expect.nextPC = state.nextPC + 4;
   662          expect.step = state.step + 1;
   663          expect.registers[8] = 0x1;
   664          expect.registers[9] = state.registers[9];
   665  
   666          bytes32 postState = mips.step(encodeState(state), proof, 0);
   667          assertEq(postState, outputState(expect), "unexpected post state");
   668      }
   669  
   670      function test_movn_succeeds() external {
   671          // test mips mov instruction
   672          uint32 insn = encodespec(0x9, 0xa, 0x8, 0xb); // movn $t0, $t1, $t2
   673          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   674          state.registers[8] = 0xa; // t0
   675          state.registers[9] = 0xb; // t1
   676          state.registers[10] = 0x1; // t2
   677  
   678          MIPS.State memory expect;
   679          expect.memRoot = state.memRoot;
   680          expect.pc = state.nextPC;
   681          expect.nextPC = state.nextPC + 4;
   682          expect.step = state.step + 1;
   683          expect.registers[8] = state.registers[9];
   684          expect.registers[9] = state.registers[9];
   685          expect.registers[10] = state.registers[10];
   686  
   687          bytes32 postState = mips.step(encodeState(state), proof, 0);
   688          assertEq(postState, outputState(expect), "unexpected post state");
   689  
   690          state.registers[10] = 0x0; // t2
   691          expect.registers[10] = 0x0; // t2
   692          expect.registers[8] = state.registers[8];
   693          postState = mips.step(encodeState(state), proof, 0);
   694          assertEq(postState, outputState(expect), "unexpected post state");
   695      }
   696  
   697      function test_movz_succeeds() external {
   698          // test mips mov instruction
   699          uint32 insn = encodespec(0x9, 0xa, 0x8, 0xa); // movz $t0, $t1, $t2
   700          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   701          state.registers[8] = 0xa; // t0
   702          state.registers[9] = 0xb; // t1
   703          state.registers[10] = 0x0; // t2
   704  
   705          MIPS.State memory expect;
   706          expect.memRoot = state.memRoot;
   707          expect.pc = state.nextPC;
   708          expect.nextPC = state.nextPC + 4;
   709          expect.step = state.step + 1;
   710          expect.registers[8] = state.registers[9];
   711          expect.registers[9] = state.registers[9];
   712          expect.registers[10] = state.registers[10];
   713  
   714          bytes32 postState = mips.step(encodeState(state), proof, 0);
   715          assertEq(postState, outputState(expect), "unexpected post state");
   716  
   717          state.registers[10] = 0x1; // t2
   718          expect.registers[10] = 0x1; // t2
   719          expect.registers[8] = state.registers[8];
   720          postState = mips.step(encodeState(state), proof, 0);
   721          assertEq(postState, outputState(expect), "unexpected post state");
   722      }
   723  
   724      function test_mflo_succeeds() external {
   725          uint32 insn = encodespec(0x0, 0x0, 0x8, 0x12); // mflo $t0
   726          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   727          state.lo = 0xdeadbeef;
   728  
   729          MIPS.State memory expect;
   730          expect.memRoot = state.memRoot;
   731          expect.pc = state.nextPC;
   732          expect.nextPC = state.nextPC + 4;
   733          expect.step = state.step + 1;
   734          expect.lo = state.lo;
   735          expect.registers[8] = state.lo;
   736  
   737          bytes32 postState = mips.step(encodeState(state), proof, 0);
   738          assertEq(postState, outputState(expect), "unexpected post state");
   739      }
   740  
   741      function test_mfhi_succeeds() external {
   742          uint32 insn = encodespec(0x0, 0x0, 0x8, 0x10); // mfhi $t0
   743          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   744          state.hi = 0xdeadbeef;
   745  
   746          MIPS.State memory expect;
   747          expect.memRoot = state.memRoot;
   748          expect.pc = state.nextPC;
   749          expect.nextPC = state.nextPC + 4;
   750          expect.step = state.step + 1;
   751          expect.hi = state.hi;
   752          expect.registers[8] = state.hi;
   753  
   754          bytes32 postState = mips.step(encodeState(state), proof, 0);
   755          assertEq(postState, outputState(expect), "unexpected post state");
   756      }
   757  
   758      function test_mthi_succeeds() external {
   759          uint32 insn = encodespec(0x8, 0x0, 0x0, 0x11); // mthi $t0
   760          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   761          state.registers[8] = 0xdeadbeef; // t0
   762  
   763          MIPS.State memory expect;
   764          expect.memRoot = state.memRoot;
   765          expect.pc = state.nextPC;
   766          expect.nextPC = state.nextPC + 4;
   767          expect.step = state.step + 1;
   768          expect.hi = state.registers[8];
   769          expect.registers[8] = state.registers[8];
   770  
   771          bytes32 postState = mips.step(encodeState(state), proof, 0);
   772          assertEq(postState, outputState(expect), "unexpected post state");
   773      }
   774  
   775      function test_mtlo_succeeds() external {
   776          uint32 insn = encodespec(0x8, 0x0, 0x0, 0x13); // mtlo $t0
   777          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   778          state.registers[8] = 0xdeadbeef; // t0
   779  
   780          MIPS.State memory expect;
   781          expect.memRoot = state.memRoot;
   782          expect.pc = state.nextPC;
   783          expect.nextPC = state.nextPC + 4;
   784          expect.step = state.step + 1;
   785          expect.lo = state.registers[8];
   786          expect.registers[8] = state.registers[8];
   787  
   788          bytes32 postState = mips.step(encodeState(state), proof, 0);
   789          assertEq(postState, outputState(expect), "unexpected post state");
   790      }
   791  
   792      function test_mul_succeeds() external {
   793          uint32 insn = encodespec2(0x9, 0xa, 0x8, 0x2); // mul t0, t1, t2
   794          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   795          state.registers[9] = 5; // t1
   796          state.registers[10] = 2; // t2
   797  
   798          MIPS.State memory expect;
   799          expect.memRoot = state.memRoot;
   800          expect.pc = state.nextPC;
   801          expect.nextPC = state.nextPC + 4;
   802          expect.step = state.step + 1;
   803          expect.registers[8] = state.registers[9] * state.registers[10]; // t0
   804          expect.registers[9] = 5;
   805          expect.registers[10] = 2;
   806  
   807          bytes32 postState = mips.step(encodeState(state), proof, 0);
   808          assertEq(postState, outputState(expect), "unexpected post state");
   809      }
   810  
   811      function test_mult_succeeds() external {
   812          uint32 insn = encodespec(0x9, 0xa, 0x0, 0x18); // mult t1, t2
   813          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   814          state.registers[9] = 0x0F_FF_00_00; // t1
   815          state.registers[10] = 100; // t2
   816  
   817          MIPS.State memory expect;
   818          expect.memRoot = state.memRoot;
   819          expect.pc = state.nextPC;
   820          expect.nextPC = state.nextPC + 4;
   821          expect.step = state.step + 1;
   822          expect.registers[9] = state.registers[9];
   823          expect.registers[10] = state.registers[10];
   824          expect.lo = 0x3F_9C_00_00;
   825          expect.hi = 0x6;
   826  
   827          bytes memory enc = encodeState(state);
   828          bytes32 postState = mips.step(enc, proof, 0);
   829          assertEq(postState, outputState(expect), "unexpected post state");
   830      }
   831  
   832      function test_multu_succeeds() external {
   833          uint32 insn = encodespec(0x9, 0xa, 0x0, 0x19); // multu t1, t2
   834          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   835          state.registers[9] = 0x0F_FF_00_00; // t1
   836          state.registers[10] = 100; // t2
   837  
   838          MIPS.State memory expect;
   839          expect.memRoot = state.memRoot;
   840          expect.pc = state.nextPC;
   841          expect.nextPC = state.nextPC + 4;
   842          expect.step = state.step + 1;
   843          expect.registers[9] = state.registers[9];
   844          expect.registers[10] = state.registers[10];
   845          expect.lo = 0x3F_9C_00_00;
   846          expect.hi = 0x6;
   847  
   848          bytes memory enc = encodeState(state);
   849          bytes32 postState = mips.step(enc, proof, 0);
   850          assertEq(postState, outputState(expect), "unexpected post state");
   851      }
   852  
   853      function test_div_succeeds() external {
   854          uint32 insn = encodespec(0x9, 0xa, 0x0, 0x1a); // div t1, t2
   855          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   856          state.registers[9] = 5; // t1
   857          state.registers[10] = 2; // t2
   858  
   859          MIPS.State memory expect;
   860          expect.memRoot = state.memRoot;
   861          expect.pc = state.nextPC;
   862          expect.nextPC = state.nextPC + 4;
   863          expect.step = state.step + 1;
   864          expect.registers[9] = state.registers[9];
   865          expect.registers[10] = state.registers[10];
   866          expect.lo = 2;
   867          expect.hi = 1;
   868  
   869          bytes memory enc = encodeState(state);
   870          bytes32 postState = mips.step(enc, proof, 0);
   871          assertEq(postState, outputState(expect), "unexpected post state");
   872      }
   873  
   874      function test_divu_succeeds() external {
   875          uint32 insn = encodespec(0x9, 0xa, 0x0, 0x1b); // divu t1, t2
   876          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   877          state.registers[9] = 5; // t1
   878          state.registers[10] = 2; // t2
   879  
   880          MIPS.State memory expect;
   881          expect.memRoot = state.memRoot;
   882          expect.pc = state.nextPC;
   883          expect.nextPC = state.nextPC + 4;
   884          expect.step = state.step + 1;
   885          expect.registers[9] = state.registers[9];
   886          expect.registers[10] = state.registers[10];
   887          expect.lo = 2;
   888          expect.hi = 1;
   889  
   890          bytes memory enc = encodeState(state);
   891          bytes32 postState = mips.step(enc, proof, 0);
   892          assertEq(postState, outputState(expect), "unexpected post state");
   893      }
   894  
   895      function test_beq_succeeds() external {
   896          uint16 boff = 0x10;
   897          uint32 insn = encodeitype(0x4, 0x9, 0x8, boff); // beq $t0, $t1, 16
   898          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   899          state.registers[8] = 0xdeadbeef; // t0
   900          state.registers[9] = 0xdeadbeef; // t1
   901  
   902          MIPS.State memory expect;
   903          expect.memRoot = state.memRoot;
   904          expect.pc = state.nextPC;
   905          expect.nextPC = state.nextPC + (uint32(boff) << 2);
   906          expect.step = state.step + 1;
   907          expect.registers[8] = 0xdeadbeef;
   908          expect.registers[9] = 0xdeadbeef;
   909  
   910          bytes32 postState = mips.step(encodeState(state), proof, 0);
   911          assertEq(postState, outputState(expect), "unexpected post state");
   912  
   913          // branch not taken
   914          state.registers[8] = 0xaa;
   915          expect.registers[8] = 0xaa;
   916          expect.nextPC = state.nextPC + 4;
   917          postState = mips.step(encodeState(state), proof, 0);
   918          assertEq(postState, outputState(expect), "unexpected post state");
   919      }
   920  
   921      function test_bne_succeeds() external {
   922          uint16 boff = 0x10;
   923          uint32 insn = encodeitype(0x5, 0x9, 0x8, boff); // bne $t0, $t1, 16
   924          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   925          state.registers[8] = 0xdeadbeef; // t0
   926          state.registers[9] = 0xaa; // t1
   927  
   928          MIPS.State memory expect;
   929          expect.memRoot = state.memRoot;
   930          expect.pc = state.nextPC;
   931          expect.nextPC = state.nextPC + (uint32(boff) << 2);
   932          expect.step = state.step + 1;
   933          expect.registers[8] = 0xdeadbeef;
   934          expect.registers[9] = 0xaa;
   935  
   936          bytes32 postState = mips.step(encodeState(state), proof, 0);
   937          assertEq(postState, outputState(expect), "unexpected post state");
   938      }
   939  
   940      function test_blez_succeeds() external {
   941          uint16 boff = 0x10;
   942          uint32 insn = encodeitype(0x6, 0x8, 0x0, boff); // blez $t0, 16
   943          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   944          state.registers[8] = 0; // t0
   945  
   946          MIPS.State memory expect;
   947          expect.memRoot = state.memRoot;
   948          expect.pc = state.nextPC;
   949          expect.nextPC = state.nextPC + (uint32(boff) << 2);
   950          expect.step = state.step + 1;
   951          expect.registers[8] = 0;
   952  
   953          bytes32 postState = mips.step(encodeState(state), proof, 0);
   954          assertEq(postState, outputState(expect), "unexpected post state");
   955      }
   956  
   957      function test_bgtz_succeeds() external {
   958          uint16 boff = 0xa0;
   959          uint32 insn = encodeitype(0x7, 0x8, 0x0, boff); // bgtz $t0, 0xa0
   960          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   961          state.registers[8] = 1; // t0
   962  
   963          MIPS.State memory expect;
   964          expect.memRoot = state.memRoot;
   965          expect.pc = state.nextPC;
   966          expect.nextPC = state.nextPC + (uint32(boff) << 2);
   967          expect.step = state.step + 1;
   968          expect.registers[8] = 1;
   969  
   970          bytes memory enc = encodeState(state);
   971          bytes32 postState = mips.step(enc, proof, 0);
   972          assertEq(postState, outputState(expect), "unexpected post state");
   973      }
   974  
   975      function test_bltz_succeeds() external {
   976          uint16 boff = 0x10;
   977          uint32 insn = encodeitype(0x1, 0x8, 0x0, boff); // bltz $t0, 16
   978          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   979          state.registers[8] = 0xF0_00_00_00; // t0
   980  
   981          MIPS.State memory expect;
   982          expect.memRoot = state.memRoot;
   983          expect.pc = state.nextPC;
   984          expect.nextPC = state.nextPC + (uint32(boff) << 2);
   985          expect.step = state.step + 1;
   986          expect.registers[8] = 0xF0_00_00_00;
   987  
   988          bytes32 postState = mips.step(encodeState(state), proof, 0);
   989          assertEq(postState, outputState(expect), "unexpected post state");
   990      }
   991  
   992      function test_bgez_succeeds() external {
   993          uint16 boff = 0x10;
   994          uint32 insn = encodeitype(0x1, 0x8, 0x1, boff); // bgez $t0, 16
   995          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
   996          state.registers[8] = 0x00_00_00_01; // t0
   997  
   998          MIPS.State memory expect;
   999          expect.memRoot = state.memRoot;
  1000          expect.pc = state.nextPC;
  1001          expect.nextPC = state.nextPC + (uint32(boff) << 2);
  1002          expect.step = state.step + 1;
  1003          expect.registers[8] = 0x00_00_00_01;
  1004  
  1005          bytes32 postState = mips.step(encodeState(state), proof, 0);
  1006          assertEq(postState, outputState(expect), "unexpected post state");
  1007      }
  1008  
  1009      function test_jump_succeeds() external {
  1010          uint32 label = 0x02_00_00_02; // set the 26th bit to assert no sign extension
  1011          uint32 insn = uint32(0x08_00_00_00) | label; // j label
  1012          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1013  
  1014          MIPS.State memory expect;
  1015          expect.memRoot = state.memRoot;
  1016          expect.pc = state.nextPC;
  1017          expect.nextPC = label << 2;
  1018          expect.step = state.step + 1;
  1019  
  1020          bytes32 postState = mips.step(encodeState(state), proof, 0);
  1021          assertEq(postState, outputState(expect), "unexpected post state");
  1022      }
  1023  
  1024      function test_jump_nonzeroRegion_succeeds() external {
  1025          uint32 pcRegion1 = 0x10000000;
  1026          uint32 label = 0x2;
  1027          uint32 insn = uint32(0x08_00_00_00) | label; // j label
  1028          (MIPS.State memory state, bytes memory proof) = constructMIPSState(pcRegion1, insn, 0x4, 0);
  1029  
  1030          MIPS.State memory expect;
  1031          expect.memRoot = state.memRoot;
  1032          expect.pc = state.nextPC;
  1033          expect.nextPC = (state.nextPC & 0xF0_00_00_00) | (uint32(label) << 2);
  1034          expect.step = state.step + 1;
  1035  
  1036          bytes memory witness = encodeState(state);
  1037          bytes32 postState = mips.step(witness, proof, 0);
  1038          assertEq(postState, outputState(expect), "unexpected post state");
  1039      }
  1040  
  1041      function test_jal_succeeds() external {
  1042          uint32 label = 0x02_00_00_02; // set the 26th bit to assert no sign extension
  1043          uint32 insn = uint32(0x0c_00_00_00) | label; // jal label
  1044          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1045  
  1046          MIPS.State memory expect;
  1047          expect.memRoot = state.memRoot;
  1048          expect.pc = state.nextPC;
  1049          expect.nextPC = label << 2;
  1050          expect.step = state.step + 1;
  1051          expect.registers[31] = state.pc + 8; // ra
  1052  
  1053          bytes32 postState = mips.step(encodeState(state), proof, 0);
  1054          assertEq(postState, outputState(expect), "unexpected post state");
  1055      }
  1056  
  1057      function test_jal_nonzeroRegion_succeeds() external {
  1058          uint32 pcRegion1 = 0x10000000;
  1059          uint32 label = 0x2;
  1060          uint32 insn = uint32(0x0c_00_00_00) | label; // jal label
  1061          (MIPS.State memory state, bytes memory proof) = constructMIPSState(pcRegion1, insn, 0x4, 0);
  1062  
  1063          MIPS.State memory expect;
  1064          expect.memRoot = state.memRoot;
  1065          expect.pc = state.nextPC;
  1066          expect.nextPC = (state.nextPC & 0xF0_00_00_00) | (uint32(label) << 2);
  1067          expect.step = state.step + 1;
  1068          expect.registers[31] = state.pc + 8; // ra
  1069  
  1070          bytes32 postState = mips.step(encodeState(state), proof, 0);
  1071          assertEq(postState, outputState(expect), "unexpected post state");
  1072      }
  1073  
  1074      function test_jr_succeeds() external {
  1075          uint16 tgt = 0x34;
  1076          uint32 insn = encodespec(0x8, 0, 0, 0x8); // jr t0
  1077          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1078          state.registers[8] = tgt;
  1079  
  1080          MIPS.State memory expect;
  1081          expect.memRoot = state.memRoot;
  1082          expect.pc = state.nextPC;
  1083          expect.nextPC = tgt;
  1084          expect.step = state.step + 1;
  1085          expect.registers[8] = tgt;
  1086  
  1087          bytes32 postState = mips.step(encodeState(state), proof, 0);
  1088          assertEq(postState, outputState(expect), "unexpected post state");
  1089      }
  1090  
  1091      function test_jalr_succeeds() external {
  1092          uint16 tgt = 0x34;
  1093          uint32 insn = encodespec(0x8, 0, 0x9, 0x9); // jalr t1, t0
  1094          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1095          state.registers[8] = tgt; // t0
  1096  
  1097          MIPS.State memory expect;
  1098          expect.memRoot = state.memRoot;
  1099          expect.pc = state.nextPC;
  1100          expect.nextPC = tgt;
  1101          expect.step = state.step + 1;
  1102          expect.registers[8] = tgt;
  1103          expect.registers[9] = state.pc + 8; // t1
  1104  
  1105          bytes32 postState = mips.step(encodeState(state), proof, 0);
  1106          assertEq(postState, outputState(expect), "unexpected post state");
  1107      }
  1108  
  1109      function test_sll_succeeds() external {
  1110          uint8 shiftamt = 4;
  1111          uint32 insn = encodespec(0x0, 0x9, 0x8, uint16(shiftamt) << 6); // sll t0, t1, 3
  1112          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1113          state.registers[9] = 0x20; // t1
  1114  
  1115          MIPS.State memory expect;
  1116          expect.memRoot = state.memRoot;
  1117          expect.pc = state.nextPC;
  1118          expect.nextPC = state.nextPC + 4;
  1119          expect.step = state.step + 1;
  1120          expect.registers[8] = state.registers[9] << shiftamt;
  1121          expect.registers[9] = state.registers[9];
  1122  
  1123          bytes memory enc = encodeState(state);
  1124          bytes32 postState = mips.step(enc, proof, 0);
  1125          assertEq(postState, outputState(expect), "unexpected post state");
  1126      }
  1127  
  1128      function test_srl_succeeds() external {
  1129          uint8 shiftamt = 4;
  1130          uint32 insn = encodespec(0x0, 0x9, 0x8, uint16(shiftamt) << 6 | 2); // srl t0, t1, 3
  1131          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1132          state.registers[9] = 0x20; // t1
  1133  
  1134          MIPS.State memory expect;
  1135          expect.memRoot = state.memRoot;
  1136          expect.pc = state.nextPC;
  1137          expect.nextPC = state.nextPC + 4;
  1138          expect.step = state.step + 1;
  1139          expect.registers[8] = state.registers[9] >> shiftamt;
  1140          expect.registers[9] = state.registers[9];
  1141  
  1142          bytes memory enc = encodeState(state);
  1143          bytes32 postState = mips.step(enc, proof, 0);
  1144          assertEq(postState, outputState(expect), "unexpected post state");
  1145      }
  1146  
  1147      function test_sra_succeeds() external {
  1148          uint8 shiftamt = 4;
  1149          uint32 insn = encodespec(0x0, 0x9, 0x8, uint16(shiftamt) << 6 | 3); // sra t0, t1, 3
  1150          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1151          state.registers[9] = 0x80_00_00_20; // t1
  1152  
  1153          MIPS.State memory expect;
  1154          expect.memRoot = state.memRoot;
  1155          expect.pc = state.nextPC;
  1156          expect.nextPC = state.nextPC + 4;
  1157          expect.step = state.step + 1;
  1158          expect.registers[8] = 0xF8_00_00_02; // 4 shifts while preserving sign bit
  1159          expect.registers[9] = state.registers[9];
  1160  
  1161          bytes memory enc = encodeState(state);
  1162          bytes32 postState = mips.step(enc, proof, 0);
  1163          assertEq(postState, outputState(expect), "unexpected post state");
  1164      }
  1165  
  1166      function test_sllv_succeeds() external {
  1167          uint32 insn = encodespec(0xa, 0x9, 0x8, 4); // sllv t0, t1, t2
  1168          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1169          state.registers[9] = 0x20; // t1
  1170          state.registers[10] = 4; // t2
  1171  
  1172          MIPS.State memory expect;
  1173          expect.memRoot = state.memRoot;
  1174          expect.pc = state.nextPC;
  1175          expect.nextPC = state.nextPC + 4;
  1176          expect.step = state.step + 1;
  1177          expect.registers[8] = state.registers[9] << state.registers[10]; // t0
  1178          expect.registers[9] = state.registers[9];
  1179          expect.registers[10] = state.registers[10];
  1180  
  1181          bytes memory enc = encodeState(state);
  1182          bytes32 postState = mips.step(enc, proof, 0);
  1183          assertEq(postState, outputState(expect), "unexpected post state");
  1184      }
  1185  
  1186      function test_srlv_succeeds() external {
  1187          uint32 insn = encodespec(0xa, 0x9, 0x8, 6); // srlv t0, t1, t2
  1188          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1189          state.registers[9] = 0x20_00; // t1
  1190          state.registers[10] = 4; // t2
  1191  
  1192          MIPS.State memory expect;
  1193          expect.memRoot = state.memRoot;
  1194          expect.pc = state.nextPC;
  1195          expect.nextPC = state.nextPC + 4;
  1196          expect.step = state.step + 1;
  1197          expect.registers[8] = state.registers[9] >> state.registers[10]; // t0
  1198          expect.registers[9] = state.registers[9];
  1199          expect.registers[10] = state.registers[10];
  1200  
  1201          bytes memory enc = encodeState(state);
  1202          bytes32 postState = mips.step(enc, proof, 0);
  1203          assertEq(postState, outputState(expect), "unexpected post state");
  1204      }
  1205  
  1206      function test_srav_succeeds() external {
  1207          uint32 insn = encodespec(0xa, 0x9, 0x8, 7); // srav t0, t1, t2
  1208          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1209          state.registers[9] = 0x20_00; // t1
  1210          state.registers[10] = 4; // t2
  1211  
  1212          MIPS.State memory expect;
  1213          expect.memRoot = state.memRoot;
  1214          expect.pc = state.nextPC;
  1215          expect.nextPC = state.nextPC + 4;
  1216          expect.step = state.step + 1;
  1217          expect.registers[8] = state.registers[9] >> state.registers[10]; // t0
  1218          expect.registers[9] = state.registers[9];
  1219          expect.registers[10] = state.registers[10];
  1220  
  1221          bytes memory enc = encodeState(state);
  1222          bytes32 postState = mips.step(enc, proof, 0);
  1223          assertEq(postState, outputState(expect), "unexpected post state");
  1224      }
  1225  
  1226      function test_lui_succeeds() external {
  1227          uint32 insn = encodeitype(0xf, 0x0, 0x8, 0x4); // lui $t0, 0x04
  1228          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1229          bytes memory encodedState = encodeState(state);
  1230  
  1231          MIPS.State memory expect;
  1232          expect.memRoot = state.memRoot;
  1233          expect.pc = state.nextPC;
  1234          expect.nextPC = state.nextPC + 4;
  1235          expect.step = state.step + 1;
  1236          expect.registers[8] = 0x00_04_00_00; // t0
  1237  
  1238          bytes32 postState = mips.step(encodedState, proof, 0);
  1239          assertEq(postState, outputState(expect), "unexpected post state");
  1240      }
  1241  
  1242      function test_clo_succeeds() external {
  1243          uint32 insn = encodespec2(0x9, 0x0, 0x8, 0x21); // clo t0, t1
  1244          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1245          state.registers[9] = 0xFF_00_00_00; // t1
  1246  
  1247          MIPS.State memory expect;
  1248          expect.memRoot = state.memRoot;
  1249          expect.pc = state.nextPC;
  1250          expect.nextPC = state.nextPC + 4;
  1251          expect.step = state.step + 1;
  1252          expect.registers[8] = 8; // t0
  1253          expect.registers[9] = state.registers[9];
  1254  
  1255          bytes32 postState = mips.step(encodeState(state), proof, 0);
  1256          assertEq(postState, outputState(expect), "unexpected post state");
  1257      }
  1258  
  1259      function test_clz_succeeds() external {
  1260          uint32 insn = encodespec2(0x9, 0x0, 0x8, 0x20); // clz t0, t1
  1261          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1262          state.registers[9] = 0x00_00_F0_00; // t1
  1263  
  1264          MIPS.State memory expect;
  1265          expect.memRoot = state.memRoot;
  1266          expect.pc = state.nextPC;
  1267          expect.nextPC = state.nextPC + 4;
  1268          expect.step = state.step + 1;
  1269          expect.registers[8] = 16; // t0
  1270          expect.registers[9] = state.registers[9];
  1271  
  1272          bytes32 postState = mips.step(encodeState(state), proof, 0);
  1273          assertEq(postState, outputState(expect), "unexpected post state");
  1274      }
  1275  
  1276      function test_preimage_read_succeeds() external {
  1277          uint32 pc = 0x0;
  1278          uint32 insn = 0x0000000c; // syscall
  1279          uint32 a1 = 0x4;
  1280          uint32 a1_val = 0x0000abba;
  1281          (bytes32 memRoot, bytes memory proof) = ffi.getCannonMemoryProof(pc, insn, a1, a1_val);
  1282  
  1283          uint32[32] memory registers;
  1284          registers[2] = 4003; // read syscall
  1285          registers[4] = 5; // fd
  1286          registers[5] = a1; // addr
  1287          registers[6] = 4; // count
  1288  
  1289          MIPS.State memory state = MIPS.State({
  1290              memRoot: memRoot,
  1291              preimageKey: bytes32(uint256(1) << 248 | 0x01),
  1292              preimageOffset: 8, // start reading past the pre-image length prefix
  1293              pc: pc,
  1294              nextPC: pc + 4,
  1295              lo: 0,
  1296              hi: 0,
  1297              heap: 0,
  1298              exitCode: 0,
  1299              exited: false,
  1300              step: 1,
  1301              registers: registers
  1302          });
  1303          bytes memory encodedState = encodeState(state);
  1304  
  1305          // prime the pre-image oracle
  1306          bytes32 word = bytes32(uint256(0xdeadbeef) << 224);
  1307          uint8 size = 4;
  1308          uint8 partOffset = 8;
  1309          oracle.loadLocalData(uint256(state.preimageKey), 0, word, size, partOffset);
  1310  
  1311          MIPS.State memory expect = state;
  1312          expect.preimageOffset += 4;
  1313          expect.pc = state.nextPC;
  1314          expect.nextPC += 4;
  1315          expect.step += 1;
  1316          expect.registers[2] = 4; // return
  1317          expect.registers[7] = 0; // errno
  1318          // recompute merkle root of written pre-image
  1319          (expect.memRoot,) = ffi.getCannonMemoryProof(pc, insn, a1, 0xdeadbeef);
  1320  
  1321          bytes32 postState = mips.step(encodedState, proof, 0);
  1322          assertEq(postState, outputState(expect), "unexpected post state");
  1323      }
  1324  
  1325      function test_preimage_write_succeeds() external {
  1326          uint32 pc = 0x0;
  1327          uint32 insn = 0x0000000c; // syscall
  1328          uint32 a1 = 0x4;
  1329          uint32 a1_val = 0x0000abba;
  1330          (bytes32 memRoot, bytes memory proof) = ffi.getCannonMemoryProof(pc, insn, a1, a1_val);
  1331  
  1332          uint32[32] memory registers;
  1333          registers[2] = 4004; // write syscall
  1334          registers[4] = 6; // fd
  1335          registers[5] = a1; // addr
  1336          registers[6] = 4; // count
  1337  
  1338          MIPS.State memory state = MIPS.State({
  1339              memRoot: memRoot,
  1340              preimageKey: bytes32(0),
  1341              preimageOffset: 1,
  1342              pc: pc,
  1343              nextPC: 4,
  1344              lo: 0,
  1345              hi: 0,
  1346              heap: 0,
  1347              exitCode: 0,
  1348              exited: false,
  1349              step: 1,
  1350              registers: registers
  1351          });
  1352          bytes memory encodedState = encodeState(state);
  1353  
  1354          MIPS.State memory expect = state;
  1355          expect.preimageOffset = 0; // preimage write resets offset
  1356          expect.pc = state.nextPC;
  1357          expect.nextPC += 4;
  1358          expect.step += 1;
  1359          expect.preimageKey = bytes32(uint256(0xabba));
  1360          expect.registers[2] = 4; // return
  1361          expect.registers[7] = 0; // errno
  1362  
  1363          bytes32 postState = mips.step(encodedState, proof, 0);
  1364          assertEq(postState, outputState(expect), "unexpected post state");
  1365      }
  1366  
  1367      function test_mmap_succeeds() external {
  1368          uint32 insn = 0x0000000c; // syscall
  1369          (bytes32 memRoot, bytes memory proof) = ffi.getCannonMemoryProof(0, insn);
  1370  
  1371          MIPS.State memory state;
  1372          state.memRoot = memRoot;
  1373          state.nextPC = 4;
  1374          state.registers[2] = 4090; // mmap syscall
  1375          state.registers[4] = 0x0; // a0
  1376          state.registers[5] = 4095; // a1
  1377          bytes memory encodedState = encodeState(state);
  1378  
  1379          MIPS.State memory expect;
  1380          expect.memRoot = state.memRoot;
  1381          // assert page allocation is aligned to 4k
  1382          expect.step = state.step + 1;
  1383          expect.pc = state.nextPC;
  1384          expect.nextPC = state.nextPC + 4;
  1385          expect.heap = state.heap + 4096;
  1386          expect.registers[2] = 0; // return old heap
  1387          expect.registers[4] = 0x0; // a0
  1388          expect.registers[5] = 4095; // a1
  1389  
  1390          bytes32 postState = mips.step(encodedState, proof, 0);
  1391          assertEq(postState, outputState(expect), "unexpected post state");
  1392      }
  1393  
  1394      function test_brk_succeeds() external {
  1395          uint32 insn = 0x0000000c; // syscall
  1396          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1397          state.registers[2] = 4045; // brk syscall
  1398          state.registers[4] = 0xdead;
  1399          bytes memory encodedState = encodeState(state);
  1400  
  1401          MIPS.State memory expect;
  1402          expect.memRoot = state.memRoot;
  1403          expect.step = state.step + 1;
  1404          expect.pc = state.nextPC;
  1405          expect.nextPC = state.nextPC + 4;
  1406          expect.registers[2] = 0x40000000;
  1407          expect.registers[4] = state.registers[4]; // registers unchanged
  1408  
  1409          bytes32 postState = mips.step(encodedState, proof, 0);
  1410          assertEq(postState, outputState(expect), "unexpected post state");
  1411      }
  1412  
  1413      function test_clone_succeeds() external {
  1414          uint32 insn = 0x0000000c; // syscall
  1415          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1416          state.registers[2] = 4120; // clone syscall
  1417  
  1418          MIPS.State memory expect;
  1419          expect.memRoot = state.memRoot;
  1420          expect.step = state.step + 1;
  1421          expect.pc = state.nextPC;
  1422          expect.nextPC = state.nextPC + 4;
  1423          expect.registers[2] = 1;
  1424  
  1425          bytes memory enc = encodeState(state);
  1426          bytes32 postState = mips.step(enc, proof, 0);
  1427          assertEq(postState, outputState(expect), "unexpected post state");
  1428      }
  1429  
  1430      function test_exit_succeeds() external {
  1431          uint32 insn = 0x0000000c; // syscall
  1432          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1433          state.registers[2] = 4246; // exit_group syscall
  1434          state.registers[4] = 0x5; // a0
  1435  
  1436          MIPS.State memory expect;
  1437          expect.memRoot = state.memRoot;
  1438          expect.pc = state.pc;
  1439          expect.nextPC = state.nextPC;
  1440          expect.step = state.step + 1;
  1441          expect.registers[2] = state.registers[2]; // unchanged
  1442          expect.registers[4] = state.registers[4]; // unchanged
  1443          expect.exited = true;
  1444          expect.exitCode = uint8(state.registers[4]);
  1445  
  1446          bytes32 postState = mips.step(encodeState(state), proof, 0);
  1447          assertEq(postState, outputState(expect), "unexpected post state");
  1448      }
  1449  
  1450      function test_fcntl_succeeds() external {
  1451          uint32 insn = 0x0000000c; // syscall
  1452          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1453          state.registers[2] = 4055; // fnctl syscall
  1454          state.registers[4] = 0x0; // a0
  1455          state.registers[5] = 0x3; // a1
  1456  
  1457          MIPS.State memory expect;
  1458          expect.memRoot = state.memRoot;
  1459          expect.pc = state.nextPC;
  1460          expect.nextPC = state.nextPC + 4;
  1461          expect.step = state.step + 1;
  1462          expect.registers[2] = 0;
  1463          expect.registers[5] = state.registers[5];
  1464  
  1465          bytes32 postState = mips.step(encodeState(state), proof, 0);
  1466          assertEq(postState, outputState(expect), "unexpected post state");
  1467  
  1468          // assert O_WRONLY
  1469          state.registers[4] = 0x1; // a0
  1470          expect.registers[4] = state.registers[4];
  1471          expect.registers[2] = 1;
  1472          postState = mips.step(encodeState(state), proof, 0);
  1473          assertEq(postState, outputState(expect), "unexpected post state");
  1474      }
  1475  
  1476      function test_prestate_exited_succeeds() external {
  1477          uint32 insn = 0x0000000c; // syscall
  1478          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1479          state.exited = true;
  1480  
  1481          bytes memory enc = encodeState(state);
  1482          bytes32 postState = mips.step(enc, proof, 0);
  1483          assertEq(postState, outputState(state), "unexpected post state");
  1484      }
  1485  
  1486      function test_illegal_instruction_fails() external {
  1487          uint32 illegal_insn = 0xFF_FF_FF_FF;
  1488          // the illegal instruction is partially decoded as containing a memory operand
  1489          // so we stuff random data to the expected address
  1490          uint32 addr = 0xFF_FF_FF_FC; // 4-byte aligned ff..ff
  1491          (bytes32 memRoot, bytes memory proof) = ffi.getCannonMemoryProof(0, illegal_insn, addr, 0);
  1492  
  1493          MIPS.State memory state;
  1494          state.memRoot = memRoot;
  1495          bytes memory encodedState = encodeState(state);
  1496          vm.expectRevert("invalid instruction");
  1497          mips.step(encodedState, proof, 0);
  1498      }
  1499  
  1500      function test_invalid_root_fails() external {
  1501          uint32 insn = 0x0000000c; // syscall
  1502          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1503          state.registers[2] = 4246; // exit_group syscall
  1504          state.registers[4] = 0x5; // a0
  1505  
  1506          // invalidate proof
  1507          for (uint256 i = 0; i < proof.length; i++) {
  1508              proof[i] = 0x0;
  1509          }
  1510          vm.expectRevert(hex"000000000000000000000000000000000000000000000000000000000badf00d");
  1511          mips.step(encodeState(state), proof, 0);
  1512      }
  1513  
  1514      function test_jump_inDelaySlot_fails() external {
  1515          uint16 label = 0x2;
  1516          uint32 insn = uint32(0x08_00_00_00) | label; // j label
  1517          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1518          state.nextPC = 0xa;
  1519  
  1520          vm.expectRevert("jump in delay slot");
  1521          mips.step(encodeState(state), proof, 0);
  1522      }
  1523  
  1524      function test_branch_inDelaySlot_fails() external {
  1525          uint16 boff = 0x10;
  1526          uint32 insn = encodeitype(0x4, 0x9, 0x8, boff); // beq $t0, $t1, 16
  1527          (MIPS.State memory state, bytes memory proof) = constructMIPSState(0, insn, 0x4, 0);
  1528          state.registers[8] = 0xdeadbeef; // t0
  1529          state.registers[9] = 0xdeadbeef; // t1
  1530          state.nextPC = 0xa;
  1531  
  1532          vm.expectRevert("branch in delay slot");
  1533          mips.step(encodeState(state), proof, 0);
  1534      }
  1535  
  1536      function encodeState(MIPS.State memory state) internal pure returns (bytes memory) {
  1537          bytes memory registers;
  1538          for (uint256 i = 0; i < state.registers.length; i++) {
  1539              registers = bytes.concat(registers, abi.encodePacked(state.registers[i]));
  1540          }
  1541          return abi.encodePacked(
  1542              state.memRoot,
  1543              state.preimageKey,
  1544              state.preimageOffset,
  1545              state.pc,
  1546              state.nextPC,
  1547              state.lo,
  1548              state.hi,
  1549              state.heap,
  1550              state.exitCode,
  1551              state.exited,
  1552              state.step,
  1553              registers
  1554          );
  1555      }
  1556  
  1557      /// @dev MIPS VM status codes:
  1558      ///      0. Exited with success (Valid)
  1559      ///      1. Exited with success (Invalid)
  1560      ///      2. Exited with failure (Panic)
  1561      ///      3. Unfinished
  1562      function vmStatus(MIPS.State memory state) internal pure returns (VMStatus out_) {
  1563          if (!state.exited) {
  1564              return VMStatuses.UNFINISHED;
  1565          } else if (state.exitCode == 0) {
  1566              return VMStatuses.VALID;
  1567          } else if (state.exitCode == 1) {
  1568              return VMStatuses.INVALID;
  1569          } else {
  1570              return VMStatuses.PANIC;
  1571          }
  1572      }
  1573  
  1574      function outputState(MIPS.State memory state) internal pure returns (bytes32 out_) {
  1575          bytes memory enc = encodeState(state);
  1576          VMStatus status = vmStatus(state);
  1577          assembly {
  1578              out_ := keccak256(add(enc, 0x20), 226)
  1579              out_ := or(and(not(shl(248, 0xFF)), out_), shl(248, status))
  1580          }
  1581      }
  1582  
  1583      function constructMIPSState(
  1584          uint32 pc,
  1585          uint32 insn,
  1586          uint32 addr,
  1587          uint32 val
  1588      )
  1589          internal
  1590          returns (MIPS.State memory state, bytes memory proof)
  1591      {
  1592          (state.memRoot, proof) = ffi.getCannonMemoryProof(pc, insn, addr, val);
  1593          state.pc = pc;
  1594          state.nextPC = pc + 4;
  1595      }
  1596  
  1597      function encodeitype(uint8 opcode, uint8 rs, uint8 rt, uint16 imm) internal pure returns (uint32 insn) {
  1598          insn = uint32(opcode) << 26 | uint32(rs) << 21 | uint32(rt) << 16 | imm;
  1599      }
  1600  
  1601      function encodespec(uint8 rs, uint8 rt, uint8 rd, uint16 funct) internal pure returns (uint32 insn) {
  1602          insn = uint32(rs) << 21 | uint32(rt) << 16 | uint32(rd) << 11 | uint32(funct);
  1603      }
  1604  
  1605      function encodespec2(uint8 rs, uint8 rt, uint8 rd, uint8 funct) internal pure returns (uint32 insn) {
  1606          insn = uint32(28) << 26 | uint32(rs) << 21 | uint32(rt) << 16 | uint32(rd) << 11 | uint32(funct);
  1607      }
  1608  }