| diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c |
| index 5ceb955..103df43 100644 |
| --- a/core/iwasm/interpreter/wasm_interp_fast.c |
| +++ b/core/iwasm/interpreter/wasm_interp_fast.c |
| @@ -593,6 +593,58 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) |
| frame_ip += 4; \ |
| } while (0) |
| |
| +#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 |
| + |
| +/* rive: one 8-byte load fetches all three little-endian operand offsets; |
| + the trailing 2 bytes overlap the next label slot, which is always |
| + present and readable */ |
| +#define GET_TRI_OPERAND_OFFSETS(off_dst, off_lhs, off_rhs) \ |
| + do { \ |
| + uint64 ops = *(uint64 *)frame_ip; \ |
| + off_rhs = (int16)ops; \ |
| + off_lhs = (int16)(ops >> 16); \ |
| + off_dst = (int16)(ops >> 32); \ |
| + } while (0) |
| + |
| +#define GET_OPERAND_AT_I32(type, off) *(type *)(frame_lp + (off)) |
| +#define GET_OPERAND_AT_F32(type, off) *(type *)(frame_lp + (off)) |
| +#define GET_OPERAND_AT_I64(type, off) (type) GET_I64_FROM_ADDR(frame_lp + (off)) |
| +#define GET_OPERAND_AT_F64(type, off) (type) GET_F64_FROM_ADDR(frame_lp + (off)) |
| +#define GET_OPERAND_AT(type, op_type, off) GET_OPERAND_AT_##op_type(type, off) |
| + |
| +#define SET_OPERAND_AT_I32(off, value) \ |
| + do { \ |
| + *(uint32 *)(frame_lp + (off)) = value; \ |
| + } while (0) |
| +#define SET_OPERAND_AT_F32(off, value) \ |
| + do { \ |
| + *(float32 *)(frame_lp + (off)) = value; \ |
| + } while (0) |
| +#define SET_OPERAND_AT_I64(off, value) \ |
| + do { \ |
| + uint32 *addr_tmp = frame_lp + (off); \ |
| + PUT_I64_TO_ADDR(addr_tmp, value); \ |
| + } while (0) |
| +#define SET_OPERAND_AT_F64(off, value) \ |
| + do { \ |
| + uint32 *addr_tmp = frame_lp + (off); \ |
| + PUT_F64_TO_ADDR(addr_tmp, value); \ |
| + } while (0) |
| +#define SET_OPERAND_AT(op_type, off, value) SET_OPERAND_AT_##op_type(off, value) |
| + |
| +#define DEF_OP_CMP(src_type, src_op_type, cond) \ |
| + do { \ |
| + int16 off_dst, off_lhs, off_rhs; \ |
| + GET_TRI_OPERAND_OFFSETS(off_dst, off_lhs, off_rhs); \ |
| + SET_OPERAND_AT( \ |
| + I32, off_dst, \ |
| + GET_OPERAND_AT(src_type, src_op_type, off_lhs) \ |
| + cond GET_OPERAND_AT(src_type, src_op_type, off_rhs)); \ |
| + frame_ip += 6; \ |
| + } while (0) |
| + |
| +#else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ |
| + |
| #define DEF_OP_CMP(src_type, src_op_type, cond) \ |
| do { \ |
| SET_OPERAND(I32, 4, \ |
| @@ -601,6 +653,8 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) |
| frame_ip += 6; \ |
| } while (0) |
| |
| +#endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ |
| + |
| #define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) \ |
| do { \ |
| SET_OPERAND( \ |
| @@ -609,6 +663,18 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) |
| frame_ip += 4; \ |
| } while (0) |
| |
| +#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 |
| +#define DEF_OP_NUMERIC(src_type1, src_type2, src_op_type, operation) \ |
| + do { \ |
| + int16 off_dst, off_lhs, off_rhs; \ |
| + GET_TRI_OPERAND_OFFSETS(off_dst, off_lhs, off_rhs); \ |
| + SET_OPERAND_AT( \ |
| + src_op_type, off_dst, \ |
| + GET_OPERAND_AT(src_type1, src_op_type, off_lhs) \ |
| + operation GET_OPERAND_AT(src_type2, src_op_type, off_rhs)); \ |
| + frame_ip += 6; \ |
| + } while (0) |
| +#else |
| #define DEF_OP_NUMERIC(src_type1, src_type2, src_op_type, operation) \ |
| do { \ |
| SET_OPERAND(src_op_type, 4, \ |
| @@ -616,6 +682,7 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) |
| operation GET_OPERAND(src_type2, src_op_type, 0)); \ |
| frame_ip += 6; \ |
| } while (0) |
| +#endif |
| |
| #define DEF_OP_REINTERPRET(src_type, src_op_type) \ |
| do { \ |
| @@ -625,6 +692,29 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) |
| |
| #define DEF_OP_NUMERIC_64 DEF_OP_NUMERIC |
| |
| +#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 |
| +#define DEF_OP_NUMERIC2(src_type1, src_type2, src_op_type, operation) \ |
| + do { \ |
| + int16 off_dst, off_lhs, off_rhs; \ |
| + GET_TRI_OPERAND_OFFSETS(off_dst, off_lhs, off_rhs); \ |
| + SET_OPERAND_AT( \ |
| + src_op_type, off_dst, \ |
| + GET_OPERAND_AT(src_type1, src_op_type, off_lhs) operation( \ |
| + GET_OPERAND_AT(src_type2, src_op_type, off_rhs) % 32)); \ |
| + frame_ip += 6; \ |
| + } while (0) |
| + |
| +#define DEF_OP_NUMERIC2_64(src_type1, src_type2, src_op_type, operation) \ |
| + do { \ |
| + int16 off_dst, off_lhs, off_rhs; \ |
| + GET_TRI_OPERAND_OFFSETS(off_dst, off_lhs, off_rhs); \ |
| + SET_OPERAND_AT( \ |
| + src_op_type, off_dst, \ |
| + GET_OPERAND_AT(src_type1, src_op_type, off_lhs) operation( \ |
| + GET_OPERAND_AT(src_type2, src_op_type, off_rhs) % 64)); \ |
| + frame_ip += 6; \ |
| + } while (0) |
| +#else |
| #define DEF_OP_NUMERIC2(src_type1, src_type2, src_op_type, operation) \ |
| do { \ |
| SET_OPERAND(src_op_type, 4, \ |
| @@ -640,6 +730,7 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame) |
| GET_OPERAND(src_type2, src_op_type, 0) % 64)); \ |
| frame_ip += 6; \ |
| } while (0) |
| +#endif |
| |
| #define DEF_ATOMIC_RMW_OPCODE(OP_NAME, op) \ |
| case WASM_OP_ATOMIC_RMW_I32_##OP_NAME: \ |