Initial version of enable loongarch target

This commit is contained in:
Wenyong Huang 2025-01-12 11:12:40 +08:00
parent 902f7d2631
commit 961c2af00e
17 changed files with 290 additions and 82 deletions

View File

@ -108,7 +108,7 @@ def build_llvm(llvm_dir, platform, backends, projects, use_clang=False, extra_fl
LLVM_TARGETS_TO_BUILD = [
'-DLLVM_TARGETS_TO_BUILD:STRING="' + ";".join(normal_backends) + '"'
if normal_backends
else '-DLLVM_TARGETS_TO_BUILD:STRING="AArch64;ARM;Mips;RISCV;X86"'
else '-DLLVM_TARGETS_TO_BUILD:STRING="AArch64;ARM;Mips;RISCV;LoongArch;X86"'
]
# if not on ARC platform, but want to add expeirmental backend ARC as target
@ -307,6 +307,11 @@ def main():
"repo_ssh": "git@github.com:espressif/llvm-project.git",
"branch": "xtensa_release_17.0.1",
},
"loongarch": {
"repo": "https://github.com/llvm/llvm-project.git",
"repo_ssh": "git@github.com:llvm/llvm-project.git",
"branch": "release/19.x",
},
"default": {
"repo": "https://github.com/llvm/llvm-project.git",
"repo_ssh": "git@github.com:llvm/llvm-project.git",

View File

@ -43,6 +43,16 @@ elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32F")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32F)
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32")
add_definitions(-DBUILD_TARGET_RISCV32_ILP32)
elseif (WAMR_BUILD_TARGET STREQUAL "LOONGARCH64" OR WAMR_BUILD_TARGET STREQUAL "LOONGARCH64_LP64D")
add_definitions(-DBUILD_TARGET_LOONGARCH64_LP64D)
elseif (WAMR_BUILD_TARGET STREQUAL "LOONGARCH64_LP64")
add_definitions(-DBUILD_TARGET_LOONGARCH64_LP64)
elseif (WAMR_BUILD_TARGET STREQUAL "LOONGARCH32" OR WAMR_BUILD_TARGET STREQUAL "LOONGARCH32_ILP32D")
add_definitions(-DBUILD_TARGET_LOONGARCH32_ILP32D)
elseif (WAMR_BUILD_TARGET STREQUAL "LOONGARCH32_ILP32F")
add_definitions(-DBUILD_TARGET_LOONGARCH32_ILP32F)
elseif (WAMR_BUILD_TARGET STREQUAL "LOONGARCH32_ILP32")
add_definitions(-DBUILD_TARGET_LOONGARCH32_ILP32)
elseif (WAMR_BUILD_TARGET STREQUAL "ARC")
add_definitions(-DBUILD_TARGET_ARC)
else ()
@ -55,7 +65,8 @@ 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.*")
OR WAMR_BUILD_TARGET MATCHES "AARCH64.*" OR WAMR_BUILD_TARGET MATCHES "RISCV64.*"
OR WAMR_BUILD_TARGET MATCHES "LOONGARCH64.*")
if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
# Add -fPIC flag if build as 64-bit
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
@ -317,11 +328,12 @@ else ()
message (" Wakeup of blocking operations enabled")
endif ()
if (WAMR_BUILD_SIMD EQUAL 1)
if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*")
if ((NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*")
AND (NOT WAMR_BUILD_TARGET MATCHES "LOONGARCH64.*"))
add_definitions (-DWASM_ENABLE_SIMD=1)
message (" SIMD enabled")
else ()
message (" SIMD disabled due to not supported on target RISCV64")
message (" SIMD disabled due to not supported on target RISCV64 or LOONGARCH64")
endif ()
endif ()
if (WAMR_BUILD_AOT_STACK_FRAME EQUAL 1)

View File

@ -31,11 +31,14 @@ endif ()
# Set WAMR_BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
# "LOONGARCH64[sub]", "LOONGARCH32[sub]"
if (NOT DEFINED WAMR_BUILD_TARGET)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)")
set (WAMR_BUILD_TARGET "AARCH64")
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
set (WAMR_BUILD_TARGET "RISCV64")
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "loongarch64")
set (WAMR_BUILD_TARGET "LOONGARCH64")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform
set (WAMR_BUILD_TARGET "X86_64")

View File

@ -22,6 +22,11 @@
&& !defined(BUILD_TARGET_RISCV32_ILP32D) \
&& !defined(BUILD_TARGET_RISCV32_ILP32F) \
&& !defined(BUILD_TARGET_RISCV32_ILP32) \
&& !defined(BUILD_TARGET_LOONGARCH64_LP64D) \
&& !defined(BUILD_TARGET_LOONGARCH64_LP64) \
&& !defined(BUILD_TARGET_LOONGARCH32_ILP32D) \
&& !defined(BUILD_TARGET_LOONGARCH32_ILP32F) \
&& !defined(BUILD_TARGET_LOONGARCH32_ILP32) \
&& !defined(BUILD_TARGET_ARC)
/* clang-format on */
#if defined(__x86_64__) || defined(__x86_64)
@ -50,6 +55,17 @@
#define BUILD_TARGET_RISCV32_ILP32F
#elif defined(__riscv) && (__riscv_xlen == 32) && (__riscv_flen == 64)
#define BUILD_TARGET_RISCV32_ILP32D
#elif defined(__loongarch) && (__loongarch_grlen == 64)
#define BUILD_TARGET_LOONGARCH64_LP64D
#elif defined(__loongarch) && (__loongarch_grlen == 32) \
&& (__loongarch_frlen == 0)
#define BUILD_TARGET_LOONGARCH32_ILP32
#elif defined(__loongarch) && (__loongarch_grlen == 32) \
&& (__loongarch_frlen == 32)
#define BUILD_TARGET_LOONGARCH32_ILP32F
#elif defined(__loongarch) && (__loongarch_grlen == 32) \
&& (__loongarch_frlen == 64)
#define BUILD_TARGET_LOONGARCH32_ILP32D
#elif defined(__arc__)
#define BUILD_TARGET_ARC
#else

View File

@ -867,6 +867,19 @@ aot_intrinsic_fill_capability_flags(AOTCompContext *comp_ctx)
add_i64_common_intrinsics(comp_ctx);
}
}
else if (!strncmp(comp_ctx->target_arch, "loongarch", 9)) {
add_intrinsic_capability(comp_ctx, AOT_INTRINSIC_FLAG_I32_CONST);
/*
* Note: Use builtin intrinsics since hardware float operation
* will cause rodata relocation
*/
add_f32_common_intrinsics(comp_ctx);
add_f64_common_intrinsics(comp_ctx);
add_common_float_integer_conversion(comp_ctx);
if (!strncmp(comp_ctx->target_arch, "loongarch32", 11)) {
add_i64_common_intrinsics(comp_ctx);
}
}
else if (!strncmp(comp_ctx->target_arch, "xtensa", 6)) {
/*
* Note: Use builtin intrinsics since hardware float operation

View File

@ -273,6 +273,7 @@ GET_U16_FROM_ADDR(const uint8 *p)
#define E_MACHINE_ARC_COMPACT2 195 /* Synopsys ARCompact V2 */
#define E_MACHINE_XTENSA 94 /* Tensilica Xtensa Architecture */
#define E_MACHINE_RISCV 243 /* RISC-V 32/64 */
#define E_MACHINE_LOONGARCH 253 /* LoongArch 32/64 */
#define E_MACHINE_WIN_I386 0x14c /* Windows i386 architecture */
#define E_MACHINE_WIN_X86_64 0x8664 /* Windows x86-64 architecture */
@ -303,7 +304,9 @@ loader_mmap(uint32 size, bool prot_exec, char *error_buf, uint32 error_buf_size)
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64)
|| defined(BUILD_TARGET_RISCV64_LP64) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64D) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64)
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX)
/* The mmapped AOT data and code in 64-bit targets had better be in
range 0 to 2G, or aot loader may fail to apply some relocations,
@ -421,6 +424,9 @@ get_aot_file_target(AOTTargetInfo *target_info, char *target_buf,
case E_MACHINE_RISCV:
machine_type = "riscv";
break;
case E_MACHINE_LOONGARCH:
machine_type = "loongarch";
break;
case E_MACHINE_ARC_COMPACT:
case E_MACHINE_ARC_COMPACT2:
machine_type = "arc";

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "aot_reloc.h"
static SymbolMap target_sym_map[] = {
/* clang-format off */
REG_COMMON_SYMBOLS
/* clang-format on */
};
void
get_current_target(char *target_buf, uint32 target_buf_size)
{
snprintf(target_buf, target_buf_size, "loongarch");
}
uint32
get_plt_item_size(void)
{
/* TODO */
return 0;
}
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)
{
/* TODO */
}
bool
apply_relocation(AOTModule *module, uint8 *target_section_addr,
uint32 target_section_size, uint64 reloc_offset,
int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
/* TODO */
return false;
}

View File

@ -70,14 +70,15 @@
#define EM_SH 42 /* SuperH */
#define EM_SPARCV9 43 /* SPARC v9 64-bit */
#define EM_H8_300 46
#define EM_IA_64 50 /* HP/Intel IA-64 */
#define EM_X86_64 62 /* AMD x86-64 */
#define EM_S390 22 /* IBM S/390 */
#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Renesas M32R */
#define EM_XTENSA 94 /* Tensilica Xtensa */
#define EM_RISCV 243 /* RISC-V */
#define EM_IA_64 50 /* HP/Intel IA-64 */
#define EM_X86_64 62 /* AMD x86-64 */
#define EM_S390 22 /* IBM S/390 */
#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Renesas M32R */
#define EM_XTENSA 94 /* Tensilica Xtensa */
#define EM_RISCV 243 /* RISC-V */
#define EM_LOONGARCH 253 /* LoongArch */
#define EM_ALPHA 0x9026
#define EM_CYGNUS_V850 0x9080
#define EM_CYGNUS_M32R 0x9041

View File

@ -25,6 +25,8 @@ 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)
elseif (WAMR_BUILD_TARGET MATCHES "LOONGARCH*")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_loongarch.c)
elseif (WAMR_BUILD_TARGET STREQUAL "ARC")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_arc.c)
else ()

View File

@ -0,0 +1,25 @@
/*
* 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:
*
* function ptr
* argv
* nstacks
*/
/* TODO */

View File

@ -89,6 +89,8 @@ elseif (WAMR_BUILD_TARGET STREQUAL "XTENSA")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_xtensa.s)
elseif (WAMR_BUILD_TARGET MATCHES "RISCV*")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_riscv.S)
elseif (WAMR_BUILD_TARGET MATCHES "LOONGARCH*")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_loongarch.S)
elseif (WAMR_BUILD_TARGET STREQUAL "ARC")
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_arc.s)
else ()

View File

@ -4869,7 +4869,10 @@ fail:
#if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP) \
|| defined(BUILD_TARGET_RISCV32_ILP32D) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_ARC)
|| defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32D) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32F) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32) || defined(BUILD_TARGET_ARC)
typedef void (*GenericFunctionPointer)(void);
void
invokeNative(GenericFunctionPointer f, uint32 *args, uint32 n_stacks);
@ -4917,7 +4920,9 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
bool is_aot_func = (NULL == signature);
#endif
#if !defined(BUILD_TARGET_RISCV32_ILP32) && !defined(BUILD_TARGET_ARC)
#if !defined(BUILD_TARGET_RISCV32_ILP32) !defined( \
BUILD_TARGET_LOONGARCH32_ILP32) \
&& !defined(BUILD_TARGET_ARC)
uint32 *fps;
int n_fps = 0;
#else
@ -4969,9 +4974,12 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
#endif
n_ints += 2;
}
#if defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_RISCV32_ILP32D) || defined(BUILD_TARGET_ARC)
#if defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_RISCV32_ILP32D) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32F) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32D) || defined(BUILD_TARGET_ARC)
/* part in register, part in stack */
else if (n_ints == MAX_REG_INTS - 1) {
n_ints++;
@ -4980,7 +4988,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
#endif
else {
/* 64-bit data in stack must be 8 bytes aligned
in arm and riscv32 */
in arm, riscv32 and loongarch32 */
#if !defined(BUILD_TARGET_ARC)
if (n_stacks & 1)
n_stacks++;
@ -4988,11 +4996,13 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
n_stacks += 2;
}
break;
#if !defined(BUILD_TARGET_RISCV32_ILP32D)
#if !defined(BUILD_TARGET_RISCV32_ILP32D) \
&& !defined(BUILD_TARGET_LOONGARCH32_ILP32D)
case VALUE_TYPE_F32:
if (n_fps < MAX_REG_FLOATS)
n_fps++;
#if defined(BUILD_TARGET_RISCV32_ILP32F)
#if defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32F)
else if (n_ints < MAX_REG_INTS) {
n_ints++;
}
@ -5001,8 +5011,10 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
n_stacks++;
break;
case VALUE_TYPE_F64:
#if defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) || defined(BUILD_TARGET_ARC)
#if defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32F) || defined(BUILD_TARGET_ARC)
if (n_ints < MAX_REG_INTS - 1) {
n_ints += 2;
}
@ -5025,7 +5037,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
#endif
else {
/* 64-bit data in stack must be 8 bytes aligned
in arm and riscv32 */
in arm, riscv32 and loongarch32 */
#if !defined(BUILD_TARGET_ARC)
if (n_stacks & 1)
n_stacks++;
@ -5033,7 +5045,8 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
n_stacks += 2;
}
break;
#else /* BUILD_TARGET_RISCV32_ILP32D */
#else /* else of !defined(BUILD_TARGET_RISCV32_ILP32D) \
&& !defined(BUILD_TARGET_LOONGARCH32_ILP32D) */
case VALUE_TYPE_F32:
case VALUE_TYPE_F64:
if (n_fps < MAX_REG_FLOATS) {
@ -5053,13 +5066,14 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
else {
/* 64-bit data in stack must be 8 bytes aligned in riscv32
*/
and loongarch32 */
if (n_stacks & 1)
n_stacks++;
n_stacks += 2;
}
break;
#endif /* BUILD_TARGET_RISCV32_ILP32D */
#endif /* end of !defined(BUILD_TARGET_RISCV32_ILP32D) \
&& !defined(BUILD_TARGET_LOONGARCH32_ILP32D) */
default:
bh_assert(0);
break;
@ -5074,11 +5088,14 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
#if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP) \
|| defined(BUILD_TARGET_RISCV32_ILP32F)
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32F)
argc1 = MAX_REG_INTS + MAX_REG_FLOATS + n_stacks;
#elif defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_ARC)
#elif defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32) || defined(BUILD_TARGET_ARC)
argc1 = MAX_REG_INTS + n_stacks;
#else /* for BUILD_TARGET_RISCV32_ILP32D */
#else /* for BUILD_TARGET_RISCV32_ILP32D and BUILD_TARGET_LOONGARCH32_ILP32D \
*/
argc1 = MAX_REG_INTS + MAX_REG_FLOATS * 2 + n_stacks;
#endif
@ -5092,12 +5109,15 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
ints = argv1;
#if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP) \
|| defined(BUILD_TARGET_RISCV32_ILP32F)
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32F)
fps = ints + MAX_REG_INTS;
stacks = fps + MAX_REG_FLOATS;
#elif defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_ARC)
#elif defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32) || defined(BUILD_TARGET_ARC)
stacks = ints + MAX_REG_INTS;
#else /* for BUILD_TARGET_RISCV32_ILP32D */
#else /* for BUILD_TARGET_RISCV32_ILP32D and BUILD_TARGET_LOONGARCH32_ILP32D \
*/
fps = ints + MAX_REG_INTS;
stacks = fps + MAX_REG_FLOATS * 2;
#endif
@ -5182,9 +5202,12 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
ints[n_ints++] = *argv_src++;
ints[n_ints++] = *argv_src++;
}
#if defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_RISCV32_ILP32D) || defined(BUILD_TARGET_ARC)
#if defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_RISCV32_ILP32D) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32F) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32D) || defined(BUILD_TARGET_ARC)
else if (n_ints == MAX_REG_INTS - 1) {
ints[n_ints++] = *argv_src++;
stacks[n_stacks++] = *argv_src++;
@ -5192,7 +5215,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
#endif
else {
/* 64-bit data in stack must be 8 bytes aligned
in arm and riscv32 */
in arm, riscv32 and loongarch32 */
#if !defined(BUILD_TARGET_ARC)
if (n_stacks & 1)
n_stacks++;
@ -5202,12 +5225,14 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
break;
}
#if !defined(BUILD_TARGET_RISCV32_ILP32D)
#if !defined(BUILD_TARGET_RISCV32_ILP32D) \
&& !defined(BUILD_TARGET_LOONGARCH32_ILP32D)
case VALUE_TYPE_F32:
{
if (n_fps < MAX_REG_FLOATS)
*(float32 *)&fps[n_fps++] = *(float32 *)argv_src++;
#if defined(BUILD_TARGET_RISCV32_ILP32F)
#if defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32F)
else if (n_ints < MAX_REG_INTS) {
ints[n_ints++] = *argv_src++;
}
@ -5218,8 +5243,10 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
case VALUE_TYPE_F64:
{
#if defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) || defined(BUILD_TARGET_ARC)
#if defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32F) || defined(BUILD_TARGET_ARC)
if (n_ints < MAX_REG_INTS - 1) {
ints[n_ints++] = *argv_src++;
ints[n_ints++] = *argv_src++;
@ -5244,7 +5271,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
#endif
else {
/* 64-bit data in stack must be 8 bytes aligned
in arm and riscv32 */
in arm, riscv32 and loongarch32 */
#if !defined(BUILD_TARGET_ARC)
if (n_stacks & 1)
n_stacks++;
@ -5254,7 +5281,8 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
break;
}
#else /* BUILD_TARGET_RISCV32_ILP32D */
#else /* else of !defined(BUILD_TARGET_RISCV32_ILP32D) \
&& !defined(BUILD_TARGET_LOONGARCH32_ILP32D) */
case VALUE_TYPE_F32:
case VALUE_TYPE_F64:
{
@ -5287,7 +5315,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
else {
/* 64-bit data in stack must be 8 bytes aligned in riscv32
*/
and loongarch32 */
if (n_stacks & 1)
n_stacks++;
if (func_type->types[i] == VALUE_TYPE_F32) {
@ -5302,7 +5330,8 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
break;
}
#endif /* BUILD_TARGET_RISCV32_ILP32D */
#endif /* end of !defined(BUILD_TARGET_RISCV32_ILP32D) \
&& !defined(BUILD_TARGET_LOONGARCH32_ILP32D) */
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
case VALUE_TYPE_EXTERNREF:
{
@ -5425,11 +5454,14 @@ fail:
wasm_runtime_free(argv1);
return ret;
}
#endif /* end of defined(BUILD_TARGET_ARM_VFP) \
|| defined(BUILD_TARGET_THUMB_VFP) \
|| defined(BUILD_TARGET_RISCV32_ILP32D) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_RISCV32_ILP32) \
#endif /* end of defined(BUILD_TARGET_ARM_VFP) \
|| defined(BUILD_TARGET_THUMB_VFP) \
|| defined(BUILD_TARGET_RISCV32_ILP32D) \
|| defined(BUILD_TARGET_RISCV32_ILP32F) \
|| defined(BUILD_TARGET_RISCV32_ILP32) \
|| defined(BUILD_TARGET_LOONGARCH32_ILP32D) \
|| defined(BUILD_TARGET_RLOONGARCH2_ILP32F) \
|| defined(BUILD_TARGET_RLOONGARCH2_ILP32) \
|| defined(BUILD_TARGET_ARC) */
#if defined(BUILD_TARGET_X86_32) || defined(BUILD_TARGET_ARM) \
@ -5689,7 +5721,9 @@ fail:
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64)
|| defined(BUILD_TARGET_RISCV64_LP64) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64D) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64)
#if WASM_ENABLE_SIMD != 0
#ifdef v128
@ -5709,7 +5743,9 @@ typedef union __declspec(intrin_type) __declspec(align(8)) v128 {
} v128;
#elif defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64)
|| defined(BUILD_TARGET_RISCV64_LP64) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64D) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64)
typedef long long v128
__attribute__((__vector_size__(16), __may_alias__, __aligned__(1)));
#elif defined(BUILD_TARGET_AARCH64)
@ -5754,13 +5790,17 @@ static V128FuncPtr invokeNative_V128 = (V128FuncPtr)(uintptr_t)invokeNative;
#else /* else of defined(_WIN32) || defined(_WIN32_) */
#define MAX_REG_FLOATS 8
#if defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64)
|| defined(BUILD_TARGET_RISCV64_LP64) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64D) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64)
#define MAX_REG_INTS 8
#else
#define MAX_REG_INTS 6
#endif /* end of defined(BUILD_TARGET_AARCH64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64) */
#endif /* end of defined(BUILD_TARGET_AARCH64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64D) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64) */
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
/*
@ -5793,17 +5833,19 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
bool is_aot_func = (NULL == signature);
#endif
#ifndef BUILD_TARGET_RISCV64_LP64
#if !defined(BUILD_TARGET_RISCV64_LP64) \
&& !defined(BUILD_TARGET_LOONGARCH64_LP64)
#if WASM_ENABLE_SIMD == 0
uint64 *fps;
#else
v128 *fps;
#endif
#else /* else of BUILD_TARGET_RISCV64_LP64 */
#else /* else of BUILD_TARGET_RISCV64_LP64/BUILD_TARGET_LOONGARCH64_LP64 */
#define fps ints
#endif /* end of BUILD_TARGET_RISCV64_LP64 */
#endif /* end of BUILD_TARGET_RISCV64_LP64/BUILD_TARGET_LOONGARCH64_LP64 */
#if defined(_WIN32) || defined(_WIN32_) || defined(BUILD_TARGET_RISCV64_LP64)
#if defined(_WIN32) || defined(_WIN32_) || defined(BUILD_TARGET_RISCV64_LP64) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64)
/* important difference in calling conventions */
#define n_fps n_ints
#else
@ -5824,7 +5866,8 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
}
}
#ifndef BUILD_TARGET_RISCV64_LP64
#if !defined(BUILD_TARGET_RISCV64_LP64) \
&& !defined(BUILD_TARGET_LOONGARCH64_LP64)
#if WASM_ENABLE_SIMD == 0
fps = argv1;
ints = fps + MAX_REG_FLOATS;
@ -5832,9 +5875,9 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
fps = (v128 *)argv1;
ints = (uint64 *)(fps + MAX_REG_FLOATS);
#endif
#else /* else of BUILD_TARGET_RISCV64_LP64 */
#else /* else of BUILD_TARGET_RISCV64_LP64/BUILD_TARGET_LOONGARCH64_LP64 */
ints = argv1;
#endif /* end of BUILD_TARGET_RISCV64_LP64 */
#endif /* end of BUILD_TARGET_RISCV64_LP64/BUILD_TARGET_LOONGARCH64_LP64 */
stacks = ints + MAX_REG_INTS;
ints[n_ints++] = (uint64)(uintptr_t)exec_env;
@ -6108,11 +6151,13 @@ fail:
return ret;
}
#endif /* end of defined(BUILD_TARGET_X86_64) \
|| defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64) */
#endif /* end of defined(BUILD_TARGET_X86_64) \
|| defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64) \
|| defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64D) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64) */
bool
wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32 element_index,

View File

@ -875,6 +875,12 @@ is_target_riscv(AOTCompContext *comp_ctx)
return !strncmp(comp_ctx->target_arch, "riscv", 5);
}
static bool
is_target_loongarch(AOTCompContext *comp_ctx)
{
return !strncmp(comp_ctx->target_arch, "loongarch", 9);
}
static bool
is_targeting_soft_float(AOTCompContext *comp_ctx, bool is_f32)
{
@ -909,7 +915,7 @@ is_targeting_soft_float(AOTCompContext *comp_ctx, bool is_f32)
else
ret = (!is_f32 || strstr(feature_string, "-fp")) ? true : false;
}
else if (is_target_riscv(comp_ctx)) {
else if (is_target_riscv(comp_ctx) || is_target_loongarch(comp_ctx)) {
/*
* Note: Use builtin intrinsics since hardware float operation
* will cause rodata relocation, this will try to use hardware

View File

@ -190,6 +190,13 @@ aot_target_precheck_can_use_musttail(const AOTCompContext *comp_ctx)
*/
return false;
}
if (strstr(comp_ctx->target_arch, "loongarch")) {
/*
* cf.
* https://github.com/bytecodealliance/wasm-micro-runtime/issues/2412
*/
return false;
}
/*
* x86-64/i386: true
*
@ -2205,7 +2212,9 @@ static ArchItem valid_archs[] = {
{ "thumbv8.1m.main", true },
{ "riscv32", true },
{ "riscv64", true },
{ "arc", true }
{ "arc", true },
{ "loongarch64", true },
{ "loongarch32", true }
};
static const char *valid_abis[] = {
@ -2817,10 +2826,10 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
}
/* Set default abi for riscv target */
if (arch && !strncmp(arch, "riscv", 5) && !abi) {
if (!strcmp(arch, "riscv64"))
if (arch && !abi) {
if (!strcmp(arch, "riscv64") || !strcmp(arch, "loongarch64"))
abi = "lp64d";
else
else if (!strcmp(arch, "riscv32") || !strcmp(arch, "loongarch32"))
abi = "ilp32d";
}
@ -2991,8 +3000,9 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
goto fail;
}
/* Add module flag and cpu feature for riscv target */
if (arch && !strncmp(arch, "riscv", 5)) {
/* Add module flag and cpu feature for riscv or loongarch target */
if (arch
&& (!strncmp(arch, "riscv", 5) || !strncmp(arch, "loongarch", 9))) {
LLVMMetadataRef meta_target_abi;
if (!(meta_target_abi = LLVMMDStringInContext2(comp_ctx->context,

View File

@ -90,7 +90,9 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
if (flags & MMAP_MAP_FIXED)
map_flags |= MAP_FIXED;
#if defined(BUILD_TARGET_RISCV64_LP64D) || defined(BUILD_TARGET_RISCV64_LP64)
#if defined(BUILD_TARGET_RISCV64_LP64D) || defined(BUILD_TARGET_RISCV64_LP64) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64D) \
|| defined(BUILD_TARGET_LOONGARCH64_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.
@ -134,7 +136,9 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
hint_addr += BH_MB;
}
}
#endif /* end of BUILD_TARGET_RISCV64_LP64D || BUILD_TARGET_RISCV64_LP64 */
#endif /* end of BUILD_TARGET_RISCV64_LP64D || BUILD_TARGET_RISCV64_LP64 \
|| BUILD_TARGET_LOONGARCH64_LP64D \
|| BUILD_TARGET_LOONGARCH64_LP64 */
/* memory hasn't been mapped or was mapped failed previously */
if (addr == MAP_FAILED) {

View File

@ -83,7 +83,9 @@ typedef sem_t korp_sem;
#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_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64)
|| defined(BUILD_TARGET_RISCV64_LP64) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64D) \
|| defined(BUILD_TARGET_LOONGARCH64_LP64)
#include <setjmp.h>
@ -111,7 +113,7 @@ os_signal_unmask();
void
os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64/LOONGARCH64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#define os_getpagesize getpagesize

View File

@ -112,13 +112,15 @@ 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(" riscv64, riscv32.\n");
printf(" riscv64, riscv32, loongarch64, loongarch32.\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, 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(" Default is gnu if target isn't riscv64, riscv32, loongarch64\n");
printf(" and loongarch32.\n");
printf(" For target riscv64 and loongarch64, default is lp64d\n");
printf(" For target riscv32 and loongarch32, default is 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");