From 1741bee182f115d899bd31642b32f70b0c7ed32f Mon Sep 17 00:00:00 2001 From: Wojciech Kosior Date: Tue, 6 Oct 2020 11:11:24 +0200 Subject: add translation of br_if instruction --- tests/wasm_compile_br_if/Makefile | 1 + tests/wasm_compile_br_if/instructions.wat | 27 +++++++++++++++++++++ tests/wasm_compile_br_if/test.v | 1 + tests/wasm_compile_br_if/words_to_verify.mem | 6 +++++ tests/wasm_compile_simple_module/test.v | 6 ++--- tools/translate.c | 36 ++++++++++++++++++++++++++++ tools/translate_xmacro.h | 3 ++- tools/wasm.h | 1 + 8 files changed, 77 insertions(+), 4 deletions(-) create mode 120000 tests/wasm_compile_br_if/Makefile create mode 100644 tests/wasm_compile_br_if/instructions.wat create mode 120000 tests/wasm_compile_br_if/test.v create mode 100644 tests/wasm_compile_br_if/words_to_verify.mem diff --git a/tests/wasm_compile_br_if/Makefile b/tests/wasm_compile_br_if/Makefile new file mode 120000 index 0000000..e451c8b --- /dev/null +++ b/tests/wasm_compile_br_if/Makefile @@ -0,0 +1 @@ +../wasm_compile_simple_module/Makefile \ No newline at end of file diff --git a/tests/wasm_compile_br_if/instructions.wat b/tests/wasm_compile_br_if/instructions.wat new file mode 100644 index 0000000..506a462 --- /dev/null +++ b/tests/wasm_compile_br_if/instructions.wat @@ -0,0 +1,27 @@ +;;; this test is loosely based on wasm_compile_br +(module + (memory 0 1) + ;; this function returns -1 if its argument is 10 or 11 and 0 otherwise + (func $eq10or11 (param $x i32) (result i32) + (if (result i32) + (i32.sub + (get_local $x) + (i32.const 10)) + (then + (br_if 0 (i32.add (i32.const -3) (i32.const 3)) + (i32.sub (get_local $x) (i32.const 11))) + (i32.const 1) + (i32.sub)) + (else + (i32.const -1)))) + (func $main + ;; write 0x00000000 at MEMORY_BOTTOM_ADDR + (i32.store offset=0x0 align=2 (i32.const 0x0) + (call $eq10or11 (i32.const 12))) + ;; write 0xFFFFFFFF at MEMORY_BOTTOM_ADDR + 0x4 + (i32.store offset=0x0 align=2 (i32.const 0x4) + (call $eq10or11 (i32.const 10))) + ;; write 0xFFFFFFFF at MEMORY_BOTTOM_ADDR + 0x8 + (i32.store offset=0x0 align=2 (i32.const 0x8) + (call $eq10or11 (i32.const 11)))) + (export "main" (func $main))) diff --git a/tests/wasm_compile_br_if/test.v b/tests/wasm_compile_br_if/test.v new file mode 120000 index 0000000..f0235d8 --- /dev/null +++ b/tests/wasm_compile_br_if/test.v @@ -0,0 +1 @@ +../wasm_compile_simple_module/test.v \ No newline at end of file diff --git a/tests/wasm_compile_br_if/words_to_verify.mem b/tests/wasm_compile_br_if/words_to_verify.mem new file mode 100644 index 0000000..aac1103 --- /dev/null +++ b/tests/wasm_compile_br_if/words_to_verify.mem @@ -0,0 +1,6 @@ +// address value + 0FFFFC 23 + + 200 00000000 + 204 FFFFFFFF + 208 FFFFFFFF diff --git a/tests/wasm_compile_simple_module/test.v b/tests/wasm_compile_simple_module/test.v index 80f5590..5e28ba1 100644 --- a/tests/wasm_compile_simple_module/test.v +++ b/tests/wasm_compile_simple_module/test.v @@ -159,7 +159,7 @@ module wasm_compile_test(); CLK <= 0; RST <= 1; - for (i = 0; i < 5000; i++) begin + for (i = 0; i < 10000; i++) begin #1; CLK <= ~CLK; @@ -194,9 +194,9 @@ module wasm_compile_test(); $finish; end // if (M_finished) - end // for (i = 0; i < 5000; i++) + end // for (i = 0; i < 10000; i++) - $display("error: cpu hasn't finished its operations in 2500 ticks"); + $display("error: cpu hasn't finished its operations in 5000 ticks"); $finish; end // initial begin endmodule // stack_machine_test diff --git a/tools/translate.c b/tools/translate.c index 64ed407..8b28aad 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -426,6 +426,42 @@ fail: return -1; } +static int _translate_br_if(struct translation *data) +{ + struct target *br_end; + struct instruction **expr = &data->function->translated_body; + struct types *backed_stack = NULL; + int retval = -1; + + br_end = add_target(data->module); + + if (!br_end) + goto fail; + + if (i_cond_jump_n(ptr_after(&br_end->instr), expr)) + goto fail; + + backed_stack = data->types_stack; + get_type(backed_stack); + + if (_translate_br(data)) + goto fail; + + br_end->instr = data->function->translated_body->prev; + retval = 0; + +fail: + if (backed_stack) { + put_type(data->types_stack); + data->types_stack = backed_stack; + } + + if (retval) + PRERR("Couldn't translate br_if instruction\n"); + + return retval; +} + static int _translate_call(struct translation *data) { uint32_t funcidx; diff --git a/tools/translate_xmacro.h b/tools/translate_xmacro.h index f68f317..958d8d9 100644 --- a/tools/translate_xmacro.h +++ b/tools/translate_xmacro.h @@ -16,11 +16,12 @@ TLS(WASM_I32_STORE8, storeb_p, i32_i32, empty) TLS(WASM_I32_STORE16, storew_p, i32_i32, empty) /* - * There are more checks to be performed in case of if, but we do them + * There are more checks to be performed in case of if and br_if, but we do them * another way and only check for the i32 condition value here. */ TC (WASM_IF, if, i32, custom) TC (WASM_BR, br, custom, custom) +TC (WASM_BR_IF, br_if, i32, custom) TC (WASM_CALL, call, custom, custom) TC (WASM_LOCAL_GET, local_get, empty, custom) TC (WASM_I32_CONST, const, empty, i32) diff --git a/tools/wasm.h b/tools/wasm.h index 0c36c11..476f892 100644 --- a/tools/wasm.h +++ b/tools/wasm.h @@ -26,6 +26,7 @@ #define WASM_ELSE 0x05 #define WASM_END 0x0B #define WASM_BR 0x0C +#define WASM_BR_IF 0x0D #define WASM_CALL 0x10 #define WASM_LOCAL_GET 0x20 -- cgit v1.2.3