blob: 8ee3d83377294a713c99cdf34000b9dd0142f886 [file] [edit]
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: \