From 3dc93d2fc5ae6f0045a926dde2ef0e1cdd63a4f3 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Tue, 20 Jul 2021 13:48:28 +0800 Subject: [PATCH 01/18] Implement mmap MAP_32BIT support for riscv --- core/app-mgr/app-manager/module_wasm_app.c | 3 +- core/iwasm/aot/aot_loader.c | 6 ++- core/iwasm/aot/arch/aot_reloc_riscv.c | 2 + .../platform/common/posix/posix_memmap.c | 50 ++++++++++++++++++- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/core/app-mgr/app-manager/module_wasm_app.c b/core/app-mgr/app-manager/module_wasm_app.c index a7d993ade1..bbd5ad49bd 100644 --- a/core/app-mgr/app-manager/module_wasm_app.c +++ b/core/app-mgr/app-manager/module_wasm_app.c @@ -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; diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index ed7b07fe1d..59e7f3f6a6 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -1034,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; @@ -2240,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; diff --git a/core/iwasm/aot/arch/aot_reloc_riscv.c b/core/iwasm/aot/arch/aot_reloc_riscv.c index 0984cb0335..61f8323818 100644 --- a/core/iwasm/aot/arch/aot_reloc_riscv.c +++ b/core/iwasm/aot/arch/aot_reloc_riscv.c @@ -16,6 +16,7 @@ #define RV_OPCODE_SW 0x23 void __divdi3(); +void __moddi3(); void __muldi3(); void __udivdi3(); void __umoddi3(); @@ -23,6 +24,7 @@ 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), diff --git a/core/shared/platform/common/posix/posix_memmap.c b/core/shared/platform/common/posix/posix_memmap.c index 825afefcdf..d2c29ede38 100644 --- a/core/shared/platform/common/posix/posix_memmap.c +++ b/core/shared/platform/common/posix/posix_memmap.c @@ -44,8 +44,56 @@ 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 might require that the code/data mapped + * is in range 0 to 2GB, we try to use mmap's first argument to allocate + * the memory which meets 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 possiblely 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 possible 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 the mapped address isn't + * in range 0 to 2GB */ + 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; From f3b7bee39c082e8fefd10206d344e51e1bc1676a Mon Sep 17 00:00:00 2001 From: wenyongh Date: Sun, 15 Dec 2019 18:53:32 +0800 Subject: [PATCH 02/18] Minor change of code comments --- .../shared/platform/common/posix/posix_memmap.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/core/shared/platform/common/posix/posix_memmap.c b/core/shared/platform/common/posix/posix_memmap.c index d2c29ede38..15a4de8b65 100644 --- a/core/shared/platform/common/posix/posix_memmap.c +++ b/core/shared/platform/common/posix/posix_memmap.c @@ -45,9 +45,9 @@ os_mmap(void *hint, size_t size, int prot, int flags) map_flags |= MAP_FIXED; #if defined(BUILD_TARGET_RISCV64_LP64D) || defined(BUILD_TARGET_RISCV64_LP64) - /* As AOT relocation in RISCV64 might require that the code/data mapped - * is in range 0 to 2GB, we try to use mmap's first argument to allocate - * the memory which meets the requirement. + /* 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; @@ -59,7 +59,7 @@ os_mmap(void *hint, size_t size, int prot, int flags) && hint_addr - text_addr < 100 * BH_MB) || (text_addr - hint_addr >= 0 && text_addr - hint_addr < 100 * BH_MB)) { - /* hint address is possiblely in text section, skip it */ + /* hint address is possibly in text section, skip it */ hint_addr += 100 * BH_MB; } @@ -67,7 +67,7 @@ os_mmap(void *hint, size_t size, int prot, int flags) && hint_addr - stack_addr < 8 * BH_MB) || (stack_addr - hint_addr >= 0 && stack_addr - hint_addr < 8 * BH_MB)) { - /* hint address is possible in native stack area, skip it */ + /* hint address is possibly in native stack area, skip it */ hint_addr += 8 * BH_MB; } @@ -77,10 +77,11 @@ os_mmap(void *hint, size_t size, int prot, int flags) 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 the mapped address isn't - * in range 0 to 2GB */ + 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; From 3df5d3030260f8530bc1e1ca9ea18668778d21b5 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Fri, 16 Jul 2021 19:42:02 +0800 Subject: [PATCH 03/18] Implement more relocation types, re-org code and fix some issues --- core/iwasm/aot/aot_runtime.c | 12 +- core/iwasm/aot/arch/aot_reloc_riscv.c | 227 +++++++++++++++---- core/iwasm/compilation/aot_emit_aot_file.c | 9 +- core/iwasm/compilation/aot_emit_numberic.c | 8 + core/iwasm/interpreter/wasm_interp_classic.c | 2 +- core/iwasm/interpreter/wasm_interp_fast.c | 2 +- 6 files changed, 211 insertions(+), 49 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 16301f5249..4cb2d342d4 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -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 diff --git a/core/iwasm/aot/arch/aot_reloc_riscv.c b/core/iwasm/aot/arch/aot_reloc_riscv.c index f0f578f016..0984cb0335 100644 --- a/core/iwasm/aot/arch/aot_reloc_riscv.c +++ b/core/iwasm/aot/arch/aot_reloc_riscv.c @@ -5,6 +5,8 @@ #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 @@ -13,7 +15,25 @@ #define RV_OPCODE_SW 0x23 -static SymbolMap target_sym_map[] = { REG_COMMON_SYMBOLS }; +void __divdi3(); +void __muldi3(); +void __udivdi3(); +void __umoddi3(); + +static SymbolMap target_sym_map[] = { + REG_COMMON_SYMBOLS + REG_SYM(__divdi3), + 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) @@ -24,7 +44,12 @@ get_current_target(char *target_buf, uint32 target_buf_size) uint32 get_plt_item_size() { - return 16; +#if __riscv_xlen == 64 + /* auipc + ld + jalr + nop + addr */ + return 20; +#else + return 0; +#endif } SymbolMap * @@ -64,17 +89,17 @@ rv_add_val(uint16 *addr, uint32 val) /** * Get imm_hi and imm_lo from given integer * - * @param long given integer, signed 32bit + * @param imm given integer, signed 32bit * @param imm_hi signed 20bit * @param imm_lo signed 12bit * */ static void -rv_calc_imm(long offset, long *imm_hi, long *imm_lo) +rv_calc_imm(int32 imm, int32 *imm_hi, int32 *imm_lo) { - long lo; - long hi = offset / 4096; - long r = offset % 4096; + int32 lo; + int32 hi = imm / 4096; + int32 r = imm % 4096; if (2047 < r) { hi++; @@ -83,7 +108,7 @@ rv_calc_imm(long offset, long *imm_hi, long *imm_lo) hi--; } - lo = offset - (hi * 4096); + lo = imm - (hi * 4096); *imm_lo = lo; *imm_hi = hi; @@ -97,43 +122,142 @@ get_plt_table_size() 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) + 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) { - long imm_hi; - long imm_lo; + 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: { - long offset = (uint8 *)symbol_addr - addr; - rv_calc_imm(offset, &imm_hi, &imm_lo); + val = (int32)(intptr_t)((uint8 *)symbol_addr - addr); + + CHECK_RELOC_OFFSET(sizeof(uint32)); + if (val != (intptr_t)((uint8 *)symbol_addr - addr)) { + if (reloc_type == R_RISCV_CALL_PLT && 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 */ - - uint32 val = + 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; @@ -141,10 +265,16 @@ apply_relocation(AOTModule *module, case R_RISCV_HI20: { - long offset = (long)symbol_addr; - uint8 *addr = target_section_addr + reloc_offset; - uint32 insn = rv_get_val((uint16 *)addr); - rv_calc_imm(offset, &imm_hi, &imm_lo); + 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; @@ -152,10 +282,16 @@ apply_relocation(AOTModule *module, case R_RISCV_LO12_I: { - long offset = (long)symbol_addr; - uint8 *addr = target_section_addr + reloc_offset; - uint32 insn = rv_get_val((uint16 *)addr); - rv_calc_imm(offset, &imm_hi, &imm_lo); + 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; @@ -163,10 +299,16 @@ apply_relocation(AOTModule *module, case R_RISCV_LO12_S: { - long offset = (long)symbol_addr; - uint8 *addr = target_section_addr + reloc_offset; - rv_calc_imm(offset, &imm_hi, &imm_lo); - uint32 val = + 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; @@ -176,9 +318,18 @@ apply_relocation(AOTModule *module, if (error_buf != NULL) snprintf(error_buf, error_buf_size, "Load relocation section failed: " - "invalid relocation type %ld.", + "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; } diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 6c8381b0ac..9fab6cfafd 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -1971,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 diff --git a/core/iwasm/compilation/aot_emit_numberic.c b/core/iwasm/compilation/aot_emit_numberic.c index dc267d726f..b1c1e0e790 100644 --- a/core/iwasm/compilation/aot_emit_numberic.c +++ b/core/iwasm/compilation/aot_emit_numberic.c @@ -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; diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index d85e180cd9..152c017411 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -2785,7 +2785,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, /* 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), diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index f5dc307358..45e0cdbe4b 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -2761,7 +2761,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, /* 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), From 9792a192d04d63cb9694bfcc598f94788afe688c Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Thu, 3 Jun 2021 17:47:09 +0800 Subject: [PATCH 04/18] Enable RISCV support in LLVM Signed-off-by: Huang Qi --- wamr-compiler/build_llvm.py | 2 +- wamr-compiler/build_llvm.sh | 2 +- wamr-compiler/build_llvm_xtensa.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wamr-compiler/build_llvm.py b/wamr-compiler/build_llvm.py index 34ae7b03f5..71f7886315 100644 --- a/wamr-compiler/build_llvm.py +++ b/wamr-compiler/build_llvm.py @@ -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 \ diff --git a/wamr-compiler/build_llvm.sh b/wamr-compiler/build_llvm.sh index 7960e36462..045b599adc 100755 --- a/wamr-compiler/build_llvm.sh +++ b/wamr-compiler/build_llvm.sh @@ -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 \ diff --git a/wamr-compiler/build_llvm_xtensa.sh b/wamr-compiler/build_llvm_xtensa.sh index c8bb9b83db..97e3404de4 100755 --- a/wamr-compiler/build_llvm_xtensa.sh +++ b/wamr-compiler/build_llvm_xtensa.sh @@ -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 \ From b3f59799b3789f463e90da1c0a186384acc2af92 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Fri, 4 Jun 2021 07:21:34 +0800 Subject: [PATCH 05/18] Add target & target-abi for riscv to wamrc Signed-off-by: Huang Qi --- core/iwasm/compilation/aot_llvm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index 7966a5477f..e299caa0eb 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -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 From 828633c948de3562fda4bf7eb0fcd7a90ad1a685 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Mon, 7 Jun 2021 17:46:34 +0800 Subject: [PATCH 06/18] Merge invokeNative for riscv32/64 into unified implementation Signed-off-by: Huang Qi --- core/iwasm/common/arch/invokeNative_riscv.S | 148 ++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 core/iwasm/common/arch/invokeNative_riscv.S diff --git a/core/iwasm/common/arch/invokeNative_riscv.S b/core/iwasm/common/arch/invokeNative_riscv.S new file mode 100644 index 0000000000..1f0f2d4e3d --- /dev/null +++ b/core/iwasm/common/arch/invokeNative_riscv.S @@ -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_FPREG_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 From 6402aa29f99279d1f600f639fda39a1e409b6fd0 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Tue, 8 Jun 2021 17:08:22 +0800 Subject: [PATCH 07/18] Remove discrete invokeNative_riscv_xxx.s for riscv Signed-off-by: Huang Qi --- .../common/arch/invokeNative_riscv32_ilp32.s | 95 --------------- .../common/arch/invokeNative_riscv32_ilp32d.s | 104 ----------------- .../common/arch/invokeNative_riscv64_lp64.s | 95 --------------- .../common/arch/invokeNative_riscv64_lp64d.s | 108 ------------------ core/iwasm/common/iwasm_common.cmake | 10 +- product-mini/platforms/nuttx/wamr.mk | 6 +- 6 files changed, 4 insertions(+), 414 deletions(-) delete mode 100644 core/iwasm/common/arch/invokeNative_riscv32_ilp32.s delete mode 100644 core/iwasm/common/arch/invokeNative_riscv32_ilp32d.s delete mode 100644 core/iwasm/common/arch/invokeNative_riscv64_lp64.s delete mode 100644 core/iwasm/common/arch/invokeNative_riscv64_lp64d.s diff --git a/core/iwasm/common/arch/invokeNative_riscv32_ilp32.s b/core/iwasm/common/arch/invokeNative_riscv32_ilp32.s deleted file mode 100644 index b0b41aa069..0000000000 --- a/core/iwasm/common/arch/invokeNative_riscv32_ilp32.s +++ /dev/null @@ -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 - diff --git a/core/iwasm/common/arch/invokeNative_riscv32_ilp32d.s b/core/iwasm/common/arch/invokeNative_riscv32_ilp32d.s deleted file mode 100644 index 49e8ec766b..0000000000 --- a/core/iwasm/common/arch/invokeNative_riscv32_ilp32d.s +++ /dev/null @@ -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 diff --git a/core/iwasm/common/arch/invokeNative_riscv64_lp64.s b/core/iwasm/common/arch/invokeNative_riscv64_lp64.s deleted file mode 100644 index 86a3c9c826..0000000000 --- a/core/iwasm/common/arch/invokeNative_riscv64_lp64.s +++ /dev/null @@ -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 - diff --git a/core/iwasm/common/arch/invokeNative_riscv64_lp64d.s b/core/iwasm/common/arch/invokeNative_riscv64_lp64d.s deleted file mode 100644 index a82df0264e..0000000000 --- a/core/iwasm/common/arch/invokeNative_riscv64_lp64d.s +++ /dev/null @@ -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 - - diff --git a/core/iwasm/common/iwasm_common.cmake b/core/iwasm/common/iwasm_common.cmake index 7e9944fc07..6bcbbdaedd 100644 --- a/core/iwasm/common/iwasm_common.cmake +++ b/core/iwasm/common/iwasm_common.cmake @@ -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 () diff --git a/product-mini/platforms/nuttx/wamr.mk b/product-mini/platforms/nuttx/wamr.mk index 03de0c7cb6..9ee06a29c0 100644 --- a/product-mini/platforms/nuttx/wamr.mk +++ b/product-mini/platforms/nuttx/wamr.mk @@ -72,11 +72,10 @@ 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 := @@ -86,12 +85,11 @@ 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 else CFLAGS += -DBUILD_TARGET_RISCV64_ILP32 - INVOKE_NATIVE += invokeNative_riscv32_ilp32.s endif + INVOKE_NATIVE += invokeNative_riscv.S AOT_RELOC := else From 6bf72fb204d7dfc59df24eaa5a7c0a9b22ea9b68 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Thu, 10 Jun 2021 13:07:40 +0800 Subject: [PATCH 08/18] Add E_MACHINE_RISCV to aot loader Signed-off-by: Huang Qi --- core/iwasm/aot/aot_loader.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 5f21d1ff4c..73675eab4b 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -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", From 80b4f232dac3fd4a8a119ab6984b920d48735821 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Wed, 16 Jun 2021 17:56:09 +0800 Subject: [PATCH 09/18] Implement relocator for riscv Signed-off-by: Huang Qi --- core/app-mgr/app-manager/module_wasm_app.c | 6 +- core/iwasm/aot/aot_loader.c | 12 ++- core/iwasm/aot/arch/aot_reloc_riscv.c | 86 ++++++++++++++++++++++ core/iwasm/aot/iwasm_aot.cmake | 2 + 4 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 core/iwasm/aot/arch/aot_reloc_riscv.c diff --git a/core/app-mgr/app-manager/module_wasm_app.c b/core/app-mgr/app-manager/module_wasm_app.c index a7d993ade1..9e86f1fb2a 100644 --- a/core/app-mgr/app-manager/module_wasm_app.c +++ b/core/app-mgr/app-manager/module_wasm_app.c @@ -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) /* 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; @@ -1415,7 +1416,8 @@ wasm_app_module_on_install_request_byte_arrive(uint8 ch, "allocate memory failed"); goto fail; } -#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) /* address must be in the first 2 Gigabytes of the process address space */ bh_assert((uintptr_t)section->section_body < INT32_MAX); diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 73675eab4b..3e1b4d7380 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -1034,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) /* 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; @@ -1053,7 +1054,8 @@ load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end, "allocate memory failed"); return false; } -#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) #if !defined(BH_PLATFORM_LINUX_SGX) && !defined(BH_PLATFORM_WINDOWS) \ && !defined(BH_PLATFORM_DARWIN) /* address must be in the first 2 Gigabytes of @@ -2239,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) /* 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; @@ -2256,7 +2259,8 @@ create_sections(const uint8 *buf, uint32 size, "mmap memory failed"); goto fail; } -#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) #if !defined(BH_PLATFORM_LINUX_SGX) && !defined(BH_PLATFORM_WINDOWS) \ && !defined(BH_PLATFORM_DARWIN) /* address must be in the first 2 Gigabytes of diff --git a/core/iwasm/aot/arch/aot_reloc_riscv.c b/core/iwasm/aot/arch/aot_reloc_riscv.c new file mode 100644 index 0000000000..c3a2c4f5bd --- /dev/null +++ b/core/iwasm/aot/arch/aot_reloc_riscv.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2021 XiaoMi Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "aot_reloc.h" + +#define R_RISCV_CALL 18 + +static SymbolMap target_sym_map[] = { REG_COMMON_SYMBOLS }; + +void +get_current_target(char *target_buf, uint32 target_buf_size) +{ + snprintf(target_buf, target_buf_size, "riscv"); +} + +uint32 +get_plt_item_size() +{ + return 16; +} + +SymbolMap * +get_target_symbol_map(uint32 *sym_num) +{ + *sym_num = sizeof(target_sym_map) / sizeof(SymbolMap); + return target_sym_map; +} + +uint32 +get_plt_table_size() +{ + return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap)); +} + +void +init_plt_table(uint8 *plt) +{} + +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) +{ + uint8 *P = target_section_addr + reloc_offset; + uint32 hi20, lo12; + + hi20 = (uint32)((unsigned long)symbol_addr & 0xfffff000); + lo12 = (uint32)(((unsigned long)symbol_addr & 0xfff) << 20); + + switch (reloc_type) { + case R_RISCV_CALL: + if ((uint32)(uintptr_t)symbol_addr != (uintptr_t)symbol_addr) { + if (error_buf != NULL) { + snprintf( + error_buf, error_buf_size, + "Jump address exceeds 32-bit address space (0-4GB)."); + } + return false; + } + + /* lui t0, hi20 */ + *(uint32 *)(P + 0) = (uint32)hi20 | 0x2b7; + /* jalr ra, lo12(t0) */ + *(uint32 *)(P + 4) = (uint32)lo12 | 0x280e7; + break; + + default: + if (error_buf != NULL) + snprintf(error_buf, error_buf_size, + "Load relocation section failed: " + "invalid relocation type %ld.", + reloc_type); + return false; + } + + return true; +} diff --git a/core/iwasm/aot/iwasm_aot.cmake b/core/iwasm/aot/iwasm_aot.cmake index e7d0549d9f..a5195d83f3 100644 --- a/core/iwasm/aot/iwasm_aot.cmake +++ b/core/iwasm/aot/iwasm_aot.cmake @@ -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 () From d5a95fc1773dfda9a8456f9e0763ca9433e491b5 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Thu, 17 Jun 2021 14:27:41 +0800 Subject: [PATCH 10/18] Fix FP offset in invokeNatvie for riscv Signed-off-by: Huang Qi --- core/iwasm/common/arch/invokeNative_riscv.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/iwasm/common/arch/invokeNative_riscv.S b/core/iwasm/common/arch/invokeNative_riscv.S index 1f0f2d4e3d..0908f73cc2 100644 --- a/core/iwasm/common/arch/invokeNative_riscv.S +++ b/core/iwasm/common/arch/invokeNative_riscv.S @@ -26,7 +26,7 @@ #define RV_OP_STOREREG sw #define RV_REG_SIZE 4 #define RV_REG_SHIFT 2 -#define RV_FP_OFFSET (8 * RV_FPREG_SIZE) +#define RV_FP_OFFSET (8 * RV_REG_SIZE) #define RV_INT_OFFSET 0 #else #define RV_OP_LOADREG ld From 666f1aa98b0c7d08786dab39ec9a3b4986274d56 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Thu, 17 Jun 2021 14:48:58 +0800 Subject: [PATCH 11/18] Add AOT support for riscv on NuttX Signed-off-by: Huang Qi --- product-mini/platforms/nuttx/wamr.mk | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/product-mini/platforms/nuttx/wamr.mk b/product-mini/platforms/nuttx/wamr.mk index 9ee06a29c0..5fc77f5a19 100644 --- a/product-mini/platforms/nuttx/wamr.mk +++ b/product-mini/platforms/nuttx/wamr.mk @@ -77,20 +77,20 @@ else 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 + CFLAGS += -DBUILD_TARGET_RISCV32_ILP32D else - CFLAGS += -DBUILD_TARGET_RISCV64_ILP32 + CFLAGS += -DBUILD_TARGET_RISCV32_ILP32 endif INVOKE_NATIVE += invokeNative_riscv.S - AOT_RELOC := + AOT_RELOC := aot_reloc_riscv.c else $(error Build target is unsupported) @@ -180,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 \ @@ -216,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} From ce8e14982ca0cb6cf5c7ad66db0102d7dd4c916d Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Sun, 27 Jun 2021 11:05:56 +0800 Subject: [PATCH 12/18] Fix some issues of riscv-aot --- build-scripts/config_common.cmake | 11 ++++++++--- build-scripts/runtime_lib.cmake | 5 ----- core/app-mgr/app-manager/module_wasm_app.c | 6 ++---- core/iwasm/aot/aot_loader.c | 12 ++++-------- core/iwasm/common/wasm_runtime_common.c | 3 ++- core/shared/platform/android/platform_internal.h | 6 ++++-- core/shared/platform/darwin/platform_internal.h | 6 ++++-- core/shared/platform/linux/platform_internal.h | 6 ++++-- wamr-compiler/CMakeLists.txt | 11 ++++++++++- 9 files changed, 38 insertions(+), 28 deletions(-) diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 68aad25883..36fb7f9cd0 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -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) diff --git a/build-scripts/runtime_lib.cmake b/build-scripts/runtime_lib.cmake index b647219d60..d6dce67f51 100644 --- a/build-scripts/runtime_lib.cmake +++ b/build-scripts/runtime_lib.cmake @@ -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) diff --git a/core/app-mgr/app-manager/module_wasm_app.c b/core/app-mgr/app-manager/module_wasm_app.c index 9e86f1fb2a..a7d993ade1 100644 --- a/core/app-mgr/app-manager/module_wasm_app.c +++ b/core/app-mgr/app-manager/module_wasm_app.c @@ -1395,8 +1395,7 @@ 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) \ - || defined(BUILD_TARGET_RISCV64) +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) /* 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; @@ -1416,8 +1415,7 @@ wasm_app_module_on_install_request_byte_arrive(uint8 ch, "allocate memory failed"); goto fail; } -#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \ - || defined(BUILD_TARGET_RISCV64) +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) /* address must be in the first 2 Gigabytes of the process address space */ bh_assert((uintptr_t)section->section_body < INT32_MAX); diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 3e1b4d7380..73675eab4b 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -1034,8 +1034,7 @@ 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) \ - || defined(BUILD_TARGET_RISCV64) +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) /* 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; @@ -1054,8 +1053,7 @@ load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end, "allocate memory failed"); return false; } -#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \ - || defined(BUILD_TARGET_RISCV64) +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) #if !defined(BH_PLATFORM_LINUX_SGX) && !defined(BH_PLATFORM_WINDOWS) \ && !defined(BH_PLATFORM_DARWIN) /* address must be in the first 2 Gigabytes of @@ -2241,8 +2239,7 @@ 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) \ - || defined(BUILD_TARGET_RISCV64) +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) /* 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; @@ -2259,8 +2256,7 @@ create_sections(const uint8 *buf, uint32 size, "mmap memory failed"); goto fail; } -#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \ - || defined(BUILD_TARGET_RISCV64) +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) #if !defined(BH_PLATFORM_LINUX_SGX) && !defined(BH_PLATFORM_WINDOWS) \ && !defined(BH_PLATFORM_DARWIN) /* address must be in the first 2 Gigabytes of diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 64ab7ac878..fb1a3bb523 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -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) diff --git a/core/shared/platform/android/platform_internal.h b/core/shared/platform/android/platform_internal.h index 82adc93ff8..703e6bf5bb 100644 --- a/core/shared/platform/android/platform_internal.h +++ b/core/shared/platform/android/platform_internal.h @@ -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 @@ -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; diff --git a/core/shared/platform/darwin/platform_internal.h b/core/shared/platform/darwin/platform_internal.h index d6ee41cdab..3fa85a3078 100644 --- a/core/shared/platform/darwin/platform_internal.h +++ b/core/shared/platform/darwin/platform_internal.h @@ -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 @@ -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 diff --git a/core/shared/platform/linux/platform_internal.h b/core/shared/platform/linux/platform_internal.h index e2a52a6bbd..3e5c7e3f06 100644 --- a/core/shared/platform/linux/platform_internal.h +++ b/core/shared/platform/linux/platform_internal.h @@ -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 @@ -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 diff --git a/wamr-compiler/CMakeLists.txt b/wamr-compiler/CMakeLists.txt index c1c8c97f79..07a13d45f6 100644 --- a/wamr-compiler/CMakeLists.txt +++ b/wamr-compiler/CMakeLists.txt @@ -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") From c3257284f971d305a9f49f8f6952bd4aefb62b17 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Fri, 9 Jul 2021 05:54:05 +0800 Subject: [PATCH 13/18] Enable setting target-abi for riscv --- core/iwasm/compilation/aot_llvm.c | 33 ++++++++++++++++++++++++++++++- wamr-compiler/main.c | 7 +++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index e299caa0eb..86945f4715 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -1192,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; @@ -1331,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: --- */ const char *vendor_sys; @@ -1402,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 = ""; diff --git a/wamr-compiler/main.c b/wamr-compiler/main.c index 4ced209b06..1f859704a1 100644 --- a/wamr-compiler/main.c +++ b/wamr-compiler/main.c @@ -20,11 +20,14 @@ print_help() { printf("Usage: wamrc [options] -o output_file wasm_file\n"); printf(" --target= Set the target arch, which has the general format: \n"); - printf(" = x86_64, i386, aarch64, arm, thumb, xtensa, mips.\n"); + printf(" = x86_64, i386, aarch64, arm, thumb, xtensa, mips,\n"); + printf(" riscv64, riscv32.\n"); printf(" Default is host arch, e.g. x86_64\n"); printf(" = for ex. on arm or thumb: v5, v6m, v7a, v7m, etc.\n"); printf(" Use --target=help to list supported targets\n"); - printf(" --target-abi= Set the target ABI, e.g. gnu, eabi, gnueabihf, etc. (default: gnu)\n"); + printf(" --target-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= Set the target CPU (default: host CPU, e.g. skylake)\n"); printf(" Use --cpu=help to list all the CPU supported\n"); From 42b1ea83c6ae19cd4b4e81581dd63df5931bbda6 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Thu, 8 Jul 2021 04:43:30 +0800 Subject: [PATCH 14/18] Enable relocation for .sdata symbol --- core/iwasm/aot/aot_loader.c | 1 + core/iwasm/aot/arch/aot_reloc_riscv.c | 13 ++++--------- core/iwasm/compilation/aot_emit_aot_file.c | 3 +++ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 73675eab4b..ed7b07fe1d 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -1505,6 +1505,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/.." */ diff --git a/core/iwasm/aot/arch/aot_reloc_riscv.c b/core/iwasm/aot/arch/aot_reloc_riscv.c index c3a2c4f5bd..a80daa40db 100644 --- a/core/iwasm/aot/arch/aot_reloc_riscv.c +++ b/core/iwasm/aot/arch/aot_reloc_riscv.c @@ -40,15 +40,10 @@ init_plt_table(uint8 *plt) 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) + 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) { uint8 *P = target_section_addr + reloc_offset; uint32 hi20, lo12; diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 64c04e2a3f..6c8381b0ac 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -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")) @@ -2012,6 +2013,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/.." */ From 9b9353d0a8f9d5cea4edbe102e8952b02965f9fd Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Tue, 13 Jul 2021 15:15:46 +0800 Subject: [PATCH 15/18] Support R_RISCV_CALL_PLT for AOT Signed-off-by: Huang Qi --- core/iwasm/aot/arch/aot_reloc_riscv.c | 114 ++++++++++++++++++++------ 1 file changed, 90 insertions(+), 24 deletions(-) diff --git a/core/iwasm/aot/arch/aot_reloc_riscv.c b/core/iwasm/aot/arch/aot_reloc_riscv.c index a80daa40db..b16394cdbe 100644 --- a/core/iwasm/aot/arch/aot_reloc_riscv.c +++ b/core/iwasm/aot/arch/aot_reloc_riscv.c @@ -5,7 +5,10 @@ #include "aot_reloc.h" -#define R_RISCV_CALL 18 +#define R_RISCV_CALL 18 +#define R_RISCV_CALL_PLT 19 + +#define RV_OPCODE_SW 0x23 static SymbolMap target_sym_map[] = { REG_COMMON_SYMBOLS }; @@ -28,6 +31,61 @@ get_target_symbol_map(uint32 *sym_num) return target_sym_map; } +/* Get a val from given address */ +static uint32 +rv_get_val(uint16_t *addr) +{ + uint32_t ret; + ret = *addr | (*(addr + 1)) << 16; + return ret; +} + +/* Set a val to given address */ +static void +rv_set_val(uint16 *addr, uint32_t 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_t val) +{ + uint32_t cur = rv_get_val(addr); + rv_set_val(addr, cur + val); +} + +/** + * Get imm_hi and imm_lo from given integer + * + * @param long given integer, signed 32bit + * @param imm_hi signed 20bit + * @param imm_lo signed 12bit + * + */ +static void +rv_calc_imm(long offset, long *imm_hi, long *imm_lo) +{ + long lo; + long hi = offset / 4096; + long r = offset % 4096; + + if (2047 < r) { + hi++; + } + else if (r < -2048) { + hi--; + } + + lo = offset - (hi * 4096); + + *imm_lo = lo; + *imm_hi = hi; +} + uint32 get_plt_table_size() { @@ -40,33 +98,42 @@ init_plt_table(uint8 *plt) 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) + 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) { - uint8 *P = target_section_addr + reloc_offset; - uint32 hi20, lo12; - - hi20 = (uint32)((unsigned long)symbol_addr & 0xfffff000); - lo12 = (uint32)(((unsigned long)symbol_addr & 0xfff) << 20); - switch (reloc_type) { case R_RISCV_CALL: - if ((uint32)(uintptr_t)symbol_addr != (uintptr_t)symbol_addr) { - if (error_buf != NULL) { - snprintf( - error_buf, error_buf_size, - "Jump address exceeds 32-bit address space (0-4GB)."); - } - return false; + case R_RISCV_CALL_PLT: + { + uint8 *P = target_section_addr + reloc_offset; + long offset = (uint8 *)symbol_addr - P; + long imm_hi; + long imm_lo; + + rv_calc_imm(offset, &imm_hi, &imm_lo); + + rv_add_val((uint16_t *)P, (imm_hi << 12)); + if ((rv_get_val((uint16_t *)(P + 4)) & 0x7f) == RV_OPCODE_SW) { + /* Adjust imm for SW : S-type */ + + uint32_t val = (((int32_t)imm_lo >> 5) << 25) + + (((int32_t)imm_lo & 0x1f) << 7); + + rv_add_val((uint16_t *)(P + 4), val); } + else { + /* Adjust imm for MV(ADDI)/JALR : I-type */ - /* lui t0, hi20 */ - *(uint32 *)(P + 0) = (uint32)hi20 | 0x2b7; - /* jalr ra, lo12(t0) */ - *(uint32 *)(P + 4) = (uint32)lo12 | 0x280e7; - break; + rv_add_val((uint16_t *)(P + 4), ((int32_t)imm_lo << 20)); + } + } break; default: if (error_buf != NULL) @@ -76,6 +143,5 @@ apply_relocation(AOTModule *module, reloc_type); return false; } - return true; } From 426c1040d07c4338893992bdc9d5f68db159bca0 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Wed, 14 Jul 2021 10:42:13 +0800 Subject: [PATCH 16/18] Support R_RISCV_HI20 for AOT Signed-off-by: Huang Qi --- core/iwasm/aot/arch/aot_reloc_riscv.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/iwasm/aot/arch/aot_reloc_riscv.c b/core/iwasm/aot/arch/aot_reloc_riscv.c index b16394cdbe..e4fee5d104 100644 --- a/core/iwasm/aot/arch/aot_reloc_riscv.c +++ b/core/iwasm/aot/arch/aot_reloc_riscv.c @@ -7,6 +7,7 @@ #define R_RISCV_CALL 18 #define R_RISCV_CALL_PLT 19 +#define R_RISCV_HI20 26 #define RV_OPCODE_SW 0x23 @@ -135,6 +136,18 @@ apply_relocation(AOTModule *module, } } break; + case R_RISCV_HI20: + { + long offset = (long)symbol_addr; + long imm_hi; + long imm_lo; + uint8 *addr = target_section_addr + reloc_offset; + uint32 insn = rv_get_val((uint16 *)addr); + rv_calc_imm(offset, &imm_hi, &imm_lo); + insn = (insn & 0x00000fff) | (imm_hi << 12); + rv_set_val((uint16*)addr, insn); + } break; + default: if (error_buf != NULL) snprintf(error_buf, error_buf_size, From 02cac0ae136d77801ef2bda44d2c81658c9a8ca8 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Wed, 14 Jul 2021 12:28:50 +0800 Subject: [PATCH 17/18] Support R_RISCV_LO12_I/S in AOT Signed-off-by: Huang Qi --- core/iwasm/aot/arch/aot_reloc_riscv.c | 47 +++++++++++++++++++-------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/core/iwasm/aot/arch/aot_reloc_riscv.c b/core/iwasm/aot/arch/aot_reloc_riscv.c index e4fee5d104..36b13c41ea 100644 --- a/core/iwasm/aot/arch/aot_reloc_riscv.c +++ b/core/iwasm/aot/arch/aot_reloc_riscv.c @@ -8,6 +8,8 @@ #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 @@ -109,38 +111,36 @@ apply_relocation(AOTModule *module, char *error_buf, uint32 error_buf_size) { + long imm_hi; + long imm_lo; + uint8 *addr = target_section_addr + reloc_offset; + switch (reloc_type) { case R_RISCV_CALL: case R_RISCV_CALL_PLT: { - uint8 *P = target_section_addr + reloc_offset; - long offset = (uint8 *)symbol_addr - P; - long imm_hi; - long imm_lo; - + long offset = (uint8 *)symbol_addr - addr; rv_calc_imm(offset, &imm_hi, &imm_lo); - rv_add_val((uint16_t *)P, (imm_hi << 12)); - if ((rv_get_val((uint16_t *)(P + 4)) & 0x7f) == RV_OPCODE_SW) { + 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 */ - uint32_t val = (((int32_t)imm_lo >> 5) << 25) - + (((int32_t)imm_lo & 0x1f) << 7); + uint32 val = (((int32)imm_lo >> 5) << 25) + + (((int32)imm_lo & 0x1f) << 7); - rv_add_val((uint16_t *)(P + 4), val); + rv_add_val((uint16 *)(addr + 4), val); } else { /* Adjust imm for MV(ADDI)/JALR : I-type */ - rv_add_val((uint16_t *)(P + 4), ((int32_t)imm_lo << 20)); + rv_add_val((uint16 *)(addr + 4), ((int32)imm_lo << 20)); } } break; case R_RISCV_HI20: { long offset = (long)symbol_addr; - long imm_hi; - long imm_lo; uint8 *addr = target_section_addr + reloc_offset; uint32 insn = rv_get_val((uint16 *)addr); rv_calc_imm(offset, &imm_hi, &imm_lo); @@ -148,6 +148,27 @@ apply_relocation(AOTModule *module, rv_set_val((uint16*)addr, insn); } break; + case R_RISCV_LO12_I: + { + long offset = (long)symbol_addr; + uint8 *addr = target_section_addr + reloc_offset; + uint32 insn = rv_get_val((uint16 *)addr); + rv_calc_imm(offset, &imm_hi, &imm_lo); + insn = (insn & 0x000fffff) | (imm_lo << 20); + rv_set_val((uint16*)addr, insn); + } break; + + case R_RISCV_LO12_S: + { + long offset = (long)symbol_addr; + uint8 *addr = target_section_addr + reloc_offset; + rv_calc_imm(offset, &imm_hi, &imm_lo); + uint32 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, From 139c5c4b42b26304b63cbef50f92539b7489977a Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Sat, 17 Jul 2021 23:16:21 +0800 Subject: [PATCH 18/18] Minor fix for code format and data type Signed-off-by: Huang Qi --- core/iwasm/aot/arch/aot_reloc_riscv.c | 35 +++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/core/iwasm/aot/arch/aot_reloc_riscv.c b/core/iwasm/aot/arch/aot_reloc_riscv.c index 36b13c41ea..f0f578f016 100644 --- a/core/iwasm/aot/arch/aot_reloc_riscv.c +++ b/core/iwasm/aot/arch/aot_reloc_riscv.c @@ -36,16 +36,16 @@ get_target_symbol_map(uint32 *sym_num) /* Get a val from given address */ static uint32 -rv_get_val(uint16_t *addr) +rv_get_val(uint16 *addr) { - uint32_t ret; + uint32 ret; ret = *addr | (*(addr + 1)) << 16; return ret; } /* Set a val to given address */ static void -rv_set_val(uint16 *addr, uint32_t val) +rv_set_val(uint16 *addr, uint32 val) { *addr = (val & 0xffff); *(addr + 1) = (val >> 16); @@ -55,9 +55,9 @@ rv_set_val(uint16 *addr, uint32_t val) /* Add a val to given address */ static void -rv_add_val(uint16 *addr, uint32_t val) +rv_add_val(uint16 *addr, uint32 val) { - uint32_t cur = rv_get_val(addr); + uint32 cur = rv_get_val(addr); rv_set_val(addr, cur + val); } @@ -126,8 +126,8 @@ apply_relocation(AOTModule *module, if ((rv_get_val((uint16 *)(addr + 4)) & 0x7f) == RV_OPCODE_SW) { /* Adjust imm for SW : S-type */ - uint32 val = (((int32)imm_lo >> 5) << 25) - + (((int32)imm_lo & 0x1f) << 7); + uint32 val = + (((int32)imm_lo >> 5) << 25) + (((int32)imm_lo & 0x1f) << 7); rv_add_val((uint16 *)(addr + 4), val); } @@ -136,7 +136,8 @@ apply_relocation(AOTModule *module, rv_add_val((uint16 *)(addr + 4), ((int32)imm_lo << 20)); } - } break; + break; + } case R_RISCV_HI20: { @@ -145,8 +146,9 @@ apply_relocation(AOTModule *module, uint32 insn = rv_get_val((uint16 *)addr); rv_calc_imm(offset, &imm_hi, &imm_lo); insn = (insn & 0x00000fff) | (imm_hi << 12); - rv_set_val((uint16*)addr, insn); - } break; + rv_set_val((uint16 *)addr, insn); + break; + } case R_RISCV_LO12_I: { @@ -155,8 +157,9 @@ apply_relocation(AOTModule *module, uint32 insn = rv_get_val((uint16 *)addr); rv_calc_imm(offset, &imm_hi, &imm_lo); insn = (insn & 0x000fffff) | (imm_lo << 20); - rv_set_val((uint16*)addr, insn); - } break; + rv_set_val((uint16 *)addr, insn); + break; + } case R_RISCV_LO12_S: { @@ -164,10 +167,10 @@ apply_relocation(AOTModule *module, uint8 *addr = target_section_addr + reloc_offset; rv_calc_imm(offset, &imm_hi, &imm_lo); uint32 val = - (((int32)imm_lo >> 5) << 25) + - (((int32)imm_lo & 0x1f) << 7); - rv_add_val((uint16*)addr, val); - } break; + (((int32)imm_lo >> 5) << 25) + (((int32)imm_lo & 0x1f) << 7); + rv_add_val((uint16 *)addr, val); + break; + } default: if (error_buf != NULL)