Skip to content

Commit da8c879

Browse files
authored
Implement riscv support for interpreter (#505)
1 parent 4c9cb30 commit da8c879

23 files changed

+805
-39
lines changed

build-scripts/config_common.cmake

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,24 @@ elseif (WAMR_BUILD_TARGET STREQUAL "MIPS")
3434
add_definitions(-DBUILD_TARGET_MIPS)
3535
elseif (WAMR_BUILD_TARGET STREQUAL "XTENSA")
3636
add_definitions(-DBUILD_TARGET_XTENSA)
37+
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64" OR WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64D")
38+
add_definitions(-DBUILD_TARGET_RISCV64_LP64D)
39+
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64")
40+
add_definitions(-DBUILD_TARGET_RISCV64_LP64)
41+
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32" OR WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32D")
42+
add_definitions(-DBUILD_TARGET_RISCV32_ILP32D)
43+
elseif (WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32")
44+
add_definitions(-DBUILD_TARGET_RISCV32_ILP32)
3745
else ()
38-
message (FATAL_ERROR "-- WAMR build target isn't set")
46+
message (FATAL_ERROR "-- WAMR build target isn't set")
3947
endif ()
4048

4149
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
4250
add_definitions(-DBH_DEBUG=1)
4351
endif ()
4452

4553
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
46-
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64" OR WAMR_BUILD_TARGET MATCHES "AARCH64.*")
54+
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.*")
4755
# Add -fPIC flag if build as 64-bit
4856
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
4957
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
@@ -55,10 +63,10 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
5563
endif ()
5664

5765
if (WAMR_BUILD_TARGET MATCHES "ARM.*")
58-
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -marm")
66+
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -marm")
5967
elseif (WAMR_BUILD_TARGET MATCHES "THUMB.*")
60-
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb")
61-
set (CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,-mthumb")
68+
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb")
69+
set (CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,-mthumb")
6270
endif ()
6371

6472
if (NOT WAMR_BUILD_INTERP EQUAL 1)

build-scripts/runtime_lib.cmake

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,14 @@ endif ()
3131
# Set default options
3232

3333
# Set WAMR_BUILD_TARGET, currently values supported:
34-
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", "MIPS", "XTENSA"
34+
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
35+
# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
3536
if (NOT DEFINED WAMR_BUILD_TARGET)
36-
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
37+
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
38+
set (WAMR_BUILD_TARGET "AARCH64")
39+
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
40+
set (WAMR_BUILD_TARGET "RISCV64")
41+
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
3742
# Build as X86_64 by default in 64-bit platform
3843
set (WAMR_BUILD_TARGET "X86_64")
3944
else ()
@@ -47,6 +52,11 @@ if (WAMR_BUILD_INTERP EQUAL 1 OR WAMR_BUILD_JIT EQUAL 1)
4752
include (${IWASM_DIR}/interpreter/iwasm_interp.cmake)
4853
endif ()
4954

55+
if (WAMR_BUILD_TARGET MATCHES "RISCV.*" AND WAMR_BUILD_AOT EQUAL 1)
56+
set (WAMR_BUILD_AOT 0)
57+
message ("-- WAMR AOT disabled as it isn't supported by riscv currently")
58+
endif ()
59+
5060
if (WAMR_BUILD_AOT EQUAL 1)
5161
include (${IWASM_DIR}/aot/iwasm_aot.cmake)
5262
if (WAMR_BUILD_JIT EQUAL 1)

core/config.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
&& !defined(BUILD_TARGET_THUMB) \
1616
&& !defined(BUILD_TARGET_THUMB_VFP) \
1717
&& !defined(BUILD_TARGET_MIPS) \
18-
&& !defined(BUILD_TARGET_XTENSA)
18+
&& !defined(BUILD_TARGET_XTENSA) \
19+
&& !defined(BUILD_TARGET_RISCV64_LP64D) \
20+
&& !defined(BUILD_TARGET_RISCV64_LP64) \
21+
&& !defined(BUILD_TARGET_RISCV32_ILP32D) \
22+
&& !defined(BUILD_TARGET_RISCV32_ILP32)
1923
#if defined(__x86_64__) || defined(__x86_64)
2024
#define BUILD_TARGET_X86_64
2125
#elif defined(__amd64__) || defined(__amd64)
@@ -34,6 +38,10 @@
3438
#define BUILD_TARGET_MIPS
3539
#elif defined(__XTENSA__)
3640
#define BUILD_TARGET_XTENSA
41+
#elif defined(__riscv) && (__riscv_xlen == 64)
42+
#define BUILD_TARGET_RISCV64_LP64D
43+
#elif defined(__riscv) && (__riscv_xlen == 32)
44+
#define BUILD_TARGET_RISCV32_ILP32D
3745
#else
3846
#error "Build target isn't set"
3947
#endif
@@ -224,7 +232,7 @@
224232

225233
/* Default min/max heap size of each app */
226234
#define APP_HEAP_SIZE_DEFAULT (8 * 1024)
227-
#define APP_HEAP_SIZE_MIN (512)
235+
#define APP_HEAP_SIZE_MIN (256)
228236
#define APP_HEAP_SIZE_MAX (512 * 1024 * 1024)
229237

230238
/* Default wasm stack size of each app */

core/iwasm/aot/aot_reloc.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ typedef struct {
4444
REG_SYM(aot_call_indirect), \
4545
REG_SYM(wasm_runtime_enlarge_memory), \
4646
REG_SYM(wasm_runtime_set_exception), \
47-
REG_SYM(aot_memset), \
48-
REG_SYM(aot_memmove), \
47+
{"memset", (void*)aot_memset}, \
48+
{"memmove", (void*)aot_memmove}, \
4949
REG_BULK_MEMORY_SYM() \
5050
REG_ATOMIC_WAIT_SYM() \
5151
REG_AOT_TRACE_SYM()
@@ -56,8 +56,8 @@ typedef struct {
5656
REG_SYM(aot_call_indirect), \
5757
REG_SYM(wasm_runtime_enlarge_memory), \
5858
REG_SYM(wasm_runtime_set_exception), \
59-
REG_SYM(aot_memset), \
60-
REG_SYM(aot_memmove), \
59+
{"memset", (void*)aot_memset}, \
60+
{"memmove", (void*)aot_memmove}, \
6161
REG_SYM(fmin), \
6262
REG_SYM(fminf), \
6363
REG_SYM(fmax), \
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright (C) 2019 Intel Corporation. All rights reserved.
3+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
*/
5+
.text
6+
.align 2
7+
#ifndef BH_PLATFORM_DARWIN
8+
.globl invokeNative
9+
.type invokeNative, function
10+
invokeNative:
11+
#else
12+
.globl _invokeNative
13+
_invokeNative:
14+
#endif /* end of BH_PLATFORM_DARWIN */
15+
16+
17+
/*
18+
* Arguments passed in:
19+
*
20+
* a0 function ptr
21+
* a1 argv
22+
* a2 nstacks
23+
*/
24+
25+
/*
26+
* sp (stack pointer)
27+
* |- sw to store 32-bit values from register to memory
28+
* |- lw to load from stack to register
29+
* fp/s0 (frame pointer)
30+
* a0-a7 (8 integer arguments)
31+
* |- sw to store
32+
* |- lw to load
33+
* t0-t6 (temporaries regisgers)
34+
* |- caller saved
35+
*/
36+
37+
/* reserve space on stack to save return address and frame pointer */
38+
addi sp, sp, -8
39+
sw fp, 0(sp) /* save frame pointer */
40+
sw ra, 4(sp) /* save return address */
41+
42+
mv fp, sp /* set frame pointer to bottom of fixed frame */
43+
44+
/* save function ptr, argv & nstacks */
45+
mv t0, a0 /* t0 = function ptr */
46+
mv t1, a1 /* t1 = argv array address */
47+
mv t2, a2 /* t2 = nstack */
48+
49+
/* fill in a0-7 integer-registers */
50+
lw a0, 0(t1) /* a0 = argv[0] */
51+
lw a1, 4(t1) /* a1 = argv[1] */
52+
lw a2, 8(t1) /* a2 = argv[2] */
53+
lw a3, 12(t1) /* a3 = argv[3] */
54+
lw a4, 16(t1) /* a4 = argv[4] */
55+
lw a5, 20(t1) /* a5 = argv[5] */
56+
lw a6, 24(t1) /* a6 = argv[6] */
57+
lw a7, 28(t1) /* a7 = argv[7] */
58+
59+
addi t1, t1, 32 /* t1 points to stack args */
60+
61+
/* directly call the function if no args in stack,
62+
x0 always holds 0 */
63+
beq t2, x0, call_func
64+
65+
/* reserve enough stack space for function arguments */
66+
sll t3, t2, 2 /* shift left 2 bits. t3 = n_stacks * 4 */
67+
sub sp, sp, t3
68+
69+
/* make 16-byte aligned */
70+
and sp, sp, ~15
71+
72+
/* save sp in t4 register */
73+
mv t4, sp
74+
75+
/* copy left arguments from caller stack to own frame stack */
76+
loop_stack_args:
77+
beq t2, x0, call_func
78+
lw t5, 0(t1) /* load stack argument, t5 = argv[i] */
79+
sw t5, 0(t4) /* store t5 to reseved stack, sp[j] = t5 */
80+
addi t1, t1, 4 /* move to next stack argument */
81+
addi t4, t4, 4 /* move to next stack pointer */
82+
addi t2, t2, -1 /* decrease t2 every loop, nstacks = nstacks -1 */
83+
j loop_stack_args
84+
85+
call_func:
86+
jalr t0
87+
88+
/* restore registers pushed in stack or saved in another register */
89+
return:
90+
mv sp, fp /* restore sp saved in fp before function call */
91+
lw fp, 0(sp) /* load previous frame poniter to fp register */
92+
lw ra, 4(sp) /* load previous return address to ra register */
93+
addi sp, sp, 8 /* pop frame, restore sp */
94+
jr ra
95+
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright (C) 2019 Intel Corporation. All rights reserved.
3+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
*/
5+
.text
6+
.align 2
7+
#ifndef BH_PLATFORM_DARWIN
8+
.globl invokeNative
9+
.type invokeNative, function
10+
invokeNative:
11+
#else
12+
.globl _invokeNative
13+
_invokeNative:
14+
#endif /* end of BH_PLATFORM_DARWIN */
15+
16+
17+
/*
18+
* Arguments passed in:
19+
*
20+
* a0 function ptr
21+
* a1 argv
22+
* a2 nstacks
23+
*/
24+
25+
/*
26+
* sp (stack pointer)
27+
* |- sw to store 32-bit values from register to memory
28+
* |- lw to load from stack to register
29+
* fp/s0 (frame pointer)
30+
* a0-a7 (8 integer arguments)
31+
* |- sw to store
32+
* |- lw to load
33+
* t0-t6 (temporaries regisgers)
34+
* |- caller saved
35+
*/
36+
37+
/* reserve space on stack to save return address and frame pointer */
38+
addi sp, sp, -8
39+
sw fp, 0(sp) /* save frame pointer */
40+
sw ra, 4(sp) /* save return address */
41+
42+
mv fp, sp /* set frame pointer to bottom of fixed frame */
43+
44+
/* save function ptr, argv & nstacks */
45+
mv t0, a0 /* t0 = function ptr */
46+
mv t1, a1 /* t1 = argv array address */
47+
mv t2, a2 /* t2 = nstack */
48+
49+
/* fill in a0-7 integer-registers */
50+
lw a0, 0(t1) /* a0 = argv[0] */
51+
lw a1, 4(t1) /* a1 = argv[1] */
52+
lw a2, 8(t1) /* a2 = argv[2] */
53+
lw a3, 12(t1) /* a3 = argv[3] */
54+
lw a4, 16(t1) /* a4 = argv[4] */
55+
lw a5, 20(t1) /* a5 = argv[5] */
56+
lw a6, 24(t1) /* a6 = argv[6] */
57+
lw a7, 28(t1) /* a7 = argv[7] */
58+
59+
/* fill in fa0-7 float-registers*/
60+
fld fa0, 32(t1) /* fa0 = argv[8] */
61+
fld fa1, 40(t1) /* fa1 = argv[9] */
62+
fld fa2, 48(t1) /* fa2 = argv[10] */
63+
fld fa3, 56(t1) /* fa3 = argv[11] */
64+
fld fa4, 64(t1) /* fa4 = argv[12] */
65+
fld fa5, 72(t1) /* fa5 = argv[13] */
66+
fld fa6, 80(t1) /* fa6 = argv[14] */
67+
fld fa7, 88(t1) /* fa7 = argv[15] */
68+
69+
addi t1, t1, 96 /* t1 points to stack args */
70+
71+
/* directly call the function if no args in stack,
72+
x0 always holds 0 */
73+
beq t2, x0, call_func
74+
75+
/* reserve enough stack space for function arguments */
76+
sll t3, t2, 2 /* shift left 2 bits. t3 = n_stacks * 4 */
77+
sub sp, sp, t3
78+
79+
/* make 16-byte aligned */
80+
and sp, sp, ~15
81+
82+
/* save sp in t4 register */
83+
mv t4, sp
84+
85+
/* copy left arguments from caller stack to own frame stack */
86+
loop_stack_args:
87+
beq t2, x0, call_func
88+
lw t5, 0(t1) /* load stack argument, t5 = argv[i] */
89+
sw t5, 0(t4) /* store t5 to reseved stack, sp[j] = t5 */
90+
addi t1, t1, 4 /* move to next stack argument */
91+
addi t4, t4, 4 /* move to next stack pointer */
92+
addi t2, t2, -1 /* decrease t2 every loop, nstacks = nstacks -1 */
93+
j loop_stack_args
94+
95+
call_func:
96+
jalr t0
97+
98+
/* restore registers pushed in stack or saved in another register */
99+
return:
100+
mv sp, fp /* restore sp saved in fp before function call */
101+
lw fp, 0(sp) /* load previous frame poniter to fp register */
102+
lw ra, 4(sp) /* load previous return address to ra register */
103+
addi sp, sp, 8 /* pop frame, restore sp */
104+
jr ra

0 commit comments

Comments
 (0)