#pragma once

#include <map>

#include "evm2wasm.h"

namespace evm2wasm
{
  static std::map<opcodeEnum, WastCode> wastSyncInterface =
  {
    {
  opcodeEnum::LOG, {
    .wast = "(func $LOG\n  (param $number i32)\n\n  (local $offset i32)\n  (local $offset0 i64)\n  (local $offset1 i64)\n  (local $offset2 i64)\n  (local $offset3 i64)\n\n  (local $length i32)\n  (local $length0 i64)\n  (local $length1 i64)\n  (local $length2 i64)\n  (local $length3 i64)\n\n  (local.set $offset0 (i64.load          (global.get $sp)))\n  (local.set $offset1 (i64.load (i32.add (global.get $sp) (i32.const  8))))\n  (local.set $offset2 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $offset3 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n\n  (local.set $length0 (i64.load (i32.sub (global.get $sp) (i32.const 32))))\n  (local.set $length1 (i64.load (i32.sub (global.get $sp) (i32.const 24))))\n  (local.set $length2 (i64.load (i32.sub (global.get $sp) (i32.const 16))))\n  (local.set $length3 (i64.load (i32.sub (global.get $sp) (i32.const  8))))\n\n  (local.set $offset\n             (call $check_overflow (local.get $offset0)\n                                   (local.get $offset1)\n                                   (local.get $offset2)\n                                   (local.get $offset3)))\n\n  (local.set $length\n             (call $check_overflow (local.get $length0)\n                                   (local.get $length1)\n                                   (local.get $length2)\n                                   (local.get $length3)))\n\n  (call $memusegas (local.get $offset) (local.get $length))\n\n  (if (i32.eq (local.get $number) (i32.const 0))\n    (then\n      (call $log\n             (local.get $offset)\n             (local.get $length)\n             (local.get $number)\n             (i32.const  0)\n             (i32.const  0)\n             (i32.const  0)\n             (i32.const  0))\n    )\n  )\n  (if (i32.eq (local.get $number) (i32.const 1))\n    (then\n    (call $log\n             (local.get $offset)\n             (local.get $length)\n             (local.get $number)\n             (call $bswap_m256 (i32.sub (global.get $sp) (i32.const  64)))\n             (i32.const  0)\n             (i32.const  0)\n             (i32.const  0))\n    )\n  )\n  (if (i32.eq (local.get $number) (i32.const 2))\n    (then\n    (call $log\n             (local.get $offset)\n             (local.get $length)\n             (local.get $number)\n             (call $bswap_m256 (i32.sub (global.get $sp) (i32.const  64)))\n             (call $bswap_m256 (i32.sub (global.get $sp) (i32.const  96)))\n             (i32.const  0)\n             (i32.const  0))\n    )\n  )\n  (if (i32.eq (local.get $number) (i32.const 3))\n    (then\n    (call $log\n             (local.get $offset)\n             (local.get $length)\n             (local.get $number)\n             (call $bswap_m256 (i32.sub (global.get $sp) (i32.const  64)))\n             (call $bswap_m256 (i32.sub (global.get $sp) (i32.const  96)))\n             (call $bswap_m256 (i32.sub (global.get $sp) (i32.const 128)))\n             (i32.const  0))\n    )\n  )\n  (if (i32.eq (local.get $number) (i32.const 4))\n    (then\n    (call $log\n             (local.get $offset)\n             (local.get $length)\n             (local.get $number)\n             (call $bswap_m256 (i32.sub (global.get $sp) (i32.const  64)))\n             (call $bswap_m256 (i32.sub (global.get $sp) (i32.const  96)))\n             (call $bswap_m256 (i32.sub (global.get $sp) (i32.const 128)))\n             (call $bswap_m256 (i32.sub (global.get $sp) (i32.const 160))))\n    )\n  )\n)\n",
    .imports = "(import \"env\" \"ethereum_log\" (func $log (param i32 i32 i32 i32 i32 i32 i32) ))"
  }
},{
  opcodeEnum::CALLDATALOAD, {
    .wast = ";; stack:\n;;  0: dataOffset\n(func $CALLDATALOAD\n  (local $writeOffset i32)\n  (local $writeOffset0 i64)\n  (local $writeOffset1 i64)\n  (local $writeOffset2 i64)\n  (local $writeOffset3 i64)\n\n  (local.set $writeOffset0 (i64.load (i32.add (global.get $sp) (i32.const  0))))\n  (local.set $writeOffset1 (i64.load (i32.add (global.get $sp) (i32.const  8))))\n  (local.set $writeOffset2 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $writeOffset3 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n\n  (i64.store (i32.add (global.get $sp) (i32.const  0)) (i64.const 0))\n  (i64.store (i32.add (global.get $sp) (i32.const  8)) (i64.const 0))\n  (i64.store (i32.add (global.get $sp) (i32.const 16)) (i64.const 0))\n  (i64.store (i32.add (global.get $sp) (i32.const 24)) (i64.const 0))\n\n  (local.set $writeOffset\n             (call $check_overflow (local.get $writeOffset0)\n                                   (local.get $writeOffset1)\n                                   (local.get $writeOffset2)\n                                   (local.get $writeOffset3)))\n\n  (call $callDataCopy (global.get $sp) (local.get $writeOffset) (i32.const 32))\n  ;; swap top stack item\n  (drop (call $bswap_m256 (global.get $sp)))\n)\n",
    .imports = "(import \"env\" \"ethereum_callDataCopy\" (func $callDataCopy (param i32 i32 i32) ))"
  }
},{
  opcodeEnum::GAS, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $GAS   (i64.store (i32.add (global.get $sp) (i32.const 32)) (call $getGasLeft))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const 56)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 48)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 40)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_getGasLeft\" (func $getGasLeft  (result i64)))"
  }
},{
  opcodeEnum::ADDRESS, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $ADDRESS   (call $getAddress(i32.add (global.get $sp) (i32.const 32)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const 32)))))",
    .imports = "(import \"env\" \"ethereum_getAddress\" (func $getAddress (param i32) ))"
  }
},{
  opcodeEnum::BALANCE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $BALANCE   (call $getExternalBalance(call $bswap_m256 (global.get $sp))(global.get $sp))(drop (call $bswap_m256 (global.get $sp))))",
    .imports = "(import \"env\" \"ethereum_getExternalBalance\" (func $getExternalBalance (param i32 i32) ))"
  }
},{
  opcodeEnum::SELFBALANCE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $SELFBALANCE   (call $getBalance(i32.add (global.get $sp) (i32.const 32)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const 32)))))",
    .imports = "(import \"env\" \"ethereum_getBalance\" (func $getBalance (param i32) ))"
  }
},{
  opcodeEnum::CHAINID, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CHAINID   (call $getChainId(i32.add (global.get $sp) (i32.const 32)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const 32)))))",
    .imports = "(import \"env\" \"ethereum_getChainId\" (func $getChainId (param i32) ))"
  }
},{
  opcodeEnum::BASEFEE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $BASEFEE   (call $getBaseFee(i32.add (global.get $sp) (i32.const 32)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const 32)))))",
    .imports = "(import \"env\" \"ethereum_getBaseFee\" (func $getBaseFee (param i32) ))"
  }
},{
  opcodeEnum::ORIGIN, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $ORIGIN   (call $getTxOrigin(i32.add (global.get $sp) (i32.const 32)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const 32)))))",
    .imports = "(import \"env\" \"ethereum_getTxOrigin\" (func $getTxOrigin (param i32) ))"
  }
},{
  opcodeEnum::CALLER, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CALLER   (call $getCaller(i32.add (global.get $sp) (i32.const 32)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const 32)))))",
    .imports = "(import \"env\" \"ethereum_getCaller\" (func $getCaller (param i32) ))"
  }
},{
  opcodeEnum::CALLVALUE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CALLVALUE   (call $getCallValue(i32.add (global.get $sp) (i32.const 32)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const 32)))))",
    .imports = "(import \"env\" \"ethereum_getCallValue\" (func $getCallValue (param i32) ))"
  }
},{
  opcodeEnum::CALLDATASIZE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CALLDATASIZE   (i64.store (i32.add (global.get $sp) (i32.const 32)) (i64.extend_i32_u (call $getCallDataSize)))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const 56)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 48)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 40)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_getCallDataSize\" (func $getCallDataSize  (result i32)))"
  }
},{
  opcodeEnum::CALLDATACOPY, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CALLDATACOPY (local $offset0 i32)(local $length0 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (global.get $sp))\n          (i64.load (i32.add (global.get $sp) (i32.const 8)))\n          (i64.load (i32.add (global.get $sp) (i32.const 16)))\n          (i64.load (i32.add (global.get $sp) (i32.const 24)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -64)))\n          (i64.load (i32.add (global.get $sp) (i32.const -56)))\n          (i64.load (i32.add (global.get $sp) (i32.const -48)))\n          (i64.load (i32.add (global.get $sp) (i32.const -40)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0))) (call $callDataCopy(local.get $offset0)(call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -32)))\n          (i64.load (i32.add (global.get $sp) (i32.const -24)))\n          (i64.load (i32.add (global.get $sp) (i32.const -16)))\n          (i64.load (i32.add (global.get $sp) (i32.const -8))))(local.get $length0)))",
    .imports = "(import \"env\" \"ethereum_callDataCopy\" (func $callDataCopy (param i32 i32 i32) ))"
  }
},{
  opcodeEnum::CODESIZE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CODESIZE   (i64.store (i32.add (global.get $sp) (i32.const 32)) (i64.extend_i32_u (call $getCodeSize)))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const 56)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 48)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 40)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_getCodeSize\" (func $getCodeSize  (result i32)))"
  }
},{
  opcodeEnum::CODECOPY, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CODECOPY (local $offset0 i32)(local $length0 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (global.get $sp))\n          (i64.load (i32.add (global.get $sp) (i32.const 8)))\n          (i64.load (i32.add (global.get $sp) (i32.const 16)))\n          (i64.load (i32.add (global.get $sp) (i32.const 24)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -64)))\n          (i64.load (i32.add (global.get $sp) (i32.const -56)))\n          (i64.load (i32.add (global.get $sp) (i32.const -48)))\n          (i64.load (i32.add (global.get $sp) (i32.const -40)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0))) (call $codeCopy(local.get $offset0)(call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -32)))\n          (i64.load (i32.add (global.get $sp) (i32.const -24)))\n          (i64.load (i32.add (global.get $sp) (i32.const -16)))\n          (i64.load (i32.add (global.get $sp) (i32.const -8))))(local.get $length0)))",
    .imports = "(import \"env\" \"ethereum_codeCopy\" (func $codeCopy (param i32 i32 i32) ))"
  }
},{
  opcodeEnum::EXTCODESIZE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $EXTCODESIZE   (i64.store (global.get $sp) (i64.extend_i32_u (call $getExternalCodeSize(call $bswap_m256 (global.get $sp)))))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const 24)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 16)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 8)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_getExternalCodeSize\" (func $getExternalCodeSize (param i32) (result i32)))"
  }
},{
  opcodeEnum::EXTCODEHASH, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $EXTCODEHASH   (call $getExternalCodeHash(call $bswap_m256 (global.get $sp))(global.get $sp))(drop (call $bswap_m256 (global.get $sp))))",
    .imports = "(import \"env\" \"ethereum_getExternalCodeHash\" (func $getExternalCodeHash (param i32 i32) ))"
  }
},{
  opcodeEnum::EXTCODECOPY, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $EXTCODECOPY (local $offset0 i32)(local $length0 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -32)))\n          (i64.load (i32.add (global.get $sp) (i32.const -24)))\n          (i64.load (i32.add (global.get $sp) (i32.const -16)))\n          (i64.load (i32.add (global.get $sp) (i32.const -8)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -96)))\n          (i64.load (i32.add (global.get $sp) (i32.const -88)))\n          (i64.load (i32.add (global.get $sp) (i32.const -80)))\n          (i64.load (i32.add (global.get $sp) (i32.const -72)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0))) (call $externalCodeCopy(call $bswap_m256 (global.get $sp))(local.get $offset0)(call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -64)))\n          (i64.load (i32.add (global.get $sp) (i32.const -56)))\n          (i64.load (i32.add (global.get $sp) (i32.const -48)))\n          (i64.load (i32.add (global.get $sp) (i32.const -40))))(local.get $length0)))",
    .imports = "(import \"env\" \"ethereum_externalCodeCopy\" (func $externalCodeCopy (param i32 i32 i32 i32) ))"
  }
},{
  opcodeEnum::GASPRICE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $GASPRICE   (call $getTxGasPrice(i32.add (global.get $sp) (i32.const 32)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const 32)))))",
    .imports = "(import \"env\" \"ethereum_getTxGasPrice\" (func $getTxGasPrice (param i32) ))"
  }
},{
  opcodeEnum::BLOCKHASH, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $BLOCKHASH   (call $getBlockHash(call $check_overflow_i64\n          (i64.load (global.get $sp))\n          (i64.load (i32.add (global.get $sp) (i32.const 8)))\n          (i64.load (i32.add (global.get $sp) (i32.const 16)))\n          (i64.load (i32.add (global.get $sp) (i32.const 24))))(global.get $sp))(drop (call $bswap_m256 (global.get $sp))))",
    .imports = "(import \"env\" \"ethereum_getBlockHash\" (func $getBlockHash (param i64 i32) ))"
  }
},{
  opcodeEnum::COINBASE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $COINBASE   (call $getBlockCoinbase(i32.add (global.get $sp) (i32.const 32)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const 32)))))",
    .imports = "(import \"env\" \"ethereum_getBlockCoinbase\" (func $getBlockCoinbase (param i32) ))"
  }
},{
  opcodeEnum::TIMESTAMP, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $TIMESTAMP   (i64.store (i32.add (global.get $sp) (i32.const 32)) (call $getBlockTimestamp))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const 56)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 48)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 40)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_getBlockTimestamp\" (func $getBlockTimestamp  (result i64)))"
  }
},{
  opcodeEnum::NUMBER, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $NUMBER   (i64.store (i32.add (global.get $sp) (i32.const 32)) (call $getBlockNumber))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const 56)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 48)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 40)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_getBlockNumber\" (func $getBlockNumber  (result i64)))"
  }
},{
  opcodeEnum::DIFFICULTY, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $DIFFICULTY   (call $getBlockDifficulty(i32.add (global.get $sp) (i32.const 32))))",
    .imports = "(import \"env\" \"ethereum_getBlockDifficulty\" (func $getBlockDifficulty (param i32) ))"
  }
},{
  opcodeEnum::GASLIMIT, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $GASLIMIT   (i64.store (i32.add (global.get $sp) (i32.const 32)) (call $getBlockGasLimit))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const 56)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 48)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 40)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_getBlockGasLimit\" (func $getBlockGasLimit  (result i64)))"
  }
},{
  opcodeEnum::CREATE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CREATE (local $offset0 i32)(local $length0 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -32)))\n          (i64.load (i32.add (global.get $sp) (i32.const -24)))\n          (i64.load (i32.add (global.get $sp) (i32.const -16)))\n          (i64.load (i32.add (global.get $sp) (i32.const -8)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -64)))\n          (i64.load (i32.add (global.get $sp) (i32.const -56)))\n          (i64.load (i32.add (global.get $sp) (i32.const -48)))\n          (i64.load (i32.add (global.get $sp) (i32.const -40)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0))) (call $create(call $bswap_m256 (global.get $sp))(local.get $offset0)(local.get $length0)(i32.add (global.get $sp) (i32.const -64)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const -64)))))",
    .imports = "(import \"env\" \"ethereum_create\" (func $create (param i32 i32 i32 i32) ))"
  }
},{
  opcodeEnum::CREATE2, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CREATE2 (local $offset0 i32)(local $length0 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -32)))\n          (i64.load (i32.add (global.get $sp) (i32.const -24)))\n          (i64.load (i32.add (global.get $sp) (i32.const -16)))\n          (i64.load (i32.add (global.get $sp) (i32.const -8)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -64)))\n          (i64.load (i32.add (global.get $sp) (i32.const -56)))\n          (i64.load (i32.add (global.get $sp) (i32.const -48)))\n          (i64.load (i32.add (global.get $sp) (i32.const -40)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0))) (call $create2(call $bswap_m256 (global.get $sp))(local.get $offset0)(local.get $length0)(call $bswap_m256 (i32.add (global.get $sp) (i32.const -96)))(i32.add (global.get $sp) (i32.const -96)))(drop (call $bswap_m256 (i32.add (global.get $sp) (i32.const -96)))))",
    .imports = "(import \"env\" \"ethereum_create2\" (func $create2 (param i32 i32 i32 i32 i32) ))"
  }
},{
  opcodeEnum::CALL, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CALL (local $offset0 i32)(local $length0 i32)(local $offset1 i32)(local $length1 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -96)))\n          (i64.load (i32.add (global.get $sp) (i32.const -88)))\n          (i64.load (i32.add (global.get $sp) (i32.const -80)))\n          (i64.load (i32.add (global.get $sp) (i32.const -72)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -128)))\n          (i64.load (i32.add (global.get $sp) (i32.const -120)))\n          (i64.load (i32.add (global.get $sp) (i32.const -112)))\n          (i64.load (i32.add (global.get $sp) (i32.const -104)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0)))(local.set $offset1 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -160)))\n          (i64.load (i32.add (global.get $sp) (i32.const -152)))\n          (i64.load (i32.add (global.get $sp) (i32.const -144)))\n          (i64.load (i32.add (global.get $sp) (i32.const -136)))))(local.set $length1 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -192)))\n          (i64.load (i32.add (global.get $sp) (i32.const -184)))\n          (i64.load (i32.add (global.get $sp) (i32.const -176)))\n          (i64.load (i32.add (global.get $sp) (i32.const -168)))))\n    (call $memusegas (local.get $offset1) (local.get $length1))\n    (local.set $offset1 (i32.add (global.get $memstart) (local.get $offset1))) (i64.store (i32.add (global.get $sp) (i32.const -192)) (i64.extend_i32_u (i32.eqz (call $call(call $check_overflow_i64\n          (i64.load (global.get $sp))\n          (i64.load (i32.add (global.get $sp) (i32.const 8)))\n          (i64.load (i32.add (global.get $sp) (i32.const 16)))\n          (i64.load (i32.add (global.get $sp) (i32.const 24))))(call $bswap_m256 (i32.add (global.get $sp) (i32.const -32)))(call $bswap_m256 (i32.add (global.get $sp) (i32.const -64)))(local.get $offset0)(local.get $length0)(local.get $offset1)(local.get $length1)))))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const -168)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const -176)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const -184)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_call\" (func $call (param i64 i32 i32 i32 i32 i32 i32) (result i32)))"
  }
},{
  opcodeEnum::CALLCODE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $CALLCODE (local $offset0 i32)(local $length0 i32)(local $offset1 i32)(local $length1 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -96)))\n          (i64.load (i32.add (global.get $sp) (i32.const -88)))\n          (i64.load (i32.add (global.get $sp) (i32.const -80)))\n          (i64.load (i32.add (global.get $sp) (i32.const -72)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -128)))\n          (i64.load (i32.add (global.get $sp) (i32.const -120)))\n          (i64.load (i32.add (global.get $sp) (i32.const -112)))\n          (i64.load (i32.add (global.get $sp) (i32.const -104)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0)))(local.set $offset1 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -160)))\n          (i64.load (i32.add (global.get $sp) (i32.const -152)))\n          (i64.load (i32.add (global.get $sp) (i32.const -144)))\n          (i64.load (i32.add (global.get $sp) (i32.const -136)))))(local.set $length1 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -192)))\n          (i64.load (i32.add (global.get $sp) (i32.const -184)))\n          (i64.load (i32.add (global.get $sp) (i32.const -176)))\n          (i64.load (i32.add (global.get $sp) (i32.const -168)))))\n    (call $memusegas (local.get $offset1) (local.get $length1))\n    (local.set $offset1 (i32.add (global.get $memstart) (local.get $offset1))) (i64.store (i32.add (global.get $sp) (i32.const -192)) (i64.extend_i32_u (i32.eqz (call $callCode(call $check_overflow_i64\n          (i64.load (global.get $sp))\n          (i64.load (i32.add (global.get $sp) (i32.const 8)))\n          (i64.load (i32.add (global.get $sp) (i32.const 16)))\n          (i64.load (i32.add (global.get $sp) (i32.const 24))))(call $bswap_m256 (i32.add (global.get $sp) (i32.const -32)))(call $bswap_m256 (i32.add (global.get $sp) (i32.const -64)))(local.get $offset0)(local.get $length0)(local.get $offset1)(local.get $length1)))))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const -168)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const -176)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const -184)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_callCode\" (func $callCode (param i64 i32 i32 i32 i32 i32 i32) (result i32)))"
  }
},{
  opcodeEnum::DELEGATECALL, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $DELEGATECALL (local $offset0 i32)(local $length0 i32)(local $offset1 i32)(local $length1 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -64)))\n          (i64.load (i32.add (global.get $sp) (i32.const -56)))\n          (i64.load (i32.add (global.get $sp) (i32.const -48)))\n          (i64.load (i32.add (global.get $sp) (i32.const -40)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -96)))\n          (i64.load (i32.add (global.get $sp) (i32.const -88)))\n          (i64.load (i32.add (global.get $sp) (i32.const -80)))\n          (i64.load (i32.add (global.get $sp) (i32.const -72)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0)))(local.set $offset1 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -128)))\n          (i64.load (i32.add (global.get $sp) (i32.const -120)))\n          (i64.load (i32.add (global.get $sp) (i32.const -112)))\n          (i64.load (i32.add (global.get $sp) (i32.const -104)))))(local.set $length1 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -160)))\n          (i64.load (i32.add (global.get $sp) (i32.const -152)))\n          (i64.load (i32.add (global.get $sp) (i32.const -144)))\n          (i64.load (i32.add (global.get $sp) (i32.const -136)))))\n    (call $memusegas (local.get $offset1) (local.get $length1))\n    (local.set $offset1 (i32.add (global.get $memstart) (local.get $offset1))) (i64.store (i32.add (global.get $sp) (i32.const -160)) (i64.extend_i32_u (i32.eqz (call $callDelegate(call $check_overflow_i64\n          (i64.load (global.get $sp))\n          (i64.load (i32.add (global.get $sp) (i32.const 8)))\n          (i64.load (i32.add (global.get $sp) (i32.const 16)))\n          (i64.load (i32.add (global.get $sp) (i32.const 24))))(call $bswap_m256 (i32.add (global.get $sp) (i32.const -32)))(local.get $offset0)(local.get $length0)(local.get $offset1)(local.get $length1)))))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const -136)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const -144)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const -152)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_callDelegate\" (func $callDelegate (param i64 i32 i32 i32 i32 i32) (result i32)))"
  }
},{
  opcodeEnum::STATICCALL, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $STATICCALL (local $offset0 i32)(local $length0 i32)(local $offset1 i32)(local $length1 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -64)))\n          (i64.load (i32.add (global.get $sp) (i32.const -56)))\n          (i64.load (i32.add (global.get $sp) (i32.const -48)))\n          (i64.load (i32.add (global.get $sp) (i32.const -40)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -96)))\n          (i64.load (i32.add (global.get $sp) (i32.const -88)))\n          (i64.load (i32.add (global.get $sp) (i32.const -80)))\n          (i64.load (i32.add (global.get $sp) (i32.const -72)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0)))(local.set $offset1 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -128)))\n          (i64.load (i32.add (global.get $sp) (i32.const -120)))\n          (i64.load (i32.add (global.get $sp) (i32.const -112)))\n          (i64.load (i32.add (global.get $sp) (i32.const -104)))))(local.set $length1 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -160)))\n          (i64.load (i32.add (global.get $sp) (i32.const -152)))\n          (i64.load (i32.add (global.get $sp) (i32.const -144)))\n          (i64.load (i32.add (global.get $sp) (i32.const -136)))))\n    (call $memusegas (local.get $offset1) (local.get $length1))\n    (local.set $offset1 (i32.add (global.get $memstart) (local.get $offset1))) (i64.store (i32.add (global.get $sp) (i32.const -160)) (i64.extend_i32_u (i32.eqz (call $callStatic(call $check_overflow_i64\n          (i64.load (global.get $sp))\n          (i64.load (i32.add (global.get $sp) (i32.const 8)))\n          (i64.load (i32.add (global.get $sp) (i32.const 16)))\n          (i64.load (i32.add (global.get $sp) (i32.const 24))))(call $bswap_m256 (i32.add (global.get $sp) (i32.const -32)))(local.get $offset0)(local.get $length0)(local.get $offset1)(local.get $length1)))))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const -136)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const -144)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const -152)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_callStatic\" (func $callStatic (param i64 i32 i32 i32 i32 i32) (result i32)))"
  }
},{
  opcodeEnum::RETURNDATACOPY, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $RETURNDATACOPY (local $offset0 i32)(local $length0 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (global.get $sp))\n          (i64.load (i32.add (global.get $sp) (i32.const 8)))\n          (i64.load (i32.add (global.get $sp) (i32.const 16)))\n          (i64.load (i32.add (global.get $sp) (i32.const 24)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -64)))\n          (i64.load (i32.add (global.get $sp) (i32.const -56)))\n          (i64.load (i32.add (global.get $sp) (i32.const -48)))\n          (i64.load (i32.add (global.get $sp) (i32.const -40)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0))) (call $returnDataCopy(local.get $offset0)(call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -32)))\n          (i64.load (i32.add (global.get $sp) (i32.const -24)))\n          (i64.load (i32.add (global.get $sp) (i32.const -16)))\n          (i64.load (i32.add (global.get $sp) (i32.const -8))))(local.get $length0)))",
    .imports = "(import \"env\" \"ethereum_returnDataCopy\" (func $returnDataCopy (param i32 i32 i32) ))"
  }
},{
  opcodeEnum::RETURNDATASIZE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $RETURNDATASIZE   (i64.store (i32.add (global.get $sp) (i32.const 32)) (i64.extend_i32_u (call $getReturnDataSize)))\n    ;; zero out mem\n    (i64.store (i32.add (global.get $sp) (i32.const 56)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 48)) (i64.const 0))\n    (i64.store (i32.add (global.get $sp) (i32.const 40)) (i64.const 0)))",
    .imports = "(import \"env\" \"ethereum_getReturnDataSize\" (func $getReturnDataSize  (result i32)))"
  }
},{
  opcodeEnum::SSTORE, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $SSTORE   (call $storageStore(call $bswap_m256 (global.get $sp))(call $bswap_m256 (i32.add (global.get $sp) (i32.const -32)))))",
    .imports = "(import \"env\" \"ethereum_storageStore\" (func $storageStore (param i32 i32) ))"
  }
},{
  opcodeEnum::SLOAD, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $SLOAD   (call $storageLoad(call $bswap_m256 (global.get $sp))(global.get $sp))(drop (call $bswap_m256 (global.get $sp))))",
    .imports = "(import \"env\" \"ethereum_storageLoad\" (func $storageLoad (param i32 i32) ))"
  }
},{
  opcodeEnum::SELFDESTRUCT, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $SELFDESTRUCT   (call $selfDestruct(call $bswap_m256 (global.get $sp))))",
    .imports = "(import \"env\" \"ethereum_selfDestruct\" (func $selfDestruct (param i32) ))"
  }
},{
  opcodeEnum::RETURN, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $RETURN (local $offset0 i32)(local $length0 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (global.get $sp))\n          (i64.load (i32.add (global.get $sp) (i32.const 8)))\n          (i64.load (i32.add (global.get $sp) (i32.const 16)))\n          (i64.load (i32.add (global.get $sp) (i32.const 24)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -32)))\n          (i64.load (i32.add (global.get $sp) (i32.const -24)))\n          (i64.load (i32.add (global.get $sp) (i32.const -16)))\n          (i64.load (i32.add (global.get $sp) (i32.const -8)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0))) (call $finish(local.get $offset0)(local.get $length0)))",
    .imports = "(import \"env\" \"ethereum_finish\" (func $finish (param i32 i32) ))"
  }
},{
  opcodeEnum::REVERT, {
    .wast = ";; generated by ./wasm/generateInterface.js\n(func $REVERT (local $offset0 i32)(local $length0 i32) (local.set $offset0 (call $check_overflow\n          (i64.load (global.get $sp))\n          (i64.load (i32.add (global.get $sp) (i32.const 8)))\n          (i64.load (i32.add (global.get $sp) (i32.const 16)))\n          (i64.load (i32.add (global.get $sp) (i32.const 24)))))(local.set $length0 (call $check_overflow\n          (i64.load (i32.add (global.get $sp) (i32.const -32)))\n          (i64.load (i32.add (global.get $sp) (i32.const -24)))\n          (i64.load (i32.add (global.get $sp) (i32.const -16)))\n          (i64.load (i32.add (global.get $sp) (i32.const -8)))))\n    (call $memusegas (local.get $offset0) (local.get $length0))\n    (local.set $offset0 (i32.add (global.get $memstart) (local.get $offset0))) (call $revert(local.get $offset0)(local.get $length0)))",
    .imports = "(import \"env\" \"ethereum_revert\" (func $revert (param i32 i32) ))"
  }
},{
  opcodeEnum::PUSH, {
    .wast = "(func $PUSH\n  (param $a0 i64)\n  (param $a1 i64)\n  (param $a2 i64)\n  (param $a3 i64)\n  (local $sp i32)\n\n  ;; increament stack pointer\n  (local.set $sp (i32.add (global.get $sp) (i32.const 32)))\n\n  (i64.store (local.get $sp) (local.get $a3))\n  (i64.store (i32.add (local.get $sp) (i32.const 8)) (local.get $a2))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $a1))\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $a0))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::MSTORE, {
    .wast = ";; stack:\n;;  0: word\n;; -1: offset\n(func $MSTORE\n  (local $sp i32)\n\n  (local $offset   i32)\n  \n  (local $offset0 i64)\n  (local $offset1 i64)\n  (local $offset2 i64)\n  (local $offset3 i64)\n\n  ;; load args from the stack\n  (local.set $offset0 (i64.load          (global.get $sp)))\n  (local.set $offset1 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n  (local.set $offset2 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $offset3 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n\n  (local.set $offset \n             (call $check_overflow (local.get $offset0)\n                                   (local.get $offset1)\n                                   (local.get $offset2)\n                                   (local.get $offset3)))\n  ;; subtrace gas useage\n  (call $memusegas (local.get $offset) (i32.const 32))\n\n  ;; pop item from the stack\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n  ;; swap top stack item\n  (drop (call $bswap_m256 (local.get $sp)))\n\n  (local.set $offset (i32.add (local.get $offset) (global.get $memstart)))\n  ;; store word to memory\n  (i64.store          (local.get $offset)                 (i64.load          (local.get $sp)))\n  (i64.store (i32.add (local.get $offset) (i32.const 8))  (i64.load (i32.add (local.get $sp) (i32.const  8))))\n  (i64.store (i32.add (local.get $offset) (i32.const 16)) (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (i64.store (i32.add (local.get $offset) (i32.const 24)) (i64.load (i32.add (local.get $sp) (i32.const 24))))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::MLOAD, {
    .wast = ";; stack:\n;;  0: offset\n(func $MLOAD\n  (local $offset i32)\n  (local $offset0 i64)\n  (local $offset1 i64)\n  (local $offset2 i64)\n  (local $offset3 i64)\n\n  ;; load args from the stack\n  (local.set $offset0 (i64.load          (global.get $sp)))\n  (local.set $offset1 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n  (local.set $offset2 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $offset3 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n\n  (local.set $offset \n             (call $check_overflow (local.get $offset0)\n                                   (local.get $offset1)\n                                   (local.get $offset2)\n                                   (local.get $offset3)))\n  ;; subttract gas useage\n  (call $memusegas (local.get $offset) (i32.const  32))\n\n  ;; FIXME: how to deal with overflow?\n  (local.set $offset (i32.add (local.get $offset) (global.get $memstart)))\n\n  (i64.store (i32.add (global.get $sp) (i32.const 24)) (i64.load (i32.add (local.get $offset) (i32.const 24))))\n  (i64.store (i32.add (global.get $sp) (i32.const 16)) (i64.load (i32.add (local.get $offset) (i32.const 16))))\n  (i64.store (i32.add (global.get $sp) (i32.const  8)) (i64.load (i32.add (local.get $offset) (i32.const  8))))\n  (i64.store          (global.get $sp)                 (i64.load          (local.get $offset)))\n\n  ;; swap\n  (drop (call $bswap_m256 (global.get $sp)))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::DUP, {
    .wast = "(func $DUP\n  (param $a0 i32)\n  (local $sp i32)\n\n  (local $sp_ref i32)\n  \n  (local.set $sp (i32.add (global.get $sp) (i32.const 32)))\n  (local.set $sp_ref (i32.sub (i32.sub (local.get $sp) (i32.const 8)) (i32.mul (local.get $a0) (i32.const 32))))\n  \n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (i64.load (local.get $sp_ref)))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (i64.load (i32.sub (local.get $sp_ref) (i32.const 8))))\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (i64.load (i32.sub (local.get $sp_ref) (i32.const 16))))\n  (i64.store          (local.get $sp)                 (i64.load (i32.sub (local.get $sp_ref) (i32.const 24))))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::ISZERO, {
    .wast = "(func $ISZERO\n  (local $a0 i64)\n  (local $a1 i64)\n  (local $a2 i64)\n  (local $a3 i64)\n\n  ;; load args from the stack\n  (local.set $a0 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n  (local.set $a1 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $a2 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n  (local.set $a3 (i64.load (global.get $sp)))\n\n  (i64.store (global.get $sp)\n    (i64.extend_i32_u\n      (call $iszero_256 (local.get $a0) (local.get $a1) (local.get $a2) (local.get $a3))\n    )\n  )\n\n  ;; zero out the rest of memory\n  (i64.store (i32.add (global.get $sp) (i32.const 8)) (i64.const 0))\n  (i64.store (i32.add (global.get $sp) (i32.const 16)) (i64.const 0))\n  (i64.store (i32.add (global.get $sp) (i32.const 24)) (i64.const 0))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::LT, {
    .wast = "(func $LT\n  (local $sp i32)\n\n  (local $a0 i64)\n  (local $a1 i64)\n  (local $a2 i64)\n  (local $a3 i64)\n  (local $b0 i64)\n  (local $b1 i64)\n  (local $b2 i64)\n  (local $b3 i64)\n\n  (local.set $sp (global.get $sp))\n\n  ;; load args from the stack\n  (local.set $a0 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $a1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $a2 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $a3 (i64.load (local.get $sp)))\n\n  (local.set $sp (i32.sub (local.get $sp) (i32.const 32)))\n\n  (local.set $b0 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $b2 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $b3 (i64.load (local.get $sp)))\n\n  (i64.store (local.get $sp) (i64.extend_i32_u\n    (i32.or  (i64.lt_u (local.get $a0) (local.get $b0)) ;; a0 < b0\n    (i32.and (i64.eq   (local.get $a0) (local.get $b0)) ;; a0 == b0\n    (i32.or  (i64.lt_u (local.get $a1) (local.get $b1)) ;; a1 < b1\n    (i32.and (i64.eq   (local.get $a1) (local.get $b1)) ;; a1 == b1\n    (i32.or  (i64.lt_u (local.get $a2) (local.get $b2)) ;; a2 < b2\n    (i32.and (i64.eq   (local.get $a2) (local.get $b2)) ;; a2 == b2\n             (i64.lt_u (local.get $a3) (local.get $b3)))))))))) ;; a3 < b3\n\n  ;; zero  out the rest of the stack item\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (i64.const 0))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::GT, {
    .wast = "(func $GT\n  (local $sp i32)\n\n  (local $a0 i64)\n  (local $a1 i64)\n  (local $a2 i64)\n  (local $a3 i64)\n  (local $b0 i64)\n  (local $b1 i64)\n  (local $b2 i64)\n  (local $b3 i64)\n\n  (local.set $sp (global.get $sp))\n\n  ;; load args from the stack\n  (local.set $a0 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $a1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $a2 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $a3 (i64.load (local.get $sp)))\n\n  (local.set $sp (i32.sub (local.get $sp) (i32.const 32)))\n\n  (local.set $b0 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $b2 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $b3 (i64.load (local.get $sp)))\n\n  (i64.store (local.get $sp) (i64.extend_i32_u\n    (i32.or (i64.gt_u (local.get $a0) (local.get $b0)) ;; a0 > b0\n    (i32.and (i64.eq   (local.get $a0) (local.get $b0)) ;; a0 == a1\n    (i32.or  (i64.gt_u (local.get $a1) (local.get $b1)) ;; a1 > b1\n    (i32.and (i64.eq   (local.get $a1) (local.get $b1)) ;; a1 == b1\n    (i32.or  (i64.gt_u (local.get $a2) (local.get $b2)) ;; a2 > b2\n    (i32.and (i64.eq   (local.get $a2) (local.get $b2)) ;; a2 == b2\n             (i64.gt_u (local.get $a3) (local.get $b3)))))))))) ;; a3 > b3\n\n  ;; zero  out the rest of the stack item\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (i64.const 0))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::SLT, {
    .wast = "(func $SLT\n  (local $sp i32)\n\n  (local $a0 i64)\n  (local $a1 i64)\n  (local $a2 i64)\n  (local $a3 i64)\n  (local $b0 i64)\n  (local $b1 i64)\n  (local $b2 i64)\n  (local $b3 i64)\n\n  ;; load args from the stack\n  (local.set $a0 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n  (local.set $a1 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $a2 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n  (local.set $a3 (i64.load (global.get $sp)))\n\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n  (local.set $b0 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $b2 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $b3 (i64.load (local.get $sp)))\n\n  (i64.store (local.get $sp) (i64.extend_i32_u\n    (i32.or  (i64.lt_s (local.get $a0) (local.get $b0)) ;; a0 < b0\n    (i32.and (i64.eq   (local.get $a0) (local.get $b0)) ;; a0 == b0\n    (i32.or  (i64.lt_u (local.get $a1) (local.get $b1)) ;; a1 < b1\n    (i32.and (i64.eq   (local.get $a1) (local.get $b1)) ;; a1 == b1\n    (i32.or  (i64.lt_u (local.get $a2) (local.get $b2)) ;; a2 < b2\n    (i32.and (i64.eq   (local.get $a2) (local.get $b2)) ;; a2 == b2\n             (i64.lt_u (local.get $a3) (local.get $b3)))))))))) ;; a3 < b3\n\n  ;; zero  out the rest of the stack item\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (i64.const 0))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::SHR, {
    .wast = "(func $SHR\n    (local $sp i32)\n    (local $x1 i64)\n    (local $x2 i64)\n    (local $x3 i64)\n    (local $x4 i64)\n    (local $y1 i64)\n    (local $y2 i64)\n    (local $y3 i64)\n    (local $y4 i64)\n\n    (local $z1 i64)\n    (local $z2 i64)\n    (local $z3 i64)\n    (local $z4 i64)\n    (local $t i64)\n\n    ;; load args from the stack\n    (local.set $x1 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n    (local.set $x2 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n    (local.set $x3 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n    (local.set $x4 (i64.load (global.get $sp)))\n\n    (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n    (local.set $y1 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n    (local.set $y2 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n    (local.set $y3 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n    (local.set $y4 (i64.load (local.get $sp)))\n\n    (block\n        (if (i32.and (i64.eqz (local.get $x1)) (i64.eqz (local.get $x2))) (then\n            (if (i64.eqz (local.get $x3)) (then\n                (if (i64.eqz (local.get $x4))\n                    (then\n                        (local.set $z1 (local.get $y1))\n                        (local.set $z2 (local.get $y2))\n                        (local.set $z3 (local.get $y3))\n                        (local.set $z4 (local.get $y4))\n                    )\n                    (else\n                        (if (i64.lt_u (local.get $x4) (i64.const 256)) (then\n                            (if (i64.ge_u (local.get $x4) (i64.const 128)) (then\n                                (local.set $y4 (local.get $y2))\n                                (local.set $y3 (local.get $y1))\n                                (local.set $y2 (i64.const 0))\n                                (local.set $y1 (i64.const 0))\n                                (local.set $x4 (i64.sub (local.get $x4) (i64.const 128)))\n                            ))\n                            (if (i64.ge_u (local.get $x4) (i64.const 64)) (then\n                                (local.set $y4 (local.get $y3))\n                                (local.set $y3 (local.get $y2))\n                                (local.set $y2 (local.get $y1))\n                                (local.set $y1 (i64.const 0))\n                                (local.set $x4 (i64.sub (local.get $x4) (i64.const 64)))\n                            ))\n                            (nop)\n                            (block\n                                (local.set $z4 (call $shr_single (local.get $y4) (local.get $x4)))\n                                (local.set $t (global.get $global_))\n\n                            )\n                            (block\n                                (local.set $z3 (call $shr_single (local.get $y3) (local.get $x4)))\n                                (local.set $t (global.get $global_))\n\n                            )\n                            (local.set $z4 (i64.or (local.get $z4) (local.get $t)))\n                            (block\n                                (local.set $z2 (call $shr_single (local.get $y2) (local.get $x4)))\n                                (local.set $t (global.get $global_))\n\n                            )\n                            (local.set $z3 (i64.or (local.get $z3) (local.get $t)))\n                            (block\n                                (local.set $z1 (call $shr_single (local.get $y1) (local.get $x4)))\n                                (local.set $t (global.get $global_))\n\n                            )\n                            (local.set $z2 (i64.or (local.get $z2) (local.get $t)))\n                        ))\n                    )\n                )\n            ))\n        ))\n\n    )\n    (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $z1))\n    (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $z2))\n    (i64.store (i32.add (local.get $sp) (i32.const  8)) (local.get $z3))\n    (i64.store          (local.get $sp)                 (local.get $z4))\n)\n\n(func $shr_single\n    (param $a i64)\n    (param $amount i64)\n    (result i64)\n    (local $x i64)\n    (local $y i64)\n    (block\n        (local.set $y (i64.shl (local.get $a) (i64.sub (i64.const 64) (local.get $amount))))\n        (local.set $x (i64.shr_u (local.get $a) (local.get $amount)))\n\n    )\n    (global.set $global_ (local.get $y))\n    (local.get $x)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::EQ, {
    .wast = "(func $EQ\n  (local $sp i32)\n\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n  (i64.store (local.get $sp)\n    (i64.extend_i32_u\n      (i32.and (i64.eq   (i64.load (i32.add (local.get $sp) (i32.const 56))) (i64.load (i32.add (local.get $sp) (i32.const 24))))\n      (i32.and (i64.eq   (i64.load (i32.add (local.get $sp) (i32.const 48))) (i64.load (i32.add (local.get $sp) (i32.const 16))))\n      (i32.and (i64.eq   (i64.load (i32.add (local.get $sp) (i32.const 40))) (i64.load (i32.add (local.get $sp) (i32.const  8))))\n               (i64.eq   (i64.load (i32.add (local.get $sp) (i32.const 32))) (i64.load          (local.get $sp))))))))\n\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (i64.const 0))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::ADD, {
    .wast = "(func $ADD\n  (local $sp i32)\n\n  (local $a i64)\n  (local $c i64)\n  (local $d i64)\n  (local $carry i64)\n\n  (local.set $sp (global.get $sp))\n\n  ;; d c b a\n  ;; pop the stack\n  (local.set $a (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $c (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $d (i64.load (local.get $sp)))\n  ;; decement the stack pointer\n  (local.set $sp (i32.sub (local.get $sp) (i32.const 8)))\n\n  ;; d\n  (local.set $carry (i64.add (local.get $d) (i64.load (i32.sub (local.get $sp) (i32.const 24)))))\n  ;; save d  to mem\n  (i64.store (i32.sub (local.get $sp) (i32.const 24)) (local.get $carry))\n  ;; check  for overflow\n  (local.set $carry (i64.extend_i32_u (i64.lt_u (local.get $carry) (local.get $d))))\n\n  ;; c use $d as reg\n  (local.set $d     (i64.add (i64.load (i32.sub (local.get $sp) (i32.const 16))) (local.get $carry)))\n  (local.set $carry (i64.extend_i32_u (i64.lt_u (local.get $d) (local.get $carry))))\n  (local.set $d     (i64.add (local.get $c) (local.get $d)))\n  ;; store the result\n  (i64.store (i32.sub (local.get $sp) (i32.const 16)) (local.get $d))\n  ;; check overflow\n  (local.set $carry (i64.or (i64.extend_i32_u  (i64.lt_u (local.get $d) (local.get $c))) (local.get $carry)))\n\n  ;; b\n  ;; add carry\n  (local.set $d     (i64.add (i64.load (i32.sub (local.get $sp) (i32.const 8))) (local.get $carry)))\n  (local.set $carry (i64.extend_i32_u (i64.lt_u (local.get $d) (local.get $carry))))\n\n  ;; use reg c\n  (local.set $c (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $d (i64.add (local.get $c) (local.get $d)))\n  (i64.store (i32.sub (local.get $sp) (i32.const 8)) (local.get $d))\n  ;; a\n  (i64.store (local.get $sp)\n             (i64.add        ;; add a\n               (local.get $a)\n               (i64.add\n                 (i64.load (local.get $sp))  ;; load the operand\n                 (i64.or  ;; carry\n                   (i64.extend_i32_u (i64.lt_u (local.get $d) (local.get $c)))\n                   (local.get $carry)))))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::SUB, {
    .wast = "(func $SUB\n  (local $sp i32)\n\n  (local $a i64)\n  (local $b i64)\n  (local $c i64)\n  (local $d i64)\n\n  (local $a1 i64)\n  (local $b1 i64)\n  (local $c1 i64)\n  (local $d1 i64)\n\n  (local $carry i64)\n  (local $temp i64)\n\n  (local.set $a (i64.load (i32.add (global.get $sp) (i32.const 24))))\n  (local.set $b (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $c (i64.load (i32.add (global.get $sp) (i32.const  8))))\n  (local.set $d (i64.load          (global.get $sp)))\n  ;; decement the stack pointer\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n  (local.set $a1 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $c1 (i64.load (i32.add (local.get $sp) (i32.const  8))))\n  (local.set $d1 (i64.load          (local.get $sp)))\n\n  ;; a * 64^3 + b*64^2 + c*64 + d\n  ;; d\n  (local.set $carry (i64.extend_i32_u (i64.lt_u (local.get $d) (local.get $d1))))\n  (local.set $d (i64.sub (local.get $d) (local.get $d1)))\n\n  ;; c\n  (local.set $temp (i64.sub (local.get $c) (local.get $carry)))\n  (local.set $carry (i64.extend_i32_u (i64.gt_u (local.get $temp) (local.get $c))))\n  (local.set $c (i64.sub (local.get $temp) (local.get $c1)))\n  (local.set $carry (i64.or (i64.extend_i32_u (i64.gt_u (local.get $c) (local.get $temp))) (local.get $carry)))\n\n  ;; b\n  (local.set $temp (i64.sub (local.get $b) (local.get $carry)))\n  (local.set $carry (i64.extend_i32_u (i64.gt_u (local.get $temp) (local.get $b))))\n  (local.set $b (i64.sub (local.get $temp) (local.get $b1)))\n\n  ;; a\n  (local.set $a (i64.sub (i64.sub (local.get $a) (i64.or (i64.extend_i32_u (i64.gt_u (local.get $b) (local.get $temp))) (local.get $carry))) (local.get $a1)))\n\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $a))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $b))\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (local.get $c))\n  (i64.store          (local.get $sp)                 (local.get $d))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::SWAP, {
    .wast = "(func $SWAP\n  (param $a0 i32)\n  (local $sp_ref i32)\n\n  (local $topa i64)\n  (local $topb i64)\n  (local $topc i64)\n  (local $topd i64)\n  \n  (local.set $sp_ref (i32.sub (i32.add  (global.get $sp) (i32.const 24)) (i32.mul (i32.add (local.get $a0) (i32.const 1)) (i32.const 32))))\n\n  (local.set $topa (i64.load (i32.add (global.get $sp) (i32.const 24))))\n  (local.set $topb (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $topc (i64.load (i32.add (global.get $sp) (i32.const  8))))\n  (local.set $topd (i64.load          (global.get $sp)))\n  \n  ;; replace the top element\n  (i64.store (i32.add (global.get $sp) (i32.const 24)) (i64.load (local.get $sp_ref)))\n  (i64.store (i32.add (global.get $sp) (i32.const 16)) (i64.load (i32.sub (local.get $sp_ref) (i32.const 8))))\n  (i64.store (i32.add (global.get $sp) (i32.const  8)) (i64.load (i32.sub (local.get $sp_ref) (i32.const 16))))\n  (i64.store          (global.get $sp)                 (i64.load (i32.sub (local.get $sp_ref) (i32.const 24))))\n\n  ;; store the old top element\n  (i64.store (local.get $sp_ref)                          (local.get $topa))\n  (i64.store (i32.sub (local.get $sp_ref) (i32.const 8))  (local.get $topb))\n  (i64.store (i32.sub (local.get $sp_ref) (i32.const 16)) (local.get $topc))\n  (i64.store (i32.sub (local.get $sp_ref) (i32.const 24)) (local.get $topd))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::check_overflow, {
    .wast = "(func $check_overflow\n  (param $a i64)\n  (param $b i64)\n  (param $c i64)\n  (param $d i64)\n  (result i32)\n\n  (local $MAX_INT i32)\n  (local.set $MAX_INT (i32.const -1))\n\n  (if\n    (i32.and\n      (i32.and\n        (i64.eqz  (local.get $d))\n        (i64.eqz  (local.get $c)))\n      (i32.and\n        (i64.eqz  (local.get $b))\n        (i64.lt_u (local.get $a) (i64.extend_i32_u (local.get $MAX_INT)))))\n     (return (i32.wrap_i64 (local.get $a))))\n\n     (return (local.get $MAX_INT))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::ADDMOD, {
    .wast = ";; stack:\n;;  0: A\n;; -1: B\n;; -2: MOD\n(func $ADDMOD\n  (local $sp i32)\n\n  (local $a i64)\n  (local $b i64)\n  (local $c i64)\n  (local $d i64)\n\n  (local $a1 i64)\n  (local $b1 i64)\n  (local $c1 i64)\n  (local $d1 i64)\n\n  (local $moda i64)\n  (local $modb i64)\n  (local $modc i64)\n  (local $modd i64)\n\n  (local $carry i64)\n\n  (local.set $sp (global.get $sp))\n\n  ;; load args from the stack\n  (local.set $a (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $c (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $d (i64.load (local.get $sp)))\n\n  (local.set $sp (i32.sub (local.get $sp) (i32.const 32)))\n\n  (local.set $a1 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $c1 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $d1 (i64.load (local.get $sp)))\n\n  (local.set $sp (i32.sub (local.get $sp) (i32.const 32)))\n\n  (local.set $moda (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $modb (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $modc (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $modd (i64.load (local.get $sp)))\n\n  ;; a * 64^3 + b*64^2 + c*64 + d\n  ;; d\n  (local.set $d     (i64.add (local.get $d1) (local.get $d)))\n  (local.set $carry (i64.extend_i32_u (i64.lt_u (local.get $d) (local.get $d1))))\n  ;; c\n  (local.set $c     (i64.add (local.get $c) (local.get $carry)))\n  (local.set $carry (i64.extend_i32_u (i64.lt_u (local.get $c) (local.get $carry))))\n  (local.set $c     (i64.add (local.get $c1) (local.get $c)))\n  (local.set $carry (i64.or (i64.extend_i32_u  (i64.lt_u (local.get $c) (local.get $c1))) (local.get $carry)))\n  ;; b\n  (local.set $b     (i64.add (local.get $b) (local.get $carry)))\n  (local.set $carry (i64.extend_i32_u (i64.lt_u (local.get $b) (local.get $carry))))\n  (local.set $b     (i64.add (local.get $b1) (local.get $b)))\n  (local.set $carry (i64.or (i64.extend_i32_u  (i64.lt_u (local.get $b) (local.get $b1))) (local.get $carry)))\n  ;; a\n  (local.set $a     (i64.add (local.get $a) (local.get $carry)))\n  (local.set $carry (i64.extend_i32_u (i64.lt_u (local.get $a) (local.get $carry))))\n  (local.set $a     (i64.add (local.get $a1) (local.get $a)))\n  (local.set $carry (i64.or (i64.extend_i32_u  (i64.lt_u (local.get $a) (local.get $a1))) (local.get $carry)))\n\n  (call $mod_320\n        (local.get $carry) (local.get $a)    (local.get $b)    (local.get $c)    (local.get $d)\n        (i64.const 0)      (local.get $moda) (local.get $modb) (local.get $modc) (local.get $modd) (local.get $sp))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::AND, {
    .wast = "(func $AND\n  (i64.store (i32.sub (global.get $sp) (i32.const 8))  (i64.and (i64.load (i32.sub (global.get $sp) (i32.const 8)))  (i64.load (i32.add (global.get $sp) (i32.const 24)))))\n  (i64.store (i32.sub (global.get $sp) (i32.const 16)) (i64.and (i64.load (i32.sub (global.get $sp) (i32.const 16))) (i64.load (i32.add (global.get $sp) (i32.const 16)))))\n  (i64.store (i32.sub (global.get $sp) (i32.const 24)) (i64.and (i64.load (i32.sub (global.get $sp) (i32.const 24))) (i64.load (i32.add (global.get $sp) (i32.const 8)))))\n  (i64.store (i32.sub (global.get $sp) (i32.const 32)) (i64.and (i64.load (i32.sub (global.get $sp) (i32.const 32))) (i64.load (global.get $sp))))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::BYTE, {
    .wast = ";; stack:\n;;  0: offset\n;; -1: value\n(func $BYTE\n    (local $sp i32)\n\n    (local $x1 i64)\n    (local $x2 i64)\n    (local $x3 i64)\n    (local $x4 i64)\n    (local $y1 i64)\n    (local $y2 i64)\n    (local $y3 i64)\n    (local $y4 i64)\n\n    (local $r1 i64)\n    (local $r2 i64)\n    (local $r3 i64)\n    (local $r4 i64)\n    (local $component i64)\n    (local $condition i64)\n\n    ;; load args from the stack\n    (local.set $x1 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n    (local.set $x2 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n    (local.set $x3 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n    (local.set $x4 (i64.load (global.get $sp)))\n\n    (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n    (local.set $y1 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n    (local.set $y2 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n    (local.set $y3 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n    (local.set $y4 (i64.load (local.get $sp)))\n\n    (block\n        (if (i64.eqz (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3))) (then\n            (nop)\n            (block\n                (local.set $condition (i64.div_u (local.get $x4) (i64.const 8)))\n                (if (i64.eq (local.get $condition) (i64.const 0)) (then\n                    (local.set $component (local.get $y1))\n                )(else\n                    (if (i64.eq (local.get $condition) (i64.const 1)) (then\n                        (local.set $component (local.get $y2))\n                    )(else\n                        (if (i64.eq (local.get $condition) (i64.const 2)) (then\n                            (local.set $component (local.get $y3))\n                        )(else\n                            (if (i64.eq (local.get $condition) (i64.const 3)) (then\n                                (local.set $component (local.get $y4))\n                            ))\n                        ))\n                    ))\n                ))\n\n            )\n            (local.set $x4 (i64.mul (i64.rem_u (local.get $x4) (i64.const 8)) (i64.const 8)))\n            (local.set $r4 (i64.shr_u (local.get $component) (i64.sub (i64.const 56) (local.get $x4))))\n            (local.set $r4 (i64.and (i64.const 255) (local.get $r4)))\n        ))\n\n    )\n    (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $r1))\n    (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $r2))\n    (i64.store (i32.add (local.get $sp) (i32.const  8)) (local.get $r3))\n    (i64.store          (local.get $sp)                 (local.get $r4))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::DIV, {
    .wast = "(func $DIV\n  (local $sp i32)\n  ;; dividend\n  (local $a i64)\n  (local $b i64)\n  (local $c i64)\n  (local $d i64)\n\n  ;; divisor\n  (local $a1 i64)\n  (local $b1 i64)\n  (local $c1 i64)\n  (local $d1 i64)\n\n  ;; quotient\n  (local $aq i64)\n  (local $bq i64)\n  (local $cq i64)\n  (local $dq i64)\n\n  ;; mask\n  (local $maska i64)\n  (local $maskb i64)\n  (local $maskc i64)\n  (local $maskd i64)\n  (local $carry i32)\n  (local $temp  i64)\n  (local $temp2  i64)\n\n  (local.set $sp (global.get $sp))\n  (local.set $maskd (i64.const 1))\n\n  ;; load args from the stack\n  (local.set $a (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $c (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $d (i64.load (local.get $sp)))\n\n  (local.set $sp (i32.sub (local.get $sp) (i32.const 32)))\n\n  (local.set $a1 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $c1 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $d1 (i64.load (local.get $sp)))\n\n  (block $main\n    ;; check div by 0\n    (if (call $iszero_256 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1))\n      (br $main)\n    )\n\n    ;; align bits\n    (block $done\n      (loop $loop\n        ;; align bits;\n        (if\n          ;; check to make sure we are not overflowing\n          (i32.or (i64.eqz (i64.clz (local.get $a1)))\n          ;;  divisor < dividend\n          (call $gte_256 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1) (local.get $a) (local.get $b) (local.get $c) (local.get $d)))\n          (br $done)\n        )\n\n        ;; divisor = divisor << 1\n        (local.set $a1 (i64.add (i64.shl (local.get $a1) (i64.const 1)) (i64.shr_u (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shl (local.get $b1) (i64.const 1)) (i64.shr_u (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shl (local.get $c1) (i64.const 1)) (i64.shr_u (local.get $d1) (i64.const 63))))\n        (local.set $d1 (i64.shl (local.get $d1) (i64.const 1)))\n\n        ;; mask = mask << 1\n        (local.set $maska (i64.add (i64.shl (local.get $maska) (i64.const 1)) (i64.shr_u (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shl (local.get $maskb) (i64.const 1)) (i64.shr_u (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shl (local.get $maskc) (i64.const 1)) (i64.shr_u (local.get $maskd) (i64.const 63))))\n        (local.set $maskd (i64.shl (local.get $maskd) (i64.const 1)))\n\n        (br $loop)\n      )\n    )\n\n\n    (block $done\n      (loop $loop\n        ;; loop while mask != 0\n        (if (call $iszero_256 (local.get $maska) (local.get $maskb) (local.get $maskc) (local.get $maskd))\n          (br $done)\n        )\n        ;; if dividend >= divisor\n        (if (call $gte_256 (local.get $a) (local.get $b) (local.get $c) (local.get $d) (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1))\n          (then\n            ;; dividend = dividend - divisor\n            (local.set $carry (i64.lt_u (local.get $d) (local.get $d1)))\n            (local.set $d     (i64.sub  (local.get $d) (local.get $d1)))\n            (local.set $temp  (i64.sub  (local.get $c) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $c)))\n            (local.set $c     (i64.sub  (local.get $temp) (local.get $c1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $c) (local.get $temp)) (local.get $carry)))\n            (local.set $temp  (i64.sub  (local.get $b) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $b)))\n            (local.set $b     (i64.sub  (local.get $temp) (local.get $b1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $b) (local.get $temp)) (local.get $carry)))\n            (local.set $a     (i64.sub  (i64.sub (local.get $a) (i64.extend_i32_u (local.get $carry))) (local.get $a1)))\n\n            ;; result = result + mask\n            (local.set $dq   (i64.add (local.get $maskd) (local.get $dq)))\n            (local.set $temp (i64.extend_i32_u (i64.lt_u (local.get $dq) (local.get $maskd))))\n            (local.set $cq   (i64.add (local.get $cq) (local.get $temp)))\n            (local.set $temp (i64.extend_i32_u (i64.lt_u (local.get $cq) (local.get $temp))))\n            (local.set $cq   (i64.add (local.get $maskc) (local.get $cq)))\n            (local.set $temp (i64.or (i64.extend_i32_u  (i64.lt_u (local.get $cq) (local.get $maskc))) (local.get $temp)))\n            (local.set $bq   (i64.add (local.get $bq) (local.get $temp)))\n            (local.set $temp (i64.extend_i32_u (i64.lt_u (local.get $bq) (local.get $temp))))\n            (local.set $bq   (i64.add (local.get $maskb) (local.get $bq)))\n            (local.set $aq   (i64.add (local.get $maska) (i64.add (local.get $aq) (i64.or (i64.extend_i32_u (i64.lt_u (local.get $bq) (local.get $maskb))) (local.get $temp)))))\n          )\n        )\n        ;; divisor = divisor >> 1\n        (local.set $d1 (i64.add (i64.shr_u (local.get $d1) (i64.const 1)) (i64.shl (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shr_u (local.get $c1) (i64.const 1)) (i64.shl (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shr_u (local.get $b1) (i64.const 1)) (i64.shl (local.get $a1) (i64.const 63))))\n        (local.set $a1 (i64.shr_u (local.get $a1) (i64.const 1)))\n\n        ;; mask = mask >> 1\n        (local.set $maskd (i64.add (i64.shr_u (local.get $maskd) (i64.const 1)) (i64.shl (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shr_u (local.get $maskc) (i64.const 1)) (i64.shl (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shr_u (local.get $maskb) (i64.const 1)) (i64.shl (local.get $maska) (i64.const 63))))\n        (local.set $maska (i64.shr_u (local.get $maska) (i64.const 1)))\n        (br $loop)\n      )\n    )\n  );; end of main\n\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $aq))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $bq))\n  (i64.store (i32.add (local.get $sp) (i32.const 8))  (local.get $cq))\n  (i64.store (local.get $sp) (local.get $dq))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::EXP, {
    .wast = "(func $EXP\n  (local $sp i32)\n\n  ;; base\n  (local $base0 i64)\n  (local $base1 i64)\n  (local $base2 i64)\n  (local $base3 i64)\n\n  ;; exp\n  (local $exp0 i64)\n  (local $exp1 i64)\n  (local $exp2 i64)\n  (local $exp3 i64)\n\n  (local $r0 i64)\n  (local $r1 i64)\n  (local $r2 i64)\n  (local $r3 i64)\n\n  (local $gasCounter i32)\n  (local.set $sp (global.get $sp))\n\n  ;; load args from the stack\n  (local.set $base0 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $base1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $base2 (i64.load (i32.add (local.get $sp) (i32.const  8))))\n  (local.set $base3 (i64.load          (local.get $sp)))\n\n  (local.set $sp (i32.sub (local.get $sp) (i32.const 32)))\n\n  (local.set $exp0 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $exp1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $exp2 (i64.load (i32.add (local.get $sp) (i32.const  8))))\n  (local.set $exp3 (i64.load          (local.get $sp)))\n\n  ;; let result = new BN[1]\n  (local.set $r3 (i64.const 1))\n\n  (block $done\n    (loop $loop\n       ;; while [exp > 0] {\n      (if (call $iszero_256 (local.get $exp0) (local.get $exp1) (local.get $exp2) (local.get $exp3))\n        (br $done)\n      )\n\n      ;; if[exp.modn[2] === 1]\n      ;; is odd?\n      (if (i64.eqz (i64.ctz (local.get $exp3)))\n\n        ;; result = result.mul[base].mod[TWO_POW256]\n        ;; r = r * a\n        (then\n          (call $mul_256 (local.get $r0) (local.get $r1) (local.get $r2) (local.get $r3) (local.get $base0) (local.get $base1) (local.get $base2) (local.get $base3) (i32.add (local.get $sp) (i32.const 24)))\n          (local.set $r0 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n          (local.set $r1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n          (local.set $r2 (i64.load (i32.add (local.get $sp) (i32.const  8))))\n          (local.set $r3 (i64.load          (local.get $sp)))\n        )\n      )\n      ;; exp = exp.shrn 1\n      (local.set $exp3 (i64.add (i64.shr_u (local.get $exp3) (i64.const 1)) (i64.shl (local.get $exp2) (i64.const 63))))\n      (local.set $exp2 (i64.add (i64.shr_u (local.get $exp2) (i64.const 1)) (i64.shl (local.get $exp1) (i64.const 63))))\n      (local.set $exp1 (i64.add (i64.shr_u (local.get $exp1) (i64.const 1)) (i64.shl (local.get $exp0) (i64.const 63))))\n      (local.set $exp0 (i64.shr_u (local.get $exp0) (i64.const 1)))\n\n      ;; base = base.mulr[baser].modr[TWO_POW256]\n      (call $mul_256 (local.get $base0) (local.get $base1) (local.get $base2) (local.get $base3) (local.get $base0) (local.get $base1) (local.get $base2) (local.get $base3) (i32.add (local.get $sp) (i32.const 24)))\n      (local.set $base0 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n      (local.set $base1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n      (local.set $base2 (i64.load (i32.add (local.get $sp) (i32.const  8))))\n      (local.set $base3 (i64.load          (local.get $sp)))\n\n      (local.set $gasCounter (i32.add (local.get $gasCounter) (i32.const 1)))\n      (br $loop)\n    )\n  )\n\n  ;; use gas\n  ;; Log256[Exponent] * 10\n  (call $useGas\n    (i64.extend_i32_u\n      (i32.mul\n        (i32.const 10)\n        (i32.div_u\n          (i32.add (local.get $gasCounter) (i32.const 7))\n          (i32.const 8)))))\n\n  ;; decement the stack pointer\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $r0))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $r1))\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (local.get $r2))\n  (i64.store          (local.get $sp)                 (local.get $r3))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::MOD, {
    .wast = "(func $MOD\n  (local $sp i32)\n\n  ;; dividend\n  (local $a i64)\n  (local $b i64)\n  (local $c i64)\n  (local $d i64)\n\n  ;; divisor\n  (local $a1 i64)\n  (local $b1 i64)\n  (local $c1 i64)\n  (local $d1 i64)\n\n  ;; quotient\n  (local $aq i64)\n  (local $bq i64)\n  (local $cq i64)\n  (local $dq i64)\n\n  ;; mask\n  (local $maska i64)\n  (local $maskb i64)\n  (local $maskc i64)\n  (local $maskd i64)\n  (local $carry i32)\n  (local $temp i64)\n\n  (local.set $maskd (i64.const 1))\n\n  ;; load args from the stack\n  (local.set $a (i64.load (i32.add (global.get $sp) (i32.const 24))))\n  (local.set $b (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $c (i64.load (i32.add (global.get $sp) (i32.const  8))))\n  (local.set $d (i64.load          (global.get $sp)))\n  ;; decement the stack pointer\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n  (local.set $a1 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $c1 (i64.load (i32.add (local.get $sp) (i32.const  8))))\n  (local.set $d1 (i64.load          (local.get $sp)))\n\n\n  (block $main\n    ;; check div by 0\n    (if (call $iszero_256 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1))\n      (then\n        (local.set $a (i64.const 0))\n        (local.set $b (i64.const 0))\n        (local.set $c (i64.const 0))\n        (local.set $d (i64.const 0))\n        (br $main)\n      )\n    )\n\n    ;; align bits\n    (block $done\n        (loop $loop\n        ;; align bits;\n        (if (i32.or (i64.eqz (i64.clz (local.get $a1))) (call $gte_256 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1) (local.get $a) (local.get $b) (local.get $c) (local.get $d)))\n          (br $done)\n        )\n\n        ;; divisor = divisor << 1\n        (local.set $a1 (i64.add (i64.shl (local.get $a1) (i64.const 1)) (i64.shr_u (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shl (local.get $b1) (i64.const 1)) (i64.shr_u (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shl (local.get $c1) (i64.const 1)) (i64.shr_u (local.get $d1) (i64.const 63))))\n        (local.set $d1 (i64.shl (local.get $d1) (i64.const 1)))\n\n        ;; mask = mask << 1\n        (local.set $maska (i64.add (i64.shl (local.get $maska) (i64.const 1)) (i64.shr_u (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shl (local.get $maskb) (i64.const 1)) (i64.shr_u (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shl (local.get $maskc) (i64.const 1)) (i64.shr_u (local.get $maskd) (i64.const 63))))\n        (local.set $maskd (i64.shl (local.get $maskd) (i64.const 1)))\n\n        (br $loop)\n      )\n    )\n\n    (block $done\n      (loop $loop\n        ;; loop while mask != 0\n        (if (call $iszero_256 (local.get $maska) (local.get $maskb) (local.get $maskc) (local.get $maskd))\n          (br $done)\n        )\n        ;; if dividend >= divisor\n        (if (call $gte_256 (local.get $a) (local.get $b) (local.get $c) (local.get $d) (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1))\n          (then\n            ;; dividend = dividend - divisor\n            (local.set $carry (i64.lt_u (local.get $d) (local.get $d1)))\n            (local.set $d     (i64.sub  (local.get $d) (local.get $d1)))\n            (local.set $temp  (i64.sub  (local.get $c) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $c)))\n            (local.set $c     (i64.sub  (local.get $temp) (local.get $c1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $c) (local.get $temp)) (local.get $carry)))\n            (local.set $temp  (i64.sub  (local.get $b) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $b)))\n            (local.set $b     (i64.sub  (local.get $temp) (local.get $b1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $b) (local.get $temp)) (local.get $carry)))\n            (local.set $a     (i64.sub  (i64.sub (local.get $a) (i64.extend_i32_u (local.get $carry))) (local.get $a1)))\n          )\n        )\n        ;; divisor = divisor >> 1\n        (local.set $d1 (i64.add (i64.shr_u (local.get $d1) (i64.const 1)) (i64.shl (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shr_u (local.get $c1) (i64.const 1)) (i64.shl (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shr_u (local.get $b1) (i64.const 1)) (i64.shl (local.get $a1) (i64.const 63))))\n        (local.set $a1 (i64.shr_u (local.get $a1) (i64.const 1)))\n\n        ;; mask = mask >> 1\n        (local.set $maskd (i64.add (i64.shr_u (local.get $maskd) (i64.const 1)) (i64.shl (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shr_u (local.get $maskc) (i64.const 1)) (i64.shl (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shr_u (local.get $maskb) (i64.const 1)) (i64.shl (local.get $maska) (i64.const 63))))\n        (local.set $maska (i64.shr_u (local.get $maska) (i64.const 1)))\n        (br $loop)\n      )\n    )\n  );; end of main\n\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $a))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $b))\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (local.get $c))\n  (i64.store          (local.get $sp)                 (local.get $d))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::MSIZE, {
    .wast = "(func $MSIZE\n  (local $sp i32)\n\n  ;; there's no input item for us to overwrite\n  (local.set $sp (i32.add (global.get $sp) (i32.const 32)))\n\n  (i64.store (i32.add (local.get $sp) (i32.const 0)) \n             (i64.mul (global.get $wordCount) (i64.const 32)))\n  (i64.store (i32.add (local.get $sp) (i32.const 8)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (i64.const 0))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::MSTORE8, {
    .wast = ";; stack:\n;;  0: offset\n;; -1: word\n(func $MSTORE8\n  (local $sp i32)\n\n  (local $offset i32)\n\n  (local $offset0 i64)\n  (local $offset1 i64)\n  (local $offset2 i64)\n  (local $offset3 i64)\n\n  ;; load args from the stack\n  (local.set $offset0 (i64.load          (global.get $sp)))\n  (local.set $offset1 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n  (local.set $offset2 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $offset3 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n\n  (local.set $offset \n             (call $check_overflow (local.get $offset0)\n                                   (local.get $offset1)\n                                   (local.get $offset2)\n                                   (local.get $offset3)))\n\n  (call $memusegas (local.get $offset) (i32.const 1))\n\n  ;; pop stack\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n  (local.set $offset (i32.add (local.get $offset) (global.get $memstart)))\n  (i32.store8 (i32.add (local.get $offset) (i32.const 0)) (i32.load (local.get $sp)))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::MUL, {
    .wast = "(func $MUL\n  (call $mul_256\n        (i64.load (i32.add (global.get $sp) (i32.const 24)))\n        (i64.load (i32.add (global.get $sp) (i32.const 16)))\n        (i64.load (i32.add (global.get $sp) (i32.const  8)))\n        (i64.load          (global.get $sp))\n        (i64.load (i32.sub (global.get $sp) (i32.const  8)))\n        (i64.load (i32.sub (global.get $sp) (i32.const 16)))\n        (i64.load (i32.sub (global.get $sp) (i32.const 24)))\n        (i64.load (i32.sub (global.get $sp) (i32.const 32)))\n        (i32.sub (global.get $sp) (i32.const 8))\n  )\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::MULMOD, {
    .wast = "(func $MULMOD\n  (local $sp i32)\n\n  (local $a i64)\n  (local $c i64)\n  (local $e i64)\n  (local $g i64)\n  (local $i i64)\n  (local $k i64)\n  (local $m i64)\n  (local $o i64)\n  (local $b i64)\n  (local $d i64)\n  (local $f i64)\n  (local $h i64)\n  (local $j i64)\n  (local $l i64)\n  (local $n i64)\n  (local $p i64)\n  (local $temp7 i64)\n  (local $temp6 i64)\n  (local $temp5 i64)\n  (local $temp4 i64)\n  (local $temp3 i64)\n  (local $temp2 i64)\n  (local $temp1 i64)\n  (local $temp0 i64)\n  (local $rowCarry i64)\n\n  (local $moda i64)\n  (local $modb i64)\n  (local $modc i64)\n  (local $modd i64)\n\n  ;; pop two items of the stack\n  (local.set $a (i64.load (i32.add (global.get $sp) (i32.const 24))))\n  (local.set $c (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $e (i64.load (i32.add (global.get $sp) (i32.const  8))))\n  (local.set $g (i64.load          (global.get $sp)))\n  (local.set $i (i64.load (i32.sub (global.get $sp) (i32.const  8))))\n  (local.set $k (i64.load (i32.sub (global.get $sp) (i32.const 16))))\n  (local.set $m (i64.load (i32.sub (global.get $sp) (i32.const 24))))\n  (local.set $o (i64.load (i32.sub (global.get $sp) (i32.const 32))))\n\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 64)))\n\n  ;; MUL\n  ;;  a b c d e f g h\n  ;;* i j k l m n o p\n  ;;----------------\n\n  ;; split the ops\n  (local.set $b (i64.and (local.get $a) (i64.const 4294967295)))\n  (local.set $a (i64.shr_u (local.get $a) (i64.const 32))) \n\n  (local.set $d (i64.and (local.get $c) (i64.const 4294967295)))\n  (local.set $c (i64.shr_u (local.get $c) (i64.const 32))) \n\n  (local.set $f (i64.and (local.get $e) (i64.const 4294967295)))\n  (local.set $e (i64.shr_u (local.get $e) (i64.const 32)))\n\n  (local.set $h (i64.and (local.get $g) (i64.const 4294967295)))\n  (local.set $g (i64.shr_u (local.get $g) (i64.const 32)))\n\n  (local.set $j (i64.and (local.get $i) (i64.const 4294967295)))\n  (local.set $i (i64.shr_u (local.get $i) (i64.const 32))) \n\n  (local.set $l (i64.and (local.get $k) (i64.const 4294967295)))\n  (local.set $k (i64.shr_u (local.get $k) (i64.const 32))) \n\n  (local.set $n (i64.and (local.get $m) (i64.const 4294967295)))\n  (local.set $m (i64.shr_u (local.get $m) (i64.const 32)))\n\n  (local.set $p (i64.and (local.get $o) (i64.const 4294967295)))\n  (local.set $o (i64.shr_u (local.get $o) (i64.const 32)))\n\n   ;; first row multiplication \n  ;; p * h\n  (local.set $temp0 (i64.mul (local.get $p) (local.get $h)))\n  ;; p * g + carry\n  (local.set $temp1 (i64.add (i64.mul (local.get $p) (local.get $g)) (i64.shr_u (local.get $temp0) (i64.const 32))))\n  ;; p * f + carry\n  (local.set $temp2 (i64.add (i64.mul (local.get $p) (local.get $f)) (i64.shr_u (local.get $temp1) (i64.const 32))))\n  ;; p * e + carry\n  (local.set $temp3 (i64.add (i64.mul (local.get $p) (local.get $e)) (i64.shr_u (local.get $temp2) (i64.const 32))))\n  ;; p * d + carry\n  (local.set $temp4 (i64.add (i64.mul (local.get $p) (local.get $d)) (i64.shr_u (local.get $temp3) (i64.const 32))))\n  ;; p * c + carry\n  (local.set $temp5 (i64.add (i64.mul (local.get $p) (local.get $c)) (i64.shr_u (local.get $temp4) (i64.const 32))))\n  ;; p * b + carry\n  (local.set $temp6 (i64.add (i64.mul (local.get $p) (local.get $b)) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; p * a + carry\n  (local.set $temp7 (i64.add (i64.mul (local.get $p) (local.get $a)) (i64.shr_u (local.get $temp6) (i64.const 32))))\n  (local.set $rowCarry (i64.shr_u (local.get $temp7) (i64.const 32)))\n\n  ;; second row\n  ;; o * h + $temp1 \n  (local.set $temp1 (i64.add (i64.mul (local.get $o) (local.get $h)) (i64.and (local.get $temp1) (i64.const 4294967295))))\n  ;; o * g + $temp2 + carry\n  (local.set $temp2 (i64.add (i64.add (i64.mul (local.get $o) (local.get $g)) (i64.and (local.get $temp2) (i64.const 4294967295))) (i64.shr_u (local.get $temp1) (i64.const 32))))\n  ;; o * f + $temp3 + carry\n  (local.set $temp3 (i64.add (i64.add (i64.mul (local.get $o) (local.get $f)) (i64.and (local.get $temp3) (i64.const 4294967295))) (i64.shr_u (local.get $temp2) (i64.const 32))))\n  ;; o * e + $temp4 + carry\n  (local.set $temp4 (i64.add (i64.add (i64.mul (local.get $o) (local.get $e)) (i64.and (local.get $temp4) (i64.const 4294967295))) (i64.shr_u (local.get $temp3) (i64.const 32))))\n  ;; o * d + $temp5 + carry\n  (local.set $temp5 (i64.add (i64.add (i64.mul (local.get $o) (local.get $d)) (i64.and (local.get $temp5) (i64.const 4294967295))) (i64.shr_u (local.get $temp4) (i64.const 32))))\n  ;; o * c + $temp6 + carry\n  (local.set $temp6 (i64.add (i64.add (i64.mul (local.get $o) (local.get $c)) (i64.and (local.get $temp6) (i64.const 4294967295))) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; o * b + $temp7 + carry\n  (local.set $temp7 (i64.add (i64.add (i64.mul (local.get $o) (local.get $b)) (i64.and (local.get $temp7) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n  ;; o * a + carry + rowCarry\n  (local.set $p (i64.add (i64.add (i64.mul (local.get $o) (local.get $a)) (i64.shr_u (local.get $temp7) (i64.const 32))) (local.get $rowCarry)))\n  (local.set $rowCarry (i64.shr_u (local.get $p) (i64.const 32)))\n\n  ;; third row - n\n  ;; n * h + $temp2 \n  (local.set $temp2 (i64.add (i64.mul (local.get $n) (local.get $h)) (i64.and (local.get $temp2) (i64.const 4294967295))))\n  ;; n * g + $temp3  carry\n  (local.set $temp3 (i64.add (i64.add (i64.mul (local.get $n) (local.get $g)) (i64.and (local.get $temp3) (i64.const 4294967295))) (i64.shr_u (local.get $temp2) (i64.const 32))))\n  ;; n * f + $temp4) + carry\n  (local.set $temp4 (i64.add (i64.add (i64.mul (local.get $n) (local.get $f)) (i64.and (local.get $temp4) (i64.const 4294967295))) (i64.shr_u (local.get $temp3) (i64.const 32))))\n  ;; n * e + $temp5 + carry\n  (local.set $temp5 (i64.add (i64.add (i64.mul (local.get $n) (local.get $e)) (i64.and (local.get $temp5) (i64.const 4294967295))) (i64.shr_u (local.get $temp4) (i64.const 32))))\n  ;; n * d + $temp6 + carry\n  (local.set $temp6 (i64.add (i64.add (i64.mul (local.get $n) (local.get $d)) (i64.and (local.get $temp6) (i64.const 4294967295))) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; n * c + $temp7 + carry\n  (local.set $temp7 (i64.add (i64.add (i64.mul (local.get $n) (local.get $c)) (i64.and (local.get $temp7) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n  ;; n * b + $p + carry\n  (local.set $p     (i64.add (i64.add (i64.mul (local.get $n) (local.get $b)) (i64.and (local.get $p)     (i64.const 4294967295))) (i64.shr_u (local.get $temp7) (i64.const 32))))\n  ;; n * a + carry\n  (local.set $o (i64.add (i64.add (i64.mul (local.get $n) (local.get $a)) (i64.shr_u (local.get $p) (i64.const 32))) (local.get $rowCarry)))\n  (local.set $rowCarry (i64.shr_u (local.get $o) (i64.const 32)))\n\n  ;; forth row \n  ;; m * h + $temp3\n  (local.set $temp3 (i64.add (i64.mul (local.get $m) (local.get $h)) (i64.and (local.get $temp3) (i64.const 4294967295))))\n  ;; m * g + $temp4 + carry\n  (local.set $temp4 (i64.add (i64.add (i64.mul (local.get $m) (local.get $g)) (i64.and (local.get $temp4) (i64.const 4294967295))) (i64.shr_u (local.get $temp3) (i64.const 32))))\n  ;; m * f + $temp5 + carry\n  (local.set $temp5 (i64.add (i64.add (i64.mul (local.get $m) (local.get $f)) (i64.and (local.get $temp5) (i64.const 4294967295))) (i64.shr_u (local.get $temp4) (i64.const 32))))\n  ;; m * e + $temp6 + carry\n  (local.set $temp6 (i64.add (i64.add (i64.mul (local.get $m) (local.get $e)) (i64.and (local.get $temp6) (i64.const 4294967295))) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; m * d + $temp7 + carry\n  (local.set $temp7 (i64.add (i64.add (i64.mul (local.get $m) (local.get $d)) (i64.and (local.get $temp7) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n  ;; m * c + $p + carry\n  (local.set $p     (i64.add (i64.add (i64.mul (local.get $m) (local.get $c)) (i64.and (local.get $p)     (i64.const 4294967295))) (i64.shr_u (local.get $temp7) (i64.const 32))))\n  ;; m * b + $o + carry\n  (local.set $o     (i64.add (i64.add (i64.mul (local.get $m) (local.get $b)) (i64.and (local.get $o)     (i64.const 4294967295))) (i64.shr_u (local.get $p)     (i64.const 32))))\n  ;; m * a + carry + rowCarry\n  (local.set $n     (i64.add (i64.add (i64.mul (local.get $m) (local.get $a)) (i64.shr_u (local.get $o) (i64.const 32))) (local.get $rowCarry)))\n  (local.set $rowCarry (i64.shr_u (local.get $n) (i64.const 32)))\n\n  ;; fith row\n  ;; l * h + $temp4\n  (local.set $temp4 (i64.add (i64.mul (local.get $l) (local.get $h)) (i64.and (local.get $temp4) (i64.const 4294967295))))\n  ;; l * g + $temp5 + carry\n  (local.set $temp5 (i64.add (i64.add (i64.mul (local.get $l) (local.get $g)) (i64.and (local.get $temp5) (i64.const 4294967295))) (i64.shr_u (local.get $temp4) (i64.const 32))))\n  ;; l * f + $temp6 + carry\n  (local.set $temp6 (i64.add (i64.add (i64.mul (local.get $l) (local.get $f)) (i64.and (local.get $temp6) (i64.const 4294967295))) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; l * e + $temp7 + carry\n  (local.set $temp7 (i64.add (i64.add (i64.mul (local.get $l) (local.get $e)) (i64.and (local.get $temp7) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n  ;; l * d + $p + carry\n  (local.set $p     (i64.add (i64.add (i64.mul (local.get $l) (local.get $d)) (i64.and (local.get $p)     (i64.const 4294967295))) (i64.shr_u (local.get $temp7) (i64.const 32))))\n  ;; l * c + $o + carry\n  (local.set $o     (i64.add (i64.add (i64.mul (local.get $l) (local.get $c)) (i64.and (local.get $o)     (i64.const 4294967295))) (i64.shr_u (local.get $p)     (i64.const 32))))\n  ;; l * b + $n + carry\n  (local.set $n     (i64.add (i64.add (i64.mul (local.get $l) (local.get $b)) (i64.and (local.get $n)     (i64.const 4294967295))) (i64.shr_u (local.get $o)     (i64.const 32))))\n  ;; l * a + carry + rowCarry\n  (local.set $m     (i64.add (i64.add (i64.mul (local.get $l) (local.get $a)) (i64.shr_u (local.get $n) (i64.const 32))) (local.get $rowCarry)))\n  (local.set $rowCarry (i64.shr_u (local.get $m) (i64.const 32)))\n\n  ;; sixth row \n  ;; k * h + $temp5\n  (local.set $temp5 (i64.add (i64.mul (local.get $k) (local.get $h)) (i64.and (local.get $temp5) (i64.const 4294967295))))\n  ;; k * g + $temp6 + carry\n  (local.set $temp6 (i64.add (i64.add (i64.mul (local.get $k) (local.get $g)) (i64.and (local.get $temp6) (i64.const 4294967295))) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; k * f + $temp7 + carry\n  (local.set $temp7 (i64.add (i64.add (i64.mul (local.get $k) (local.get $f)) (i64.and (local.get $temp7) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n  ;; k * e + $p + carry\n  (local.set $p     (i64.add (i64.add (i64.mul (local.get $k) (local.get $e)) (i64.and (local.get $p)     (i64.const 4294967295))) (i64.shr_u (local.get $temp7) (i64.const 32))))\n  ;; k * d + $o + carry\n  (local.set $o     (i64.add (i64.add (i64.mul (local.get $k) (local.get $d)) (i64.and (local.get $o)     (i64.const 4294967295))) (i64.shr_u (local.get $p)     (i64.const 32))))\n  ;; k * c + $n + carry\n  (local.set $n     (i64.add (i64.add (i64.mul (local.get $k) (local.get $c)) (i64.and (local.get $n)     (i64.const 4294967295))) (i64.shr_u (local.get $o)     (i64.const 32))))\n  ;; k * b + $m + carry\n  (local.set $m     (i64.add (i64.add (i64.mul (local.get $k) (local.get $b)) (i64.and (local.get $m)     (i64.const 4294967295))) (i64.shr_u (local.get $n)     (i64.const 32))))\n  ;; k * a + carry\n  (local.set $l     (i64.add (i64.add (i64.mul (local.get $k) (local.get $a)) (i64.shr_u (local.get $m) (i64.const 32))) (local.get $rowCarry)))\n  (local.set $rowCarry (i64.shr_u (local.get $l) (i64.const 32)))\n\n  ;; seventh row\n  ;; j * h + $temp6\n  (local.set $temp6 (i64.add (i64.mul (local.get $j) (local.get $h)) (i64.and (local.get $temp6) (i64.const 4294967295))))\n  ;; j * g + $temp7 + carry\n  (local.set $temp7 (i64.add (i64.add (i64.mul (local.get $j) (local.get $g)) (i64.and (local.get $temp7) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n  ;; j * f + $p +carry\n  (local.set $p     (i64.add (i64.add (i64.mul (local.get $j) (local.get $f)) (i64.and (local.get $p)     (i64.const 4294967295))) (i64.shr_u (local.get $temp7) (i64.const 32))))\n  ;; j * e + $o + carry\n  (local.set $o     (i64.add (i64.add (i64.mul (local.get $j) (local.get $e)) (i64.and (local.get $o)     (i64.const 4294967295))) (i64.shr_u (local.get $p)     (i64.const 32))))\n  ;; j * d + $n + carry\n  (local.set $n     (i64.add (i64.add (i64.mul (local.get $j) (local.get $d)) (i64.and (local.get $n)     (i64.const 4294967295))) (i64.shr_u (local.get $o)     (i64.const 32))))\n  ;; j * c + $m + carry\n  (local.set $m     (i64.add (i64.add (i64.mul (local.get $j) (local.get $c)) (i64.and (local.get $m)     (i64.const 4294967295))) (i64.shr_u (local.get $n)     (i64.const 32))))\n  ;; j * b + $l + carry\n  (local.set $l     (i64.add (i64.add (i64.mul (local.get $j) (local.get $b)) (i64.and (local.get $l)     (i64.const 4294967295))) (i64.shr_u (local.get $m)     (i64.const 32))))\n  ;; j * a + carry\n  (local.set $k     (i64.add (i64.add (i64.mul (local.get $j) (local.get $a)) (i64.shr_u (local.get $l) (i64.const 32))) (local.get $rowCarry)))\n  (local.set $rowCarry (i64.shr_u (local.get $k) (i64.const 32)))\n\n  ;; eigth row\n  ;; i * h + $temp7 \n  (local.set $temp7 (i64.add (i64.mul (local.get $i) (local.get $h)) (i64.and (local.get $temp7) (i64.const 4294967295))))\n  ;; i * g + $p \n  (local.set $p     (i64.add (i64.add (i64.mul (local.get $i) (local.get $g)) (i64.and (local.get $p)     (i64.const 4294967295))) (i64.shr_u (local.get $temp7) (i64.const 32))))\n  ;; i * f + $o + carry\n  (local.set $o     (i64.add (i64.add (i64.mul (local.get $i) (local.get $f)) (i64.and (local.get $o)     (i64.const 4294967295))) (i64.shr_u (local.get $p)     (i64.const 32))))\n  ;; i * e + $n + carry\n  (local.set $n     (i64.add (i64.add (i64.mul (local.get $i) (local.get $e)) (i64.and (local.get $n)     (i64.const 4294967295))) (i64.shr_u (local.get $o)     (i64.const 32))))\n  ;; i * d + $m + carry\n  (local.set $m     (i64.add (i64.add (i64.mul (local.get $i) (local.get $d)) (i64.and (local.get $m)     (i64.const 4294967295))) (i64.shr_u (local.get $n)     (i64.const 32))))\n  ;; i * c + $l + carry\n  (local.set $l     (i64.add (i64.add (i64.mul (local.get $i) (local.get $c)) (i64.and (local.get $l)     (i64.const 4294967295))) (i64.shr_u (local.get $m)     (i64.const 32))))\n  ;; i * b + $k + carry\n  (local.set $k     (i64.add (i64.add (i64.mul (local.get $i) (local.get $b)) (i64.and (local.get $k)     (i64.const 4294967295))) (i64.shr_u (local.get $l)     (i64.const 32))))\n  ;; i * a + carry\n  (local.set $j     (i64.add (i64.add (i64.mul (local.get $i) (local.get $a)) (i64.shr_u (local.get $k) (i64.const 32))) (local.get $rowCarry)))\n\n  ;; combine terms\n  (local.set $a (local.get $j))\n  (local.set $b (i64.or (i64.shl (local.get $k)     (i64.const 32)) (i64.and (local.get $l)     (i64.const 4294967295))))\n  (local.set $c (i64.or (i64.shl (local.get $m)     (i64.const 32)) (i64.and (local.get $n)     (i64.const 4294967295))))\n  (local.set $d (i64.or (i64.shl (local.get $o)     (i64.const 32)) (i64.and (local.get $p)     (i64.const 4294967295))))\n  (local.set $e (i64.or (i64.shl (local.get $temp7) (i64.const 32)) (i64.and (local.get $temp6) (i64.const 4294967295))))\n  (local.set $f (i64.or (i64.shl (local.get $temp5) (i64.const 32)) (i64.and (local.get $temp4) (i64.const 4294967295))))\n  (local.set $g (i64.or (i64.shl (local.get $temp3) (i64.const 32)) (i64.and (local.get $temp2) (i64.const 4294967295))))\n  (local.set $h (i64.or (i64.shl (local.get $temp1) (i64.const 32)) (i64.and (local.get $temp0) (i64.const 4294967295))))\n\n  ;; pop the MOD argmunet off the stack\n  (local.set $moda (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $modb (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $modc (i64.load (i32.add (local.get $sp) (i32.const  8))))\n  (local.set $modd (i64.load          (local.get $sp)))\n\n  (call $mod_512\n         (local.get $a) (local.get $b) (local.get $c) (local.get $d) (local.get $e) (local.get $f) (local.get $g) (local.get $h) \n         (i64.const 0)  (i64.const 0) (i64.const 0)  (i64.const 0)  (local.get $moda) (local.get $modb) (local.get $modc) (local.get $modd) (i32.add (local.get $sp) (i32.const 24))\n  )\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::NOT, {
    .wast = "(func $NOT\n  ;; FIXME: consider using 0xffffffffffffffff instead of -1?\n  (i64.store (i32.add (global.get $sp) (i32.const 24)) (i64.xor (i64.load (i32.add (global.get $sp) (i32.const 24))) (i64.const -1)))\n  (i64.store (i32.add (global.get $sp) (i32.const 16)) (i64.xor (i64.load (i32.add (global.get $sp) (i32.const 16))) (i64.const -1)))\n  (i64.store (i32.add (global.get $sp) (i32.const  8)) (i64.xor (i64.load (i32.add (global.get $sp) (i32.const  8))) (i64.const -1)))\n  (i64.store (i32.add (global.get $sp) (i32.const  0)) (i64.xor (i64.load (i32.add (global.get $sp) (i32.const  0))) (i64.const -1)))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::OR, {
    .wast = "(func $OR\n  (i64.store (i32.sub (global.get $sp) (i32.const  8)) (i64.or (i64.load (i32.sub (global.get $sp) (i32.const  8))) (i64.load (i32.add (global.get $sp) (i32.const 24)))))\n  (i64.store (i32.sub (global.get $sp) (i32.const 16)) (i64.or (i64.load (i32.sub (global.get $sp) (i32.const 16))) (i64.load (i32.add (global.get $sp) (i32.const 16)))))\n  (i64.store (i32.sub (global.get $sp) (i32.const 24)) (i64.or (i64.load (i32.sub (global.get $sp) (i32.const 24))) (i64.load (i32.add (global.get $sp) (i32.const  8)))))\n  (i64.store (i32.sub (global.get $sp) (i32.const 32)) (i64.or (i64.load (i32.sub (global.get $sp) (i32.const 32))) (i64.load          (global.get $sp))))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::PC, {
    .wast = "(func $PC\n  (param $pc i32)\n  (local $sp i32)\n\n  ;; add one to the stack\n  (local.set $sp (i32.add (global.get $sp) (i32.const 32)))\n  (i64.store (local.get $sp) (i64.extend_i32_u (local.get $pc)))\n\n  ;; zero out rest of stack\n  (i64.store (i32.add (local.get $sp) (i32.const 8)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (i64.const 0))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::SAR, {
    .wast = "(func $SAR\n    (local $sp i32)\n    (local $x1 i64)\n    (local $x2 i64)\n    (local $x3 i64)\n    (local $x4 i64)\n    (local $y1 i64)\n    (local $y2 i64)\n    (local $y3 i64)\n    (local $y4 i64)\n\n    (local $z1 i64)\n    (local $z2 i64)\n    (local $z3 i64)\n    (local $z4 i64)\n\n    ;; load args from the stack\n    (local.set $x1 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n    (local.set $x2 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n    (local.set $x3 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n    (local.set $x4 (i64.load (global.get $sp)))\n\n    (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n    (local.set $y1 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n    (local.set $y2 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n    (local.set $y3 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n    (local.set $y4 (i64.load (local.get $sp)))\n\n    (block $label_sar_internal\n        (if (i64.gt_u (i64.clz (local.get $y1)) (i64.const 0)) (then\n            (block\n                (local.set $z1 (call $shr_ (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4) (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)))\n                (local.set $z2 (global.get $global_))\n                (local.set $z3 (global.get $global__1))\n                (local.set $z4 (global.get $global__2))\n\n            )\n            (br $label_sar_internal)\n        ))\n        (if (call $gte_256x256_64 (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4) (i64.const 0) (i64.const 0) (i64.const 0) (i64.const 256)) (then\n            (local.set $z1 (i64.const 18446744073709551615))\n            (local.set $z2 (i64.const 18446744073709551615))\n            (local.set $z3 (i64.const 18446744073709551615))\n            (local.set $z4 (i64.const 18446744073709551615))\n        ))\n        (if (call $lt_256x256_64 (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4) (i64.const 0) (i64.const 0) (i64.const 0) (i64.const 256)) (then\n            (block\n                (local.set $y1 (call $shr_ (i64.const 0) (i64.const 0) (i64.const 0) (local.get $x4) (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)))\n                (local.set $y2 (global.get $global_))\n                (local.set $y3 (global.get $global__1))\n                (local.set $y4 (global.get $global__2))\n\n            )\n            (block\n                (local.set $z1 (call $shl_ (i64.const 0) (i64.const 0) (i64.const 0) (i64.sub (i64.const 256) (local.get $x4)) (i64.const 18446744073709551615) (i64.const 18446744073709551615) (i64.const 18446744073709551615) (i64.const 18446744073709551615)))\n                (local.set $z2 (global.get $global_))\n                (local.set $z3 (global.get $global__1))\n                (local.set $z4 (global.get $global__2))\n\n            )\n            (block\n                (local.set $z1 (call $or_ (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4) (local.get $z1) (local.get $z2) (local.get $z3) (local.get $z4)))\n                (local.set $z2 (global.get $global_))\n                (local.set $z3 (global.get $global__1))\n                (local.set $z4 (global.get $global__2))\n\n            )\n        ))\n\n    )\n    (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $z1))\n    (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $z2))\n    (i64.store (i32.add (local.get $sp) (i32.const  8)) (local.get $z3))\n    (i64.store          (local.get $sp)                 (local.get $z4))\n)\n\n(func $lt_256x256_64\n    (param $x1 i64)\n    (param $x2 i64)\n    (param $x3 i64)\n    (param $x4 i64)\n    (param $y1 i64)\n    (param $y2 i64)\n    (param $y3 i64)\n    (param $y4 i64)\n    (result i32)\n    (local $z i32)\n    (local $condition_106 i32)\n    (local $condition_107 i32)\n    (local $condition_108 i32)\n    (block\n        (block\n            (local.set $condition_106 (call $cmp (local.get $x1) (local.get $y1)))\n            (if (i32.eq (local.get $condition_106) (i32.const 0)) (then\n                (block\n                    (local.set $condition_107 (call $cmp (local.get $x2) (local.get $y2)))\n                    (if (i32.eq (local.get $condition_107) (i32.const 0)) (then\n                        (block\n                            (local.set $condition_108 (call $cmp (local.get $x3) (local.get $y3)))\n                            (if (i32.eq (local.get $condition_108) (i32.const 0)) (then\n                                (local.set $z (i64.lt_u (local.get $x4) (local.get $y4)))\n                            )(else\n                                (if (i32.eq (local.get $condition_108) (i32.const 1)) (then\n                                    (local.set $z (i32.const 0))\n                                )(else\n                                    (local.set $z (i32.const 1))\n                                ))\n                            ))\n\n                        )\n                    )(else\n                        (if (i32.eq (local.get $condition_107) (i32.const 1)) (then\n                            (local.set $z (i32.const 0))\n                        )(else\n                            (local.set $z (i32.const 1))\n                        ))\n                    ))\n\n                )\n            )(else\n                (if (i32.eq (local.get $condition_106) (i32.const 1)) (then\n                    (local.set $z (i32.const 0))\n                )(else\n                    (local.set $z (i32.const 1))\n                ))\n            ))\n\n        )\n\n    )\n    (local.get $z)\n)\n\n(func $gte_256x256_64\n    (param $x1 i64)\n    (param $x2 i64)\n    (param $x3 i64)\n    (param $x4 i64)\n    (param $y1 i64)\n    (param $y2 i64)\n    (param $y3 i64)\n    (param $y4 i64)\n    (result i32)\n    (local $z i32)\n    (block\n        (local.set $z (i32.eqz (call $lt_256x256_64 (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4) (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))))\n\n    )\n    (local.get $z)\n)\n\n\n(func $or_\n    (param $x1 i64)\n    (param $x2 i64)\n    (param $x3 i64)\n    (param $x4 i64)\n    (param $y1 i64)\n    (param $y2 i64)\n    (param $y3 i64)\n    (param $y4 i64)\n    (result i64)\n    (local $r1 i64)\n    (local $r2 i64)\n    (local $r3 i64)\n    (local $r4 i64)\n    (block\n        (local.set $r1 (i64.or (local.get $x1) (local.get $y1)))\n        (local.set $r2 (i64.or (local.get $x2) (local.get $y2)))\n        (local.set $r3 (i64.or (local.get $x3) (local.get $y3)))\n        (local.set $r4 (i64.or (local.get $x4) (local.get $y4)))\n\n    )\n    (global.set $global_ (local.get $r2))\n    (global.set $global__1 (local.get $r3))\n    (global.set $global__2 (local.get $r4))\n    (local.get $r1)\n)\n\n\n(func $cmp\n    (param $a i64)\n    (param $b i64)\n    (result i32)\n    (local $r i32)\n    (block\n        (local.set $r (select (i32.const 4294967295) (i64.ne (local.get $a) (local.get $b)) (i64.lt_u (local.get $a) (local.get $b))))\n\n    )\n    (local.get $r)\n)\n\n\n(func $shr_single_\n    (param $a i64)\n    (param $amount i64)\n    (result i64)\n    (local $x i64)\n    (local $y i64)\n    (block\n        (local.set $y (i64.shl (local.get $a) (i64.sub (i64.const 64) (local.get $amount))))\n        (local.set $x (i64.shr_u (local.get $a) (local.get $amount)))\n\n    )\n    (global.set $global_ (local.get $y))\n    (local.get $x)\n)\n\n(func $shr_\n    (param $x1 i64)\n    (param $x2 i64)\n    (param $x3 i64)\n    (param $x4 i64)\n    (param $y1 i64)\n    (param $y2 i64)\n    (param $y3 i64)\n    (param $y4 i64)\n    (result i64)\n    (local $z1 i64)\n    (local $z2 i64)\n    (local $z3 i64)\n    (local $z4 i64)\n    (local $t i64)\n    (block\n        (if (i32.and (i64.eqz (local.get $x1)) (i64.eqz (local.get $x2))) (then\n            (if (i64.eqz (local.get $x3)) (then\n                (if (i64.eqz (local.get $x4))\n                    (then\n                        (local.set $z1 (local.get $y1))\n                        (local.set $z2 (local.get $y2))\n                        (local.set $z3 (local.get $y3))\n                        (local.set $z4 (local.get $y4))\n                    )\n                    (else\n                        (if (i64.lt_u (local.get $x4) (i64.const 256)) (then\n                            (if (i64.ge_u (local.get $x4) (i64.const 128)) (then\n                                (local.set $y4 (local.get $y2))\n                                (local.set $y3 (local.get $y1))\n                                (local.set $y2 (i64.const 0))\n                                (local.set $y1 (i64.const 0))\n                                (local.set $x4 (i64.sub (local.get $x4) (i64.const 128)))\n                            ))\n                            (if (i64.ge_u (local.get $x4) (i64.const 64)) (then\n                                (local.set $y4 (local.get $y3))\n                                (local.set $y3 (local.get $y2))\n                                (local.set $y2 (local.get $y1))\n                                (local.set $y1 (i64.const 0))\n                                (local.set $x4 (i64.sub (local.get $x4) (i64.const 64)))\n                            ))\n                            (nop)\n                            (block\n                                (local.set $z4 (call $shr_single_ (local.get $y4) (local.get $x4)))\n                                (local.set $t (global.get $global_))\n\n                            )\n                            (block\n                                (local.set $z3 (call $shr_single_ (local.get $y3) (local.get $x4)))\n                                (local.set $t (global.get $global_))\n\n                            )\n                            (local.set $z4 (i64.or (local.get $z4) (local.get $t)))\n                            (block\n                                (local.set $z2 (call $shr_single_ (local.get $y2) (local.get $x4)))\n                                (local.set $t (global.get $global_))\n\n                            )\n                            (local.set $z3 (i64.or (local.get $z3) (local.get $t)))\n                            (block\n                                (local.set $z1 (call $shr_single_ (local.get $y1) (local.get $x4)))\n                                (local.set $t (global.get $global_))\n\n                            )\n                            (local.set $z2 (i64.or (local.get $z2) (local.get $t)))\n                        ))\n                    )\n                )\n            ))\n        ))\n\n    )\n    (global.set $global_ (local.get $z2))\n    (global.set $global__1 (local.get $z3))\n    (global.set $global__2 (local.get $z4))\n    (local.get $z1)\n)\n\n\n(func $shl_single_\n    (param $a i64)\n    (param $amount i64)\n    (result i64)\n    (local $x i64)\n    (local $y i64)\n    (block\n        (local.set $x (i64.shr_u (local.get $a) (i64.sub (i64.const 64) (local.get $amount))))\n        (local.set $y (i64.shl (local.get $a) (local.get $amount)))\n\n    )\n    (global.set $global_ (local.get $y))\n    (local.get $x)\n)\n\n(func $shl_\n    (param $x1 i64)\n    (param $x2 i64)\n    (param $x3 i64)\n    (param $x4 i64)\n    (param $y1 i64)\n    (param $y2 i64)\n    (param $y3 i64)\n    (param $y4 i64)\n    (result i64)\n    (local $z1 i64)\n    (local $z2 i64)\n    (local $z3 i64)\n    (local $z4 i64)\n    (local $t i64)\n    (local $r i64)\n    (block\n        (if (i32.and (i64.eqz (local.get $x1)) (i64.eqz (local.get $x2))) (then\n            (if (i64.eqz (local.get $x3)) (then\n                (if (i64.eqz (local.get $x4))\n                    (then\n                        (local.set $z1 (local.get $y1))\n                        (local.set $z2 (local.get $y2))\n                        (local.set $z3 (local.get $y3))\n                        (local.set $z4 (local.get $y4))\n                    )\n                    (else\n                        (if (i64.lt_u (local.get $x4) (i64.const 256)) (then\n                            (if (i64.ge_u (local.get $x4) (i64.const 128)) (then\n                                (local.set $y1 (local.get $y3))\n                                (local.set $y2 (local.get $y4))\n                                (local.set $y3 (i64.const 0))\n                                (local.set $y4 (i64.const 0))\n                                (local.set $x4 (i64.sub (local.get $x4) (i64.const 128)))\n                            ))\n                            (if (i64.ge_u (local.get $x4) (i64.const 64)) (then\n                                (local.set $y1 (local.get $y2))\n                                (local.set $y2 (local.get $y3))\n                                (local.set $y3 (local.get $y4))\n                                (local.set $y4 (i64.const 0))\n                                (local.set $x4 (i64.sub (local.get $x4) (i64.const 64)))\n                            ))\n                            (nop)\n                            (block\n                                (local.set $t (call $shl_single_ (local.get $y4) (local.get $x4)))\n                                (local.set $z4 (global.get $global_))\n\n                            )\n                            (block\n                                (local.set $r (call $shl_single_ (local.get $y3) (local.get $x4)))\n                                (local.set $z3 (global.get $global_))\n\n                            )\n                            (local.set $z3 (i64.or (local.get $z3) (local.get $t)))\n                            (block\n                                (local.set $t (call $shl_single_ (local.get $y2) (local.get $x4)))\n                                (local.set $z2 (global.get $global_))\n\n                            )\n                            (local.set $z2 (i64.or (local.get $z2) (local.get $r)))\n                            (block\n                                (local.set $r (call $shl_single_ (local.get $y1) (local.get $x4)))\n                                (local.set $z1 (global.get $global_))\n\n                            )\n                            (local.set $z1 (i64.or (local.get $z1) (local.get $t)))\n                        ))\n                    )\n                )\n            ))\n        ))\n\n    )\n    (global.set $global_ (local.get $z2))\n    (global.set $global__1 (local.get $z3))\n    (global.set $global__2 (local.get $z4))\n    (local.get $z1)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::SDIV, {
    .wast = "(func $SDIV\n  (local $sp i32)\n\n  ;; dividend\n  (local $a i64)\n  (local $b i64)\n  (local $c i64)\n  (local $d i64)\n\n  ;; divisor\n  (local $a1 i64)\n  (local $b1 i64)\n  (local $c1 i64)\n  (local $d1 i64)\n\n  ;; quotient\n  (local $aq i64)\n  (local $bq i64)\n  (local $cq i64)\n  (local $dq i64)\n\n  ;; mask\n  (local $maska i64)\n  (local $maskb i64)\n  (local $maskc i64)\n  (local $maskd i64)\n  (local $carry i32)\n  (local $temp  i64)\n  (local $temp2 i64)\n  (local $sign i32)\n\n  (local.set $maskd (i64.const 1))\n\n  ;; load args from the stack\n  (local.set $a (i64.load (i32.add (global.get $sp) (i32.const 24))))\n  (local.set $b (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $c (i64.load (i32.add (global.get $sp) (i32.const 8))))\n  (local.set $d (i64.load (global.get $sp)))\n\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n  (local.set $a1 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $c1 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $d1 (i64.load (local.get $sp)))\n\n  ;; get the resulting sign\n  (local.set $sign (i32.wrap_i64 (i64.shr_u (i64.xor (local.get $a1) (local.get $a)) (i64.const 63))))\n\n  ;; convert to unsigned value\n  (if (i64.eqz (i64.clz (local.get $a)))\n    (then\n      (local.set $a (i64.xor (local.get $a) (i64.const -1)))\n      (local.set $b (i64.xor (local.get $b) (i64.const -1)))\n      (local.set $c (i64.xor (local.get $c) (i64.const -1)))\n      (local.set $d (i64.xor (local.get $d) (i64.const -1)))\n\n      ;; a = a + 1\n      (local.set $d (i64.add (local.get $d) (i64.const 1)))\n      (local.set $carry (i64.eqz (local.get $d)))\n      (local.set $c (i64.add (local.get $c) (i64.extend_i32_u (local.get $carry))))\n      (local.set $carry (i32.and (i64.eqz (local.get $c)) (local.get $carry)))\n      (local.set $b (i64.add (local.get $b) (i64.extend_i32_u (local.get $carry))))\n      (local.set $carry (i32.and (i64.eqz (local.get $b)) (local.get $carry)))\n      (local.set $a (i64.add (local.get $a) (i64.extend_i32_u (local.get $carry))))\n    )\n  )\n  (if (i64.eqz (i64.clz (local.get $a1)))\n    (then\n      (local.set $a1 (i64.xor (local.get $a1) (i64.const -1)))\n      (local.set $b1 (i64.xor (local.get $b1) (i64.const -1)))\n      (local.set $c1 (i64.xor (local.get $c1) (i64.const -1)))\n      (local.set $d1 (i64.xor (local.get $d1) (i64.const -1)))\n\n      (local.set $d1 (i64.add (local.get $d1) (i64.const 1)))\n      (local.set $carry (i64.eqz (local.get $d1)))\n      (local.set $c1 (i64.add (local.get $c1) (i64.extend_i32_u (local.get $carry))))\n      (local.set $carry (i32.and (i64.eqz (local.get $c1)) (local.get $carry)))\n      (local.set $b1 (i64.add (local.get $b1) (i64.extend_i32_u (local.get $carry))))\n      (local.set $carry (i32.and (i64.eqz (local.get $b1)) (local.get $carry)))\n      (local.set $a1 (i64.add (local.get $a1) (i64.extend_i32_u (local.get $carry))))\n    )\n  )\n\n  (block $main\n    ;; check div by 0\n    (if (call $iszero_256 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1))\n      (br $main)\n    )\n\n    ;; align bits\n    (block $done\n      (loop $loop\n        ;; align bits;\n        (if (i32.or (i64.eqz (i64.clz (local.get $a1))) (call $gte_256 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1) (local.get $a) (local.get $b) (local.get $c) (local.get $d)))\n          (br $done)\n        )\n\n        ;; divisor = divisor << 1\n        (local.set $a1 (i64.add (i64.shl (local.get $a1) (i64.const 1)) (i64.shr_u (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shl (local.get $b1) (i64.const 1)) (i64.shr_u (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shl (local.get $c1) (i64.const 1)) (i64.shr_u (local.get $d1) (i64.const 63))))\n        (local.set $d1 (i64.shl (local.get $d1) (i64.const 1)))\n\n        ;; mask = mask << 1\n        (local.set $maska (i64.add (i64.shl (local.get $maska) (i64.const 1)) (i64.shr_u (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shl (local.get $maskb) (i64.const 1)) (i64.shr_u (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shl (local.get $maskc) (i64.const 1)) (i64.shr_u (local.get $maskd) (i64.const 63))))\n        (local.set $maskd (i64.shl (local.get $maskd) (i64.const 1)))\n\n        (br $loop)\n      )\n    )\n\n    (block $done\n      (loop $loop\n        ;; loop while mask != 0\n        (if (call $iszero_256 (local.get $maska) (local.get $maskb) (local.get $maskc) (local.get $maskd))\n          (br $done)\n        )\n        ;; if dividend >= divisor\n        (if (call $gte_256 (local.get $a) (local.get $b) (local.get $c) (local.get $d) (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1))\n          (then\n            ;; dividend = dividend - divisor\n            (local.set $carry (i64.lt_u (local.get $d) (local.get $d1)))\n            (local.set $d     (i64.sub  (local.get $d) (local.get $d1)))\n            (local.set $temp  (i64.sub  (local.get $c) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $c)))\n            (local.set $c     (i64.sub  (local.get $temp) (local.get $c1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $c) (local.get $temp)) (local.get $carry)))\n            (local.set $temp  (i64.sub  (local.get $b) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $b)))\n            (local.set $b     (i64.sub  (local.get $temp) (local.get $b1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $b) (local.get $temp)) (local.get $carry)))\n            (local.set $a     (i64.sub  (i64.sub (local.get $a) (i64.extend_i32_u (local.get $carry))) (local.get $a1)))\n\n            ;; result = result + mask\n            (local.set $dq    (i64.add  (local.get $maskd) (local.get $dq)))\n            (local.set $carry (i64.lt_u (local.get $dq) (local.get $maskd)))\n            (local.set $temp  (i64.add  (local.get $cq) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.lt_u (local.get $temp) (local.get $cq)))\n            (local.set $cq    (i64.add  (local.get $maskc) (local.get $temp)))\n            (local.set $carry (i32.or   (i64.lt_u (local.get $cq) (local.get $maskc)) (local.get $carry)))\n            (local.set $temp  (i64.add  (local.get $bq) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.lt_u (local.get $temp) (local.get $bq)))\n            (local.set $bq    (i64.add  (local.get $maskb) (local.get $temp)))\n            (local.set $carry (i32.or   (i64.lt_u (local.get $bq) (local.get $maskb)) (local.get $carry)))\n            (local.set $aq    (i64.add  (local.get $maska) (i64.add (local.get $aq) (i64.extend_i32_u (local.get $carry)))))\n          )\n        )\n        ;; divisor = divisor >> 1\n        (local.set $d1 (i64.add (i64.shr_u (local.get $d1) (i64.const 1)) (i64.shl (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shr_u (local.get $c1) (i64.const 1)) (i64.shl (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shr_u (local.get $b1) (i64.const 1)) (i64.shl (local.get $a1) (i64.const 63))))\n        (local.set $a1 (i64.shr_u (local.get $a1) (i64.const 1)))\n\n        ;; mask = mask >> 1\n        (local.set $maskd (i64.add (i64.shr_u (local.get $maskd) (i64.const 1)) (i64.shl (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shr_u (local.get $maskc) (i64.const 1)) (i64.shl (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shr_u (local.get $maskb) (i64.const 1)) (i64.shl (local.get $maska) (i64.const 63))))\n        (local.set $maska (i64.shr_u (local.get $maska) (i64.const 1)))\n        (br $loop)\n      )\n    )\n  );; end of main\n\n  ;; convert to signed\n  (if (local.get $sign)\n    (then\n      (local.set $aq (i64.xor (local.get $aq) (i64.const -1)))\n      (local.set $bq (i64.xor (local.get $bq) (i64.const -1)))\n      (local.set $cq (i64.xor (local.get $cq) (i64.const -1)))\n      (local.set $dq (i64.xor (local.get $dq) (i64.const -1)))\n\n      (local.set $dq (i64.add (local.get $dq) (i64.const 1)))\n      (local.set $cq (i64.add (local.get $cq) (i64.extend_i32_u (i64.eqz (local.get $dq)))))\n      (local.set $bq (i64.add (local.get $bq) (i64.extend_i32_u (i64.eqz (local.get $cq)))))\n      (local.set $aq (i64.add (local.get $aq) (i64.extend_i32_u (i64.eqz (local.get $bq)))))\n    )\n  )\n\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $aq))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $bq))\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (local.get $cq))\n  (i64.store          (local.get $sp)                 (local.get $dq))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::SGT, {
    .wast = "(func $SGT\n  (local $sp i32)\n\n  (local $a0 i64)\n  (local $a1 i64)\n  (local $a2 i64)\n  (local $a3 i64)\n  (local $b0 i64)\n  (local $b1 i64)\n  (local $b2 i64)\n  (local $b3 i64)\n\n  ;; load args from the stack\n  (local.set $a0 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n  (local.set $a1 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $a2 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n  (local.set $a3 (i64.load (global.get $sp)))\n\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n  (local.set $b0 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $b2 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n  (local.set $b3 (i64.load (local.get $sp)))\n\n  (i64.store (local.get $sp) (i64.extend_i32_u\n    (i32.or  (i64.gt_s (local.get $a0) (local.get $b0)) ;; a0 > b0\n    (i32.and (i64.eq   (local.get $a0) (local.get $b0)) ;; a0 == a1\n    (i32.or  (i64.gt_u (local.get $a1) (local.get $b1)) ;; a1 > b1\n    (i32.and (i64.eq   (local.get $a1) (local.get $b1)) ;; a1 == b1\n    (i32.or  (i64.gt_u (local.get $a2) (local.get $b2)) ;; a2 > b2\n    (i32.and (i64.eq   (local.get $a2) (local.get $b2)) ;; a2 == b2\n             (i64.gt_u (local.get $a3) (local.get $b3)))))))))) ;; a3 > b3\n\n  ;; zero  out the rest of the stack item\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (i64.const 0))\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (i64.const 0))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::SHA3, {
    .wast = "(func $SHA3\n  (local $dataOffset i32)\n  (local $dataOffset0 i64)\n  (local $dataOffset1 i64)\n  (local $dataOffset2 i64)\n  (local $dataOffset3 i64)\n\n  (local $length i32)\n  (local $length0 i64)\n  (local $length1 i64)\n  (local $length2 i64)\n  (local $length3 i64)\n\n  (local $contextOffset i32)\n  (local $outputOffset i32)\n\n  (local.set $length0 (i64.load (i32.sub (global.get $sp) (i32.const 32))))\n  (local.set $length1 (i64.load (i32.sub (global.get $sp) (i32.const 24))))\n  (local.set $length2 (i64.load (i32.sub (global.get $sp) (i32.const 16))))\n  (local.set $length3 (i64.load (i32.sub (global.get $sp) (i32.const 8))))\n\n  (local.set $dataOffset0 (i64.load (i32.add (global.get $sp) (i32.const 0))))\n  (local.set $dataOffset1 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n  (local.set $dataOffset2 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $dataOffset3 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n\n  (local.set $length\n             (call $check_overflow (local.get $length0)\n                                   (local.get $length1)\n                                   (local.get $length2)\n                                   (local.get $length3)))\n  (local.set $dataOffset\n             (call $check_overflow (local.get $dataOffset0)\n                                   (local.get $dataOffset1)\n                                   (local.get $dataOffset2)\n                                   (local.get $dataOffset3)))\n\n  ;; charge copy fee ceil(words/32) * 6\n  (call $useGas (i64.extend_i32_u (i32.mul (i32.div_u (i32.add (local.get $length) (i32.const 31)) (i32.const 32)) (i32.const 6))))\n  (call $memusegas (local.get $dataOffset) (local.get $length))\n\n  (local.set $dataOffset (i32.add (global.get $memstart) (local.get $dataOffset)))\n\n  (local.set $contextOffset (i32.const 32808))\n  (local.set $outputOffset (i32.sub (global.get $sp) (i32.const 32)))\n\n  (call $keccak (local.get $contextOffset) (local.get $dataOffset) (local.get $length) (local.get $outputOffset))\n\n  (drop (call $bswap_m256 (local.get $outputOffset)))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::SHL, {
    .wast = "(func $SHL\n    (local $sp i32)\n    (local $x1 i64)\n    (local $x2 i64)\n    (local $x3 i64)\n    (local $x4 i64)\n    (local $y1 i64)\n    (local $y2 i64)\n    (local $y3 i64)\n    (local $y4 i64)\n\n    (local $z1 i64)\n    (local $z2 i64)\n    (local $z3 i64)\n    (local $z4 i64)\n    (local $t i64)\n    (local $r i64)\n\n    ;; load args from the stack\n    (local.set $x1 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n    (local.set $x2 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n    (local.set $x3 (i64.load (i32.add (global.get $sp) (i32.const 8))))\n    (local.set $x4 (i64.load (global.get $sp)))\n\n    (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n    (local.set $y1 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n    (local.set $y2 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n    (local.set $y3 (i64.load (i32.add (local.get $sp) (i32.const 8))))\n    (local.set $y4 (i64.load (local.get $sp)))\n\n    (block\n        (if (i32.and (i64.eqz (local.get $x1)) (i64.eqz (local.get $x2))) (then\n            (if (i64.eqz (local.get $x3)) (then\n                (if (i64.eqz (local.get $x4))\n                    (then\n                        (local.set $z1 (local.get $y1))\n                        (local.set $z2 (local.get $y2))\n                        (local.set $z3 (local.get $y3))\n                        (local.set $z4 (local.get $y4))\n                    )\n                    (else\n                        (if (i64.lt_u (local.get $x4) (i64.const 256)) (then\n                            (if (i64.ge_u (local.get $x4) (i64.const 128)) (then\n                                (local.set $y1 (local.get $y3))\n                                (local.set $y2 (local.get $y4))\n                                (local.set $y3 (i64.const 0))\n                                (local.set $y4 (i64.const 0))\n                                (local.set $x4 (i64.sub (local.get $x4) (i64.const 128)))\n                            ))\n                            (if (i64.ge_u (local.get $x4) (i64.const 64)) (then\n                                (local.set $y1 (local.get $y2))\n                                (local.set $y2 (local.get $y3))\n                                (local.set $y3 (local.get $y4))\n                                (local.set $y4 (i64.const 0))\n                                (local.set $x4 (i64.sub (local.get $x4) (i64.const 64)))\n                            ))\n                            (nop)\n                            (block\n                                (local.set $t (call $shl_single (local.get $y4) (local.get $x4)))\n                                (local.set $z4 (global.get $global_))\n\n                            )\n                            (block\n                                (local.set $r (call $shl_single (local.get $y3) (local.get $x4)))\n                                (local.set $z3 (global.get $global_))\n\n                            )\n                            (local.set $z3 (i64.or (local.get $z3) (local.get $t)))\n                            (block\n                                (local.set $t (call $shl_single (local.get $y2) (local.get $x4)))\n                                (local.set $z2 (global.get $global_))\n\n                            )\n                            (local.set $z2 (i64.or (local.get $z2) (local.get $r)))\n                            (block\n                                (local.set $r (call $shl_single (local.get $y1) (local.get $x4)))\n                                (local.set $z1 (global.get $global_))\n\n                            )\n                            (local.set $z1 (i64.or (local.get $z1) (local.get $t)))\n                        ))\n                    )\n                )\n            ))\n        ))\n\n    )\n    (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $z1))\n    (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $z2))\n    (i64.store (i32.add (local.get $sp) (i32.const  8)) (local.get $z3))\n    (i64.store          (local.get $sp)                 (local.get $z4))\n)\n\n(func $shl_single\n    (param $a i64)\n    (param $amount i64)\n    (result i64)\n    (local $x i64)\n    (local $y i64)\n    (block\n        (local.set $x (i64.shr_u (local.get $a) (i64.sub (i64.const 64) (local.get $amount))))\n        (local.set $y (i64.shl (local.get $a) (local.get $amount)))\n\n    )\n    (global.set $global_ (local.get $y))\n    (local.get $x)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::SIGNEXTEND, {
    .wast = "(func $SIGNEXTEND\n  (local $sp i32)\n\n  (local $a0 i64)\n  (local $a1 i64)\n  (local $a2 i64)\n  (local $a3 i64)\n\n  (local $b0 i64)\n  (local $b1 i64)\n  (local $b2 i64)\n  (local $b3 i64)\n  (local $sign i64)\n  (local $t i32)\n  (local $end i32)\n\n  (local.set $a0 (i64.load (i32.add (global.get $sp) (i32.const 24))))\n  (local.set $a1 (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $a2 (i64.load (i32.add (global.get $sp) (i32.const  8))))\n  (local.set $a3 (i64.load          (global.get $sp)))\n\n  (local.set $end (global.get $sp))\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n  (if (i32.and\n        (i32.and\n          (i32.and\n            (i64.lt_u (local.get $a3) (i64.const 32))\n            (i64.eqz (local.get $a2)))\n          (i64.eqz (local.get $a1)))\n        (i64.eqz (local.get $a0)))\n    (then\n      (local.set $t (i32.add (i32.wrap_i64 (local.get $a3)) (local.get $sp)))\n      (local.set $sign (i64.shr_s (i64.load8_s (local.get $t)) (i64.const 8)))\n      (local.set $t (i32.add (local.get $t) (i32.const 1)))\n      (block $done\n        (loop $loop\n          (if (i32.lt_u (local.get $end) (local.get $t))\n            (br $done)\n          )\n          (i64.store (local.get $t) (local.get $sign))\n          (local.set $t (i32.add (local.get $t) (i32.const 8)))\n          (br $loop)\n        )\n      )\n    )\n  )\n)\n\n",
    .imports = ""
  }
},{
  opcodeEnum::SMOD, {
    .wast = "(func $SMOD\n  (local $sp i32)\n  ;; dividend\n  (local $a i64)\n  (local $b i64)\n  (local $c i64)\n  (local $d i64)\n\n  ;; divisor\n  (local $a1 i64)\n  (local $b1 i64)\n  (local $c1 i64)\n  (local $d1 i64)\n\n  ;; quotient\n  (local $aq i64)\n  (local $bq i64)\n  (local $cq i64)\n  (local $dq i64)\n\n  ;; mask\n  (local $maska i64)\n  (local $maskb i64)\n  (local $maskc i64)\n  (local $maskd i64)\n  (local $carry i32)\n  (local $sign i32)\n  (local $temp  i64)\n  (local $temp2  i64)\n\n  ;; load args from the stack\n  (local.set $a (i64.load (i32.add (global.get $sp) (i32.const 24))))\n  (local.set $b (i64.load (i32.add (global.get $sp) (i32.const 16))))\n  (local.set $c (i64.load (i32.add (global.get $sp) (i32.const  8))))\n  (local.set $d (i64.load          (global.get $sp)))\n  ;; decement the stack pointer\n  (local.set $sp (i32.sub (global.get $sp) (i32.const 32)))\n\n  (local.set $a1 (i64.load (i32.add (local.get $sp) (i32.const 24))))\n  (local.set $b1 (i64.load (i32.add (local.get $sp) (i32.const 16))))\n  (local.set $c1 (i64.load (i32.add (local.get $sp) (i32.const  8))))\n  (local.set $d1 (i64.load          (local.get $sp)))\n\n  (local.set $maskd (i64.const 1))\n  (local.set $sign (i32.wrap_i64 (i64.shr_u (local.get $d) (i64.const 63))))\n\n  ;; convert to unsigned value\n  (if (i64.eqz (i64.clz (local.get $a)))\n    (then\n      (local.set $a (i64.xor (local.get $a) (i64.const -1)))\n      (local.set $b (i64.xor (local.get $b) (i64.const -1)))\n      (local.set $c (i64.xor (local.get $c) (i64.const -1)))\n      (local.set $d (i64.xor (local.get $d) (i64.const -1)))\n\n      ;; a = a + 1\n      (local.set $d (i64.add (local.get $d) (i64.const 1)))\n      (local.set $carry (i64.eqz (local.get $d)))\n      (local.set $c (i64.add (local.get $c) (i64.extend_i32_u (local.get $carry))))\n      (local.set $carry (i32.and (i64.eqz (local.get $c)) (local.get $carry)))\n      (local.set $b (i64.add (local.get $b) (i64.extend_i32_u (local.get $carry))))\n      (local.set $carry (i32.and (i64.eqz (local.get $b)) (local.get $carry)))\n      (local.set $a (i64.add (local.get $a) (i64.extend_i32_u (local.get $carry))))\n    )\n  )\n\n  (if (i64.eqz (i64.clz (local.get $a1)))\n    (then\n      (local.set $a1 (i64.xor (local.get $a1) (i64.const -1)))\n      (local.set $b1 (i64.xor (local.get $b1) (i64.const -1)))\n      (local.set $c1 (i64.xor (local.get $c1) (i64.const -1)))\n      (local.set $d1 (i64.xor (local.get $d1) (i64.const -1)))\n\n      (local.set $d1 (i64.add (local.get $d1) (i64.const 1)))\n      (local.set $carry (i64.eqz (local.get $d1)))\n      (local.set $c1 (i64.add (local.get $c1) (i64.extend_i32_u (local.get $carry))))\n      (local.set $carry (i32.and (i64.eqz (local.get $c1)) (local.get $carry)))\n      (local.set $b1 (i64.add (local.get $b1) (i64.extend_i32_u (local.get $carry))))\n      (local.set $carry (i32.and (i64.eqz (local.get $b1)) (local.get $carry)))\n      (local.set $a1 (i64.add (local.get $a1) (i64.extend_i32_u (local.get $carry))))\n    )\n  )\n\n  (block $main\n    ;; check div by 0\n    (if (call $iszero_256 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1))\n      (then\n        (local.set $a (i64.const 0))\n        (local.set $b (i64.const 0))\n        (local.set $c (i64.const 0))\n        (local.set $d (i64.const 0))\n        (br $main)\n      )\n    )\n\n    ;; align bits\n    (block $done\n      (loop $loop\n        ;; align bits;\n        (if (i32.or (i64.eqz (i64.clz (local.get $a1))) (call $gte_256 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1) (local.get $a) (local.get $b) (local.get $c) (local.get $d)))\n          (br $done)\n        )\n\n        ;; divisor = divisor << 1\n        (local.set $a1 (i64.add (i64.shl (local.get $a1) (i64.const 1)) (i64.shr_u (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shl (local.get $b1) (i64.const 1)) (i64.shr_u (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shl (local.get $c1) (i64.const 1)) (i64.shr_u (local.get $d1) (i64.const 63))))\n        (local.set $d1 (i64.shl (local.get $d1) (i64.const 1)))\n\n        ;; mask = mask << 1\n        (local.set $maska (i64.add (i64.shl (local.get $maska) (i64.const 1)) (i64.shr_u (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shl (local.get $maskb) (i64.const 1)) (i64.shr_u (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shl (local.get $maskc) (i64.const 1)) (i64.shr_u (local.get $maskd) (i64.const 63))))\n        (local.set $maskd (i64.shl (local.get $maskd) (i64.const 1)))\n\n        (br $loop)\n      )\n    )\n\n    (block $done\n      (loop $loop\n        ;; loop while mask != 0\n        (if (call $iszero_256 (local.get $maska) (local.get $maskb) (local.get $maskc) (local.get $maskd))\n          (br $done)\n        )\n        ;; if dividend >= divisor\n        (if (call $gte_256 (local.get $a) (local.get $b) (local.get $c) (local.get $d) (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1))\n          (then\n            ;; dividend = dividend - divisor\n            (local.set $carry (i64.lt_u (local.get $d) (local.get $d1)))\n            (local.set $d     (i64.sub  (local.get $d) (local.get $d1)))\n            (local.set $temp  (i64.sub  (local.get $c) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $c)))\n            (local.set $c     (i64.sub  (local.get $temp) (local.get $c1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $c) (local.get $temp)) (local.get $carry)))\n            (local.set $temp  (i64.sub  (local.get $b) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $b)))\n            (local.set $b     (i64.sub  (local.get $temp) (local.get $b1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $b) (local.get $temp)) (local.get $carry)))\n            (local.set $a     (i64.sub  (i64.sub (local.get $a) (i64.extend_i32_u (local.get $carry))) (local.get $a1)))\n          )\n        )\n        ;; divisor = divisor >> 1\n        (local.set $d1 (i64.add (i64.shr_u (local.get $d1) (i64.const 1)) (i64.shl (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shr_u (local.get $c1) (i64.const 1)) (i64.shl (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shr_u (local.get $b1) (i64.const 1)) (i64.shl (local.get $a1) (i64.const 63))))\n        (local.set $a1 (i64.shr_u (local.get $a1) (i64.const 1)))\n\n        ;; mask = mask >> 1\n        (local.set $maskd (i64.add (i64.shr_u (local.get $maskd) (i64.const 1)) (i64.shl (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shr_u (local.get $maskc) (i64.const 1)) (i64.shl (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shr_u (local.get $maskb) (i64.const 1)) (i64.shl (local.get $maska) (i64.const 63))))\n        (local.set $maska (i64.shr_u (local.get $maska) (i64.const 1)))\n        (br $loop)\n      )\n    )\n  )\n\n  ;; convert to signed\n  (if (local.get $sign)\n    (then\n      (local.set $a (i64.xor (local.get $a) (i64.const -1)))\n      (local.set $b (i64.xor (local.get $b) (i64.const -1)))\n      (local.set $c (i64.xor (local.get $c) (i64.const -1)))\n      (local.set $d (i64.xor (local.get $d) (i64.const -1)))\n\n      (local.set $d (i64.add (local.get $d) (i64.const 1)))\n      (local.set $c (i64.add (local.get $c) (i64.extend_i32_u (i64.eqz (local.get $d)))))\n      (local.set $b (i64.add (local.get $b) (i64.extend_i32_u (i64.eqz (local.get $c)))))\n      (local.set $a (i64.add (local.get $a) (i64.extend_i32_u (i64.eqz (local.get $b)))))\n    )\n  )\n\n  ;; save the stack\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $a))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $b))\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (local.get $c))\n  (i64.store          (local.get $sp)                 (local.get $d))\n) ;; end for SMOD\n",
    .imports = ""
  }
},{
  opcodeEnum::XOR, {
    .wast = "(func $XOR\n  (i64.store (i32.sub (global.get $sp) (i32.const  8)) (i64.xor (i64.load (i32.sub (global.get $sp) (i32.const  8))) (i64.load (i32.add (global.get $sp) (i32.const 24)))))\n  (i64.store (i32.sub (global.get $sp) (i32.const 16)) (i64.xor (i64.load (i32.sub (global.get $sp) (i32.const 16))) (i64.load (i32.add (global.get $sp) (i32.const 16)))))\n  (i64.store (i32.sub (global.get $sp) (i32.const 24)) (i64.xor (i64.load (i32.sub (global.get $sp) (i32.const 24))) (i64.load (i32.add (global.get $sp) (i32.const  8)))))\n  (i64.store (i32.sub (global.get $sp) (i32.const 32)) (i64.xor (i64.load (i32.sub (global.get $sp) (i32.const 32))) (i64.load (i32.add (global.get $sp) (i32.const  0)))))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::bswap_i32, {
    .wast = "(func $bswap_i32\n  (param $int i32)\n  (result i32)\n\n  (i32.or\n    (i32.or\n      (i32.and (i32.shr_u (local.get $int) (i32.const 24)) (i32.const 0xff)) ;; 7 -> 0\n      (i32.and (i32.shr_u (local.get $int) (i32.const 8)) (i32.const 0xff00))) ;; 6 -> 1\n    (i32.or\n      (i32.and (i32.shl (local.get $int) (i32.const 8)) (i32.const 0xff0000)) ;; 5 -> 2\n      (i32.and (i32.shl (local.get $int) (i32.const 24)) (i32.const 0xff000000)))) ;; 4 -> 3\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::bswap_i64, {
    .wast = "(func $bswap_i64\n  (param $int i64)\n  (result i64)\n\n  (i64.or\n    (i64.or\n      (i64.or\n        (i64.and (i64.shr_u (local.get $int) (i64.const 56)) (i64.const 0xff)) ;; 7 -> 0\n        (i64.and (i64.shr_u (local.get $int) (i64.const 40)) (i64.const 0xff00))) ;; 6 -> 1\n      (i64.or\n        (i64.and (i64.shr_u (local.get $int) (i64.const 24)) (i64.const 0xff0000)) ;; 5 -> 2\n        (i64.and (i64.shr_u (local.get $int) (i64.const  8)) (i64.const 0xff000000)))) ;; 4 -> 3\n    (i64.or\n      (i64.or\n        (i64.and (i64.shl (local.get $int) (i64.const 8))   (i64.const 0xff00000000)) ;; 3 -> 4\n        (i64.and (i64.shl (local.get $int) (i64.const 24))   (i64.const 0xff0000000000))) ;; 2 -> 5\n      (i64.or\n        (i64.and (i64.shl (local.get $int) (i64.const 40))   (i64.const 0xff000000000000)) ;; 1 -> 6\n        (i64.and (i64.shl (local.get $int) (i64.const 56))   (i64.const 0xff00000000000000))))) ;; 0 -> 7\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::bswap_m128, {
    .wast = "(func $bswap_m128\n  (param $sp i32)\n  (result i32)\n  (local $temp i64)\n\n  (local.set $temp (call $bswap_i64 (i64.load (local.get $sp))))\n  (i64.store (local.get $sp) (call $bswap_i64 (i64.load (i32.add (local.get $sp) (i32.const 8)))))\n  (i64.store (i32.add (local.get $sp) (i32.const 8)) (local.get $temp))\n  (local.get $sp)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::bswap_m160, {
    .wast = "(func $bswap_m160\n  (param $sp i32)\n  (result i32)\n  (local $temp i64)\n\n  (local.set $temp (call $bswap_i64 (i64.load (local.get $sp))))\n  (i64.store (local.get $sp) (call $bswap_i64 (i64.load (i32.add (local.get $sp) (i32.const 12)))))\n  (i64.store (i32.add (local.get $sp) (i32.const 12)) (local.get $temp))\n\n  (i32.store (i32.add (local.get $sp) (i32.const 8)) (call $bswap_i32 (i32.load (i32.add (local.get $sp) (i32.const 8)))))\n  (local.get $sp)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::bswap_m256, {
    .wast = "(func $bswap_m256\n  (param $sp i32)\n  (result i32)\n  (local $temp i64)\n\n  (local.set $temp (call $bswap_i64 (i64.load (local.get $sp))))\n  (i64.store (local.get $sp) (call $bswap_i64 (i64.load (i32.add (local.get $sp) (i32.const 24)))))\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $temp))\n\n  (local.set $temp (call $bswap_i64 (i64.load (i32.add (local.get $sp) (i32.const 8)))))\n  (i64.store (i32.add (local.get $sp) (i32.const  8)) (call $bswap_i64 (i64.load (i32.add (local.get $sp) (i32.const 16)))))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $temp))\n  (local.get $sp)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::callback, {
    .wast = "(func $callback\n  (call $main)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::callback_128, {
    .wast = "(func $callback_128\n  (param $result i32)\n\n  (drop (call $bswap_m128 (global.get $sp)))\n  (call $main)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::callback_160, {
    .wast = "(func $callback_160\n  (param $result i32)\n\n  (drop (call $bswap_m160 (global.get $sp)))\n  (call $main)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::callback_256, {
    .wast = "(func $callback_256\n  (param $result i32)\n\n  (drop (call $bswap_m256 (global.get $sp)))\n  (call $main)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::callback_32, {
    .wast = "(func $callback_32\n  (param $result i32)\n\n  (i64.store (global.get $sp) (i64.extend_i32_u (local.get $result)))\n  ;; zero out mem\n  (i64.store (i32.add (global.get $sp) (i32.const 24)) (i64.const 0))\n  (i64.store (i32.add (global.get $sp) (i32.const 16)) (i64.const 0))\n  (i64.store (i32.add (global.get $sp) (i32.const 8)) (i64.const 0))\n\n  (call $main)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::check_overflow_i64, {
    .wast = "(func $check_overflow_i64\n  (param $a i64)\n  (param $b i64)\n  (param $c i64)\n  (param $d i64)\n  (result i64)\n\n  (if\n    (i32.and \n      (i32.and \n        (i64.eqz  (local.get $d))\n        (i64.eqz  (local.get $c)))\n      (i64.eqz  (local.get $b)))\n    (return (local.get $a)))\n\n    (return (i64.const 0xffffffffffffffff))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::gte_256, {
    .wast = ";; is a less than or equal to b // a >= b\n(func $gte_256\n  (param $a0 i64)\n  (param $a1 i64)\n  (param $a2 i64)\n  (param $a3 i64)\n\n  (param $b0 i64)\n  (param $b1 i64)\n  (param $b2 i64)\n  (param $b3 i64)\n\n  (result i32)\n\n  ;; a0 > b0 || [a0 == b0 && [a1 > b1 || [a1 == b1 && [a2 > b2 || [a2 == b2 && a3 >= b3 ]]]]\n  (i32.or  (i64.gt_u (local.get $a0) (local.get $b0)) ;; a0 > b0\n  (i32.and (i64.eq   (local.get $a0) (local.get $b0))\n  (i32.or  (i64.gt_u (local.get $a1) (local.get $b1)) ;; a1 > b1\n  (i32.and (i64.eq   (local.get $a1) (local.get $b1)) ;; a1 == b1\n  (i32.or  (i64.gt_u (local.get $a2) (local.get $b2)) ;; a2 > b2\n  (i32.and (i64.eq   (local.get $a2) (local.get $b2))\n           (i64.ge_u (local.get $a3) (local.get $b3))))))))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::gte_320, {
    .wast = "(func $gte_320\n  (param $a0 i64)\n  (param $a1 i64)\n  (param $a2 i64)\n  (param $a3 i64)\n  (param $a4 i64)\n\n  (param $b0 i64)\n  (param $b1 i64)\n  (param $b2 i64)\n  (param $b3 i64)\n  (param $b4 i64)\n\n  (result i32)\n\n  ;; a0 > b0 || [a0 == b0 && [a1 > b1 || [a1 == b1 && [a2 > b2 || [a2 == b2 && a3 >= b3 ]]]]\n  (i32.or  (i64.gt_u (local.get $a0) (local.get $b0)) ;; a0 > b0\n  (i32.and (i64.eq   (local.get $a0) (local.get $b0))\n  (i32.or  (i64.gt_u (local.get $a1) (local.get $b1)) ;; a1 > b1\n  (i32.and (i64.eq   (local.get $a1) (local.get $b1)) ;; a1 == b1\n  (i32.or  (i64.gt_u (local.get $a2) (local.get $b2)) ;; a2 > b2\n  (i32.and (i64.eq   (local.get $a2) (local.get $b2))\n  (i32.or  (i64.gt_u (local.get $a3) (local.get $b3)) ;; a2 > b2\n  (i32.and (i64.eq   (local.get $a3) (local.get $b3))\n           (i64.ge_u (local.get $a4) (local.get $b4))))))))))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::gte_512, {
    .wast = "(func $gte_512\n  (param $a0 i64)\n  (param $a1 i64)\n  (param $a2 i64)\n  (param $a3 i64)\n  (param $a4 i64)\n  (param $a5 i64)\n  (param $a6 i64)\n  (param $a7 i64)\n\n  (param $b0 i64)\n  (param $b1 i64)\n  (param $b2 i64)\n  (param $b3 i64)\n  (param $b4 i64)\n  (param $b5 i64)\n  (param $b6 i64)\n  (param $b7 i64)\n\n  (result i32)\n\n  ;; a0 > b0 || [a0 == b0 && [a1 > b1 || [a1 == b1 && [a2 > b2 || [a2 == b2 && a3 >= b3 ]]]]\n  (i32.or  (i64.gt_u (local.get $a0) (local.get $b0)) ;; a0 > b0\n  (i32.and (i64.eq   (local.get $a0) (local.get $b0))\n  (i32.or  (i64.gt_u (local.get $a1) (local.get $b1)) ;; a1 > b1\n  (i32.and (i64.eq   (local.get $a1) (local.get $b1)) ;; a1 == b1\n  (i32.or  (i64.gt_u (local.get $a2) (local.get $b2)) ;; a2 > b2\n  (i32.and (i64.eq   (local.get $a2) (local.get $b2))\n  (i32.or  (i64.gt_u (local.get $a3) (local.get $b3)) ;; a3 > b3\n  (i32.and (i64.eq   (local.get $a3) (local.get $b3))\n  (i32.or  (i64.gt_u (local.get $a4) (local.get $b4)) ;; a4 > b4\n  (i32.and (i64.eq   (local.get $a4) (local.get $b4))\n  (i32.or  (i64.gt_u (local.get $a5) (local.get $b5)) ;; a5 > b5\n  (i32.and (i64.eq   (local.get $a5) (local.get $b5))\n  (i32.or  (i64.gt_u (local.get $a6) (local.get $b6)) ;; a6 > b6\n  (i32.and (i64.eq   (local.get $a6) (local.get $b6))\n           (i64.ge_u (local.get $a7) (local.get $b7))))))))))))))))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::iszero_256, {
    .wast = "(func $iszero_256\n  (param i64)\n  (param i64)\n  (param i64)\n  (param i64)\n  (result i32)\n\n  (i64.eqz (i64.or (i64.or (i64.or (local.get 0) (local.get 1)) (local.get 2)) (local.get 3))) \n)\n",
    .imports = ""
  }
},{
  opcodeEnum::iszero_320, {
    .wast = "(func $iszero_320\n  (param i64)\n  (param i64)\n  (param i64)\n  (param i64)\n  (param i64)\n  (result i32)\n\n  (i64.eqz (i64.or (i64.or (i64.or (i64.or (local.get 0) (local.get 1)) (local.get 2)) (local.get 3)) (local.get 4)))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::iszero_512, {
    .wast = "(func $iszero_512\n  (param i64)\n  (param i64)\n  (param i64)\n  (param i64)\n  (param i64)\n  (param i64)\n  (param i64)\n  (param i64)\n  (result i32)\n  (i64.eqz (i64.or (i64.or (i64.or (i64.or (i64.or (i64.or (i64.or (local.get 0) (local.get 1)) (local.get 2)) (local.get 3)) (local.get 4)) (local.get 5)) (local.get 6)) (local.get 7)))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::keccak, {
    .wast = ";;\n;; Copied from https://github.com/axic/keccak-wasm (has more comments)\n;;\n\n(func $keccak_theta\n  (param $context_offset i32)\n\n  (local $C0 i64)\n  (local $C1 i64)\n  (local $C2 i64)\n  (local $C3 i64)\n  (local $C4 i64)\n  (local $D0 i64)\n  (local $D1 i64)\n  (local $D2 i64)\n  (local $D3 i64)\n  (local $D4 i64)\n\n  ;; C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20];\n  (local.set $C0\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 0)))\n      (i64.xor\n        (i64.load (i32.add (local.get $context_offset) (i32.const 40)))\n        (i64.xor\n          (i64.load (i32.add (local.get $context_offset) (i32.const 80)))\n          (i64.xor\n            (i64.load (i32.add (local.get $context_offset) (i32.const 120)))\n            (i64.load (i32.add (local.get $context_offset) (i32.const 160)))\n          )\n        )\n      )\n    )\n  )\n\n  (local.set $C1\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 8)))\n      (i64.xor\n        (i64.load (i32.add (local.get $context_offset) (i32.const 48)))\n        (i64.xor\n          (i64.load (i32.add (local.get $context_offset) (i32.const 88)))\n          (i64.xor\n            (i64.load (i32.add (local.get $context_offset) (i32.const 128)))\n            (i64.load (i32.add (local.get $context_offset) (i32.const 168)))\n          )\n        )\n      )\n    )\n  )\n\n  (local.set $C2\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 16)))\n      (i64.xor\n        (i64.load (i32.add (local.get $context_offset) (i32.const 56)))\n        (i64.xor\n          (i64.load (i32.add (local.get $context_offset) (i32.const 96)))\n          (i64.xor\n            (i64.load (i32.add (local.get $context_offset) (i32.const 136)))\n            (i64.load (i32.add (local.get $context_offset) (i32.const 176)))\n          )\n        )\n      )\n    )\n  )\n\n  (local.set $C3\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 24)))\n      (i64.xor\n        (i64.load (i32.add (local.get $context_offset) (i32.const 64)))\n        (i64.xor\n          (i64.load (i32.add (local.get $context_offset) (i32.const 104)))\n          (i64.xor\n            (i64.load (i32.add (local.get $context_offset) (i32.const 144)))\n            (i64.load (i32.add (local.get $context_offset) (i32.const 184)))\n          )\n        )\n      )\n    )\n  )\n\n  (local.set $C4\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 32)))\n      (i64.xor\n        (i64.load (i32.add (local.get $context_offset) (i32.const 72)))\n        (i64.xor\n          (i64.load (i32.add (local.get $context_offset) (i32.const 112)))\n          (i64.xor\n            (i64.load (i32.add (local.get $context_offset) (i32.const 152)))\n            (i64.load (i32.add (local.get $context_offset) (i32.const 192)))\n          )\n        )\n      )\n    )\n  )\n\n  ;; D[0] = ROTL64(C[1], 1) ^ C[4];\n  (local.set $D0\n    (i64.xor\n      (local.get $C4)\n      (i64.rotl\n        (local.get $C1)\n        (i64.const 1)\n      )\n    )\n  )\n\n  ;; D[1] = ROTL64(C[2], 1) ^ C[0];\n  (local.set $D1\n    (i64.xor\n      (local.get $C0)\n      (i64.rotl\n        (local.get $C2)\n        (i64.const 1)\n      )\n    )\n  )\n\n  ;; D[2] = ROTL64(C[3], 1) ^ C[1];\n  (local.set $D2\n    (i64.xor\n      (local.get $C1)\n      (i64.rotl\n        (local.get $C3)\n        (i64.const 1)\n      )\n    )\n  )\n\n  ;; D[3] = ROTL64(C[4], 1) ^ C[2];\n  (local.set $D3\n    (i64.xor\n      (local.get $C2)\n      (i64.rotl\n        (local.get $C4)\n        (i64.const 1)\n      )\n    )\n  )\n\n  ;; D[4] = ROTL64(C[0], 1) ^ C[3];\n  (local.set $D4\n    (i64.xor\n      (local.get $C3)\n      (i64.rotl\n        (local.get $C0)\n        (i64.const 1)\n      )\n    )\n  )\n\n  ;; A[x]      ^= D[x];\n  ;; A[x + 5]  ^= D[x];\n  ;; A[x + 10] ^= D[x];\n  ;; A[x + 15] ^= D[x];\n  ;; A[x + 20] ^= D[x];\n  \n  ;; x = 0\n  (i64.store (i32.add (local.get $context_offset) (i32.const 0))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 0)))\n      (local.get $D0)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 40))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 40)))\n      (local.get $D0)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 80))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 80)))\n      (local.get $D0)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 120))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 120)))\n      (local.get $D0)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 160))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 160)))\n      (local.get $D0)\n    )\n  )\n\n  ;; x = 1\n  (i64.store (i32.add (local.get $context_offset) (i32.const 8))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 8)))\n      (local.get $D1)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 48))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 48)))\n      (local.get $D1)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 88))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 88)))\n      (local.get $D1)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 128))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 128)))\n      (local.get $D1)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 168))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 168)))\n      (local.get $D1)\n    )\n  )\n\n  ;; x = 2\n  (i64.store (i32.add (local.get $context_offset) (i32.const 16))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 16)))\n      (local.get $D2)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 56))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 56)))\n      (local.get $D2)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 96))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 96)))\n      (local.get $D2)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 136))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 136)))\n      (local.get $D2)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 176))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 176)))\n      (local.get $D2)\n    )\n  )\n\n  ;; x = 3\n  (i64.store (i32.add (local.get $context_offset) (i32.const 24))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 24)))\n      (local.get $D3)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 64))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 64)))\n      (local.get $D3)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 104))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 104)))\n      (local.get $D3)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 144))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 144)))\n      (local.get $D3)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 184))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 184)))\n      (local.get $D3)\n    )\n  )\n\n  ;; x = 4\n  (i64.store (i32.add (local.get $context_offset) (i32.const 32))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 32)))\n      (local.get $D4)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 72))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 72)))\n      (local.get $D4)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 112))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 112)))\n      (local.get $D4)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 152))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 152)))\n      (local.get $D4)\n    )\n  )\n\n  (i64.store (i32.add (local.get $context_offset) (i32.const 192))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 192)))\n      (local.get $D4)\n    )\n  )\n)\n\n(func $keccak_rho\n  (param $context_offset i32)\n  (param $rotation_consts i32)\n\n  ;;(local $tmp i32)\n\n  ;; state[ 1] = ROTL64(state[ 1],  1);\n  ;;(local.set $tmp (i32.add (local.get $context_offset) (i32.const 1)))\n  ;;(i64.store (local.get $tmp) (i64.rotl (i64.load (local.get $context_offset)) (i64.const 1)))\n\n  ;;(local.set $tmp (i32.add (local.get $context_offset) (i32.const 2)))\n  ;;(i64.store (local.get $tmp) (i64.rotl (i64.load (local.get $context_offset)) (i64.const 62)))\n\n  (local $tmp i32)\n  (local $i i32)\n\n  ;; for (i = 0; i <= 24; i++)\n  (local.set $i (i32.const 0))\n  (block $done\n    (loop $loop\n      (if (i32.ge_u (local.get $i) (i32.const 24))\n        (br $done)\n      )\n\n      (local.set $tmp (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (i32.const 1) (local.get $i)))))\n\n      (i64.store (local.get $tmp) (i64.rotl (i64.load (local.get $tmp)) (i64.load8_u (i32.add (local.get $rotation_consts) (local.get $i)))))\n\n      (local.set $i (i32.add (local.get $i) (i32.const 1)))\n      (br $loop)\n    )\n  )\n)\n\n(func $keccak_pi\n  (param $context_offset i32)\n\n  (local $A1 i64)\n  (local.set $A1 (i64.load (i32.add (local.get $context_offset) (i32.const 8))))\n\n  ;; Swap non-overlapping fields, i.e. $A1 = $A6, etc.\n  ;; NOTE: $A0 is untouched\n  (i64.store (i32.add (local.get $context_offset) (i32.const 8)) (i64.load (i32.add (local.get $context_offset) (i32.const 48))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 48)) (i64.load (i32.add (local.get $context_offset) (i32.const 72))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 72)) (i64.load (i32.add (local.get $context_offset) (i32.const 176))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 176)) (i64.load (i32.add (local.get $context_offset) (i32.const 112))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 112)) (i64.load (i32.add (local.get $context_offset) (i32.const 160))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 160)) (i64.load (i32.add (local.get $context_offset) (i32.const 16))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 16)) (i64.load (i32.add (local.get $context_offset) (i32.const 96))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 96)) (i64.load (i32.add (local.get $context_offset) (i32.const 104))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 104)) (i64.load (i32.add (local.get $context_offset) (i32.const 152))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 152)) (i64.load (i32.add (local.get $context_offset) (i32.const 184))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 184)) (i64.load (i32.add (local.get $context_offset) (i32.const 120))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 120)) (i64.load (i32.add (local.get $context_offset) (i32.const 32))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 32)) (i64.load (i32.add (local.get $context_offset) (i32.const 192))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 192)) (i64.load (i32.add (local.get $context_offset) (i32.const 168))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 168)) (i64.load (i32.add (local.get $context_offset) (i32.const 64))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 64)) (i64.load (i32.add (local.get $context_offset) (i32.const 128))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 128)) (i64.load (i32.add (local.get $context_offset) (i32.const 40))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 40)) (i64.load (i32.add (local.get $context_offset) (i32.const 24))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 24)) (i64.load (i32.add (local.get $context_offset) (i32.const 144))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 144)) (i64.load (i32.add (local.get $context_offset) (i32.const 136))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 136)) (i64.load (i32.add (local.get $context_offset) (i32.const 88))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 88)) (i64.load (i32.add (local.get $context_offset) (i32.const 56))))\n  (i64.store (i32.add (local.get $context_offset) (i32.const 56)) (i64.load (i32.add (local.get $context_offset) (i32.const 80))))\n\n  ;; Place the previously saved overlapping field\n  (i64.store (i32.add (local.get $context_offset) (i32.const 80)) (local.get $A1))\n)\n\n(func $keccak_chi\n  (param $context_offset i32)\n\n  (local $A0 i64)\n  (local $A1 i64)\n  (local $i i32)\n\n  ;; for (round = 0; round < 25; i += 5)\n  (local.set $i (i32.const 0))\n  (block $done\n    (loop $loop\n      (if (i32.ge_u (local.get $i) (i32.const 25))\n        (br $done)\n      )\n\n      (local.set $A0 (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (local.get $i)))))\n      (local.set $A1 (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 1))))))\n\n      ;; A[0 + i] ^= ~A1 & A[2 + i];\n      (i64.store (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (local.get $i)))\n        (i64.xor\n          (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (local.get $i))))\n          (i64.and\n            (i64.xor (local.get $A1) (i64.const 0xFFFFFFFFFFFFFFFF)) ;; bitwise not\n            (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 2)))))\n          )\n        )\n      )\n\n      ;; A[1 + i] ^= ~A[2 + i] & A[3 + i];\n      (i64.store (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 1))))\n        (i64.xor\n          (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 1)))))\n          (i64.and\n            (i64.xor (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 2))))) (i64.const 0xFFFFFFFFFFFFFFFF)) ;; bitwise not\n            (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 3)))))\n          )\n        )\n      )\n\n      ;; A[2 + i] ^= ~A[3 + i] & A[4 + i];\n      (i64.store (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 2))))\n        (i64.xor\n          (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 2)))))\n          (i64.and\n            (i64.xor (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 3))))) (i64.const 0xFFFFFFFFFFFFFFFF)) ;; bitwise not\n            (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 4)))))\n          )\n        )\n      )\n\n      ;; A[3 + i] ^= ~A[4 + i] & A0;\n      (i64.store (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 3))))\n        (i64.xor\n          (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 3)))))\n          (i64.and\n            (i64.xor (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 4))))) (i64.const 0xFFFFFFFFFFFFFFFF)) ;; bitwise not\n            (local.get $A0)\n          )\n        )\n      )\n\n      ;; A[4 + i] ^= ~A0 & A1;\n      (i64.store (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 4))))\n        (i64.xor\n          (i64.load (i32.add (local.get $context_offset) (i32.mul (i32.const 8) (i32.add (local.get $i) (i32.const 4)))))\n          (i64.and\n            (i64.xor (local.get $A0) (i64.const 0xFFFFFFFFFFFFFFFF)) ;; bitwise not\n            (local.get $A1)\n          )\n        )\n      )\n\n      (local.set $i (i32.add (local.get $i) (i32.const 5)))\n      (br $loop)\n    )\n  )\n)\n\n(func $keccak_permute\n  (param $context_offset i32)\n\n  (local $rotation_consts i32)\n  (local $round_consts i32)\n  (local $round i32)\n\n  (local.set $round_consts (i32.add (local.get $context_offset) (i32.const 400)))\n  (local.set $rotation_consts (i32.add (local.get $context_offset) (i32.const 592)))\n\n  ;; for (round = 0; round < 24; round++)\n  (local.set $round (i32.const 0))\n  (block $done\n    (loop $loop\n      (if (i32.ge_u (local.get $round) (i32.const 24))\n        (br $done)\n      )\n\n      ;; theta transform\n      (call $keccak_theta (local.get $context_offset))\n\n      ;; rho transform\n      (call $keccak_rho (local.get $context_offset) (local.get $rotation_consts))\n\n      ;; pi transform\n      (call $keccak_pi (local.get $context_offset))\n\n      ;; chi transform\n      (call $keccak_chi (local.get $context_offset))\n\n      ;; iota transform\n      ;; context_offset[0] ^= KECCAK_ROUND_CONSTANTS[round];\n      (i64.store (local.get $context_offset)\n        (i64.xor\n          (i64.load (local.get $context_offset))\n          (i64.load (i32.add (local.get $round_consts) (i32.mul (i32.const 8) (local.get $round))))\n        )\n      )\n\n      (local.set $round (i32.add (local.get $round) (i32.const 1)))\n      (br $loop)\n    )  \n  ) \n)\n\n(func $keccak_block\n  (param $input_offset i32)\n  (param $input_length i32) ;; ignored, we expect keccak256\n  (param $context_offset i32)\n\n  ;; read blocks in little-endian order and XOR against context_offset\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 0))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 0)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 0)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 8))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 8)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 8)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 16))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 16)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 16)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 24))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 24)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 24)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 32))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 32)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 32)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 40))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 40)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 40)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 48))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 48)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 48)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 56))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 56)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 56)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 64))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 64)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 64)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 72))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 72)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 72)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 80))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 80)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 80)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 88))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 88)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 88)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 96))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 96)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 96)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 104))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 104)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 104)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 112))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 112)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 112)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 120))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 120)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 120)))\n    )\n  )\n\n  (i64.store\n    (i32.add (local.get $context_offset) (i32.const 128))\n    (i64.xor\n      (i64.load (i32.add (local.get $context_offset) (i32.const 128)))\n      (i64.load (i32.add (local.get $input_offset) (i32.const 128)))\n    )\n  )\n  \n  (call $keccak_permute (local.get $context_offset))\n)\n\n;;\n;; Initialise the context\n;;\n(func $keccak_init\n  (param $context_offset i32)\n  (local $round_consts i32)\n  (local $rotation_consts i32)\n\n  (call $keccak_reset (local.get $context_offset))\n\n  ;; insert the round constants (used by $KECCAK_IOTA)\n  (local.set $round_consts (i32.add (local.get $context_offset) (i32.const 400)))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 0)) (i64.const 0x0000000000000001))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 8)) (i64.const 0x0000000000008082))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 16)) (i64.const 0x800000000000808A))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 24)) (i64.const 0x8000000080008000))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 32)) (i64.const 0x000000000000808B))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 40)) (i64.const 0x0000000080000001))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 48)) (i64.const 0x8000000080008081))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 56)) (i64.const 0x8000000000008009))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 64)) (i64.const 0x000000000000008A))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 72)) (i64.const 0x0000000000000088))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 80)) (i64.const 0x0000000080008009))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 88)) (i64.const 0x000000008000000A))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 96)) (i64.const 0x000000008000808B))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 104)) (i64.const 0x800000000000008B))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 112)) (i64.const 0x8000000000008089))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 120)) (i64.const 0x8000000000008003))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 128)) (i64.const 0x8000000000008002))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 136)) (i64.const 0x8000000000000080))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 144)) (i64.const 0x000000000000800A))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 152)) (i64.const 0x800000008000000A))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 160)) (i64.const 0x8000000080008081))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 168)) (i64.const 0x8000000000008080))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 176)) (i64.const 0x0000000080000001))\n  (i64.store (i32.add (local.get $round_consts) (i32.const 184)) (i64.const 0x8000000080008008))\n\n  ;; insert the rotation constants (used by $keccak_rho)\n  (local.set $rotation_consts (i32.add (local.get $context_offset) (i32.const 592)))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 0)) (i32.const 1))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 1)) (i32.const 62))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 2)) (i32.const 28))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 3)) (i32.const 27))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 4)) (i32.const 36))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 5)) (i32.const 44))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 6)) (i32.const 6))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 7)) (i32.const 55))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 8)) (i32.const 20))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 9)) (i32.const 3))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 10)) (i32.const 10))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 11)) (i32.const 43))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 12)) (i32.const 25))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 13)) (i32.const 39))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 14)) (i32.const 41))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 15)) (i32.const 45))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 16)) (i32.const 15))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 17)) (i32.const 21))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 18)) (i32.const 8))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 19)) (i32.const 18))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 20)) (i32.const 2))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 21)) (i32.const 61))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 22)) (i32.const 56))\n  (i32.store8 (i32.add (local.get $rotation_consts) (i32.const 23)) (i32.const 14))\n)\n\n;;\n;; Reset the context\n;;\n(func $keccak_reset\n  (param $context_offset i32)\n\n  ;; clear out the context memory\n  (drop (call $memset (local.get $context_offset) (i32.const 0) (i32.const 400)))\n)\n\n;;\n;; Push input to the context\n;;\n(func $keccak_update\n  (param $context_offset i32)\n  (param $input_offset i32)\n  (param $input_length i32)\n\n  (local $residue_offset i32)\n  (local $residue_buffer i32)\n  (local $residue_index i32)\n  (local $tmp i32)\n\n  ;; this is where we store the pointer\n  (local.set $residue_offset (i32.add (local.get $context_offset) (i32.const 200)))\n  ;; this is where the buffer is\n  (local.set $residue_buffer (i32.add (local.get $context_offset) (i32.const 208)))\n\n  (local.set $residue_index (i32.load (local.get $residue_offset)))\n\n  ;; process residue from last block\n  (if (i32.ne (local.get $residue_index) (i32.const 0))\n    (then\n      ;; the space left in the residue buffer\n      (local.set $tmp (i32.sub (i32.const 136) (local.get $residue_index)))\n\n      ;; limit to what we have as an input\n      (if (i32.lt_u (local.get $input_length) (local.get $tmp))\n        (local.set $tmp (local.get $input_length))\n      )\n\n      ;; fill up the residue buffer\n      (drop (call $memcpy\n        (i32.add (local.get $residue_buffer) (local.get $residue_index))\n        (local.get $input_offset)\n        (local.get $tmp)\n      ))\n\n      (local.set $residue_index (i32.add (local.get $residue_index) (local.get $tmp)))\n\n      ;; block complete\n      (if (i32.eq (local.get $residue_index) (i32.const 136))\n        (call $keccak_block (local.get $input_offset) (i32.const 136) (local.get $context_offset))\n\n        (local.set $residue_index (i32.const 0))\n      )\n\n      (i32.store (local.get $residue_offset) (local.get $residue_index))\n\n      (local.set $input_length (i32.sub (local.get $input_length) (local.get $tmp)))\n    )\n  )\n\n  ;; while (input_length > block_size)\n  (block $done\n    (loop $loop\n      (if (i32.lt_u (local.get $input_length) (i32.const 136))\n        (br $done)\n      )\n\n      (call $keccak_block (local.get $input_offset) (i32.const 136) (local.get $context_offset))\n\n      (local.set $input_offset (i32.add (local.get $input_offset) (i32.const 136)))\n      (local.set $input_length (i32.sub (local.get $input_length) (i32.const 136)))\n      (br $loop)\n    )\n  )\n\n  ;; copy to the residue buffer\n  (if (i32.gt_u (local.get $input_length) (i32.const 0))\n    (then\n      (drop (call $memcpy\n        (i32.add (local.get $residue_buffer) (local.get $residue_index))\n        (local.get $input_offset)\n        (local.get $input_length)\n      ))\n\n      (local.set $residue_index (i32.add (local.get $residue_index) (local.get $input_length)))\n      (i32.store (local.get $residue_offset) (local.get $residue_index))\n    )\n  )\n)\n\n;;\n;; Finalise and return the hash\n;;\n;; The 256 bit hash is returned at the output offset.\n;;\n(func $keccak_finish\n  (param $context_offset i32)\n  (param $output_offset i32)\n\n  (local $residue_offset i32)\n  (local $residue_buffer i32)\n  (local $residue_index i32)\n  (local $tmp i32)\n\n  ;; this is where we store the pointer\n  (local.set $residue_offset (i32.add (local.get $context_offset) (i32.const 200)))\n  ;; this is where the buffer is\n  (local.set $residue_buffer (i32.add (local.get $context_offset) (i32.const 208)))\n\n  (local.set $residue_index (i32.load (local.get $residue_offset)))\n  (local.set $tmp (local.get $residue_index))\n\n  ;; clear the rest of the residue buffer\n  (drop (call $memset (i32.add (local.get $residue_buffer) (local.get $tmp)) (i32.const 0) (i32.sub (i32.const 136) (local.get $tmp))))\n\n  ;; ((char*)ctx->message)[ctx->rest] |= 0x01;\n  (local.set $tmp (i32.add (local.get $residue_buffer) (local.get $residue_index)))\n  (i32.store8 (local.get $tmp) (i32.or (i32.load8_u (local.get $tmp)) (i32.const 0x01)))\n\n  ;; ((char*)ctx->message)[block_size - 1] |= 0x80;\n  (local.set $tmp (i32.add (local.get $residue_buffer) (i32.const 135)))\n  (i32.store8 (local.get $tmp) (i32.or (i32.load8_u (local.get $tmp)) (i32.const 0x80)))\n\n  (call $keccak_block (local.get $residue_buffer) (i32.const 136) (local.get $context_offset))\n\n  ;; the first 32 bytes pointed at by $output_offset is the final hash\n  (i64.store (local.get $output_offset) (i64.load (local.get $context_offset)))\n  (i64.store (i32.add (local.get $output_offset) (i32.const 8)) (i64.load (i32.add (local.get $context_offset) (i32.const 8))))\n  (i64.store (i32.add (local.get $output_offset) (i32.const 16)) (i64.load (i32.add (local.get $context_offset) (i32.const 16))))\n  (i64.store (i32.add (local.get $output_offset) (i32.const 24)) (i64.load (i32.add (local.get $context_offset) (i32.const 24))))\n)\n\n;;\n;; Calculate the hash. Helper method incorporating the above three.\n;;\n(func $keccak\n  (param $context_offset i32)\n  (param $input_offset i32)\n  (param $input_length i32)\n  (param $output_offset i32)\n\n  (call $keccak_init (local.get $context_offset))\n  (call $keccak_update (local.get $context_offset) (local.get $input_offset) (local.get $input_length))\n  (call $keccak_finish (local.get $context_offset) (local.get $output_offset))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::memcpy, {
    .wast = ";;\n;; memcpy from ewasm-libc/ewasm-cleanup\n;;\n(func $memcpy\n  (param $dst i32)\n  (param $src i32)\n  (param $length i32)\n  (result i32)\n\n  (local $i i32)\n\n  (local.set $i (i32.const 0))\n\n  (block $done\n    (loop $loop\n      (if (i32.ge_u (local.get $i) (local.get $length))\n        (br $done)\n      )\n\n      (i32.store8 (i32.add (local.get $dst) (local.get $i)) (i32.load8_u (i32.add (local.get $src) (local.get $i))))\n\n      (local.set $i (i32.add (local.get $i) (i32.const 1)))\n      (br $loop)\n    )\n  )\n\n  (return (local.get $dst))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::memset, {
    .wast = ";;\n;; memcpy from ewasm-libc/ewasm-cleanup\n;;\n(func $memset\n  (param $ptr i32)\n  (param $value i32)\n  (param $length i32)\n  (result i32)\n  (local $i i32)\n\n  (local.set $i (i32.const 0))\n\n  (block $done\n    (loop $loop\n      (if (i32.ge_u (local.get $i) (local.get $length))\n        (br $done)\n      )\n\n      (i32.store8 (i32.add (local.get $ptr) (local.get $i)) (local.get $value))\n\n      (local.set $i (i32.add (local.get $i) (i32.const 1)))\n      (br $loop)\n    )\n  )\n  (local.get $ptr)\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::memusegas, {
    .wast = "(func $memusegas\n  (param $offset i32)\n  (param $length i32)\n\n  (local $cost i64)\n  ;; the number of new words being allocated\n  (local $newWordCount i64)\n\n  (if (i32.eqz (local.get $length))\n    (then (return))\n  )\n\n  ;; const newMemoryWordCount = Math.ceil[[offset + length] / 32]\n  (local.set $newWordCount\n    (i64.div_u (i64.add (i64.const 31) (i64.add (i64.extend_i32_u (local.get $offset)) (i64.extend_i32_u (local.get $length))))\n               (i64.const 32)))\n\n  ;;if [runState.highestMem >= highestMem]  return\n  (if (i64.le_u (local.get $newWordCount) (global.get $wordCount))\n    (then (return))\n  )\n\n  ;; words * 3 + words ^2 / 512\n  (local.set $cost\n     (i64.add\n       (i64.mul (local.get $newWordCount) (i64.const 3))\n       (i64.div_u\n         (i64.mul (local.get $newWordCount)\n                  (local.get $newWordCount))\n         (i64.const 512))))\n\n  (call $useGas  (i64.sub (local.get $cost) (global.get $prevMemCost)))\n  (global.set $prevMemCost (local.get $cost))\n  (global.set $wordCount (local.get $newWordCount))\n\n  ;; grow actual memory\n  ;; the first 31704 bytes are guaranteed to be available\n  ;; adjust for 32 bytes  - the maximal size of MSTORE write\n  ;; TODO it should be memory.size * page_size\n  (local.set $offset (i32.add (local.get $length) (i32.add (local.get $offset) (global.get $memstart))))\n  (if (i32.gt_u (local.get $offset) (i32.mul (i32.const 65536) (memory.size)))\n    (then\n      (drop (memory.grow\n        (i32.div_u (i32.add (i32.const 65535) (i32.sub (local.get $offset) (memory.size))) (i32.const 65536))))\n    )\n  )\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::mod_320, {
    .wast = "(func $mod_320\n  ;; dividend\n  (param $a i64)\n  (param $b i64)\n  (param $c i64)\n  (param $d i64)\n  (param $e i64)\n\n  ;; divisor\n  (param $a1 i64)\n  (param $b1 i64)\n  (param $c1 i64)\n  (param $d1 i64)\n  (param $e1 i64)\n\n  ;; stack pointer\n  (param $sp i32)\n\n  ;; quotient\n  (local $aq i64)\n  (local $bq i64)\n  (local $cq i64)\n  (local $dq i64)\n  (local $eq i64)\n\n  ;; mask\n  (local $maska i64)\n  (local $maskb i64)\n  (local $maskc i64)\n  (local $maskd i64)\n  (local $maske i64)\n\n  (local $carry i32)\n  (local $temp i64)\n\n  (local.set $maske (i64.const 1))\n  (block $main\n    ;; check div by 0\n    (if (call $iszero_320 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1) (local.get $e1))\n      (then\n        (local.set $a (i64.const 0))\n        (local.set $b (i64.const 0))\n        (local.set $c (i64.const 0))\n        (local.set $d (i64.const 0))\n        (local.set $e (i64.const 0))\n        (br $main)\n      )\n    )\n\n    (block $done\n      ;; align bits\n      (loop $loop\n        ;; align bits;\n        (if (i32.or (i64.eqz (i64.clz (local.get $a1))) (call $gte_320\n                                                            (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1) (local.get $e1)\n                                                            (local.get $a) (local.get $b) (local.get $c) (local.get $d) (local.get $e)))\n          (br $done)\n        )\n\n        ;; divisor = divisor << 1\n        (local.set $a1 (i64.add (i64.shl (local.get $a1) (i64.const 1)) (i64.shr_u (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shl (local.get $b1) (i64.const 1)) (i64.shr_u (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shl (local.get $c1) (i64.const 1)) (i64.shr_u (local.get $d1) (i64.const 63))))\n        (local.set $d1 (i64.add (i64.shl (local.get $d1) (i64.const 1)) (i64.shr_u (local.get $e1) (i64.const 63))))\n        (local.set $e1 (i64.shl (local.get $e1) (i64.const 1)))\n\n        ;; mask = mask << 1\n        (local.set $maska (i64.add (i64.shl (local.get $maska) (i64.const 1)) (i64.shr_u (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shl (local.get $maskb) (i64.const 1)) (i64.shr_u (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shl (local.get $maskc) (i64.const 1)) (i64.shr_u (local.get $maskd) (i64.const 63))))\n        (local.set $maskd (i64.add (i64.shl (local.get $maskd) (i64.const 1)) (i64.shr_u (local.get $maske) (i64.const 63))))\n        (local.set $maske (i64.shl (local.get $maske) (i64.const 1)))\n        (br $loop)\n      )\n    )\n\n    (block $done\n      (loop $loop\n        ;; loop while mask != 0\n        (if (call $iszero_320 (local.get $maska) (local.get $maskb) (local.get $maskc) (local.get $maskd) (local.get $maske))\n          (br $done)\n        )\n        ;; if dividend >= divisor\n        (if (call $gte_320 (local.get $a) (local.get $b) (local.get $c) (local.get $d) (local.get $e) (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1) (local.get $e1))\n          (then\n            ;; dividend = dividend - divisor\n            (local.set $carry (i64.lt_u (local.get $e) (local.get $e1)))\n            (local.set $e     (i64.sub  (local.get $e) (local.get $e1)))\n\n            (local.set $temp  (i64.sub  (local.get $d) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $d)))\n            (local.set $d     (i64.sub  (local.get $temp) (local.get $d1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $d) (local.get $temp)) (local.get $carry)))\n\n            (local.set $temp  (i64.sub  (local.get $c) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $c)))\n            (local.set $c     (i64.sub  (local.get $temp) (local.get $c1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $c) (local.get $temp)) (local.get $carry)))\n\n            (local.set $temp  (i64.sub  (local.get $b) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $b)))\n            (local.set $b     (i64.sub  (local.get $temp) (local.get $b1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $b) (local.get $temp)) (local.get $carry)))\n\n            (local.set $a     (i64.sub  (i64.sub (local.get $a) (i64.extend_i32_u (local.get $carry))) (local.get $a1)))\n          )\n        )\n        ;; divisor = divisor >> 1\n        (local.set $e1 (i64.add (i64.shr_u (local.get $e1) (i64.const 1)) (i64.shl (local.get $d1) (i64.const 63))))\n        (local.set $d1 (i64.add (i64.shr_u (local.get $d1) (i64.const 1)) (i64.shl (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shr_u (local.get $c1) (i64.const 1)) (i64.shl (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shr_u (local.get $b1) (i64.const 1)) (i64.shl (local.get $a1) (i64.const 63))))\n        (local.set $a1 (i64.shr_u (local.get $a1) (i64.const 1)))\n\n        ;; mask = mask >> 1\n        (local.set $maske (i64.add (i64.shr_u (local.get $maske) (i64.const 1)) (i64.shl (local.get $maskd) (i64.const 63))))\n        (local.set $maskd (i64.add (i64.shr_u (local.get $maskd) (i64.const 1)) (i64.shl (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shr_u (local.get $maskc) (i64.const 1)) (i64.shl (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shr_u (local.get $maskb) (i64.const 1)) (i64.shl (local.get $maska) (i64.const 63))))\n        (local.set $maska (i64.shr_u (local.get $maska) (i64.const 1)))\n        (br $loop)\n      )\n    )\n  );; end of main\n  (i64.store (i32.add (local.get $sp) (i32.const 24)) (local.get $b))\n  (i64.store (i32.add (local.get $sp) (i32.const 16)) (local.get $c))\n  (i64.store (i32.add (local.get $sp) (i32.const 8))  (local.get $d))\n  (i64.store (local.get $sp)                          (local.get $e))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::mod_512, {
    .wast = ";; Modulo 0x06\n(func $mod_512\n  ;; dividend\n  (param $a i64)\n  (param $b i64)\n  (param $c i64)\n  (param $d i64)\n  (param $e i64)\n  (param $f i64)\n  (param $g i64)\n  (param $h i64)\n\n  ;; divisor\n  (param $a1 i64)\n  (param $b1 i64)\n  (param $c1 i64)\n  (param $d1 i64)\n  (param $e1 i64)\n  (param $f1 i64)\n  (param $g1 i64)\n  (param $h1 i64)\n\n  (param $sp i32)\n\n  ;; quotient\n  (local $aq i64)\n  (local $bq i64)\n  (local $cq i64)\n  (local $dq i64)\n\n  ;; mask\n  (local $maska i64)\n  (local $maskb i64)\n  (local $maskc i64)\n  (local $maskd i64)\n  (local $maske i64)\n  (local $maskf i64)\n  (local $maskg i64)\n  (local $maskh i64)\n\n  (local $carry i32)\n  (local $temp i64)\n\n  (local.set $maskh (i64.const 1))\n\n  (block $main\n    ;; check div by 0\n    (if (call $iszero_512 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1) (local.get $e1) (local.get $f1) (local.get $g1) (local.get $h1))\n      (then\n        (local.set $e (i64.const 0))\n        (local.set $f (i64.const 0))\n        (local.set $g (i64.const 0))\n        (local.set $h (i64.const 0))\n        (br $main)\n      )\n    )\n\n    ;; align bits\n    (block $done\n      (loop $loop\n        ;; align bits;\n        (if (i32.or (i64.eqz (i64.clz (local.get $a1)))\n          (call $gte_512 (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1) (local.get $e1) (local.get $f1) (local.get $g1) (local.get $h1)\n                         (local.get $a)  (local.get $b)  (local.get $c)  (local.get $d)  (local.get $e)  (local.get $f)  (local.get $g)  (local.get $h)))\n          (br $done)\n        )\n\n        ;; divisor = divisor << 1\n        (local.set $a1 (i64.add (i64.shl (local.get $a1) (i64.const 1)) (i64.shr_u (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shl (local.get $b1) (i64.const 1)) (i64.shr_u (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shl (local.get $c1) (i64.const 1)) (i64.shr_u (local.get $d1) (i64.const 63))))\n        (local.set $d1 (i64.add (i64.shl (local.get $d1) (i64.const 1)) (i64.shr_u (local.get $e1) (i64.const 63))))\n        (local.set $e1 (i64.add (i64.shl (local.get $e1) (i64.const 1)) (i64.shr_u (local.get $f1) (i64.const 63))))\n        (local.set $f1 (i64.add (i64.shl (local.get $f1) (i64.const 1)) (i64.shr_u (local.get $g1) (i64.const 63))))\n        (local.set $g1 (i64.add (i64.shl (local.get $g1) (i64.const 1)) (i64.shr_u (local.get $h1) (i64.const 63))))\n        (local.set $h1 (i64.shl (local.get $h1) (i64.const 1)))\n\n        ;; mask = mask << 1\n        (local.set $maska (i64.add (i64.shl (local.get $maska) (i64.const 1)) (i64.shr_u (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shl (local.get $maskb) (i64.const 1)) (i64.shr_u (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shl (local.get $maskc) (i64.const 1)) (i64.shr_u (local.get $maskd) (i64.const 63))))\n        (local.set $maskd (i64.add (i64.shl (local.get $maskd) (i64.const 1)) (i64.shr_u (local.get $maske) (i64.const 63))))\n        (local.set $maske (i64.add (i64.shl (local.get $maske) (i64.const 1)) (i64.shr_u (local.get $maskf) (i64.const 63))))\n        (local.set $maskf (i64.add (i64.shl (local.get $maskf) (i64.const 1)) (i64.shr_u (local.get $maskg) (i64.const 63))))\n        (local.set $maskg (i64.add (i64.shl (local.get $maskg) (i64.const 1)) (i64.shr_u (local.get $maskh) (i64.const 63))))\n        (local.set $maskh (i64.shl (local.get $maskh) (i64.const 1)))\n        (br $loop)\n      )\n    )\n\n    (block $done\n      (loop $loop\n        ;; loop while mask != 0\n        (if (call $iszero_512 (local.get $maska) (local.get $maskb) (local.get $maskc) (local.get $maskd) (local.get $maske) (local.get $maskf) (local.get $maskg) (local.get $maskh))\n          (br $done)\n        )\n        ;; if dividend >= divisor\n        (if (call $gte_512\n          (local.get $a)  (local.get $b)  (local.get $c)  (local.get $d)  (local.get $e)  (local.get $f)  (local.get $g)  (local.get $h)\n          (local.get $a1) (local.get $b1) (local.get $c1) (local.get $d1) (local.get $e1) (local.get $f1) (local.get $g1) (local.get $h1))\n          (then\n            ;; dividend = dividend - divisor\n            (local.set $carry (i64.lt_u (local.get $h) (local.get $h1)))\n            (local.set $h     (i64.sub  (local.get $h) (local.get $h1)))\n\n            (local.set $temp  (i64.sub  (local.get $g) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $g)))\n            (local.set $g     (i64.sub  (local.get $temp) (local.get $g1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $g) (local.get $temp)) (local.get $carry)))\n\n            (local.set $temp  (i64.sub  (local.get $f) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $f)))\n            (local.set $f     (i64.sub  (local.get $temp) (local.get $f1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $f) (local.get $temp)) (local.get $carry)))\n\n            (local.set $temp  (i64.sub  (local.get $e) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $e)))\n            (local.set $e     (i64.sub  (local.get $temp) (local.get $e1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $e) (local.get $temp)) (local.get $carry)))\n\n            (local.set $temp  (i64.sub  (local.get $d) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $d)))\n            (local.set $d     (i64.sub  (local.get $temp) (local.get $d1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $d) (local.get $temp)) (local.get $carry)))\n\n            (local.set $temp  (i64.sub  (local.get $c) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $c)))\n            (local.set $c     (i64.sub  (local.get $temp) (local.get $c1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $c) (local.get $temp)) (local.get $carry)))\n\n            (local.set $temp  (i64.sub  (local.get $b) (i64.extend_i32_u (local.get $carry))))\n            (local.set $carry (i64.gt_u (local.get $temp) (local.get $b)))\n            (local.set $b     (i64.sub  (local.get $temp) (local.get $b1)))\n            (local.set $carry (i32.or   (i64.gt_u (local.get $b) (local.get $temp)) (local.get $carry)))\n            (local.set $a     (i64.sub  (i64.sub (local.get $a) (i64.extend_i32_u (local.get $carry))) (local.get $a1)))\n          )\n        )\n        ;; divisor = divisor >> 1\n        (local.set $h1 (i64.add (i64.shr_u (local.get $h1) (i64.const 1)) (i64.shl (local.get $g1) (i64.const 63))))\n        (local.set $g1 (i64.add (i64.shr_u (local.get $g1) (i64.const 1)) (i64.shl (local.get $f1) (i64.const 63))))\n        (local.set $f1 (i64.add (i64.shr_u (local.get $f1) (i64.const 1)) (i64.shl (local.get $e1) (i64.const 63))))\n        (local.set $e1 (i64.add (i64.shr_u (local.get $e1) (i64.const 1)) (i64.shl (local.get $d1) (i64.const 63))))\n        (local.set $d1 (i64.add (i64.shr_u (local.get $d1) (i64.const 1)) (i64.shl (local.get $c1) (i64.const 63))))\n        (local.set $c1 (i64.add (i64.shr_u (local.get $c1) (i64.const 1)) (i64.shl (local.get $b1) (i64.const 63))))\n        (local.set $b1 (i64.add (i64.shr_u (local.get $b1) (i64.const 1)) (i64.shl (local.get $a1) (i64.const 63))))\n        (local.set $a1 (i64.shr_u (local.get $a1) (i64.const 1)))\n\n        ;; mask = mask >> 1\n        (local.set $maskh (i64.add (i64.shr_u (local.get $maskh) (i64.const 1)) (i64.shl (local.get $maskg) (i64.const 63))))\n        (local.set $maskg (i64.add (i64.shr_u (local.get $maskg) (i64.const 1)) (i64.shl (local.get $maskf) (i64.const 63))))\n        (local.set $maskf (i64.add (i64.shr_u (local.get $maskf) (i64.const 1)) (i64.shl (local.get $maske) (i64.const 63))))\n        (local.set $maske (i64.add (i64.shr_u (local.get $maske) (i64.const 1)) (i64.shl (local.get $maskd) (i64.const 63))))\n        (local.set $maskd (i64.add (i64.shr_u (local.get $maskd) (i64.const 1)) (i64.shl (local.get $maskc) (i64.const 63))))\n        (local.set $maskc (i64.add (i64.shr_u (local.get $maskc) (i64.const 1)) (i64.shl (local.get $maskb) (i64.const 63))))\n        (local.set $maskb (i64.add (i64.shr_u (local.get $maskb) (i64.const 1)) (i64.shl (local.get $maska) (i64.const 63))))\n        (local.set $maska (i64.shr_u (local.get $maska) (i64.const 1)))\n        (br $loop)\n      )\n    )\n  );; end of main\n\n  (i64.store (local.get $sp) (local.get $e))\n  (i64.store (i32.sub (local.get $sp) (i32.const 8)) (local.get $f))\n  (i64.store (i32.sub (local.get $sp) (i32.const 16)) (local.get $g))\n  (i64.store (i32.sub (local.get $sp) (i32.const 24)) (local.get $h))\n)\n",
    .imports = ""
  }
},{
  opcodeEnum::mul_256, {
    .wast = "(func $mul_256\n  ;;  a b c d e f g h\n  ;;* i j k l m n o p\n  ;;----------------\n  (param $a i64)\n  (param $c i64)\n  (param $e i64)\n  (param $g i64)\n\n  (param $i i64)\n  (param $k i64)\n  (param $m i64)\n  (param $o i64)\n\n  (param $sp i32)\n\n  (local $b i64)\n  (local $d i64)\n  (local $f i64)\n  (local $h i64)\n  (local $j i64)\n  (local $l i64)\n  (local $n i64)\n  (local $p i64)\n  (local $temp6 i64)\n  (local $temp5 i64)\n  (local $temp4 i64)\n  (local $temp3 i64)\n  (local $temp2 i64)\n  (local $temp1 i64)\n  (local $temp0 i64)\n\n  ;; split the ops\n  (local.set $b (i64.and (local.get $a) (i64.const 4294967295)))\n  (local.set $a (i64.shr_u (local.get $a) (i64.const 32))) \n\n  (local.set $d (i64.and (local.get $c) (i64.const 4294967295)))\n  (local.set $c (i64.shr_u (local.get $c) (i64.const 32))) \n\n  (local.set $f (i64.and (local.get $e) (i64.const 4294967295)))\n  (local.set $e (i64.shr_u (local.get $e) (i64.const 32)))\n\n  (local.set $h (i64.and (local.get $g) (i64.const 4294967295)))\n  (local.set $g (i64.shr_u (local.get $g) (i64.const 32)))\n\n  (local.set $j (i64.and (local.get $i) (i64.const 4294967295)))\n  (local.set $i (i64.shr_u (local.get $i) (i64.const 32))) \n\n  (local.set $l (i64.and (local.get $k) (i64.const 4294967295)))\n  (local.set $k (i64.shr_u (local.get $k) (i64.const 32))) \n\n  (local.set $n (i64.and (local.get $m) (i64.const 4294967295)))\n  (local.set $m (i64.shr_u (local.get $m) (i64.const 32)))\n\n  (local.set $p (i64.and (local.get $o) (i64.const 4294967295)))\n  (local.set $o (i64.shr_u (local.get $o) (i64.const 32)))\n  ;; first row multiplication \n  ;; p * h\n  (local.set $temp0 (i64.mul (local.get $p) (local.get $h)))\n  ;; p * g + carry\n  (local.set $temp1 (i64.add (i64.mul (local.get $p) (local.get $g)) (i64.shr_u (local.get $temp0) (i64.const 32))))\n  ;; p * f + carry\n  (local.set $temp2 (i64.add (i64.mul (local.get $p) (local.get $f)) (i64.shr_u (local.get $temp1) (i64.const 32))))\n  ;; p * e + carry\n  (local.set $temp3 (i64.add (i64.mul (local.get $p) (local.get $e)) (i64.shr_u (local.get $temp2) (i64.const 32))))\n  ;; p * d + carry\n  (local.set $temp4 (i64.add (i64.mul (local.get $p) (local.get $d)) (i64.shr_u (local.get $temp3) (i64.const 32))))\n  ;; p * c + carry\n  (local.set $temp5  (i64.add (i64.mul (local.get $p) (local.get $c)) (i64.shr_u (local.get $temp4) (i64.const 32))))\n  ;; p * b + carry\n  (local.set $temp6  (i64.add (i64.mul (local.get $p) (local.get $b)) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; p * a + carry\n  (local.set $a  (i64.add (i64.mul (local.get $p) (local.get $a)) (i64.shr_u (local.get $temp6) (i64.const 32))))\n  ;; second row\n  ;; o * h + $temp1 \"pg\"\n  (local.set $temp1 (i64.add (i64.mul (local.get $o) (local.get $h)) (i64.and (local.get $temp1) (i64.const 4294967295))))\n  ;; o * g + $temp2 \"pf\" + carry\n  (local.set $temp2 (i64.add (i64.add (i64.mul (local.get $o) (local.get $g)) (i64.and (local.get $temp2) (i64.const 4294967295))) (i64.shr_u (local.get $temp1) (i64.const 32))))\n  ;; o * f + $temp3 \"pe\" + carry\n  (local.set $temp3 (i64.add (i64.add (i64.mul (local.get $o) (local.get $f)) (i64.and (local.get $temp3) (i64.const 4294967295))) (i64.shr_u (local.get $temp2) (i64.const 32))))\n  ;; o * e + $temp4  + carry\n  (local.set $temp4 (i64.add (i64.add (i64.mul (local.get $o) (local.get $e)) (i64.and (local.get $temp4) (i64.const 4294967295))) (i64.shr_u (local.get $temp3) (i64.const 32))))\n  ;; o * d + $temp5  + carry\n  (local.set $temp5 (i64.add (i64.add (i64.mul (local.get $o) (local.get $d)) (i64.and (local.get $temp5) (i64.const 4294967295))) (i64.shr_u (local.get $temp4) (i64.const 32))))\n  ;; o * c + $temp6  + carry\n  (local.set $temp6 (i64.add (i64.add (i64.mul (local.get $o) (local.get $c)) (i64.and (local.get $temp6) (i64.const 4294967295))) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; o * b + $a  + carry\n  (local.set $a (i64.add (i64.add (i64.mul (local.get $o) (local.get $b)) (i64.and (local.get $a) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n  ;; third row - n\n  ;; n * h + $temp2 \n  (local.set $temp2 (i64.add (i64.mul (local.get $n) (local.get $h)) (i64.and (local.get $temp2) (i64.const 4294967295))))\n  ;; n * g + $temp3 + carry\n  (local.set $temp3 (i64.add (i64.add (i64.mul (local.get $n) (local.get $g)) (i64.and (local.get $temp3) (i64.const 4294967295))) (i64.shr_u (local.get $temp2) (i64.const 32))))\n  ;; n * f + $temp4 + carry\n  (local.set $temp4 (i64.add (i64.add (i64.mul (local.get $n) (local.get $f)) (i64.and (local.get $temp4) (i64.const 4294967295))) (i64.shr_u (local.get $temp3) (i64.const 32))))\n  ;; n * e + $temp5  + carry\n  (local.set $temp5 (i64.add (i64.add (i64.mul (local.get $n) (local.get $e)) (i64.and (local.get $temp5) (i64.const 4294967295))) (i64.shr_u (local.get $temp4) (i64.const 32))))\n  ;; n * d + $temp6  + carry\n  (local.set $temp6 (i64.add (i64.add (i64.mul (local.get $n) (local.get $d)) (i64.and (local.get $temp6) (i64.const 4294967295))) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; n * c + $a  + carry\n  (local.set $a (i64.add (i64.add (i64.mul (local.get $n) (local.get $c)) (i64.and (local.get $a) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n\n  ;; forth row \n  ;; m * h + $temp3\n  (local.set $temp3 (i64.add (i64.mul (local.get $m) (local.get $h)) (i64.and (local.get $temp3) (i64.const 4294967295))))\n  ;; m * g + $temp4 + carry\n  (local.set $temp4 (i64.add (i64.add (i64.mul (local.get $m) (local.get $g)) (i64.and (local.get $temp4) (i64.const 4294967295))) (i64.shr_u (local.get $temp3) (i64.const 32))))\n  ;; m * f + $temp5 + carry\n  (local.set $temp5 (i64.add (i64.add (i64.mul (local.get $m) (local.get $f)) (i64.and (local.get $temp5) (i64.const 4294967295))) (i64.shr_u (local.get $temp4) (i64.const 32))))\n  ;; m * e + $temp6 + carry\n  (local.set $temp6 (i64.add (i64.add (i64.mul (local.get $m) (local.get $e)) (i64.and (local.get $temp6) (i64.const 4294967295))) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; m * d + $a + carry\n  (local.set $a (i64.add (i64.add (i64.mul (local.get $m) (local.get $d)) (i64.and (local.get $a) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n\n  ;; fith row\n  ;; l * h + $temp4\n  (local.set $temp4 (i64.add (i64.mul (local.get $l) (local.get $h)) (i64.and (local.get $temp4) (i64.const 4294967295))))\n  ;; l * g + $temp5 + carry\n  (local.set $temp5 (i64.add (i64.add (i64.mul (local.get $l) (local.get $g)) (i64.and (local.get $temp5) (i64.const 4294967295))) (i64.shr_u (local.get $temp4) (i64.const 32))))\n  ;; l * f + $temp6 + carry\n  (local.set $temp6 (i64.add (i64.add (i64.mul (local.get $l) (local.get $f)) (i64.and (local.get $temp6) (i64.const 4294967295))) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; l * e + $a + carry\n  (local.set $a (i64.add (i64.add (i64.mul (local.get $l) (local.get $e)) (i64.and (local.get $a) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n\n  ;; sixth row \n  ;; k * h + $temp5\n  (local.set $temp5 (i64.add (i64.mul (local.get $k) (local.get $h)) (i64.and (local.get $temp5) (i64.const 4294967295))))\n  ;; k * g + $temp6 + carry\n  (local.set $temp6 (i64.add (i64.add (i64.mul (local.get $k) (local.get $g)) (i64.and (local.get $temp6) (i64.const 4294967295))) (i64.shr_u (local.get $temp5) (i64.const 32))))\n  ;; k * f + $a + carry\n  (local.set $a (i64.add (i64.add (i64.mul (local.get $k) (local.get $f)) (i64.and (local.get $a) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))))\n\n  ;; seventh row\n  ;; j * h + $temp6\n  (local.set $temp6 (i64.add (i64.mul (local.get $j) (local.get $h)) (i64.and (local.get $temp6) (i64.const 4294967295))))\n  ;; j * g + $a + carry\n\n  ;; eigth row\n  ;; i * h + $a\n  (local.set $a (i64.add (i64.mul (local.get $i) (local.get $h)) (i64.and (i64.add (i64.add (i64.mul (local.get $j) (local.get $g)) (i64.and (local.get $a) (i64.const 4294967295))) (i64.shr_u (local.get $temp6) (i64.const 32))) (i64.const 4294967295))))\n\n  ;; combine terms\n  (local.set $a (i64.or (i64.shl (local.get $a) (i64.const 32)) (i64.and (local.get $temp6) (i64.const 4294967295))))\n  (local.set $c (i64.or (i64.shl (local.get $temp5) (i64.const 32)) (i64.and (local.get $temp4) (i64.const 4294967295))))\n  (local.set $e (i64.or (i64.shl (local.get $temp3) (i64.const 32)) (i64.and (local.get $temp2) (i64.const 4294967295))))\n  (local.set $g (i64.or (i64.shl (local.get $temp1) (i64.const 32)) (i64.and (local.get $temp0) (i64.const 4294967295))))\n\n  ;; save stack \n  (i64.store (local.get $sp) (local.get $a))\n  (i64.store (i32.sub (local.get $sp) (i32.const 8)) (local.get $c))\n  (i64.store (i32.sub (local.get $sp) (i32.const 16)) (local.get $e))\n  (i64.store (i32.sub (local.get $sp) (i32.const 24)) (local.get $g))\n)\n",
    .imports = ""
  }
}
  };
}