Implement AOT support for RISCV (#649)

Enable RISCV AOT support, the supported ABIs are LP64 and LP64D for riscv64, ILP32 and ILP32D for riscv32.
For wamrc:
    use --target=riscv64/riscv32 to specify the target arch of output AOT file,
    use --target-abi=lp64d/lp64/ilp32d/ilp32 to specify the target ABI,
    if --target-abi isn't specified, by default lp64d is used for riscv64, and ilp32d is used for riscv32.

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
Co-authored-by: wenyongh <wenyong.huang@intel.com>
This commit is contained in:
Huang Qi 2021-07-22 11:16:47 +08:00 committed by GitHub
parent ea06c19a9d
commit e4023c8e02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 667 additions and 459 deletions

View File

@ -51,7 +51,8 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
endif ()
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64" OR WAMR_BUILD_TARGET MATCHES "AARCH64.*" OR WAMR_BUILD_TARGET MATCHES "RISCV64.*")
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64"
OR WAMR_BUILD_TARGET MATCHES "AARCH64.*" OR WAMR_BUILD_TARGET MATCHES "RISCV64.*")
if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
# Add -fPIC flag if build as 64-bit
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
@ -186,8 +187,12 @@ else ()
add_definitions (-DWASM_DISABLE_HW_BOUND_CHECK=0)
endif ()
if (WAMR_BUILD_SIMD EQUAL 1)
add_definitions (-DWASM_ENABLE_SIMD=1)
message (" SIMD enabled")
if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*")
add_definitions (-DWASM_ENABLE_SIMD=1)
message (" SIMD enabled")
else ()
message (" SIMD disabled due to not supported on target RISCV64")
endif ()
endif ()
if (WAMR_BUILD_MEMORY_PROFILING EQUAL 1)
add_definitions (-DWASM_ENABLE_MEMORY_PROFILING=1)

View File

@ -52,11 +52,6 @@ if (WAMR_BUILD_INTERP EQUAL 1 OR WAMR_BUILD_JIT EQUAL 1)
include (${IWASM_DIR}/interpreter/iwasm_interp.cmake)
endif ()
if (WAMR_BUILD_TARGET MATCHES "RISCV.*" AND WAMR_BUILD_AOT EQUAL 1)
set (WAMR_BUILD_AOT 0)
message ("-- WAMR AOT disabled as it isn't supported by riscv currently")
endif ()
if (WAMR_BUILD_AOT EQUAL 1)
include (${IWASM_DIR}/aot/iwasm_aot.cmake)
if (WAMR_BUILD_JIT EQUAL 1)

View File

@ -1395,7 +1395,8 @@ wasm_app_module_on_install_request_byte_arrive(uint8 ch,
if (section->section_type == AOT_SECTION_TYPE_TEXT) {
int map_prot =
MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) || defined(BUILD_TARGET_RISCV64_LP64)
/* aot code and data in x86_64 must be in range 0 to 2G due to
relocation for R_X86_64_32/32S/PC32 */
int map_flags = MMAP_MAP_32BIT;

View File

@ -182,6 +182,7 @@ GET_U64_FROM_ADDR(uint32 *addr)
#define E_MACHINE_MIPS_X 51 /* Stanford MIPS-X */
#define E_MACHINE_X86_64 62 /* AMD x86-64 architecture */
#define E_MACHINE_XTENSA 94 /* Tensilica Xtensa Architecture */
#define E_MACHINE_RISCV 243 /* RISC-V 32/64 */
#define E_MACHINE_WIN_X86_64 0x8664 /* Windowx x86-64 architecture */
/* Legal values for e_version */
@ -257,6 +258,9 @@ get_aot_file_target(AOTTargetInfo *target_info,
case E_MACHINE_XTENSA:
machine_type = "xtensa";
break;
case E_MACHINE_RISCV:
machine_type = "riscv";
break;
default:
set_error_buf_v(error_buf, error_buf_size,
"unknown machine type %d",
@ -1030,7 +1034,8 @@ load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end,
/* Create each data section */
for (i = 0; i < module->data_section_count; i++) {
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) || defined(BUILD_TARGET_RISCV64_LP64)
/* aot code and data in x86_64 must be in range 0 to 2G due to
relocation for R_X86_64_32/32S/PC32 */
int map_flags = MMAP_MAP_32BIT;
@ -1501,6 +1506,7 @@ do_text_relocation(AOTModule *module,
symbol_addr = module->code;
}
else if (!strcmp(symbol, ".data")
|| !strcmp(symbol, ".sdata")
|| !strcmp(symbol, ".rdata")
|| !strcmp(symbol, ".rodata")
/* ".rodata.cst4/8/16/.." */
@ -2235,7 +2241,8 @@ create_sections(const uint8 *buf, uint32 size,
if (section_size > 0) {
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE
| MMAP_PROT_EXEC;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) || defined(BUILD_TARGET_RISCV64_LP64)
/* aot code and data in x86_64 must be in range 0 to 2G due to
relocation for R_X86_64_32/32S/PC32 */
int map_flags = MMAP_MAP_32BIT;

View File

@ -2776,12 +2776,12 @@ aot_table_copy(AOTModuleInstance *module_inst,
/* if src_offset >= dst_offset, copy from front to back */
/* if src_offset < dst_offset, copy from back to front */
/* merge all together */
bh_memcpy_s((uint8 *)(dst_tbl_inst) + offsetof(AOTTableInstance, data)
+ dst_offset * sizeof(uint32),
(dst_tbl_inst->cur_size - dst_offset) * sizeof(uint32),
(uint8 *)(src_tbl_inst) + offsetof(AOTTableInstance, data)
+ src_offset * sizeof(uint32),
length * sizeof(uint32));
bh_memmove_s((uint8 *)(dst_tbl_inst) + offsetof(AOTTableInstance, data)
+ dst_offset * sizeof(uint32),
(dst_tbl_inst->cur_size - dst_offset) * sizeof(uint32),
(uint8 *)(src_tbl_inst) + offsetof(AOTTableInstance, data)
+ src_offset * sizeof(uint32),
length * sizeof(uint32));
}
void

View File

@ -0,0 +1,337 @@
/*
* Copyright (C) 2021 XiaoMi Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "aot_reloc.h"
#define R_RISCV_32 1
#define R_RISCV_64 2
#define R_RISCV_CALL 18
#define R_RISCV_CALL_PLT 19
#define R_RISCV_HI20 26
#define R_RISCV_LO12_I 27
#define R_RISCV_LO12_S 28
#define RV_OPCODE_SW 0x23
void __divdi3();
void __moddi3();
void __muldi3();
void __udivdi3();
void __umoddi3();
static SymbolMap target_sym_map[] = {
REG_COMMON_SYMBOLS
REG_SYM(__divdi3),
REG_SYM(__moddi3),
REG_SYM(__muldi3),
REG_SYM(__udivdi3),
REG_SYM(__umoddi3),
};
static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
{
if (error_buf != NULL)
snprintf(error_buf, error_buf_size, "%s", string);
}
void
get_current_target(char *target_buf, uint32 target_buf_size)
{
snprintf(target_buf, target_buf_size, "riscv");
}
uint32
get_plt_item_size()
{
#if __riscv_xlen == 64
/* auipc + ld + jalr + nop + addr */
return 20;
#else
return 0;
#endif
}
SymbolMap *
get_target_symbol_map(uint32 *sym_num)
{
*sym_num = sizeof(target_sym_map) / sizeof(SymbolMap);
return target_sym_map;
}
/* Get a val from given address */
static uint32
rv_get_val(uint16 *addr)
{
uint32 ret;
ret = *addr | (*(addr + 1)) << 16;
return ret;
}
/* Set a val to given address */
static void
rv_set_val(uint16 *addr, uint32 val)
{
*addr = (val & 0xffff);
*(addr + 1) = (val >> 16);
asm volatile("fence.i");
}
/* Add a val to given address */
static void
rv_add_val(uint16 *addr, uint32 val)
{
uint32 cur = rv_get_val(addr);
rv_set_val(addr, cur + val);
}
/**
* Get imm_hi and imm_lo from given integer
*
* @param imm given integer, signed 32bit
* @param imm_hi signed 20bit
* @param imm_lo signed 12bit
*
*/
static void
rv_calc_imm(int32 imm, int32 *imm_hi, int32 *imm_lo)
{
int32 lo;
int32 hi = imm / 4096;
int32 r = imm % 4096;
if (2047 < r) {
hi++;
}
else if (r < -2048) {
hi--;
}
lo = imm - (hi * 4096);
*imm_lo = lo;
*imm_hi = hi;
}
uint32
get_plt_table_size()
{
return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap));
}
void
init_plt_table(uint8 *plt)
{
#if __riscv_xlen == 64
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
uint8 *p;
for (i = 0; i < num; i++) {
p = plt;
/* auipc t1, 0 */
*(uint16*)p = 0x0317;
p += 2;
*(uint16*)p = 0x0000;
p += 2;
/* ld t1, 8(t1) */
*(uint16*)p = 0x3303;
p += 2;
*(uint16*)p = 0x00C3;
p += 2;
/* jr t1 */
*(uint16*)p = 0x8302;
p += 2;
/* nop */
*(uint16*)p = 0x0001;
p += 2;
bh_memcpy_s(p, 8, &target_sym_map[i].symbol_addr, 8);
p += 8;
plt += get_plt_item_size();
}
#endif
}
typedef struct RelocTypeStrMap {
uint32 reloc_type;
char *reloc_str;
} RelocTypeStrMap;
#define RELOC_TYPE_MAP(reloc_type) { reloc_type, #reloc_type }
static RelocTypeStrMap reloc_type_str_maps[] = {
RELOC_TYPE_MAP(R_RISCV_32),
RELOC_TYPE_MAP(R_RISCV_CALL),
RELOC_TYPE_MAP(R_RISCV_CALL_PLT),
RELOC_TYPE_MAP(R_RISCV_HI20),
RELOC_TYPE_MAP(R_RISCV_LO12_I),
RELOC_TYPE_MAP(R_RISCV_LO12_S),
};
static const char *
reloc_type_to_str(uint32 reloc_type)
{
uint32 i;
for (i = 0; i < sizeof(reloc_type_str_maps) / sizeof(RelocTypeStrMap); i++) {
if (reloc_type_str_maps[i].reloc_type == reloc_type)
return reloc_type_str_maps[i].reloc_str;
}
return "Unknown_Reloc_Type";
}
static bool
check_reloc_offset(uint32 target_section_size,
uint64 reloc_offset, uint32 reloc_data_size,
char *error_buf, uint32 error_buf_size)
{
if (!(reloc_offset < (uint64)target_section_size
&& reloc_offset + reloc_data_size <= (uint64)target_section_size)) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: invalid relocation offset.");
return false;
}
return true;
}
bool
apply_relocation(AOTModule *module,
uint8 *target_section_addr, uint32 target_section_size,
uint64 reloc_offset, uint64 reloc_addend, uint32 reloc_type,
void *symbol_addr, int32 symbol_index,
char *error_buf, uint32 error_buf_size)
{
int32 val, imm_hi, imm_lo, insn;
uint8 *addr = target_section_addr + reloc_offset;
char buf[128];
switch (reloc_type) {
case R_RISCV_32:
{
uint32 val_32 = (uint32)(uintptr_t)((uint8 *)symbol_addr + reloc_addend);
CHECK_RELOC_OFFSET(sizeof(uint32));
if (val_32 != (uintptr_t)((uint8 *)symbol_addr + reloc_addend)) {
goto fail_addr_out_of_range;
}
rv_set_val((uint16 *)addr, val_32);
break;
}
case R_RISCV_64:
{
uint64 val_64 = (uint64)(uintptr_t)((uint8 *)symbol_addr + reloc_addend);
CHECK_RELOC_OFFSET(sizeof(uint64));
bh_memcpy_s(addr, 8, &val_64, 8);
break;
}
case R_RISCV_CALL:
case R_RISCV_CALL_PLT:
{
val = (int32)(intptr_t)((uint8 *)symbol_addr - addr);
CHECK_RELOC_OFFSET(sizeof(uint32));
if (val != (intptr_t)((uint8 *)symbol_addr - addr)) {
if (symbol_index >= 0) {
/* Call runtime function by plt code */
symbol_addr = (uint8*)module->code + module->code_size
- get_plt_table_size()
+ get_plt_item_size() * symbol_index;
val = (int32)(intptr_t)((uint8*)symbol_addr - addr);
}
}
if (val != (intptr_t)((uint8 *)symbol_addr - addr)) {
goto fail_addr_out_of_range;
}
rv_calc_imm(val, &imm_hi, &imm_lo);
rv_add_val((uint16 *)addr, (imm_hi << 12));
if ((rv_get_val((uint16 *)(addr + 4)) & 0x7f) == RV_OPCODE_SW) {
/* Adjust imm for SW : S-type */
val =
(((int32)imm_lo >> 5) << 25) + (((int32)imm_lo & 0x1f) << 7);
rv_add_val((uint16 *)(addr + 4), val);
}
else {
/* Adjust imm for MV(ADDI)/JALR : I-type */
rv_add_val((uint16 *)(addr + 4), ((int32)imm_lo << 20));
}
break;
}
case R_RISCV_HI20:
{
val = (int32)(intptr_t)(symbol_addr + reloc_addend);
CHECK_RELOC_OFFSET(sizeof(uint32));
if (val != (intptr_t)((uint8 *)symbol_addr + reloc_addend)) {
goto fail_addr_out_of_range;
}
addr = target_section_addr + reloc_offset;
insn = rv_get_val((uint16 *)addr);
rv_calc_imm(val, &imm_hi, &imm_lo);
insn = (insn & 0x00000fff) | (imm_hi << 12);
rv_set_val((uint16 *)addr, insn);
break;
}
case R_RISCV_LO12_I:
{
val = (int32)(intptr_t)(symbol_addr + reloc_addend);
CHECK_RELOC_OFFSET(sizeof(uint32));
if (val != (intptr_t)((uint8 *)symbol_addr + reloc_addend)) {
goto fail_addr_out_of_range;
}
addr = target_section_addr + reloc_offset;
insn = rv_get_val((uint16 *)addr);
rv_calc_imm(val, &imm_hi, &imm_lo);
insn = (insn & 0x000fffff) | (imm_lo << 20);
rv_set_val((uint16 *)addr, insn);
break;
}
case R_RISCV_LO12_S:
{
val = (int32)(intptr_t)(symbol_addr + reloc_addend);
CHECK_RELOC_OFFSET(sizeof(uint32));
if (val != (intptr_t)((uint8 *)symbol_addr + reloc_addend)) {
goto fail_addr_out_of_range;
}
addr = target_section_addr + reloc_offset;
rv_calc_imm(val, &imm_hi, &imm_lo);
val =
(((int32)imm_lo >> 5) << 25) + (((int32)imm_lo & 0x1f) << 7);
rv_add_val((uint16 *)addr, val);
break;
}
default:
if (error_buf != NULL)
snprintf(error_buf, error_buf_size,
"Load relocation section failed: "
"invalid relocation type %d.",
reloc_type);
return false;
}
return true;
fail_addr_out_of_range:
snprintf(buf, sizeof(buf),
"AOT module load failed: "
"relocation truncated to fit %s failed.",
reloc_type_to_str(reloc_type));
set_error_buf(error_buf, error_buf_size, buf);
return false;
}

View File

@ -23,6 +23,8 @@ elseif (WAMR_BUILD_TARGET STREQUAL "MIPS")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_mips.c)
elseif (WAMR_BUILD_TARGET STREQUAL "XTENSA")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_xtensa.c)
elseif (WAMR_BUILD_TARGET MATCHES "RISCV*")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_riscv.c)
else ()
message (FATAL_ERROR "Build target isn't set")
endif ()

View File

@ -0,0 +1,148 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
/*
* The float abi macros used bellow are from risc-v c api:
* https://github.com/riscv/riscv-c-api-doc/blob/master/riscv-c-api.md
*
*/
#if defined(__riscv_float_abi_soft)
#define RV_FPREG_SIZE 0
#elif defined(__riscv_float_abi_single)
#define RV_OP_LOADFPREG flw
#define RV_OP_STROEFPREG fsw
#define RV_FPREG_SIZE 4
#elif defined(__riscv_float_abi_double)
#define RV_OP_LOADFPREG fld
#define RV_OP_STROEFPREG fsd
#define RV_FPREG_SIZE 8
#endif
#if __riscv_xlen == 32
#define RV_OP_LOADREG lw
#define RV_OP_STOREREG sw
#define RV_REG_SIZE 4
#define RV_REG_SHIFT 2
#define RV_FP_OFFSET (8 * RV_REG_SIZE)
#define RV_INT_OFFSET 0
#else
#define RV_OP_LOADREG ld
#define RV_OP_STOREREG sd
#define RV_REG_SIZE 8
#define RV_REG_SHIFT 3
#define RV_FP_OFFSET 0
#define RV_INT_OFFSET (8 * RV_FPREG_SIZE)
#endif
.text
.align 2
#ifndef BH_PLATFORM_DARWIN
.globl invokeNative
.type invokeNative, function
invokeNative:
#else
.globl _invokeNative
_invokeNative:
#endif /* end of BH_PLATFORM_DARWIN */
/*
* Arguments passed in:
*
* a0 function ptr
* a1 argv
* a2 nstacks
*/
/*
* sp (stack pointer)
* |- sd/sw to store 64/32-bit values from register to memory
* |- ld/lw to load from stack to register
* fp/s0 (frame pointer)
* a0-a7 (8 integer arguments)
* |- sd/sw to store
* |- ld/lw to load
* fa0-a7 (8 float arguments)
* |- fsd/fsw to store
* |- fld/fsw to load
* t0-t6 (temporaries regisgers)
* |- caller saved
*/
/* reserve space on stack to save return address and frame pointer */
addi sp, sp, - 2 * RV_REG_SIZE
RV_OP_STOREREG fp, 0 * RV_REG_SIZE(sp) /* save frame pointer */
RV_OP_STOREREG ra, 1 * RV_REG_SIZE(sp) /* save return address */
mv fp, sp /* set frame pointer to bottom of fixed frame */
/* save function ptr, argv & nstacks */
mv t0, a0 /* t0 = function ptr */
mv t1, a1 /* t1 = argv array address */
mv t2, a2 /* t2 = nstack */
#ifndef __riscv_float_abi_soft
/* fill in fa0-7 float-registers*/
RV_OP_LOADFPREG fa0, RV_FP_OFFSET + 0 * RV_FPREG_SIZE(t1) /* fa0 */
RV_OP_LOADFPREG fa1, RV_FP_OFFSET + 1 * RV_FPREG_SIZE(t1) /* fa1 */
RV_OP_LOADFPREG fa2, RV_FP_OFFSET + 2 * RV_FPREG_SIZE(t1) /* fa2 */
RV_OP_LOADFPREG fa3, RV_FP_OFFSET + 3 * RV_FPREG_SIZE(t1) /* fa3 */
RV_OP_LOADFPREG fa4, RV_FP_OFFSET + 4 * RV_FPREG_SIZE(t1) /* fa4 */
RV_OP_LOADFPREG fa5, RV_FP_OFFSET + 5 * RV_FPREG_SIZE(t1) /* fa5 */
RV_OP_LOADFPREG fa6, RV_FP_OFFSET + 6 * RV_FPREG_SIZE(t1) /* fa6 */
RV_OP_LOADFPREG fa7, RV_FP_OFFSET + 7 * RV_FPREG_SIZE(t1) /* fa7 */
#endif
/* fill in a0-7 integer-registers*/
RV_OP_LOADREG a0, RV_INT_OFFSET + 0 * RV_REG_SIZE(t1) /* a0 */
RV_OP_LOADREG a1, RV_INT_OFFSET + 1 * RV_REG_SIZE(t1) /* a1 */
RV_OP_LOADREG a2, RV_INT_OFFSET + 2 * RV_REG_SIZE(t1) /* a2 */
RV_OP_LOADREG a3, RV_INT_OFFSET + 3 * RV_REG_SIZE(t1) /* a3 */
RV_OP_LOADREG a4, RV_INT_OFFSET + 4 * RV_REG_SIZE(t1) /* a4 */
RV_OP_LOADREG a5, RV_INT_OFFSET + 5 * RV_REG_SIZE(t1) /* a5 */
RV_OP_LOADREG a6, RV_INT_OFFSET + 6 * RV_REG_SIZE(t1) /* a6 */
RV_OP_LOADREG a7, RV_INT_OFFSET + 7 * RV_REG_SIZE(t1) /* a7 */
/* t1 points to stack args */
/* RV_FPREG_SIZE is zero when __riscv_float_abi_soft defined */
addi t1, t1, RV_REG_SIZE * 8 + RV_FPREG_SIZE * 8
/* directly call the function if no args in stack,
x0 always holds 0 */
beq t2, x0, call_func
/* reserve enough stack space for function arguments */
sll t3, t2, RV_REG_SHIFT /* shift left 3 bits. t3 = n_stacks * 8 */
sub sp, sp, t3
/* make 16-byte aligned */
li t3, 15
not t3, t3
and sp, sp, t3
/* save sp in t4 register */
mv t4, sp
/* copy left arguments from caller stack to own frame stack */
loop_stack_args:
beq t2, x0, call_func
RV_OP_LOADREG t5, 0(t1) /* load stack argument, t5 = argv[i] */
RV_OP_STOREREG t5, 0(t4) /* store t5 to reseved stack, sp[j] = t5 */
addi t1, t1, RV_REG_SIZE /* move to next stack argument */
addi t4, t4, RV_REG_SIZE /* move to next stack pointer */
addi t2, t2, -1 /* decrease t2 every loop, nstacks = nstacks -1 */
j loop_stack_args
call_func:
jalr t0
/* restore registers pushed in stack or saved in another register */
return:
mv sp, fp /* restore sp saved in fp before function call */
RV_OP_LOADREG fp, 0 * RV_REG_SIZE(sp) /* load previous frame poniter to fp register */
RV_OP_LOADREG ra, 1 * RV_REG_SIZE(sp) /* load previous return address to ra register */
addi sp, sp, 2 * RV_REG_SIZE /* pop frame, restore sp */
jr ra

View File

@ -1,95 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
.text
.align 2
#ifndef BH_PLATFORM_DARWIN
.globl invokeNative
.type invokeNative, function
invokeNative:
#else
.globl _invokeNative
_invokeNative:
#endif /* end of BH_PLATFORM_DARWIN */
/*
* Arguments passed in:
*
* a0 function ptr
* a1 argv
* a2 nstacks
*/
/*
* sp (stack pointer)
* |- sw to store 32-bit values from register to memory
* |- lw to load from stack to register
* fp/s0 (frame pointer)
* a0-a7 (8 integer arguments)
* |- sw to store
* |- lw to load
* t0-t6 (temporaries regisgers)
* |- caller saved
*/
/* reserve space on stack to save return address and frame pointer */
addi sp, sp, -8
sw fp, 0(sp) /* save frame pointer */
sw ra, 4(sp) /* save return address */
mv fp, sp /* set frame pointer to bottom of fixed frame */
/* save function ptr, argv & nstacks */
mv t0, a0 /* t0 = function ptr */
mv t1, a1 /* t1 = argv array address */
mv t2, a2 /* t2 = nstack */
/* fill in a0-7 integer-registers */
lw a0, 0(t1) /* a0 = argv[0] */
lw a1, 4(t1) /* a1 = argv[1] */
lw a2, 8(t1) /* a2 = argv[2] */
lw a3, 12(t1) /* a3 = argv[3] */
lw a4, 16(t1) /* a4 = argv[4] */
lw a5, 20(t1) /* a5 = argv[5] */
lw a6, 24(t1) /* a6 = argv[6] */
lw a7, 28(t1) /* a7 = argv[7] */
addi t1, t1, 32 /* t1 points to stack args */
/* directly call the function if no args in stack,
x0 always holds 0 */
beq t2, x0, call_func
/* reserve enough stack space for function arguments */
sll t3, t2, 2 /* shift left 2 bits. t3 = n_stacks * 4 */
sub sp, sp, t3
/* make 16-byte aligned */
and sp, sp, ~15
/* save sp in t4 register */
mv t4, sp
/* copy left arguments from caller stack to own frame stack */
loop_stack_args:
beq t2, x0, call_func
lw t5, 0(t1) /* load stack argument, t5 = argv[i] */
sw t5, 0(t4) /* store t5 to reseved stack, sp[j] = t5 */
addi t1, t1, 4 /* move to next stack argument */
addi t4, t4, 4 /* move to next stack pointer */
addi t2, t2, -1 /* decrease t2 every loop, nstacks = nstacks -1 */
j loop_stack_args
call_func:
jalr t0
/* restore registers pushed in stack or saved in another register */
return:
mv sp, fp /* restore sp saved in fp before function call */
lw fp, 0(sp) /* load previous frame poniter to fp register */
lw ra, 4(sp) /* load previous return address to ra register */
addi sp, sp, 8 /* pop frame, restore sp */
jr ra

View File

@ -1,104 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
.text
.align 2
#ifndef BH_PLATFORM_DARWIN
.globl invokeNative
.type invokeNative, function
invokeNative:
#else
.globl _invokeNative
_invokeNative:
#endif /* end of BH_PLATFORM_DARWIN */
/*
* Arguments passed in:
*
* a0 function ptr
* a1 argv
* a2 nstacks
*/
/*
* sp (stack pointer)
* |- sw to store 32-bit values from register to memory
* |- lw to load from stack to register
* fp/s0 (frame pointer)
* a0-a7 (8 integer arguments)
* |- sw to store
* |- lw to load
* t0-t6 (temporaries regisgers)
* |- caller saved
*/
/* reserve space on stack to save return address and frame pointer */
addi sp, sp, -8
sw fp, 0(sp) /* save frame pointer */
sw ra, 4(sp) /* save return address */
mv fp, sp /* set frame pointer to bottom of fixed frame */
/* save function ptr, argv & nstacks */
mv t0, a0 /* t0 = function ptr */
mv t1, a1 /* t1 = argv array address */
mv t2, a2 /* t2 = nstack */
/* fill in a0-7 integer-registers */
lw a0, 0(t1) /* a0 = argv[0] */
lw a1, 4(t1) /* a1 = argv[1] */
lw a2, 8(t1) /* a2 = argv[2] */
lw a3, 12(t1) /* a3 = argv[3] */
lw a4, 16(t1) /* a4 = argv[4] */
lw a5, 20(t1) /* a5 = argv[5] */
lw a6, 24(t1) /* a6 = argv[6] */
lw a7, 28(t1) /* a7 = argv[7] */
/* fill in fa0-7 float-registers*/
fld fa0, 32(t1) /* fa0 = argv[8] */
fld fa1, 40(t1) /* fa1 = argv[9] */
fld fa2, 48(t1) /* fa2 = argv[10] */
fld fa3, 56(t1) /* fa3 = argv[11] */
fld fa4, 64(t1) /* fa4 = argv[12] */
fld fa5, 72(t1) /* fa5 = argv[13] */
fld fa6, 80(t1) /* fa6 = argv[14] */
fld fa7, 88(t1) /* fa7 = argv[15] */
addi t1, t1, 96 /* t1 points to stack args */
/* directly call the function if no args in stack,
x0 always holds 0 */
beq t2, x0, call_func
/* reserve enough stack space for function arguments */
sll t3, t2, 2 /* shift left 2 bits. t3 = n_stacks * 4 */
sub sp, sp, t3
/* make 16-byte aligned */
and sp, sp, ~15
/* save sp in t4 register */
mv t4, sp
/* copy left arguments from caller stack to own frame stack */
loop_stack_args:
beq t2, x0, call_func
lw t5, 0(t1) /* load stack argument, t5 = argv[i] */
sw t5, 0(t4) /* store t5 to reseved stack, sp[j] = t5 */
addi t1, t1, 4 /* move to next stack argument */
addi t4, t4, 4 /* move to next stack pointer */
addi t2, t2, -1 /* decrease t2 every loop, nstacks = nstacks -1 */
j loop_stack_args
call_func:
jalr t0
/* restore registers pushed in stack or saved in another register */
return:
mv sp, fp /* restore sp saved in fp before function call */
lw fp, 0(sp) /* load previous frame poniter to fp register */
lw ra, 4(sp) /* load previous return address to ra register */
addi sp, sp, 8 /* pop frame, restore sp */
jr ra

View File

@ -1,95 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
.text
.align 2
#ifndef BH_PLATFORM_DARWIN
.globl invokeNative
.type invokeNative, function
invokeNative:
#else
.globl _invokeNative
_invokeNative:
#endif /* end of BH_PLATFORM_DARWIN */
/*
* Arguments passed in:
*
* a0 function ptr
* a1 argv
* a2 nstacks
*/
/*
* sp (stack pointer)
* |- sd to store 64-bit values from register to memory
* |- ld to load from stack to register
* fp/s0 (frame pointer)
* a0-a7 (8 integer arguments)
* |- sd to store
* |- ld to load
* t0-t6 (temporaries regisgers)
* |- caller saved
*/
/* reserve space on stack to save return address and frame pointer */
addi sp, sp, -16
sd fp, 0(sp) /* save frame pointer */
sd ra, 8(sp) /* save return address */
mv fp, sp /* set frame pointer to bottom of fixed frame */
/* save function ptr, argv & nstacks */
mv t0, a0 /* t0 = function ptr */
mv t1, a1 /* t1 = argv array address */
mv t2, a2 /* t2 = nstack */
/* fill in a0-7 integer-registers*/
ld a0, 0(t1) /* a0 = argv[0] */
ld a1, 8(t1) /* a1 = argv[1] */
ld a2, 16(t1) /* a2 = argv[2] */
ld a3, 24(t1) /* a3 = argv[3] */
ld a4, 32(t1) /* a4 = argv[4] */
ld a5, 40(t1) /* a5 = argv[5] */
ld a6, 48(t1) /* a6 = argv[6] */
ld a7, 56(t1) /* a7 = argv[7] */
addi t1, t1, 64 /* t1 points to stack args */
/* directly call the function if no args in stack,
x0 always holds 0 */
beq t2, x0, call_func
/* reserve enough stack space for function arguments */
sll t3, t2, 3 /* shift left 3 bits. t3 = n_stacks * 8 */
sub sp, sp, t3
/* make 16-byte aligned */
and sp, sp, ~(15LL)
/* save sp in t4 register */
mv t4, sp
/* copy left arguments from caller stack to own frame stack */
loop_stack_args:
beq t2, x0, call_func
ld t5, 0(t1) /* load stack argument, t5 = argv[i] */
sd t5, 0(t4) /* store t5 to reseved stack, sp[j] = t5 */
addi t1, t1, 8 /* move to next stack argument */
addi t4, t4, 8 /* move to next stack pointer */
addi t2, t2, -1 /* decrease t2 every loop, nstacks = nstacks -1 */
j loop_stack_args
call_func:
jalr t0
/* restore registers pushed in stack or saved in another register */
return:
mv sp, fp /* restore sp saved in fp before function call */
ld fp, 0(sp) /* load previous frame poniter to fp register */
ld ra, 8(sp) /* load previous return address to ra register */
addi sp, sp, 16 /* pop frame, restore sp */
jr ra

View File

@ -1,108 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
.text
.align 2
#ifndef BH_PLATFORM_DARWIN
.globl invokeNative
.type invokeNative, function
invokeNative:
#else
.globl _invokeNative
_invokeNative:
#endif /* end of BH_PLATFORM_DARWIN */
/*
* Arguments passed in:
*
* a0 function ptr
* a1 argv
* a2 nstacks
*/
/*
* sp (stack pointer)
* |- sd to store 64-bit values from register to memory
* |- ld to load from stack to register
* fp/s0 (frame pointer)
* a0-a7 (8 integer arguments)
* |- sd to store
* |- ld to load
* fa0-a7 (8 float arguments)
* |- fsd to store
* |- fld to load
* t0-t6 (temporaries regisgers)
* |- caller saved
*/
/* reserve space on stack to save return address and frame pointer */
addi sp, sp, -16
sd fp, 0(sp) /* save frame pointer */
sd ra, 8(sp) /* save return address */
mv fp, sp /* set frame pointer to bottom of fixed frame */
/* save function ptr, argv & nstacks */
mv t0, a0 /* t0 = function ptr */
mv t1, a1 /* t1 = argv array address */
mv t2, a2 /* t2 = nstack */
/* fill in fa0-7 float-registers*/
fld fa0, 0(t1) /* fa0 = argv[0] */
fld fa1, 8(t1) /* fa1 = argv[1] */
fld fa2, 16(t1) /* fa2 = argv[2] */
fld fa3, 24(t1) /* fa3 = argv[3] */
fld fa4, 32(t1) /* fa4 = argv[4] */
fld fa5, 40(t1) /* fa5 = argv[5] */
fld fa6, 48(t1) /* fa6 = argv[6] */
fld fa7, 56(t1) /* fa7 = argv[7] */
/* fill in a0-7 integer-registers*/
ld a0, 64(t1) /* a0 = argv[8] */
ld a1, 72(t1) /* a1 = argv[9] */
ld a2, 80(t1) /* a2 = argv[10] */
ld a3, 88(t1) /* a3 = argv[11] */
ld a4, 96(t1) /* a4 = argv[12] */
ld a5, 104(t1) /* a5 = argv[13] */
ld a6, 112(t1) /* a6 = argv[14] */
ld a7, 120(t1) /* a7 = argv[15] */
addi t1, t1, 128 /* t1 points to stack args */
/* directly call the function if no args in stack,
x0 always holds 0 */
beq t2, x0, call_func
/* reserve enough stack space for function arguments */
sll t3, t2, 3 /* shift left 3 bits. t3 = n_stacks * 8 */
sub sp, sp, t3
/* make 16-byte aligned */
and sp, sp, ~(15LL)
/* save sp in t4 register */
mv t4, sp
/* copy left arguments from caller stack to own frame stack */
loop_stack_args:
beq t2, x0, call_func
ld t5, 0(t1) /* load stack argument, t5 = argv[i] */
sd t5, 0(t4) /* store t5 to reseved stack, sp[j] = t5 */
addi t1, t1, 8 /* move to next stack argument */
addi t4, t4, 8 /* move to next stack pointer */
addi t2, t2, -1 /* decrease t2 every loop, nstacks = nstacks -1 */
j loop_stack_args
call_func:
jalr t0
/* restore registers pushed in stack or saved in another register */
return:
mv sp, fp /* restore sp saved in fp before function call */
ld fp, 0(sp) /* load previous frame poniter to fp register */
ld ra, 8(sp) /* load previous return address to ra register */
addi sp, sp, 16 /* pop frame, restore sp */
jr ra

View File

@ -66,14 +66,8 @@ elseif (WAMR_BUILD_TARGET STREQUAL "MIPS")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_mips.s)
elseif (WAMR_BUILD_TARGET STREQUAL "XTENSA")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_xtensa.s)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64" OR WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64D")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_riscv64_lp64d.s)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_riscv64_lp64.s)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32" OR WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32D")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_riscv32_ilp32d.s)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_riscv32_ilp32.s)
elseif (WAMR_BUILD_TARGET MATCHES "RISCV*")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_riscv.S)
else ()
message (FATAL_ERROR "Build target isn't set")
endif ()

View File

@ -3061,7 +3061,8 @@ typedef union __declspec(intrin_type) __declspec(align(8)) v128 {
unsigned __int32 m128i_u32[4];
unsigned __int64 m128i_u64[2];
} v128;
#elif defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
#elif defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) || defined(BUILD_TARGET_RISCV64_LP64)
typedef long long v128 __attribute__ ((__vector_size__ (16),
__may_alias__, __aligned__ (1)));
#elif defined(BUILD_TARGET_AARCH64)

View File

@ -1752,6 +1752,7 @@ is_data_section(LLVMSectionIteratorRef sec_itr, char *section_name)
uint32 relocation_count = 0;
return (!strcmp(section_name, ".data")
|| !strcmp(section_name, ".sdata")
|| !strcmp(section_name, ".rodata")
/* ".rodata.cst4/8/16/.." */
|| !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst"))
@ -1970,10 +1971,13 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
relocation->relocation_type = (uint32)type;
relocation->symbol_name = (char *)LLVMGetSymbolName(rel_sym);
/* for ".LCPIxxx" relocation, transform the symbol name to real
* section name and set addend to the symbol address */
/* for ".LCPIxxx", ".LJTIxxx" and ".LBBxxx" relocation,
* transform the symbol name to real section name and set
* addend to the offset of the symbol in the real section */
if (relocation->symbol_name
&& str_starts_with(relocation->symbol_name, ".LCPI")) {
&& (str_starts_with(relocation->symbol_name, ".LCPI")
|| str_starts_with(relocation->symbol_name, ".LJTI")
|| str_starts_with(relocation->symbol_name, ".LBB"))) {
/* change relocation->relocation_addend and relocation->symbol_name */
LLVMSectionIteratorRef contain_section;
if (!(contain_section
@ -2012,6 +2016,8 @@ is_relocation_section_name(char *section_name)
|| !strcmp(section_name, ".rela.literal")
|| !strcmp(section_name, ".rela.data")
|| !strcmp(section_name, ".rel.data")
|| !strcmp(section_name, ".rela.sdata")
|| !strcmp(section_name, ".rel.sdata")
|| !strcmp(section_name, ".rela.rodata")
|| !strcmp(section_name, ".rel.rodata")
/* ".rela.rodata.cst4/8/16/.." */

View File

@ -767,6 +767,12 @@ is_target_mips(AOTCompContext *comp_ctx)
return !strncmp(comp_ctx->target_arch, "mips", 4);
}
static bool
is_target_riscv(AOTCompContext *comp_ctx)
{
return !strncmp(comp_ctx->target_arch, "riscv", 5);
}
static bool
is_targeting_soft_float(AOTCompContext *comp_ctx, bool is_f32)
{
@ -796,6 +802,8 @@ is_targeting_soft_float(AOTCompContext *comp_ctx, bool is_f32)
* so user must specify '--cpu-features=-fp' to wamrc if the target
* doesn't have or enable Floating-Point Coprocessor Option on xtensa. */
ret = (!is_f32 || strstr(feature_string, "-fp")) ? true : false;
else if (is_target_riscv(comp_ctx))
ret = !strstr(feature_string, "+d") ? true : false;
else
ret = true;

View File

@ -1087,14 +1087,22 @@ static ArchItem valid_archs[] = {
{ "thumbv8r", true },
{ "thumbv8m.base", true },
{ "thumbv8m.main", true },
{ "thumbv8.1m.main", true }
{ "thumbv8.1m.main", true },
{ "riscv32", true},
{ "riscv64", true}
};
static const char *valid_abis[] = {
"gnu",
"eabi",
"gnueabihf",
"msvc"
"msvc",
"ilp32",
"ilp32f",
"ilp32d",
"lp64",
"lp64f",
"lp64d"
};
static void
@ -1184,7 +1192,7 @@ aot_create_comp_context(AOTCompData *comp_data,
char *cpu = NULL, *features, buf[128];
char *triple_norm_new = NULL, *cpu_new = NULL;
char *err = NULL, *fp_round= "round.tonearest", *fp_exce = "fpexcept.strict";
char triple_buf[32] = {0};
char triple_buf[32] = { 0 }, features_buf[128] = { 0 };
uint32 opt_level, size_level;
LLVMCodeModel code_model;
LLVMTargetDataRef target_data_ref;
@ -1323,6 +1331,14 @@ aot_create_comp_context(AOTCompData *comp_data,
goto fail;
}
/* Set default abi for riscv target */
if (arch && !strncmp(arch, "riscv", 5) && !abi) {
if (!strcmp(arch, "riscv64"))
abi = "lp64d";
else
abi = "ilp32d";
}
if (arch) {
/* Construct target triple: <arch>-<vendor>-<sys>-<abi> */
const char *vendor_sys;
@ -1394,6 +1410,29 @@ aot_create_comp_context(AOTCompData *comp_data,
goto fail;
}
/* Add module flag and cpu feature for riscv target */
if (arch && !strncmp(arch, "riscv", 5)) {
LLVMMetadataRef meta_target_abi;
if (!(meta_target_abi = LLVMMDStringInContext2(comp_ctx->context,
abi, strlen(abi)))) {
aot_set_last_error("create metadata string failed.");
goto fail;
}
LLVMAddModuleFlag(comp_ctx->module, LLVMModuleFlagBehaviorError,
"target-abi", strlen("target-abi"), meta_target_abi);
if (!strcmp(abi, "lp64d") || !strcmp(abi, "ilp32d")) {
if (features) {
snprintf(features_buf, sizeof(features_buf),
"%s%s", features, ",+d");
features = features_buf;
}
else
features = "+d";
}
}
if (!features)
features = "";

View File

@ -2785,7 +2785,7 @@ label_pop_csp_n:
/* if s >= d, copy from front to back */
/* if s < d, copy from back to front */
/* merge all together */
bh_memcpy_s(
bh_memmove_s(
(uint8 *)(dst_tbl_inst) + offsetof(WASMTableInstance, base_addr)
+ d * sizeof(uint32),
(dst_tbl_inst->cur_size - d) * sizeof(uint32),

View File

@ -2761,7 +2761,7 @@ recover_br_info:
/* if s >= d, copy from front to back */
/* if s < d, copy from back to front */
/* merge all together */
bh_memcpy_s(
bh_memmove_s(
(uint8 *)dst_tbl_inst + offsetof(WASMTableInstance, base_addr)
+ d * sizeof(uint32),
(dst_tbl_inst->cur_size - d) * sizeof(uint32),

View File

@ -61,7 +61,9 @@ typedef pthread_t korp_thread;
#if WASM_DISABLE_HW_BOUND_CHECK == 0
#if defined(BUILD_TARGET_X86_64) \
|| defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64)
|| defined(BUILD_TARGET_AARCH64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64)
#include <setjmp.h>
@ -86,7 +88,7 @@ bool os_thread_signal_inited();
void os_signal_unmask();
void os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64 */
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
typedef long int __syscall_slong_t;

View File

@ -44,8 +44,57 @@ os_mmap(void *hint, size_t size, int prot, int flags)
if (flags & MMAP_MAP_FIXED)
map_flags |= MAP_FIXED;
#if defined(BUILD_TARGET_RISCV64_LP64D) || defined(BUILD_TARGET_RISCV64_LP64)
/* As AOT relocation in RISCV64 may require that the code/data mapped
* is in range 0 to 2GB, we try to map the memory with hint address
* (mmap's first argument) to meet the requirement.
*/
if (!hint && !(flags & MMAP_MAP_FIXED) && (flags & MMAP_MAP_32BIT)) {
uint8 *stack_addr = (uint8*)&map_prot;
uint8 *text_addr = (uint8*)os_mmap;
/* hint address begins with 1MB */
static uint8 *hint_addr = (uint8 *)(uintptr_t)BH_MB;
if ((hint_addr - text_addr >= 0
&& hint_addr - text_addr < 100 * BH_MB)
|| (text_addr - hint_addr >= 0
&& text_addr - hint_addr < 100 * BH_MB)) {
/* hint address is possibly in text section, skip it */
hint_addr += 100 * BH_MB;
}
if ((hint_addr - stack_addr >= 0
&& hint_addr - stack_addr < 8 * BH_MB)
|| (stack_addr - hint_addr >= 0
&& stack_addr - hint_addr < 8 * BH_MB)) {
/* hint address is possibly in native stack area, skip it */
hint_addr += 8 * BH_MB;
}
/* try 10 times, step with 1MB each time */
for (i = 0;
i < 10 && hint_addr < (uint8 *)(uintptr_t)(2ULL * BH_GB);
i++) {
addr = mmap(hint_addr, request_size, map_prot, map_flags, -1, 0);
if (addr != MAP_FAILED) {
if (addr > (uint8 *)(uintptr_t)(2ULL * BH_GB)) {
/* unmap and try again if the mapped address doesn't
* meet the requirement */
os_munmap(addr, request_size);
}
else {
/* reset next hint address */
hint_addr += request_size;
return addr;
}
}
hint_addr += BH_MB;
}
}
#endif
/* try 5 times */
for (i = 0; i < 5; i ++) {
for (i = 0; i < 5; i++) {
addr = mmap(hint, request_size, map_prot, map_flags, -1, 0);
if (addr != MAP_FAILED)
break;

View File

@ -62,7 +62,9 @@ typedef pthread_t korp_thread;
#if WASM_DISABLE_HW_BOUND_CHECK == 0
#if defined(BUILD_TARGET_X86_64) \
|| defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64)
|| defined(BUILD_TARGET_AARCH64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64)
#include <setjmp.h>
@ -87,7 +89,7 @@ bool os_thread_signal_inited();
void os_signal_unmask();
void os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64 */
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#ifdef __cplusplus

View File

@ -61,7 +61,9 @@ typedef pthread_t korp_thread;
#if WASM_DISABLE_HW_BOUND_CHECK == 0
#if defined(BUILD_TARGET_X86_64) \
|| defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64)
|| defined(BUILD_TARGET_AARCH64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64)
#include <setjmp.h>
@ -86,7 +88,7 @@ bool os_thread_signal_inited();
void os_signal_unmask();
void os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64 */
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#ifdef __cplusplus

View File

@ -72,27 +72,25 @@ ifeq (${CONFIG_ARCH_FPU},y)
$(error riscv64 lp64f is unsupported)
else ifeq (${CONFIG_ARCH_DPFPU}, y)
CFLAGS += -DBUILD_TARGET_RISCV64_LP64D
INVOKE_NATIVE += invokeNative_riscv64_lp64d.s
else
CFLAGS += -DBUILD_TARGET_RISCV64_LP64
INVOKE_NATIVE += invokeNative_riscv64_lp64.s
endif
INVOKE_NATIVE += invokeNative_riscv.S
AOT_RELOC :=
AOT_RELOC := aot_reloc_riscv.c
else ifeq (${WAMR_BUILD_TARGET}, RISCV32)
ifeq (${CONFIG_ARCH_FPU}, y)
$(error riscv32 ilp32f is unsupported)
else ifeq (${CONFIG_ARCH_DPFPU}, y)
CFLAGS += -DBUILD_TARGET_RISCV64_ILP32D
INVOKE_NATIVE += invokeNative_riscv32_ilp32d.s
CFLAGS += -DBUILD_TARGET_RISCV32_ILP32D
else
CFLAGS += -DBUILD_TARGET_RISCV64_ILP32
INVOKE_NATIVE += invokeNative_riscv32_ilp32.s
CFLAGS += -DBUILD_TARGET_RISCV32_ILP32
endif
AOT_RELOC :=
INVOKE_NATIVE += invokeNative_riscv.S
AOT_RELOC := aot_reloc_riscv.c
else
$(error Build target is unsupported)
@ -182,7 +180,8 @@ CFLAGS += -Wno-strict-prototypes -Wno-shadow -Wno-unused-variable
CFLAGS += -Wno-int-conversion -Wno-implicit-function-declaration
CFLAGS += -I${CORE_ROOT} \
-I${IWASM_ROOT}/include \
-I${IWASM_ROOT}/include \
-I${IWASM_ROOT}/interpreter \
-I${IWASM_ROOT}/common \
-I${IWASM_ROOT}/libraries/thread-mgr \
-I${SHARED_ROOT}/include \
@ -218,7 +217,8 @@ CSRCS += nuttx_platform.c \
wasm_runtime_common.c \
wasm_native.c \
wasm_exec_env.c \
wasm_memory.c
wasm_memory.c \
wasm_c_api.c
ASRCS += ${INVOKE_NATIVE}

View File

@ -68,6 +68,14 @@ elseif (WAMR_BUILD_TARGET MATCHES "AARCH64.*")
elseif (WAMR_BUILD_TARGET MATCHES "ARM.*")
add_definitions(-DBUILD_TARGET_ARM)
add_definitions(-DBUILD_TARGET="${WAMR_BUILD_TARGET}")
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64" OR WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64D")
add_definitions(-DBUILD_TARGET_RISCV64_LP64D)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64")
add_definitions(-DBUILD_TARGET_RISCV64_LP64)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32" OR WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32D")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32D)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32)
else ()
message (FATAL_ERROR "-- Build target isn't set")
endif ()
@ -75,7 +83,8 @@ endif ()
message ("-- Build as target ${WAMR_BUILD_TARGET}")
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64" OR WAMR_BUILD_TARGET MATCHES "AARCH64.*")
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64"
OR WAMR_BUILD_TARGET MATCHES "AARCH64.*" OR WAMR_BUILD_TARGET MATCHES "RISCV64.*")
if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
# Add -fPIC flag if build as 64-bit
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")

View File

@ -66,7 +66,7 @@ def main():
cmd = 'cmake ../llvm \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_BUILD_TYPE:STRING="Release" \
-DLLVM_TARGETS_TO_BUILD:STRING="X86;ARM;AArch64;Mips" \
-DLLVM_TARGETS_TO_BUILD:STRING="X86;ARM;AArch64;Mips;RISCV" \
-DLLVM_INCLUDE_GO_TESTS=OFF \
-DLLVM_INCLUDE_TOOLS=OFF \
-DLLVM_INCLUDE_UTILS=OFF \

View File

@ -27,7 +27,7 @@ if [ ! -f bin/llvm-lto ]; then
cmake ../llvm \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_BUILD_TYPE:STRING="Release" \
-DLLVM_TARGETS_TO_BUILD:STRING="X86;ARM;AArch64;Mips" \
-DLLVM_TARGETS_TO_BUILD:STRING="X86;ARM;AArch64;Mips;RISCV" \
-DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF \
-DLLVM_OPTIMIZED_TABLEGEN:BOOL=ON \
-DLLVM_ENABLE_ZLIB:BOOL=OFF \

View File

@ -27,7 +27,7 @@ if [ ! -f bin/llvm-lto ]; then
cmake ../llvm \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_BUILD_TYPE:STRING="Release" \
-DLLVM_TARGETS_TO_BUILD:STRING="X86;ARM;AArch64;Mips" \
-DLLVM_TARGETS_TO_BUILD:STRING="X86;ARM;AArch64;Mips;RISCV" \
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD:STRING="Xtensa" \
-DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF \
-DLLVM_OPTIMIZED_TABLEGEN:BOOL=ON \

View File

@ -20,11 +20,14 @@ print_help()
{
printf("Usage: wamrc [options] -o output_file wasm_file\n");
printf(" --target=<arch-name> Set the target arch, which has the general format: <arch><sub>\n");
printf(" <arch> = x86_64, i386, aarch64, arm, thumb, xtensa, mips.\n");
printf(" <arch> = x86_64, i386, aarch64, arm, thumb, xtensa, mips,\n");
printf(" riscv64, riscv32.\n");
printf(" Default is host arch, e.g. x86_64\n");
printf(" <sub> = for ex. on arm or thumb: v5, v6m, v7a, v7m, etc.\n");
printf(" Use --target=help to list supported targets\n");
printf(" --target-abi=<abi> Set the target ABI, e.g. gnu, eabi, gnueabihf, etc. (default: gnu)\n");
printf(" --target-abi=<abi> Set the target ABI, e.g. gnu, eabi, gnueabihf, msvc, etc.\n");
printf(" Default is gnu if target isn't riscv64 or riscv32\n");
printf(" For target riscv64 and riscv32, default is lp64d and ilp32d\n");
printf(" Use --target-abi=help to list all the ABI supported\n");
printf(" --cpu=<cpu> Set the target CPU (default: host CPU, e.g. skylake)\n");
printf(" Use --cpu=help to list all the CPU supported\n");