Make all instructions non-faulting; handle faulting case in gen_safe_{read,write} (#44)

This commit is contained in:
Fabian 2018-08-21 18:07:45 -05:00
parent 60d4a28e2c
commit d4d7d236d5
15 changed files with 261 additions and 208 deletions

View file

@ -236,8 +236,29 @@ fn gen_safe_read(ctx: &mut JitContext, bits: BitSize) {
}
// Pseudo:
// else { leave_on_stack(safe_read*_slow(address)); if(page_fault) return }
// else {
// *previous_ip = *instruction_pointer & ~0xFFF | start_of_instruction;
// leave_on_stack(safe_read*_slow(address));
// if(page_fault) return;
// }
builder.instruction_body.else_();
builder
.instruction_body
.push_i32(global_pointers::PREVIOUS_IP as i32);
builder
.instruction_body
.load_aligned_i32(global_pointers::INSTRUCTION_POINTER);
builder.instruction_body.push_i32(!0xFFF);
builder.instruction_body.and_i32();
builder
.instruction_body
.push_i32(ctx.start_of_current_instruction as i32 & 0xFFF);
builder.instruction_body.or_i32();
builder.instruction_body.store_aligned_i32();
builder.instruction_body.get_local(&address_local);
match bits {
BitSize::WORD => {
@ -341,8 +362,29 @@ fn gen_safe_write(
}
// Pseudo:
// else { safe_write*_slow(address, value); if(page_fault) return; }
// else {
// *previous_ip = *instruction_pointer & ~0xFFF | start_of_instruction;
// safe_write*_slow(address, value);
// if(page_fault) return;
// }
builder.instruction_body.else_();
builder
.instruction_body
.push_i32(global_pointers::PREVIOUS_IP as i32);
builder
.instruction_body
.load_aligned_i32(global_pointers::INSTRUCTION_POINTER);
builder.instruction_body.push_i32(!0xFFF);
builder.instruction_body.and_i32();
builder
.instruction_body
.push_i32(ctx.start_of_current_instruction as i32 & 0xFFF);
builder.instruction_body.or_i32();
builder.instruction_body.store_aligned_i32();
builder.instruction_body.get_local(&address_local);
builder.instruction_body.get_local(&value_local);
match bits {

View file

@ -19,7 +19,6 @@ pub const WASM_TABLE_SIZE: u32 = 0x10000;
pub const HASH_PRIME: u32 = 6151;
pub const CHECK_JIT_CACHE_ARRAY_INVARIANTS: bool = false;
pub const ENABLE_JIT_NONFAULTING_OPTIMZATION: bool = true;
pub const JIT_MAX_ITERATIONS_PER_FUNCTION: u32 = 10000;
@ -380,6 +379,7 @@ impl cached_code {
pub struct JitContext<'a> {
pub cpu: &'a mut CpuContext,
pub builder: &'a mut WasmBuilder,
pub start_of_current_instruction: u32,
}
pub const JIT_INSTR_BLOCK_BOUNDARY_FLAG: u32 = 1 << 0;
@ -643,16 +643,14 @@ fn jit_find_basic_blocks(
}
}
let mut basic_blocks: Vec<BasicBlock> =
basic_blocks.into_iter().map(|(_, block)| block).collect();
basic_blocks.sort_by_key(|block| block.addr);
let basic_blocks: Vec<BasicBlock> = basic_blocks.into_iter().map(|(_, block)| block).collect();
for i in 0..basic_blocks.len() - 1 {
let next_block_addr = basic_blocks[i + 1].addr;
let next_block_end_addr = basic_blocks[i + 1].end_addr;
let next_block_is_entry = basic_blocks[i + 1].is_entry_block;
let block = &basic_blocks[i];
dbg_assert!(block.addr < next_block_addr);
if next_block_addr < block.end_addr {
dbg_log!(
"Overlapping first=[from={:x} to={:x} is_entry={}] second=[from={:x} to={:x} is_entry={}]",
@ -1045,6 +1043,7 @@ fn jit_generate_module(
let ctx = &mut JitContext {
cpu: &mut cpu.clone(),
builder,
start_of_current_instruction: 0,
};
codegen::gen_fn1_const(ctx, "jmp_rel16", jump_offset as u32);
}
@ -1108,11 +1107,7 @@ fn jit_generate_basic_block(
last_instruction_addr: u32,
stop_addr: u32,
) {
let mut len = 0;
let mut end_addr;
let mut was_block_boundary;
let mut eip_delta = 0;
let mut count = 0;
// First iteration of do-while assumes the caller confirms this condition
dbg_assert!(!is_near_end_of_page(start_addr));
@ -1123,6 +1118,19 @@ fn jit_generate_basic_block(
if false {
::opstats::gen_opstats(builder, cpu::read32(cpu.eip));
}
if cpu.eip == last_instruction_addr {
// Before the last instruction:
// - Set eip to *after* the instruction
// - Set previous_eip to *before* the instruction
builder.commit_instruction_body_to_cs();
codegen::gen_set_previous_eip_offset_from_eip(
builder,
last_instruction_addr - start_addr,
);
codegen::gen_increment_instruction_pointer(builder, stop_addr - start_addr);
}
let start_eip = cpu.eip;
let mut instruction_flags = 0;
jit_instructions::jit_instruction(&mut cpu, builder, &mut instruction_flags);
@ -1141,55 +1149,18 @@ fn jit_generate_basic_block(
}
let instruction_length = end_eip - start_eip;
was_block_boundary = instruction_flags & JIT_INSTR_BLOCK_BOUNDARY_FLAG != 0;
let was_block_boundary = instruction_flags & JIT_INSTR_BLOCK_BOUNDARY_FLAG != 0;
dbg_assert!((end_eip == stop_addr) == (start_eip == last_instruction_addr));
dbg_assert!(instruction_length < MAX_INSTRUCTION_LENGTH);
if ENABLE_JIT_NONFAULTING_OPTIMZATION {
// There are a few conditions to keep in mind to optimize the update of previous_ip and
// instruction_pointer:
// - previous_ip MUST be updated just before a faulting instruction
// - instruction_pointer MUST be updated before jump instructions (since they use the EIP
// value for instruction logic)
// - Nonfaulting instructions don't need either to be updated
if was_block_boundary {
// prev_ip = eip + eip_delta, so that previous_ip points to the start of this instruction
codegen::gen_set_previous_eip_offset_from_eip(builder, eip_delta);
// eip += eip_delta + len(jump) so instruction logic uses the correct eip
codegen::gen_increment_instruction_pointer(builder, eip_delta + instruction_length);
builder.commit_instruction_body_to_cs();
eip_delta = 0;
}
else if instruction_flags & JIT_INSTR_NONFAULTING_FLAG == 0 {
// Faulting instruction
// prev_ip = eip + eip_delta, so that previous_ip points to the start of this instruction
codegen::gen_set_previous_eip_offset_from_eip(builder, eip_delta);
builder.commit_instruction_body_to_cs();
// Leave this instruction's length to be updated in the next batch, whatever it may be
eip_delta += instruction_length;
}
else {
// Non-faulting, so we skip setting previous_ip and simply queue the instruction length
// for whenever eip is updated next
profiler::stat_increment(stat::S_NONFAULTING_OPTIMIZATION);
eip_delta += instruction_length;
}
}
else {
codegen::gen_set_previous_eip(builder);
codegen::gen_increment_instruction_pointer(builder, instruction_length);
builder.commit_instruction_body_to_cs();
}
end_addr = cpu.eip;
len += 1;
let end_addr = cpu.eip;
count += 1;
if end_addr == stop_addr {
// no page was crossed
dbg_assert!(Page::page_of(end_addr) == Page::page_of(start_addr));
break;
}
@ -1201,18 +1172,7 @@ fn jit_generate_basic_block(
}
}
if ENABLE_JIT_NONFAULTING_OPTIMZATION {
// When the block ends in a non-jump instruction, we may have uncommitted updates still
if eip_delta > 0 {
builder.commit_instruction_body_to_cs();
codegen::gen_increment_instruction_pointer(builder, eip_delta);
}
}
codegen::gen_increment_timestamp_counter(builder, len);
// no page was crossed
dbg_assert!(Page::page_of(end_addr) == Page::page_of(start_addr));
codegen::gen_increment_timestamp_counter(builder, count);
}
pub fn jit_increase_hotness_and_maybe_compile(

View file

@ -16,7 +16,12 @@ use wasmgen::wasm_util::WasmBuf;
pub fn jit_instruction(cpu: &mut CpuContext, builder: &mut WasmBuilder, instr_flags: &mut u32) {
cpu.prefixes = 0;
let ctx = &mut JitContext { cpu, builder };
let start_of_current_instruction = cpu.eip;
let ctx = &mut JitContext {
cpu,
builder,
start_of_current_instruction,
};
::gen::jit::jit(
ctx.cpu.read_imm8() as u32 | (ctx.cpu.osize_32() as u32) << 8,
ctx,

View file

@ -33,6 +33,12 @@
(i32.load
(i32.const 556))
(i32.const 5)))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(set_local $l0
(i32.sub
(i32.load
@ -75,6 +81,14 @@
(get_local $l2))
(get_local $l0)))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 0)))
(call $e.safe_write32_slow_jit
(get_local $l2)
(get_local $l0))
@ -92,12 +106,6 @@
(i32.load
(i32.const 556))
(i32.const 1)))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(set_local $p0
(i32.const 2))
(br $L0))
@ -111,14 +119,15 @@
(i32.load
(i32.const 556))
(i32.const 1)))
(call $e.instr_F4)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(call $e.instr_F4)
(return))
(call $e.instr32_40)
(i32.store
(i32.const 560)
(i32.add
@ -131,7 +140,12 @@
(i32.load
(i32.const 556))
(i32.const 2)))
(call $e.instr32_40)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 2)))
(i32.const 556)
(i32.load
(i32.const 740))
@ -167,6 +181,14 @@
(i32.const -4096))
(get_local $l1))))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 7)))
(call $e.safe_read32s_slow_jit
(get_local $l1))
(if $I8
@ -181,11 +203,5 @@
(i32.const 4)))
(i32.add)
(i32.store)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 2)))
(return))
(unreachable))))

View file

@ -23,6 +23,7 @@
(block $B4
(br_table $B4 $B3 $B2 $B1
(get_local $p0)))
(call $e.instr32_43)
(i32.store
(i32.const 560)
(i32.add
@ -35,16 +36,15 @@
(i32.load
(i32.const 556))
(i32.const 4)))
(call $e.instr32_43)
(call $e.instr32_83_7_reg
(i32.const 0)
(i32.const 10))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 2)))
(call $e.instr32_83_7_reg
(i32.const 0)
(i32.const 10))
(return))
(i32.store
(i32.const 560)
@ -87,12 +87,12 @@
(i32.load
(i32.const 556))
(i32.const 1)))
(call $e.instr_F4)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(call $e.instr_F4)
(return))
(unreachable))))

View file

@ -35,15 +35,15 @@
(i32.load
(i32.const 556))
(i32.const 3)))
(call $e.instr32_83_7_reg
(i32.const 0)
(i32.const 5))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(call $e.instr32_83_7_reg
(i32.const 0)
(i32.const 5))
(return))
(i32.store
(i32.const 560)
@ -76,7 +76,10 @@
(set_local $p0
(i32.const 2))))
(br $L0))
(call $e.instr32_41)
(i32.store
(i32.const 560)
(i32.load
(i32.const 556)))
(i32.store
(i32.const 556)
(i32.add
@ -89,9 +92,11 @@
(i32.load
(i32.const 664))
(i32.const 1)))
(call $e.instr32_41)
(set_local $p0
(i32.const 3))
(br $L0))
(call $e.instr32_43)
(i32.store
(i32.const 560)
(i32.add
@ -104,13 +109,12 @@
(i32.load
(i32.const 556))
(i32.const 2)))
(call $e.instr32_43)
(call $e.instr_F4)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 2)))
(call $e.instr_F4)
(return))
(unreachable))))

View file

@ -30,18 +30,18 @@
(i32.load
(i32.const 556))
(i32.const 2)))
(call $e.instr32_FF_2_mem
(i32.add
(i32.load
(i32.const 4))
(call $e.get_seg
(i32.const 3))))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(call $e.instr32_FF_2_mem
(i32.add
(i32.load
(i32.const 4))
(call $e.get_seg
(i32.const 3))))
(return))
(i32.store
(i32.const 560)
@ -53,12 +53,12 @@
(i32.load
(i32.const 556))
(i32.const 1)))
(call $e.instr_F4)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(call $e.instr_F4)
(return))
(unreachable))))

View file

@ -21,12 +21,6 @@
(block $B2
(br_table $B2 $B1
(get_local $p0)))
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 3)))
(call $e.instr16_B8
(i32.const 51966))
(i32.store16
@ -61,6 +55,14 @@
(i32.const -4096))
(get_local $l0))))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 3)))
(call $e.safe_read16_slow_jit
(get_local $l0))
(if $I4
@ -68,12 +70,6 @@
(i32.const 540))
(then
(return))))))
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 7)))
(i32.store16
(i32.const 12)
(if $I5 (result i32)
@ -106,6 +102,14 @@
(i32.const -4096))
(get_local $l1))))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 7)))
(call $e.safe_read16_slow_jit
(get_local $l1))
(if $I6
@ -113,12 +117,6 @@
(i32.const 540))
(then
(return))))))
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 19)))
(i32.store16
(i32.const 32)
(i32.const 36))
@ -166,6 +164,14 @@
(get_local $l0))
(get_local $l1)))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 19)))
(call $e.safe_write16_slow_jit
(get_local $l0)
(get_local $l1))
@ -174,12 +180,6 @@
(i32.const 540))
(then
(return)))))
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 21)))
(set_local $l1
(i32.add
(i32.and
@ -221,6 +221,14 @@
(get_local $l1))
(get_local $l0)))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 21)))
(call $e.safe_write16_slow_jit
(get_local $l1)
(get_local $l0))
@ -229,18 +237,6 @@
(i32.const 540))
(then
(return)))))
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 31)))
(i32.store
(i32.const 556)
(i32.add
(i32.load
(i32.const 556))
(i32.const 32)))
(i32.store16
(i32.const 8)
(i32.load16_u
@ -257,12 +253,24 @@
(i32.const 4)
(i32.load16_u
(i32.const 8)))
(call $e.instr_F4)
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 31)))
(i32.store
(i32.const 556)
(i32.add
(i32.load
(i32.const 556))
(i32.const 32)))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 12)))
(call $e.instr_F4)
(return))
(unreachable))))

View file

@ -20,10 +20,6 @@
(block $B2
(br_table $B2 $B1
(get_local $p0)))
(i32.store
(i32.const 560)
(i32.load
(i32.const 556)))
(set_local $l0
(i32.add
(i32.add
@ -62,6 +58,14 @@
(get_local $l0))
(get_local $l1)))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 0)))
(call $e.safe_write32_slow_jit
(get_local $l0)
(get_local $l1))
@ -70,12 +74,6 @@
(i32.const 540))
(then
(return)))))
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 6)))
(set_local $l1
(i32.add
(i32.add
@ -114,6 +112,14 @@
(get_local $l1))
(get_local $l0)))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 6)))
(call $e.safe_write32_slow_jit
(get_local $l1)
(get_local $l0))
@ -122,12 +128,6 @@
(i32.const 540))
(then
(return)))))
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 12)))
(i32.store
(i32.const 28)
(if $I7 (result i32)
@ -163,6 +163,14 @@
(i32.const -4096))
(get_local $l0))))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 12)))
(call $e.safe_read32s_slow_jit
(get_local $l0))
(if $I8
@ -170,12 +178,6 @@
(i32.const 540))
(then
(return))))))
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 18)))
(i32.store
(i32.const 32)
(if $I9 (result i32)
@ -211,6 +213,14 @@
(i32.const -4096))
(get_local $l1))))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 18)))
(call $e.safe_read32s_slow_jit
(get_local $l1))
(if $I10
@ -230,12 +240,12 @@
(i32.load
(i32.const 556))
(i32.const 25)))
(call $e.instr_F4)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 5)))
(call $e.instr_F4)
(return))
(unreachable))))

View file

@ -22,18 +22,6 @@
(block $B2
(br_table $B2 $B1
(get_local $p0)))
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 28)))
(i32.store
(i32.const 556)
(i32.add
(i32.load
(i32.const 556))
(i32.const 29)))
(call $e.instr32_B8
(i32.const -889270259))
(call $e.instr32_B9
@ -58,12 +46,24 @@
(i32.const 4)
(i32.load
(i32.const 8)))
(call $e.instr_F4)
(i32.store
(i32.const 560)
(i32.add
(i32.load
(i32.const 556))
(i32.const 28)))
(i32.store
(i32.const 556)
(i32.add
(i32.load
(i32.const 556))
(i32.const 29)))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 9)))
(call $e.instr_F4)
(return))
(unreachable))))

View file

@ -19,10 +19,6 @@
(block $B2
(br_table $B2 $B1
(get_local $p0)))
(i32.store
(i32.const 560)
(i32.load
(i32.const 556)))
(i32.const 4)
(if $I3 (result i32)
(i32.and
@ -56,6 +52,14 @@
(i32.const -4096))
(get_local $l1))))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 0)))
(call $e.safe_read32s_slow_jit
(get_local $l1))
(if $I4
@ -81,12 +85,12 @@
(i32.load
(i32.const 556))
(i32.const 2)))
(call $e.instr_F4)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 2)))
(call $e.instr_F4)
(return))
(unreachable))))

View file

@ -19,10 +19,6 @@
(block $B2
(br_table $B2 $B1
(get_local $p0)))
(i32.store
(i32.const 560)
(i32.load
(i32.const 556)))
(set_local $l0
(i32.load
(i32.const 4)))
@ -62,6 +58,14 @@
(get_local $l2))
(get_local $l0)))
(else
(i32.store
(i32.const 560)
(i32.or
(i32.and
(i32.load
(i32.const 556))
(i32.const -4096))
(i32.const 0)))
(call $e.safe_write32_slow_jit
(get_local $l2)
(get_local $l0))
@ -85,12 +89,12 @@
(i32.load
(i32.const 556))
(i32.const 2)))
(call $e.instr_F4)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 2)))
(call $e.instr_F4)
(return))
(unreachable))))

View file

@ -31,6 +31,12 @@
(i32.load
(i32.const 556))
(i32.const 2)))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(if $I4
(i32.and
(i32.load
@ -41,12 +47,6 @@
(return)))
(call $e.instr_DE_0_reg
(i32.const 1))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(return))
(i32.store
(i32.const 560)
@ -58,12 +58,12 @@
(i32.load
(i32.const 556))
(i32.const 1)))
(call $e.instr_F4)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(call $e.instr_F4)
(return))
(unreachable))))

View file

@ -31,6 +31,12 @@
(i32.load
(i32.const 556))
(i32.const 4)))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(i32.store
(i32.const 648)
(i32.or
@ -51,12 +57,6 @@
(i32.store
(i32.const 648)
(i32.const 0))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(return))
(i32.store
(i32.const 560)
@ -68,12 +68,12 @@
(i32.load
(i32.const 556))
(i32.const 1)))
(call $e.instr_F4)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(call $e.instr_F4)
(return))
(unreachable))))

View file

@ -34,15 +34,15 @@
(i32.load
(i32.const 556))
(i32.const 3)))
(call $e.instr32_83_7_reg
(i32.const 0)
(i32.const 10))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(call $e.instr32_83_7_reg
(i32.const 0)
(i32.const 10))
(return))
(i32.store
(i32.const 560)
@ -75,6 +75,7 @@
(set_local $p0
(i32.const 2))))
(br $L0))
(call $e.instr32_43)
(i32.store
(i32.const 560)
(i32.add
@ -87,19 +88,18 @@
(i32.load
(i32.const 556))
(i32.const 3)))
(call $e.instr32_43)
(i32.store
(i32.const 556)
(i32.add
(i32.load
(i32.const 556))
(i32.const -8)))
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 2)))
(i32.store
(i32.const 556)
(i32.add
(i32.load
(i32.const 556))
(i32.const -8)))
(set_local $p0
(i32.const 0))
(br $L0))
@ -113,12 +113,12 @@
(i32.load
(i32.const 556))
(i32.const 1)))
(call $e.instr_F4)
(i32.store
(i32.const 664)
(i32.add
(i32.load
(i32.const 664))
(i32.const 1)))
(call $e.instr_F4)
(return))
(unreachable))))