Re-org address unalignment access for fast-interp (#597)

And clear some compile warnings on wasm loader, add ${UV_A_LIBS} for some CMakeLists.txt.
This commit is contained in:
Wenyong Huang
2021-04-01 03:50:46 -05:00
committed by GitHub
parent 22bcfe204e
commit 7db2221ad9
12 changed files with 790 additions and 796 deletions

View File

@ -2825,20 +2825,6 @@ fail:
* Implementation of wasm_runtime_invoke_native()
*/
#define PUT_I64_TO_ADDR(addr, value) do { \
union { int64 val; uint32 parts[2]; } u; \
u.val = (value); \
(addr)[0] = u.parts[0]; \
(addr)[1] = u.parts[1]; \
} while (0)
#define PUT_F64_TO_ADDR(addr, value) do { \
union { float64 val; uint32 parts[2]; } u; \
u.val = (value); \
(addr)[0] = u.parts[0]; \
(addr)[1] = u.parts[1]; \
} while (0)
/* The invoke native implementation on ARM platform with VFP co-processor */
#if defined(BUILD_TARGET_ARM_VFP) \
|| defined(BUILD_TARGET_THUMB_VFP) \

View File

@ -25,6 +25,230 @@
extern "C" {
#endif
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
#define PUT_I64_TO_ADDR(addr, value) do { \
*(int64*)(addr) = (int64)(value); \
} while (0)
#define PUT_F64_TO_ADDR(addr, value) do { \
*(float64*)(addr) = (float64)(value); \
} while (0)
#define GET_I64_FROM_ADDR(addr) (*(int64*)(addr))
#define GET_F64_FROM_ADDR(addr) (*(float64*)(addr))
/* For STORE opcodes */
#define STORE_I64 PUT_I64_TO_ADDR
#define STORE_U32(addr, value) do { \
*(uint32*)(addr) = (uint32)(value); \
} while (0)
#define STORE_U16(addr, value) do { \
*(uint16*)(addr) = (uint16)(value); \
} while (0)
/* For LOAD opcodes */
#define LOAD_I64(addr) (*(int64*)(addr))
#define LOAD_F64(addr) (*(float64*)(addr))
#define LOAD_I32(addr) (*(int32*)(addr))
#define LOAD_U32(addr) (*(uint32*)(addr))
#define LOAD_I16(addr) (*(int16*)(addr))
#define LOAD_U16(addr) (*(uint16*)(addr))
#define STORE_PTR(addr, ptr) do { \
*(void**)addr = (void*)ptr; \
} while (0)
#define LOAD_PTR(addr) (*(void**)(addr))
#else /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */
#define PUT_I64_TO_ADDR(addr, value) do { \
uint32 *addr_u32 = (uint32*)(addr); \
union { int64 val; uint32 parts[2]; } u; \
u.val = (int64)(value); \
addr_u32[0] = u.parts[0]; \
addr_u32[1] = u.parts[1]; \
} while (0)
#define PUT_F64_TO_ADDR(addr, value) do { \
uint32 *addr_u32 = (uint32*)(addr); \
union { float64 val; uint32 parts[2]; } u; \
u.val = (value); \
addr_u32[0] = u.parts[0]; \
addr_u32[1] = u.parts[1]; \
} while (0)
static inline int64
GET_I64_FROM_ADDR(uint32 *addr)
{
union { int64 val; uint32 parts[2]; } u;
u.parts[0] = addr[0];
u.parts[1] = addr[1];
return u.val;
}
static inline float64
GET_F64_FROM_ADDR (uint32 *addr)
{
union { float64 val; uint32 parts[2]; } u;
u.parts[0] = addr[0];
u.parts[1] = addr[1];
return u.val;
}
/* For STORE opcodes */
#define STORE_I64(addr, value) do { \
uintptr_t addr1 = (uintptr_t)(addr); \
union { int64 val; uint32 u32[2]; \
uint16 u16[4]; uint8 u8[8]; } u; \
if ((addr1 & (uintptr_t)7) == 0) \
*(int64*)(addr) = (int64)(value); \
else { \
u.val = (int64)(value); \
if ((addr1 & (uintptr_t)3) == 0) { \
((uint32*)(addr))[0] = u.u32[0]; \
((uint32*)(addr))[1] = u.u32[1]; \
} \
else if ((addr1 & (uintptr_t)1) == 0) { \
((uint16*)(addr))[0] = u.u16[0]; \
((uint16*)(addr))[1] = u.u16[1]; \
((uint16*)(addr))[2] = u.u16[2]; \
((uint16*)(addr))[3] = u.u16[3]; \
} \
else { \
int32 t; \
for (t = 0; t < 8; t++) \
((uint8*)(addr))[t] = u.u8[t]; \
} \
} \
} while (0)
#define STORE_U32(addr, value) do { \
uintptr_t addr1 = (uintptr_t)(addr); \
union { uint32 val; \
uint16 u16[2]; uint8 u8[4]; } u; \
if ((addr1 & (uintptr_t)3) == 0) \
*(uint32*)(addr) = (uint32)(value); \
else { \
u.val = (uint32)(value); \
if ((addr1 & (uintptr_t)1) == 0) { \
((uint16*)(addr))[0] = u.u16[0]; \
((uint16*)(addr))[1] = u.u16[1]; \
} \
else { \
((uint8*)(addr))[0] = u.u8[0]; \
((uint8*)(addr))[1] = u.u8[1]; \
((uint8*)(addr))[2] = u.u8[2]; \
((uint8*)(addr))[3] = u.u8[3]; \
} \
} \
} while (0)
#define STORE_U16(addr, value) do { \
union { uint16 val; uint8 u8[2]; } u; \
u.val = (uint16)(value); \
((uint8*)(addr))[0] = u.u8[0]; \
((uint8*)(addr))[1] = u.u8[1]; \
} while (0)
/* For LOAD opcodes */
static inline int64
LOAD_I64(void *addr)
{
uintptr_t addr1 = (uintptr_t)addr;
union { int64 val; uint32 u32[2];
uint16 u16[4]; uint8 u8[8]; } u;
if ((addr1 & (uintptr_t)7) == 0)
return *(int64*)addr;
if ((addr1 & (uintptr_t)3) == 0) {
u.u32[0] = ((uint32*)addr)[0];
u.u32[1] = ((uint32*)addr)[1];
}
else if ((addr1 & (uintptr_t)1) == 0) {
u.u16[0] = ((uint16*)addr)[0];
u.u16[1] = ((uint16*)addr)[1];
u.u16[2] = ((uint16*)addr)[2];
u.u16[3] = ((uint16*)addr)[3];
}
else {
int32 t;
for (t = 0; t < 8; t++)
u.u8[t] = ((uint8*)addr)[t];
}
return u.val;
}
static inline float64
LOAD_F64(void *addr)
{
uintptr_t addr1 = (uintptr_t)addr;
union { float64 val; uint32 u32[2];
uint16 u16[4]; uint8 u8[8]; } u;
if ((addr1 & (uintptr_t)7) == 0)
return *(float64*)addr;
if ((addr1 & (uintptr_t)3) == 0) {
u.u32[0] = ((uint32*)addr)[0];
u.u32[1] = ((uint32*)addr)[1];
}
else if ((addr1 & (uintptr_t)1) == 0) {
u.u16[0] = ((uint16*)addr)[0];
u.u16[1] = ((uint16*)addr)[1];
u.u16[2] = ((uint16*)addr)[2];
u.u16[3] = ((uint16*)addr)[3];
}
else {
int32 t;
for (t = 0; t < 8; t++)
u.u8[t] = ((uint8*)addr)[t];
}
return u.val;
}
static inline int32
LOAD_I32(void *addr)
{
uintptr_t addr1 = (uintptr_t)addr;
union { int32 val; uint16 u16[2]; uint8 u8[4]; } u;
if ((addr1 & (uintptr_t)3) == 0)
return *(int32*)addr;
if ((addr1 & (uintptr_t)1) == 0) {
u.u16[0] = ((uint16*)addr)[0];
u.u16[1] = ((uint16*)addr)[1];
}
else {
u.u8[0] = ((uint8*)addr)[0];
u.u8[1] = ((uint8*)addr)[1];
u.u8[2] = ((uint8*)addr)[2];
u.u8[3] = ((uint8*)addr)[3];
}
return u.val;
}
static inline int16
LOAD_I16(void *addr)
{
uintptr_t addr1 = (uintptr_t)addr;
union { int16 val; uint8 u8[2]; } u;
if ((addr1 & (uintptr_t)1)) {
u.u8[0] = ((uint8*)addr)[0];
u.u8[1] = ((uint8*)addr)[1];
return u.val;
}
return *(int16*)addr;
}
#define LOAD_U32(addr) ((uint32)LOAD_I32(addr))
#define LOAD_U16(addr) ((uint16)LOAD_I16(addr))
#if UINTPTR_MAX == UINT32_MAX
#define STORE_PTR(addr, ptr) STORE_U32(addr, (uintptr_t)ptr)
#elif UINTPTR_MAX == UINT64_MAX
#define STORE_PTR(addr, ptr) STORE_I64(addr, (uintptr_t)ptr)
#endif
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */
typedef struct WASMModuleCommon {
/* Module type, for module loaded from WASM bytecode binary,
this field is Wasm_Module_Bytecode, and this structure should