Skip to content

Commit c0104dc

Browse files
authored
Merge pull request #9 from wasm-micro-runtime/dev/test_addr_align
Re-org address unalignment access for fast-interp, fix warnings, update some CMakeListst.txt
2 parents c9a4716 + 629c97f commit c0104dc

File tree

12 files changed

+788
-794
lines changed

12 files changed

+788
-794
lines changed

core/config.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,29 +131,31 @@
131131
#define WASM_ENABLE_LOG 1
132132
#endif
133133

134-
#if defined(BUILD_TARGET_X86_32) || defined(BUILD_TARGET_X86_64)
135-
#define WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS 1
134+
#ifndef WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS
135+
#if defined(BUILD_TARGET_X86_32) || defined(BUILD_TARGET_X86_64) \
136+
|| defined(BUILD_TARGET_AARCH64)
137+
#define WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS 1
136138
#else
137-
#define WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS 0
139+
#define WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS 0
140+
#endif
138141
#endif
139142

140143
/* WASM Interpreter labels-as-values feature */
144+
#ifndef WASM_ENABLE_LABELS_AS_VALUES
141145
#ifdef __GNUC__
142146
#define WASM_ENABLE_LABELS_AS_VALUES 1
143147
#else
144148
#define WASM_ENABLE_LABELS_AS_VALUES 0
145149
#endif
150+
#endif
146151

147152
/* Enable fast interpreter or not */
148153
#ifndef WASM_ENABLE_FAST_INTERP
149154
#define WASM_ENABLE_FAST_INTERP 0
150155
#endif
151156

152157
#if WASM_ENABLE_FAST_INTERP != 0
153-
#define WASM_ENABLE_ABS_LABEL_ADDR 1
154158
#define WASM_DEBUG_PREPROCESSOR 0
155-
#else
156-
#define WASM_ENABLE_ABS_LABEL_ADDR 0
157159
#endif
158160

159161
/* Enable opcode counter or not */

core/iwasm/aot/aot_runtime.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,21 +1001,6 @@ aot_lookup_function(const AOTModuleInstance *module_inst,
10011001
return NULL;
10021002
}
10031003

1004-
#define PUT_I64_TO_ADDR(addr, value) do { \
1005-
union { int64 val; uint32 parts[2]; } u; \
1006-
u.val = (value); \
1007-
(addr)[0] = u.parts[0]; \
1008-
(addr)[1] = u.parts[1]; \
1009-
} while (0)
1010-
1011-
#define PUT_F64_TO_ADDR(addr, value) do { \
1012-
union { float64 val; uint32 parts[2]; } u; \
1013-
u.val = (value); \
1014-
(addr)[0] = u.parts[0]; \
1015-
(addr)[1] = u.parts[1]; \
1016-
} while (0)
1017-
1018-
10191004
#ifdef OS_ENABLE_HW_BOUND_CHECK
10201005

10211006
#define STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT 3

core/iwasm/common/wasm_runtime_common.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2825,20 +2825,6 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
28252825
* Implementation of wasm_runtime_invoke_native()
28262826
*/
28272827

2828-
#define PUT_I64_TO_ADDR(addr, value) do { \
2829-
union { int64 val; uint32 parts[2]; } u; \
2830-
u.val = (value); \
2831-
(addr)[0] = u.parts[0]; \
2832-
(addr)[1] = u.parts[1]; \
2833-
} while (0)
2834-
2835-
#define PUT_F64_TO_ADDR(addr, value) do { \
2836-
union { float64 val; uint32 parts[2]; } u; \
2837-
u.val = (value); \
2838-
(addr)[0] = u.parts[0]; \
2839-
(addr)[1] = u.parts[1]; \
2840-
} while (0)
2841-
28422828
/* The invoke native implementation on ARM platform with VFP co-processor */
28432829
#if defined(BUILD_TARGET_ARM_VFP) \
28442830
|| defined(BUILD_TARGET_THUMB_VFP) \

core/iwasm/common/wasm_runtime_common.h

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,230 @@
2525
extern "C" {
2626
#endif
2727

28+
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
29+
30+
#define PUT_I64_TO_ADDR(addr, value) do { \
31+
*(int64*)(addr) = (int64)(value); \
32+
} while (0)
33+
#define PUT_F64_TO_ADDR(addr, value) do { \
34+
*(float64*)(addr) = (float64)(value); \
35+
} while (0)
36+
37+
#define GET_I64_FROM_ADDR(addr) (*(int64*)(addr))
38+
#define GET_F64_FROM_ADDR(addr) (*(float64*)(addr))
39+
40+
/* For STORE opcodes */
41+
#define STORE_I64 PUT_I64_TO_ADDR
42+
#define STORE_U32(addr, value) do { \
43+
*(uint32*)(addr) = (uint32)(value); \
44+
} while (0)
45+
#define STORE_U16(addr, value) do { \
46+
*(uint16*)(addr) = (uint16)(value); \
47+
} while (0)
48+
49+
/* For LOAD opcodes */
50+
#define LOAD_I64(addr) (*(int64*)(addr))
51+
#define LOAD_F64(addr) (*(float64*)(addr))
52+
#define LOAD_I32(addr) (*(int32*)(addr))
53+
#define LOAD_U32(addr) (*(uint32*)(addr))
54+
#define LOAD_I16(addr) (*(int16*)(addr))
55+
#define LOAD_U16(addr) (*(uint16*)(addr))
56+
57+
#define STORE_PTR(addr, ptr) do { \
58+
*(void**)addr = (void*)ptr; \
59+
} while (0)
60+
#define LOAD_PTR(addr) (*(void**)(addr))
61+
62+
#else /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */
63+
64+
#define PUT_I64_TO_ADDR(addr, value) do { \
65+
uint32 *addr_u32 = (uint32*)(addr); \
66+
union { int64 val; uint32 parts[2]; } u; \
67+
u.val = (int64)(value); \
68+
addr_u32[0] = u.parts[0]; \
69+
addr_u32[1] = u.parts[1]; \
70+
} while (0)
71+
#define PUT_F64_TO_ADDR(addr, value) do { \
72+
uint32 *addr_u32 = (uint32*)(addr); \
73+
union { float64 val; uint32 parts[2]; } u; \
74+
u.val = (value); \
75+
addr_u32[0] = u.parts[0]; \
76+
addr_u32[1] = u.parts[1]; \
77+
} while (0)
78+
79+
static inline int64
80+
GET_I64_FROM_ADDR(uint32 *addr)
81+
{
82+
union { int64 val; uint32 parts[2]; } u;
83+
u.parts[0] = addr[0];
84+
u.parts[1] = addr[1];
85+
return u.val;
86+
}
87+
88+
static inline float64
89+
GET_F64_FROM_ADDR (uint32 *addr)
90+
{
91+
union { float64 val; uint32 parts[2]; } u;
92+
u.parts[0] = addr[0];
93+
u.parts[1] = addr[1];
94+
return u.val;
95+
}
96+
97+
/* For STORE opcodes */
98+
#define STORE_I64(addr, value) do { \
99+
uintptr_t addr1 = (uintptr_t)(addr); \
100+
union { int64 val; uint32 u32[2]; \
101+
uint16 u16[4]; uint8 u8[8]; } u; \
102+
if ((addr1 & (uintptr_t)7) == 0) \
103+
*(int64*)(addr) = (int64)(value); \
104+
else { \
105+
u.val = (int64)(value); \
106+
if ((addr1 & (uintptr_t)3) == 0) { \
107+
((uint32*)(addr))[0] = u.u32[0]; \
108+
((uint32*)(addr))[1] = u.u32[1]; \
109+
} \
110+
else if ((addr1 & (uintptr_t)1) == 0) { \
111+
((uint16*)(addr))[0] = u.u16[0]; \
112+
((uint16*)(addr))[1] = u.u16[1]; \
113+
((uint16*)(addr))[2] = u.u16[2]; \
114+
((uint16*)(addr))[3] = u.u16[3]; \
115+
} \
116+
else { \
117+
int32 t; \
118+
for (t = 0; t < 8; t++) \
119+
((uint8*)(addr))[t] = u.u8[t]; \
120+
} \
121+
} \
122+
} while (0)
123+
124+
#define STORE_U32(addr, value) do { \
125+
uintptr_t addr1 = (uintptr_t)(addr); \
126+
union { uint32 val; \
127+
uint16 u16[2]; uint8 u8[4]; } u; \
128+
if ((addr1 & (uintptr_t)3) == 0) \
129+
*(uint32*)(addr) = (uint32)(value); \
130+
else { \
131+
u.val = (uint32)(value); \
132+
if ((addr1 & (uintptr_t)1) == 0) { \
133+
((uint16*)(addr))[0] = u.u16[0]; \
134+
((uint16*)(addr))[1] = u.u16[1]; \
135+
} \
136+
else { \
137+
((uint8*)(addr))[0] = u.u8[0]; \
138+
((uint8*)(addr))[1] = u.u8[1]; \
139+
((uint8*)(addr))[2] = u.u8[2]; \
140+
((uint8*)(addr))[3] = u.u8[3]; \
141+
} \
142+
} \
143+
} while (0)
144+
145+
#define STORE_U16(addr, value) do { \
146+
union { uint16 val; uint8 u8[2]; } u; \
147+
u.val = (uint16)(value); \
148+
((uint8*)(addr))[0] = u.u8[0]; \
149+
((uint8*)(addr))[1] = u.u8[1]; \
150+
} while (0)
151+
152+
/* For LOAD opcodes */
153+
static inline int64
154+
LOAD_I64(void *addr)
155+
{
156+
uintptr_t addr1 = (uintptr_t)addr;
157+
union { int64 val; uint32 u32[2];
158+
uint16 u16[4]; uint8 u8[8]; } u;
159+
if ((addr1 & (uintptr_t)7) == 0)
160+
return *(int64*)addr;
161+
162+
if ((addr1 & (uintptr_t)3) == 0) {
163+
u.u32[0] = ((uint32*)addr)[0];
164+
u.u32[1] = ((uint32*)addr)[1];
165+
}
166+
else if ((addr1 & (uintptr_t)1) == 0) {
167+
u.u16[0] = ((uint16*)addr)[0];
168+
u.u16[1] = ((uint16*)addr)[1];
169+
u.u16[2] = ((uint16*)addr)[2];
170+
u.u16[3] = ((uint16*)addr)[3];
171+
}
172+
else {
173+
int32 t;
174+
for (t = 0; t < 8; t++)
175+
u.u8[t] = ((uint8*)addr)[t];
176+
}
177+
return u.val;
178+
}
179+
180+
static inline float64
181+
LOAD_F64(void *addr)
182+
{
183+
uintptr_t addr1 = (uintptr_t)addr;
184+
union { float64 val; uint32 u32[2];
185+
uint16 u16[4]; uint8 u8[8]; } u;
186+
if ((addr1 & (uintptr_t)7) == 0)
187+
return *(float64*)addr;
188+
189+
if ((addr1 & (uintptr_t)3) == 0) {
190+
u.u32[0] = ((uint32*)addr)[0];
191+
u.u32[1] = ((uint32*)addr)[1];
192+
}
193+
else if ((addr1 & (uintptr_t)1) == 0) {
194+
u.u16[0] = ((uint16*)addr)[0];
195+
u.u16[1] = ((uint16*)addr)[1];
196+
u.u16[2] = ((uint16*)addr)[2];
197+
u.u16[3] = ((uint16*)addr)[3];
198+
}
199+
else {
200+
int32 t;
201+
for (t = 0; t < 8; t++)
202+
u.u8[t] = ((uint8*)addr)[t];
203+
}
204+
return u.val;
205+
}
206+
207+
static inline int32
208+
LOAD_I32(void *addr)
209+
{
210+
uintptr_t addr1 = (uintptr_t)addr;
211+
union { int32 val; uint16 u16[2]; uint8 u8[4]; } u;
212+
if ((addr1 & (uintptr_t)3) == 0)
213+
return *(int32*)addr;
214+
215+
if ((addr1 & (uintptr_t)1) == 0) {
216+
u.u16[0] = ((uint16*)addr)[0];
217+
u.u16[1] = ((uint16*)addr)[1];
218+
}
219+
else {
220+
u.u8[0] = ((uint8*)addr)[0];
221+
u.u8[1] = ((uint8*)addr)[1];
222+
u.u8[2] = ((uint8*)addr)[2];
223+
u.u8[3] = ((uint8*)addr)[3];
224+
}
225+
return u.val;
226+
}
227+
228+
static inline int16
229+
LOAD_I16(void *addr)
230+
{
231+
uintptr_t addr1 = (uintptr_t)addr;
232+
union { int16 val; uint8 u8[2]; } u;
233+
if ((addr1 & (uintptr_t)1)) {
234+
u.u8[0] = ((uint8*)addr)[0];
235+
u.u8[1] = ((uint8*)addr)[1];
236+
return u.val;
237+
}
238+
return *(int16*)addr;
239+
}
240+
241+
#define LOAD_U32(addr) ((uint32)LOAD_I32(addr))
242+
#define LOAD_U16(addr) ((uint16)LOAD_I16(addr))
243+
244+
#if UINTPTR_MAX == UINT32_MAX
245+
#define STORE_PTR(addr, ptr) STORE_U32(addr, (uintptr_t)ptr)
246+
#elif UINTPTR_MAX == UINT64_MAX
247+
#define STORE_PTR(addr, ptr) STORE_I64(addr, (uintptr_t)ptr)
248+
#endif
249+
250+
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */
251+
28252
typedef struct WASMModuleCommon {
29253
/* Module type, for module loaded from WASM bytecode binary,
30254
this field is Wasm_Module_Bytecode, and this structure should

0 commit comments

Comments
 (0)