From: Brendan Hansen Date: Fri, 16 Dec 2022 05:00:08 +0000 (-0600) Subject: refactored to remove many unnecessary switch statements X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=bb587e87c6a3f6318709da43a36adb76afbdd72a;p=onyx.git refactored to remove many unnecessary switch statements --- diff --git a/interpreter/include/vm.h b/interpreter/include/vm.h index 5b0b195c..cb12a09a 100644 --- a/interpreter/include/vm.h +++ b/interpreter/include/vm.h @@ -241,9 +241,9 @@ struct ovm_instr_t { }; }; -#define OVM_INSTR_TYPE(instr) ((instr).full_instr >> 24) -#define OVM_INSTR_INSTR(instr) ((instr).full_instr & 0xffffff) -#define OVM_INSTR_MASK 0xff +#define OVM_INSTR_TYPE(instr) ((instr).full_instr & 0x7) +#define OVM_INSTR_INSTR(instr) (((instr).full_instr >> 3) & 0xff) +#define OVM_INSTR_MASK 0x7ff #define OVMI_ATOMIC 0x00800000 // Flag an instruction as atomic @@ -273,77 +273,77 @@ struct ovm_instr_t { #define OVMI_REG_SET 0x17 // #r = %a #define OVMI_IDX_ARR 0x18 // %r = (a)[%b] -#define OVMI_LT 0x20 // %r = %a < %b -#define OVMI_LT_S 0x21 // %r = %a < %b -#define OVMI_LE 0x22 // %r = %a <= %b -#define OVMI_LE_S 0x23 // %r = %a <= %b -#define OVMI_EQ 0x24 // %r = %a == %b -#define OVMI_GE 0x25 // %r = %a >= %b -#define OVMI_GE_S 0x26 // %r = %a >= %b -#define OVMI_GT 0x27 // %r = %a > %b -#define OVMI_GT_S 0x28 // %r = %a > %b -#define OVMI_NE 0x29 // %r = %a != %b - -#define OVMI_PARAM 0x30 // push %a -#define OVMI_RETURN 0x31 // return %a -#define OVMI_CALL 0x32 // %r = a(...) -#define OVMI_CALLI 0x33 // %r = %a(...) - -#define OVMI_BR 0x40 // br pc + a // Relative branching -#define OVMI_BR_Z 0x41 // br pc + a if %b == 0 -#define OVMI_BR_NZ 0x42 // br pc + a if %b != 0 -#define OVMI_BRI 0x43 // br pc + %a // Relative branching -#define OVMI_BRI_Z 0x44 // br pc + %a if %b == 0 -#define OVMI_BRI_NZ 0x45 // br pc + %a if %b != 0 - -#define OVMI_CLZ 0x50 // %r = clz(%a) -#define OVMI_CTZ 0x51 // %r = ctr(%a) -#define OVMI_POPCNT 0x52 // %r = popcnt(%a) -#define OVMI_ROTL 0x53 // %r = rotl(%a, %b) -#define OVMI_ROTR 0x54 // %r = rotr(%a, %b) +#define OVMI_LT 0x19 // %r = %a < %b +#define OVMI_LT_S 0x1a // %r = %a < %b +#define OVMI_LE 0x1b // %r = %a <= %b +#define OVMI_LE_S 0x1c // %r = %a <= %b +#define OVMI_EQ 0x1d // %r = %a == %b +#define OVMI_GE 0x1e // %r = %a >= %b +#define OVMI_GE_S 0x1f // %r = %a >= %b +#define OVMI_GT 0x20 // %r = %a > %b +#define OVMI_GT_S 0x21 // %r = %a > %b +#define OVMI_NE 0x22 // %r = %a != %b + +#define OVMI_PARAM 0x23 // push %a +#define OVMI_RETURN 0x24 // return %a +#define OVMI_CALL 0x25 // %r = a(...) +#define OVMI_CALLI 0x26 // %r = %a(...) + +#define OVMI_BR 0x27 // br pc + a // Relative branching +#define OVMI_BR_Z 0x28 // br pc + a if %b == 0 +#define OVMI_BR_NZ 0x29 // br pc + a if %b != 0 +#define OVMI_BRI 0x2a // br pc + %a // Relative branching +#define OVMI_BRI_Z 0x2b // br pc + %a if %b == 0 +#define OVMI_BRI_NZ 0x2c // br pc + %a if %b != 0 + +#define OVMI_CLZ 0x2d // %r = clz(%a) +#define OVMI_CTZ 0x2e // %r = ctr(%a) +#define OVMI_POPCNT 0x2f // %r = popcnt(%a) +#define OVMI_ROTL 0x30 // %r = rotl(%a, %b) +#define OVMI_ROTR 0x31 // %r = rotr(%a, %b) // These instructions are only implemented for floats. -#define OVMI_ABS 0x55 // %r = |%a| -#define OVMI_NEG 0x56 // %r = -%a -#define OVMI_CEIL 0x57 // %r = ceil(%a) -#define OVMI_FLOOR 0x58 // %r = floor(%a) -#define OVMI_TRUNC 0x59 // %r = trunc(%a) -#define OVMI_NEAREST 0x5A // %r = nearest(%a) -#define OVMI_SQRT 0x5B // %r = sqrt(%a) -#define OVMI_MIN 0x5C // %r = min(%a, %b) -#define OVMI_MAX 0x5D // %r = max(%a, %b) -#define OVMI_COPYSIGN 0x5E // %r = copysign(%a, %b) +#define OVMI_ABS 0x32 // %r = |%a| +#define OVMI_NEG 0x33 // %r = -%a +#define OVMI_CEIL 0x34 // %r = ceil(%a) +#define OVMI_FLOOR 0x35 // %r = floor(%a) +#define OVMI_TRUNC 0x36 // %r = trunc(%a) +#define OVMI_NEAREST 0x37 // %r = nearest(%a) +#define OVMI_SQRT 0x38 // %r = sqrt(%a) +#define OVMI_MIN 0x39 // %r = min(%a, %b) +#define OVMI_MAX 0x3a // %r = max(%a, %b) +#define OVMI_COPYSIGN 0x3b // %r = copysign(%a, %b) // For conversion operations, the "type" of the instruction is // destination type, the type in the name is the source type. // // There are a couple of cast operations that are not available, // such as unsigned conversion from 32-bit integers to floats. -#define OVMI_CVT_I8 0x60 // %r = (t) %a -#define OVMI_CVT_I8_S 0x61 // %r = (t) %a (sign aware) -#define OVMI_CVT_I16 0x62 // %r = (t) %a -#define OVMI_CVT_I16_S 0x63 // %r = (t) %a (sign aware) -#define OVMI_CVT_I32 0x64 // %r = (t) %a -#define OVMI_CVT_I32_S 0x65 // %r = (t) %a (sign aware) -#define OVMI_CVT_I64 0x66 // %r = (t) %a -#define OVMI_CVT_I64_S 0x67 // %r = (t) %a (sign aware) -#define OVMI_CVT_F32 0x68 // %r = (t) %a -#define OVMI_CVT_F32_S 0x69 // %r = (t) %a (sign aware) -#define OVMI_CVT_F64 0x6A // %r = (t) %a -#define OVMI_CVT_F64_S 0x6B // %r = (t) %a (sign aware) -#define OVMI_TRANSMUTE_I32 0x6C // %r = *(t *) &%a (reinterpret bytes) -#define OVMI_TRANSMUTE_I64 0x6D // %r = *(t *) &%a (reinterpret bytes) -#define OVMI_TRANSMUTE_F32 0x6E // %r = *(t *) &%a (reinterpret bytes) -#define OVMI_TRANSMUTE_F64 0x6F // %r = *(t *) &%a (reinterpret bytes) - -#define OVMI_CMPXCHG 0x70 // %r = %r == %a ? %b : %r - -#define OVMI_BREAK 0xff +#define OVMI_CVT_I8 0x3c // %r = (t) %a +#define OVMI_CVT_I8_S 0x3d // %r = (t) %a (sign aware) +#define OVMI_CVT_I16 0x3e // %r = (t) %a +#define OVMI_CVT_I16_S 0x3f // %r = (t) %a (sign aware) +#define OVMI_CVT_I32 0x40 // %r = (t) %a +#define OVMI_CVT_I32_S 0x41 // %r = (t) %a (sign aware) +#define OVMI_CVT_I64 0x42 // %r = (t) %a +#define OVMI_CVT_I64_S 0x43 // %r = (t) %a (sign aware) +#define OVMI_CVT_F32 0x44 // %r = (t) %a +#define OVMI_CVT_F32_S 0x45 // %r = (t) %a (sign aware) +#define OVMI_CVT_F64 0x46 // %r = (t) %a +#define OVMI_CVT_F64_S 0x47 // %r = (t) %a (sign aware) +#define OVMI_TRANSMUTE_I32 0x48 // %r = *(t *) &%a (reinterpret bytes) +#define OVMI_TRANSMUTE_I64 0x49 // %r = *(t *) &%a (reinterpret bytes) +#define OVMI_TRANSMUTE_F32 0x4a // %r = *(t *) &%a (reinterpret bytes) +#define OVMI_TRANSMUTE_F64 0x4b // %r = *(t *) &%a (reinterpret bytes) + +#define OVMI_CMPXCHG 0x4c // %r = %r == %a ? %b : %r + +#define OVMI_BREAK 0x4d // // OVM_TYPED_INSTR(OVMI_ADD, OVM_TYPE_I32) == instruction for adding i32s // -#define OVM_TYPED_INSTR(instr, type) (((type) << 24) | (instr)) +#define OVM_TYPED_INSTR(instr, type) (((instr) << 3) | (type)) #endif diff --git a/interpreter/src/vm/code_builder.c b/interpreter/src/vm/code_builder.c index d7f696f2..bb4429a2 100644 --- a/interpreter/src/vm/code_builder.c +++ b/interpreter/src/vm/code_builder.c @@ -144,7 +144,7 @@ void ovm_code_builder_add_nop(ovm_code_builder_t *builder) { void ovm_code_builder_add_break(ovm_code_builder_t *builder) { ovm_instr_t break_ = {0}; - break_.full_instr = OVMI_BREAK; + break_.full_instr = OVM_TYPED_INSTR(OVMI_BREAK, OVM_TYPE_NONE); debug_info_builder_emit_location(builder->debug_builder); ovm_program_add_instructions(builder->program, 1, &break_); } @@ -200,7 +200,7 @@ void ovm_code_builder_add_unop(ovm_code_builder_t *builder, u32 instr) { void ovm_code_builder_add_branch(ovm_code_builder_t *builder, i32 label_idx) { ovm_instr_t branch_instr = {0}; - branch_instr.full_instr = OVMI_BR; + branch_instr.full_instr = OVM_TYPED_INSTR(OVMI_BR, OVM_TYPE_NONE); branch_instr.a = -1; branch_patch_t patch; @@ -218,9 +218,9 @@ void ovm_code_builder_add_branch(ovm_code_builder_t *builder, i32 label_idx) { void ovm_code_builder_add_cond_branch(ovm_code_builder_t *builder, i32 label_idx, bool branch_if_true, bool targets_else) { ovm_instr_t branch_instr = {0}; if (branch_if_true) { - branch_instr.full_instr = OVMI_BR_NZ; + branch_instr.full_instr = OVM_TYPED_INSTR(OVMI_BR_NZ, OVM_TYPE_NONE); } else { - branch_instr.full_instr = OVMI_BR_Z; + branch_instr.full_instr = OVM_TYPED_INSTR(OVMI_BR_Z, OVM_TYPE_NONE); } branch_instr.a = -1; @@ -259,16 +259,16 @@ void ovm_code_builder_add_branch_table(ovm_code_builder_t *builder, i32 count, i instrs[1].a = index_register; instrs[1].b = tmp_register; - instrs[2].full_instr = OVMI_BR_Z; + instrs[2].full_instr = OVM_TYPED_INSTR(OVMI_BR_Z, OVM_TYPE_NONE); instrs[2].a = -1; instrs[2].b = tmp_register; - instrs[3].full_instr = OVMI_IDX_ARR; + instrs[3].full_instr = OVM_TYPED_INSTR(OVMI_IDX_ARR, OVM_TYPE_NONE); instrs[3].r = tmp_register; instrs[3].a = table_idx; instrs[3].b = index_register; - instrs[4].full_instr = OVMI_BRI; + instrs[4].full_instr = OVM_TYPED_INSTR(OVMI_BRI, OVM_TYPE_NONE); instrs[4].a = tmp_register; POP_VALUE(builder); @@ -301,7 +301,7 @@ void ovm_code_builder_add_branch_table(ovm_code_builder_t *builder, i32 count, i void ovm_code_builder_add_return(ovm_code_builder_t *builder) { ovm_instr_t instr = {0}; - instr.full_instr = OVMI_RETURN; + instr.full_instr = OVM_TYPED_INSTR(OVMI_RETURN, OVM_TYPE_NONE); i32 values_on_stack = bh_arr_length(builder->execution_stack); assert(values_on_stack == 0 || values_on_stack == 1); @@ -323,7 +323,7 @@ static void ovm_code_builder_add_params(ovm_code_builder_t *builder, i32 param_c fori (i, 0, param_count) { ovm_instr_t param_instr = {0}; - param_instr.full_instr = OVMI_PARAM; + param_instr.full_instr = OVM_TYPED_INSTR(OVMI_PARAM, OVM_TYPE_NONE); param_instr.a = flipped_params[param_count - 1 - i]; debug_info_builder_emit_location(builder->debug_builder); @@ -335,7 +335,7 @@ void ovm_code_builder_add_call(ovm_code_builder_t *builder, i32 func_idx, i32 pa ovm_code_builder_add_params(builder, param_count); ovm_instr_t call_instr = {0}; - call_instr.full_instr = OVMI_CALL; + call_instr.full_instr = OVM_TYPED_INSTR(OVMI_CALL, OVM_TYPE_NONE); call_instr.a = func_idx; call_instr.r = -1; @@ -355,12 +355,12 @@ void ovm_code_builder_add_indirect_call(ovm_code_builder_t *builder, i32 param_c ovm_instr_t call_instrs[2] = {0}; // idxarr %k, table, %j - call_instrs[0].full_instr = OVMI_IDX_ARR; + call_instrs[0].full_instr = OVM_TYPED_INSTR(OVMI_IDX_ARR, OVM_TYPE_NONE); call_instrs[0].r = NEXT_VALUE(builder); call_instrs[0].a = builder->func_table_arr_idx; call_instrs[0].b = POP_VALUE(builder); - call_instrs[1].full_instr = OVMI_CALLI; + call_instrs[1].full_instr = OVM_TYPED_INSTR(OVMI_CALLI, OVM_TYPE_NONE); call_instrs[1].a = call_instrs[0].r; call_instrs[1].r = -1; @@ -385,7 +385,7 @@ void ovm_code_builder_drop_value(ovm_code_builder_t *builder) { void ovm_code_builder_add_local_get(ovm_code_builder_t *builder, i32 local_idx) { ovm_instr_t instr = {0}; - instr.full_instr = OVMI_MOV; + instr.full_instr = OVM_TYPED_INSTR(OVMI_MOV, OVM_TYPE_NONE); instr.r = NEXT_VALUE(builder); instr.a = local_idx; // This makes the assumption that the params will be in // the lower "address space" of the value numbers. This @@ -401,7 +401,7 @@ void ovm_code_builder_add_local_get(ovm_code_builder_t *builder, i32 local_idx) void ovm_code_builder_add_local_set(ovm_code_builder_t *builder, i32 local_idx) { ovm_instr_t instr = {0}; - instr.full_instr = OVMI_MOV; + instr.full_instr = OVM_TYPED_INSTR(OVMI_MOV, OVM_TYPE_NONE); instr.r = local_idx; // This makes the assumption that the params will be in // the lower "address space" of the value numbers. This // will be true for web assembly, because that's how it @@ -415,7 +415,7 @@ void ovm_code_builder_add_local_set(ovm_code_builder_t *builder, i32 local_idx) void ovm_code_builder_add_local_tee(ovm_code_builder_t *builder, i32 local_idx) { ovm_instr_t instr = {0}; - instr.full_instr = OVMI_MOV; + instr.full_instr = OVM_TYPED_INSTR(OVMI_MOV, OVM_TYPE_NONE); instr.r = local_idx; // This makes the assumption that the params will be in // the lower "address space" of the value numbers. This // will be true for web assembly, because that's how it @@ -431,7 +431,7 @@ void ovm_code_builder_add_local_tee(ovm_code_builder_t *builder, i32 local_idx) void ovm_code_builder_add_register_get(ovm_code_builder_t *builder, i32 reg_idx) { ovm_instr_t instr = {0}; - instr.full_instr = OVMI_REG_GET; + instr.full_instr = OVM_TYPED_INSTR(OVMI_REG_GET, OVM_TYPE_NONE); instr.r = NEXT_VALUE(builder); instr.a = reg_idx; @@ -443,7 +443,7 @@ void ovm_code_builder_add_register_get(ovm_code_builder_t *builder, i32 reg_idx) void ovm_code_builder_add_register_set(ovm_code_builder_t *builder, i32 reg_idx) { ovm_instr_t instr = {0}; - instr.full_instr = OVMI_REG_SET; + instr.full_instr = OVM_TYPED_INSTR(OVMI_REG_SET, OVM_TYPE_NONE); instr.r = reg_idx; instr.a = POP_VALUE(builder); @@ -479,7 +479,7 @@ void ovm_code_builder_add_store(ovm_code_builder_t *builder, u32 ovm_type, i32 o void ovm_code_builder_add_cmpxchg(ovm_code_builder_t *builder, u32 ovm_type, i32 offset) { if (offset == 0) { ovm_instr_t cmpxchg_instr = {0}; - cmpxchg_instr.full_instr = OVM_TYPED_INSTR(OVMI_ATOMIC | OVMI_CMPXCHG, ovm_type); + cmpxchg_instr.full_instr = OVMI_ATOMIC | OVM_TYPED_INSTR(OVMI_CMPXCHG, ovm_type); cmpxchg_instr.b = POP_VALUE(builder); cmpxchg_instr.a = POP_VALUE(builder); cmpxchg_instr.r = POP_VALUE(builder); @@ -510,7 +510,7 @@ void ovm_code_builder_add_cmpxchg(ovm_code_builder_t *builder, u32 ovm_type, i32 instrs[1].b = instrs[0].r; // cmpxchg.x %m, %n - instrs[2].full_instr = OVM_TYPED_INSTR(OVMI_ATOMIC | OVMI_CMPXCHG, ovm_type); + instrs[2].full_instr = OVMI_ATOMIC | OVM_TYPED_INSTR(OVMI_CMPXCHG, ovm_type); instrs[2].r = instrs[1].r; instrs[2].a = expected_reg; instrs[2].b = value_reg; @@ -525,7 +525,7 @@ void ovm_code_builder_add_cmpxchg(ovm_code_builder_t *builder, u32 ovm_type, i32 void ovm_code_builder_add_memory_copy(ovm_code_builder_t *builder) { ovm_instr_t instr = {0}; - instr.full_instr = OVMI_COPY; + instr.full_instr = OVM_TYPED_INSTR(OVMI_COPY, OVM_TYPE_NONE); instr.b = POP_VALUE(builder); instr.a = POP_VALUE(builder); instr.r = POP_VALUE(builder); @@ -536,7 +536,7 @@ void ovm_code_builder_add_memory_copy(ovm_code_builder_t *builder) { void ovm_code_builder_add_memory_fill(ovm_code_builder_t *builder) { ovm_instr_t instr = {0}; - instr.full_instr = OVMI_FILL; + instr.full_instr = OVM_TYPED_INSTR(OVMI_FILL, OVM_TYPE_NONE); instr.b = POP_VALUE(builder); instr.a = POP_VALUE(builder); instr.r = POP_VALUE(builder); @@ -549,7 +549,7 @@ void ovm_code_builder_add_memory_fill(ovm_code_builder_t *builder) { // CopyNPaste from _add_load void ovm_code_builder_add_atomic_load(ovm_code_builder_t *builder, u32 ovm_type, i32 offset) { ovm_instr_t load_instr = {0}; - load_instr.full_instr = OVM_TYPED_INSTR(OVMI_ATOMIC | OVMI_LOAD, ovm_type); + load_instr.full_instr = OVMI_ATOMIC | OVM_TYPED_INSTR(OVMI_LOAD, ovm_type); load_instr.b = offset; load_instr.a = POP_VALUE(builder); load_instr.r = NEXT_VALUE(builder); @@ -564,7 +564,7 @@ void ovm_code_builder_add_atomic_load(ovm_code_builder_t *builder, u32 ovm_type, // CopyNPaste from _add_store void ovm_code_builder_add_atomic_store(ovm_code_builder_t *builder, u32 ovm_type, i32 offset) { ovm_instr_t store_instr = {0}; - store_instr.full_instr = OVM_TYPED_INSTR(OVMI_ATOMIC | OVMI_STORE, ovm_type); + store_instr.full_instr = OVMI_ATOMIC | OVM_TYPED_INSTR(OVMI_STORE, ovm_type); store_instr.b = offset; store_instr.a = POP_VALUE(builder); store_instr.r = POP_VALUE(builder); diff --git a/interpreter/src/vm/vm.c b/interpreter/src/vm/vm.c index e9f123c1..1c4c4d72 100644 --- a/interpreter/src/vm/vm.c +++ b/interpreter/src/vm/vm.c @@ -135,6 +135,11 @@ void ovm_program_add_instructions(ovm_program_t *program, i32 instr_count, ovm_i } +static char *ovm_instr_name(i32 full_instr) { + return ""; +} + +#if 0 static char *ovm_instr_name(i32 full_instr) { #define C(...) \ case __VA_ARGS__: return #__VA_ARGS__; \ @@ -411,6 +416,7 @@ static char *ovm_instr_name(i32 full_instr) { return buf; } } +#endif void ovm_program_print_instructions(ovm_program_t *program, i32 start_instr, i32 instr_count) { fori (i, start_instr, start_instr + instr_count) { @@ -739,7 +745,7 @@ static inline void __ovm_debug_hook(ovm_engine_t *engine, ovm_state_t *state) { #define NEXT_OP \ if (instr->full_instr & OVMI_ATOMIC) pthread_mutex_unlock(&state->engine->atomic_mutex); \ - __ovm_debug_hook(state->engine, state); \ + if (state->debug) __ovm_debug_hook(state->engine, state); \ instr = &code[state->pc++]; \ if (instr->full_instr & OVMI_ATOMIC) pthread_mutex_lock(&state->engine->atomic_mutex); \ return ovmi_dispatch[instr->full_instr & OVM_INSTR_MASK](instr, state, memory, code); @@ -766,68 +772,34 @@ OVMI_INSTR_EXEC(ovmi_exec_nop) { // #define OVM_OP_EXEC(name, op) \ - OVMI_INSTR_EXEC(ovmi_exec_##name) { \ - switch (OVM_INSTR_TYPE(*instr)) { \ - OVM_OP(OVM_TYPE_I8 , op, i8) \ - OVM_OP(OVM_TYPE_I16, op, i16) \ - OVM_OP(OVM_TYPE_I32, op, i32) \ - OVM_OP(OVM_TYPE_I64, op, i64) \ - OVM_OP(OVM_TYPE_F32, op, f32) \ - OVM_OP(OVM_TYPE_F64, op, f64) \ - } \ - NEXT_OP; \ - } + OVMI_INSTR_EXEC(ovmi_exec_##name##_i32) { OVM_OP(OVM_TYPE_I32, op, i32); NEXT_OP; } \ + OVMI_INSTR_EXEC(ovmi_exec_##name##_i64) { OVM_OP(OVM_TYPE_I64, op, i64); NEXT_OP; } \ + OVMI_INSTR_EXEC(ovmi_exec_##name##_f32) { OVM_OP(OVM_TYPE_F32, op, f32); NEXT_OP; } \ + OVMI_INSTR_EXEC(ovmi_exec_##name##_f64) { OVM_OP(OVM_TYPE_F64, op, f64); NEXT_OP; } #define OVM_OP_UNSIGNED_EXEC(name, op) \ - OVMI_INSTR_EXEC(ovmi_exec_##name) { \ - switch (OVM_INSTR_TYPE(*instr)) { \ - OVM_OP(OVM_TYPE_I8 , op, u8) \ - OVM_OP(OVM_TYPE_I16, op, u16) \ - OVM_OP(OVM_TYPE_I32, op, u32) \ - OVM_OP(OVM_TYPE_I64, op, u64) \ - OVM_OP(OVM_TYPE_F32, op, f32) \ - OVM_OP(OVM_TYPE_F64, op, f64) \ - } \ - NEXT_OP; \ - } + OVMI_INSTR_EXEC(ovmi_exec_##name##_i32) { OVM_OP(OVM_TYPE_I32, op, u32); NEXT_OP; } \ + OVMI_INSTR_EXEC(ovmi_exec_##name##_i64) { OVM_OP(OVM_TYPE_I64, op, u64); NEXT_OP; } \ + OVMI_INSTR_EXEC(ovmi_exec_##name##_f32) { OVM_OP(OVM_TYPE_F32, op, f32); NEXT_OP; } \ + OVMI_INSTR_EXEC(ovmi_exec_##name##_f64) { OVM_OP(OVM_TYPE_F64, op, f64); NEXT_OP; } #define OVM_OP_INTEGER_EXEC(name, op) \ - OVMI_INSTR_EXEC(ovmi_exec_##name) { \ - switch (OVM_INSTR_TYPE(*instr)) { \ - OVM_OP(OVM_TYPE_I8 , op, i8) \ - OVM_OP(OVM_TYPE_I16, op, i16) \ - OVM_OP(OVM_TYPE_I32, op, i32) \ - OVM_OP(OVM_TYPE_I64, op, i64) \ - } \ - NEXT_OP; \ - } + OVMI_INSTR_EXEC(ovmi_exec_##name##_i32) { OVM_OP(OVM_TYPE_I32, op, i32); NEXT_OP; } \ + OVMI_INSTR_EXEC(ovmi_exec_##name##_i64) { OVM_OP(OVM_TYPE_I64, op, i64); NEXT_OP; } #define OVM_OP_INTEGER_UNSIGNED_EXEC(name, op) \ - OVMI_INSTR_EXEC(ovmi_exec_##name) { \ - switch (OVM_INSTR_TYPE(*instr)) { \ - OVM_OP(OVM_TYPE_I8 , op, u8) \ - OVM_OP(OVM_TYPE_I16, op, u16) \ - OVM_OP(OVM_TYPE_I32, op, u32) \ - OVM_OP(OVM_TYPE_I64, op, u64) \ - } \ - NEXT_OP; \ - } + OVMI_INSTR_EXEC(ovmi_exec_##name##_i32) { OVM_OP(OVM_TYPE_I32, op, u32); NEXT_OP; } \ + OVMI_INSTR_EXEC(ovmi_exec_##name##_i64) { OVM_OP(OVM_TYPE_I64, op, u64); NEXT_OP; } #define OVM_OP_FLOAT_EXEC(name, op) \ - OVMI_INSTR_EXEC(ovmi_exec_##name) { \ - switch (OVM_INSTR_TYPE(*instr)) { \ - OVM_OP(OVM_TYPE_F32, op, f32) \ - OVM_OP(OVM_TYPE_F64, op, f64) \ - } \ - NEXT_OP; \ - } + OVMI_INSTR_EXEC(ovmi_exec_##name##_f32) { OVM_OP(OVM_TYPE_F32, op, f32); NEXT_OP; } \ + OVMI_INSTR_EXEC(ovmi_exec_##name##_f64) { OVM_OP(OVM_TYPE_F64, op, f64); NEXT_OP; } + #define OVM_OP(t, op, ctype) \ - case t: \ - ovm_assert(VAL(instr->a).type == t && VAL(instr->b).type == t); \ - VAL(instr->r).ctype = VAL(instr->a).ctype op VAL(instr->b).ctype; \ - VAL(instr->r).type = t; \ - break; + ovm_assert(VAL(instr->a).type == t && VAL(instr->b).type == t); \ + VAL(instr->r).ctype = VAL(instr->a).ctype op VAL(instr->b).ctype; \ + VAL(instr->r).type = t; OVM_OP_EXEC(add, +) OVM_OP_EXEC(sub, -) @@ -846,31 +818,14 @@ OVM_OP_INTEGER_EXEC(sar, >>) #undef OVM_OP #define OVM_OP(t, func, ctype) \ - case t: \ - ovm_assert(VAL(instr->a).type == t && VAL(instr->b).type == t); \ - VAL(instr->r).ctype = func( VAL(instr->a).ctype, VAL(instr->b).ctype ); \ - VAL(instr->r).type = t; \ - break; - -OVMI_INSTR_EXEC(ovmi_exec_rotl) { - switch (OVM_INSTR_TYPE(*instr)) { - OVM_OP(OVM_TYPE_I8 , __rolb, u8) - OVM_OP(OVM_TYPE_I16, __rolw, u16) - OVM_OP(OVM_TYPE_I32, __rold, u32) - OVM_OP(OVM_TYPE_I64, __rolq, u64) - } - NEXT_OP; -} + ovm_assert(VAL(instr->a).type == t && VAL(instr->b).type == t); \ + VAL(instr->r).ctype = func( VAL(instr->a).ctype, VAL(instr->b).ctype ); \ + VAL(instr->r).type = t; -OVMI_INSTR_EXEC(ovmi_exec_rotr) { - switch (OVM_INSTR_TYPE(*instr)) { - OVM_OP(OVM_TYPE_I8 , __rorb, u8) - OVM_OP(OVM_TYPE_I16, __rorw, u16) - OVM_OP(OVM_TYPE_I32, __rord, u32) - OVM_OP(OVM_TYPE_I64, __rorq, u64) - } - NEXT_OP; -} +OVMI_INSTR_EXEC(ovmi_exec_rotl_i32) { OVM_OP(OVM_TYPE_I32, __rold, u32); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_rotl_i64) { OVM_OP(OVM_TYPE_I64, __rolq, u64); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_rotr_i32) { OVM_OP(OVM_TYPE_I32, __rord, u32); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_rotr_i64) { OVM_OP(OVM_TYPE_I64, __rorq, u64); NEXT_OP; } OVM_OP_FLOAT_EXEC(min, bh_min) OVM_OP_FLOAT_EXEC(max, bh_max) @@ -880,41 +835,16 @@ OVM_OP_FLOAT_EXEC(copysign, __ovm_copysign) #define OVM_OP(t, op, ctype) \ - case t: \ - ovm_assert(VAL(instr->a).type == t); \ - VAL(instr->r).type = t; \ - VAL(instr->r).ctype = (ctype) op (VAL(instr->a).ctype); \ - break; - -OVMI_INSTR_EXEC(ovmi_exec_clz) { - switch (OVM_INSTR_TYPE(*instr)) { - OVM_OP(OVM_TYPE_I8 , __builtin_clz, u8) - OVM_OP(OVM_TYPE_I16, __builtin_clz, u16) - OVM_OP(OVM_TYPE_I32, __builtin_clz, u32) - OVM_OP(OVM_TYPE_I64, __builtin_clzll, u64) - } - NEXT_OP; -} + ovm_assert(VAL(instr->a).type == t); \ + VAL(instr->r).type = t; \ + VAL(instr->r).ctype = (ctype) op (VAL(instr->a).ctype); -OVMI_INSTR_EXEC(ovmi_exec_ctz) { - switch (OVM_INSTR_TYPE(*instr)) { - OVM_OP(OVM_TYPE_I8 , __builtin_ctz, u8) - OVM_OP(OVM_TYPE_I16, __builtin_ctz, u16) - OVM_OP(OVM_TYPE_I32, __builtin_ctz, u32) - OVM_OP(OVM_TYPE_I64, __builtin_ctzll, u64) - } - NEXT_OP; -} - -OVMI_INSTR_EXEC(ovmi_exec_popcount) { - switch (OVM_INSTR_TYPE(*instr)) { - OVM_OP(OVM_TYPE_I8 , __builtin_popcount, u8) - OVM_OP(OVM_TYPE_I16, __builtin_popcount, u16) - OVM_OP(OVM_TYPE_I32, __builtin_popcount, u32) - OVM_OP(OVM_TYPE_I64, __builtin_popcountll, u64) - } - NEXT_OP; -} +OVMI_INSTR_EXEC(ovmi_exec_clz_i32) { OVM_OP(OVM_TYPE_I32, __builtin_clz, u32); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_clz_i64) { OVM_OP(OVM_TYPE_I64, __builtin_clzll, u64); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_ctz_i32) { OVM_OP(OVM_TYPE_I32, __builtin_ctz, u32); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_ctz_i64) { OVM_OP(OVM_TYPE_I64, __builtin_ctzll, u64); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_popcount_i32) { OVM_OP(OVM_TYPE_I32, __builtin_popcount, u32); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_popcount_i64) { OVM_OP(OVM_TYPE_I64, __builtin_popcountll, u64); NEXT_OP; } OVM_OP_FLOAT_EXEC(abs, __ovm_abs) OVM_OP_FLOAT_EXEC(neg, -) @@ -928,11 +858,9 @@ OVM_OP_FLOAT_EXEC(sqrt, sqrt) #define OVM_OP(t, op, ctype) \ - case t: \ - ovm_assert(VAL(instr->a).type == t && VAL(instr->b).type == t); \ - VAL(instr->r).type = OVM_TYPE_I32; \ - VAL(instr->r).i32 = ((VAL(instr->a).ctype op VAL(instr->b).ctype)) ? 1 : 0; \ - break; + ovm_assert(VAL(instr->a).type == t && VAL(instr->b).type == t); \ + VAL(instr->r).type = OVM_TYPE_I32; \ + VAL(instr->r).i32 = ((VAL(instr->a).ctype op VAL(instr->b).ctype)) ? 1 : 0; OVM_OP_EXEC(eq, ==) OVM_OP_EXEC(ne, !=) @@ -954,24 +882,15 @@ OVM_OP_EXEC(ge_s, >=) // #define OVM_IMM(t, dtype, stype) \ - case t: \ - VAL(instr->r).type = t; \ - VAL(instr->r).u64 = 0; \ - VAL(instr->r).dtype = instr->stype; \ - break; - - -OVMI_INSTR_EXEC(ovmi_exec_imm) { - switch (OVM_INSTR_TYPE(*instr)) { - OVM_IMM(OVM_TYPE_I8, u8, i); - OVM_IMM(OVM_TYPE_I16, u16, i); - OVM_IMM(OVM_TYPE_I32, u32, i); - OVM_IMM(OVM_TYPE_I64, u64, l); - OVM_IMM(OVM_TYPE_F32, f32, f); - OVM_IMM(OVM_TYPE_F64, f64, d); - } - NEXT_OP; -} + VAL(instr->r).type = t; \ + VAL(instr->r).u64 = 0; \ + VAL(instr->r).dtype = instr->stype; + + +OVMI_INSTR_EXEC(ovmi_exec_imm_i32) { OVM_IMM(OVM_TYPE_I32, u32, i); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_imm_i64) { OVM_IMM(OVM_TYPE_I64, u64, l); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_imm_f32) { OVM_IMM(OVM_TYPE_F32, f32, f); NEXT_OP; } +OVMI_INSTR_EXEC(ovmi_exec_imm_f64) { OVM_IMM(OVM_TYPE_F64, f64, d); NEXT_OP; } #undef OVM_IMM @@ -980,52 +899,41 @@ OVMI_INSTR_EXEC(ovmi_exec_mov) { NEXT_OP; } -#define OVM_LOAD(type_, stype) \ - case type_: {\ +#define OVM_LOAD(otype, type_, stype) \ + OVMI_INSTR_EXEC(ovmi_exec_load_##otype) { \ + ovm_assert(VAL(instr->a).type == OVM_TYPE_I32); \ + u32 dest = VAL(instr->a).u32 + (u32) instr->b; \ + if (dest == 0) __ovm_trigger_exception(state); \ VAL(instr->r).stype = * (stype *) &memory[dest]; \ VAL(instr->r).type = type_; \ - break; \ + NEXT_OP; \ } -OVMI_INSTR_EXEC(ovmi_exec_load) { - ovm_assert(VAL(instr->a).type == OVM_TYPE_I32); - u32 dest = VAL(instr->a).u32 + (u32) instr->b; - if (dest == 0) __ovm_trigger_exception(state); - - switch (OVM_INSTR_TYPE(*instr)) { - OVM_LOAD(OVM_TYPE_I8, u8) - OVM_LOAD(OVM_TYPE_I16, u16) - OVM_LOAD(OVM_TYPE_I32, u32) - OVM_LOAD(OVM_TYPE_I64, u64) - OVM_LOAD(OVM_TYPE_F32, f32) - OVM_LOAD(OVM_TYPE_F64, f64) - } - NEXT_OP; -} +OVM_LOAD(i8, OVM_TYPE_I8, u8) +OVM_LOAD(i16, OVM_TYPE_I16, u16) +OVM_LOAD(i32, OVM_TYPE_I32, u32) +OVM_LOAD(i64, OVM_TYPE_I64, u64) +OVM_LOAD(f32, OVM_TYPE_F32, f32) +OVM_LOAD(f64, OVM_TYPE_F64, f64) #undef OVM_LOAD -#define OVM_STORE(type_, stype) \ - case type_: \ +#define OVM_STORE(otype, type_, stype) \ + OVMI_INSTR_EXEC(ovmi_exec_store_##otype) { \ + ovm_assert(VAL(instr->r).type == OVM_TYPE_I32); \ + u32 dest = VAL(instr->r).u32 + (u32) instr->b; \ + if (dest == 0) __ovm_trigger_exception(state); \ *(stype *) &memory[dest] = VAL(instr->a).stype; \ - break; - + NEXT_OP; \ + } -OVMI_INSTR_EXEC(ovmi_exec_store) { - ovm_assert(VAL(instr->r).type == OVM_TYPE_I32); - u32 dest = VAL(instr->r).u32 + (u32) instr->b; - if (dest == 0) __ovm_trigger_exception(state); - switch (OVM_INSTR_TYPE(*instr)) { - OVM_STORE(OVM_TYPE_I8, u8) - OVM_STORE(OVM_TYPE_I16, u16) - OVM_STORE(OVM_TYPE_I32, u32) - OVM_STORE(OVM_TYPE_I64, u64) - OVM_STORE(OVM_TYPE_F32, f32) - OVM_STORE(OVM_TYPE_F64, f64) - } - NEXT_OP; -} +OVM_STORE(i8, OVM_TYPE_I8, u8) +OVM_STORE(i16, OVM_TYPE_I16, u16) +OVM_STORE(i32, OVM_TYPE_I32, u32) +OVM_STORE(i64, OVM_TYPE_I64, u64) +OVM_STORE(f32, OVM_TYPE_F32, f32) +OVM_STORE(f64, OVM_TYPE_F64, f64) #undef OVM_STORE @@ -1242,10 +1150,10 @@ OVMI_INSTR_EXEC(ovmi_exec_cvt) { VAL(instr->r) = tmp_val; \ break - case OVM_TYPED_INSTR(OVMI_TRANSMUTE_I32, OVM_TYPE_F32): CVT(u32, f32, OVM_TYPE_F32, f32); - case OVM_TYPED_INSTR(OVMI_TRANSMUTE_I64, OVM_TYPE_F64): CVT(u64, f64, OVM_TYPE_F64, f64); - case OVM_TYPED_INSTR(OVMI_TRANSMUTE_F32, OVM_TYPE_I32): CVT(f32, u32, OVM_TYPE_I32, u32); - case OVM_TYPED_INSTR(OVMI_TRANSMUTE_F64, OVM_TYPE_I64): CVT(f64, u64, OVM_TYPE_I64, u64); + case OVM_TYPED_INSTR(OVMI_TRANSMUTE_I32, OVM_TYPE_F32): CVT(u32, f32, OVM_TYPE_F32, f32); + case OVM_TYPED_INSTR(OVMI_TRANSMUTE_I64, OVM_TYPE_F64): CVT(u64, f64, OVM_TYPE_F64, f64); + case OVM_TYPED_INSTR(OVMI_TRANSMUTE_F32, OVM_TYPE_I32): CVT(f32, u32, OVM_TYPE_I32, u32); + case OVM_TYPED_INSTR(OVMI_TRANSMUTE_F64, OVM_TYPE_I64): CVT(f64, u64, OVM_TYPE_I64, u64); #undef CVT } @@ -1259,7 +1167,7 @@ OVMI_INSTR_EXEC(ovmi_exec_cvt) { // #define CMPXCHG(otype, ctype) \ - case otype: {\ + OVMI_INSTR_EXEC(ovmi_exec_cmpxchg_##ctype) { \ if (VAL(instr->r).u32 == 0) __ovm_trigger_exception(state); \ ctype *addr = (ctype *) &memory[VAL(instr->r).u32]; \ \ @@ -1270,19 +1178,11 @@ OVMI_INSTR_EXEC(ovmi_exec_cvt) { if (*addr == VAL(instr->a).ctype) { \ *addr = VAL(instr->b).ctype ; \ } \ - break; \ - } - -OVMI_INSTR_EXEC(ovmi_exec_cmpxchg) { - switch (OVM_INSTR_TYPE(*instr)) { - CMPXCHG(OVM_TYPE_I8, i8) - CMPXCHG(OVM_TYPE_I16, i16) - CMPXCHG(OVM_TYPE_I32, i32) - CMPXCHG(OVM_TYPE_I64, i64) + NEXT_OP; \ } - NEXT_OP; -} +CMPXCHG(OVM_TYPE_I32, i32) +CMPXCHG(OVM_TYPE_I64, i64) #undef CMPXCHG @@ -1296,198 +1196,92 @@ OVMI_INSTR_EXEC(ovmi_exec_illegal) { // Dispatch table // -static ovmi_instr_exec_t ovmi_dispatch[256] = { - // 0x00 - ovmi_exec_nop, - ovmi_exec_add, - ovmi_exec_sub, - ovmi_exec_mul, - ovmi_exec_div, - ovmi_exec_div_s, - ovmi_exec_rem, - ovmi_exec_rem_s, - ovmi_exec_and, - ovmi_exec_or, - ovmi_exec_xor, - ovmi_exec_shl, - ovmi_exec_shr, - ovmi_exec_sar, - ovmi_exec_illegal, - ovmi_exec_illegal, - - // 0x10 - ovmi_exec_imm, - ovmi_exec_mov, - ovmi_exec_load, - ovmi_exec_store, - ovmi_exec_copy, - ovmi_exec_fill, - ovmi_exec_reg_get, - ovmi_exec_reg_set, - ovmi_exec_idx_arr, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - - // 0x20 - ovmi_exec_lt, - ovmi_exec_lt_s, - ovmi_exec_le, - ovmi_exec_le_s, - ovmi_exec_eq, - ovmi_exec_ge, - ovmi_exec_ge_s, - ovmi_exec_gt, - ovmi_exec_gt_s, - ovmi_exec_ne, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - - // 0x30 - ovmi_exec_param, - ovmi_exec_return, - ovmi_exec_call, - ovmi_exec_calli, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - - // 0x40 - ovmi_exec_br, - ovmi_exec_br_z, - ovmi_exec_br_nz, - ovmi_exec_bri, - ovmi_exec_bri_z, - ovmi_exec_bri_nz, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - - // 0x50 - ovmi_exec_clz, - ovmi_exec_ctz, - ovmi_exec_popcount, - ovmi_exec_rotl, - ovmi_exec_rotr, - ovmi_exec_abs, - ovmi_exec_neg, - ovmi_exec_ceil, - ovmi_exec_floor, - ovmi_exec_trunc, - ovmi_exec_nearest, - ovmi_exec_sqrt, - ovmi_exec_min, - ovmi_exec_max, - ovmi_exec_copysign, - ovmi_exec_illegal, - - // 0x60 - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - ovmi_exec_cvt, - - // 0x70 - ovmi_exec_cmpxchg, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - ovmi_exec_illegal, - - // 0x80 - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - - // 0x90 - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - - // 0xA0 - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - - // 0xB0 - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - - // 0xC0 - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - - // 0xD0 - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - - // 0xE0 - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - - // 0xF0 - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, - ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, ovmi_exec_illegal, +#define IROW_UNTYPED(name) ovmi_exec_##name, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#define IROW_TYPED(name) NULL, ovmi_exec_##name##_i8, ovmi_exec_##name##_i16, ovmi_exec_##name##_i32, ovmi_exec_##name##_i64, ovmi_exec_##name##_f32, ovmi_exec_##name##_f64, NULL, +#define IROW_PARTIAL(name) NULL, NULL, NULL, ovmi_exec_##name##_i32, ovmi_exec_##name##_i64, ovmi_exec_##name##_f32, ovmi_exec_##name##_f64, NULL, +#define IROW_INT(name) NULL, NULL, NULL, ovmi_exec_##name##_i32, ovmi_exec_##name##_i64, NULL, NULL, NULL, +#define IROW_FLOAT(name) NULL, NULL, NULL, NULL, NULL, ovmi_exec_##name##_f32, ovmi_exec_##name##_f64, NULL, +#define IROW_SAME(name) ovmi_exec_##name,ovmi_exec_##name,ovmi_exec_##name,ovmi_exec_##name,ovmi_exec_##name,ovmi_exec_##name,ovmi_exec_##name,NULL, + +static ovmi_instr_exec_t ovmi_dispatch[] = { + IROW_UNTYPED(nop) // 0x00 + IROW_PARTIAL(add) + IROW_PARTIAL(sub) + IROW_PARTIAL(mul) + IROW_PARTIAL(div) + IROW_PARTIAL(div_s) + IROW_INT(rem) + IROW_INT(rem_s) + IROW_INT(and) + IROW_INT(or) + IROW_INT(xor) + IROW_INT(shl) + IROW_INT(shr) + IROW_INT(sar) + IROW_SAME(illegal) + IROW_SAME(illegal) + IROW_PARTIAL(imm) // 0x10 + IROW_UNTYPED(mov) + IROW_TYPED(load) + IROW_TYPED(store) + IROW_UNTYPED(copy) + IROW_UNTYPED(fill) + IROW_UNTYPED(reg_get) + IROW_UNTYPED(reg_set) + IROW_UNTYPED(idx_arr) + IROW_PARTIAL(lt) + IROW_PARTIAL(lt_s) + IROW_PARTIAL(le) + IROW_PARTIAL(le_s) + IROW_PARTIAL(eq) + IROW_PARTIAL(ge) + IROW_PARTIAL(ge_s) + IROW_PARTIAL(gt) // 0x20 + IROW_PARTIAL(gt_s) + IROW_PARTIAL(ne) + IROW_UNTYPED(param) + IROW_UNTYPED(return) + IROW_UNTYPED(call) + IROW_UNTYPED(calli) + IROW_UNTYPED(br) + IROW_UNTYPED(br_z) + IROW_UNTYPED(br_nz) + IROW_UNTYPED(bri) + IROW_UNTYPED(bri_z) + IROW_UNTYPED(bri_nz) + IROW_INT(clz) + IROW_INT(ctz) + IROW_INT(popcount) + IROW_INT(rotl) // 0x30 + IROW_INT(rotr) + IROW_FLOAT(abs) + IROW_FLOAT(neg) + IROW_FLOAT(ceil) + IROW_FLOAT(floor) + IROW_FLOAT(trunc) + IROW_FLOAT(nearest) + IROW_FLOAT(sqrt) + IROW_FLOAT(min) + IROW_FLOAT(max) + IROW_FLOAT(copysign) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) // 0x40 + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_SAME(cvt) + IROW_INT(cmpxchg) + IROW_SAME(illegal) }; diff --git a/shared/lib/linux_x86_64/lib/libovmwasm.so b/shared/lib/linux_x86_64/lib/libovmwasm.so index d21e744d..eb055686 100755 Binary files a/shared/lib/linux_x86_64/lib/libovmwasm.so and b/shared/lib/linux_x86_64/lib/libovmwasm.so differ