Skip to content

Commit fcefadf

Browse files
Merge pull request #112 from janweinstock/dev-riscv
Adding riscv64 support
2 parents 68edea8 + d8d28d9 commit fcefadf

File tree

5 files changed

+177
-0
lines changed

5 files changed

+177
-0
lines changed

CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,8 @@ elseif (HAS__i386_DEFINED)
424424
set (QT_ARCH "i386")
425425
elseif (HAS__aarch64__DEFINED)
426426
set (QT_ARCH "aarch64")
427+
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64")
428+
set (QT_ARCH "riscv64")
427429
else (ENABLE_PTHREADS)
428430
message (WARNING "QuickThreads is not supported on ${CMAKE_SYSTEM} on ${CMAKE_SYSTEM_PROCESSOR}.")
429431
set (QT_ARCH "IGNORE")

src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ set(SYSTEMC_CORE_SRC
415415
$<$<STREQUAL:${QT_ARCH},x86_64>:sysc/packages/qt/md/iX86_64.s>
416416
$<$<STREQUAL:${QT_ARCH},i386>:sysc/packages/qt/md/i386.s>
417417
$<$<STREQUAL:${QT_ARCH},aarch64>:sysc/packages/qt/md/aarch64.s>
418+
$<$<STREQUAL:${QT_ARCH},riscv64>:sysc/packages/qt/md/riscv64.s>
418419
$<$<STREQUAL:${QT_ARCH},multi>:sysc/packages/qt/md/multi.s>
419420
sysc/packages/qt/md/aarch64.h
420421
sysc/packages/qt/md/i386.h

src/sysc/packages/qt/md/riscv64.h

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#ifndef QUICKTHREADS_RISCV64_H
2+
#define QUICKTHREADS_RISCV64_H
3+
4+
// For QUICKTHREADS_SPUT in qt.h
5+
typedef unsigned long qt_word_t;
6+
7+
extern void qt_start(void);
8+
extern void qt_vstart(void);
9+
10+
extern void qt_error(void);
11+
extern void qt_align(void);
12+
13+
// Stack must be 16-byte aligned at all times.
14+
#define QUICKTHREADS_STKALIGN (16)
15+
#define QUICKTHREADS_STKBASE (26 * sizeof(qt_word_t))
16+
#define QUICKTHREADS_VSTKBASE (5 * sizeof(qt_word_t))
17+
18+
#define QUICKTHREADS_GROW_DOWN
19+
#define QUICKTHREADS_ADJ(sp) (((char *)sp) - QUICKTHREADS_STKBASE)
20+
21+
// Initialize a single-argument thread.
22+
//
23+
// Set up link index to point to the true initializer, qt_start,
24+
// which will call only(pu, pt, userf) read from the stack.
25+
//
26+
// (*helper)(old_sp, a0, a1) will be called in between on the current
27+
// stack, so FRAME_INDEX needs to be correct and the other values
28+
// appropriately stored.
29+
#define QUICKTHREADS_ARGS(sp, pu, pt, userf, only) \
30+
(QUICKTHREADS_SPUT(QUICKTHREADS_ADJ(sp), QUICKTHREADS_LINK_INDEX, qt_start), \
31+
QUICKTHREADS_SPUT(QUICKTHREADS_ADJ(sp), QUICKTHREADS_FRAME_INDEX, sp), \
32+
QUICKTHREADS_SPUT(QUICKTHREADS_ADJ(sp), QUICKTHREADS_ONLY_INDEX, only), \
33+
QUICKTHREADS_SPUT(QUICKTHREADS_ADJ(sp), QUICKTHREADS_USER_INDEX, userf), \
34+
QUICKTHREADS_SPUT(QUICKTHREADS_ADJ(sp), QUICKTHREADS_ARGT_INDEX, pt), \
35+
QUICKTHREADS_SPUT(QUICKTHREADS_ADJ(sp), QUICKTHREADS_ARGU_INDEX, pu), \
36+
((qt_t *)QUICKTHREADS_ADJ(sp)))
37+
38+
#define QUICKTHREADS_LINK_INDEX 0 // ra; standard
39+
#define QUICKTHREADS_FRAME_INDEX 1 // fp; standard
40+
#define QUICKTHREADS_ONLY_INDEX 2 // s1; arbitrary
41+
#define QUICKTHREADS_USER_INDEX 3 // s2; arbitrary
42+
#define QUICKTHREADS_ARGT_INDEX 4 // s3; arbitrary
43+
#define QUICKTHREADS_ARGU_INDEX 5 // s4; arbitrary
44+
45+
#endif // QUICKTHREADS_RISCV64_H

src/sysc/packages/qt/md/riscv64.s

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# QuickThreads -- Threads-building toolkit.
2+
# Copyright (c) 1993 by David Keppel
3+
#
4+
# Permission to use, copy, modify and distribute this software and
5+
# its documentation for any purpose and without fee is hereby
6+
# granted, provided that the above copyright notice and this notice
7+
# appear in all copies. This software is provided as a
8+
# proof-of-concept and for demonstration purposes; there is no
9+
# representation about the suitability of this software for any
10+
# purpose.
11+
#
12+
# 64-bit RISC-V Architecture Support
13+
# written by Jan Henrik Weinstock, MachineWare GmbH
14+
15+
.text
16+
.align 2
17+
18+
# qt_block and qt_blocki can be called from C via:
19+
#
20+
# void* qt_block(qt_helper_t* h, void* a0, void* a1, qt_t* newthread);
21+
# void* qt_blocki(qt_helper_t* h, void* a0, void* a1, qt_t* newthread);
22+
#
23+
# qt_blocki should only save integer registers (not used by SystemC)
24+
# symbols with leading "_" needed for SystemV compatiblity
25+
.globl _qt_blocki
26+
.globl qt_blocki
27+
.globl _qt_block
28+
.globl qt_block
29+
_qt_block:
30+
qt_block:
31+
_qt_blocki:
32+
qt_blocki:
33+
# Allocate stack frame for 13 integer and 12 fp-registers, 16 byte aligned
34+
addi sp, sp, -208
35+
36+
# Save non-volatile integer registers (ra, fp, s1-s11)
37+
sd ra, 0(sp)
38+
sd fp, 8(sp) # s0 / frame pointer
39+
sd s1, 16(sp)
40+
sd s2, 24(sp)
41+
sd s3, 32(sp)
42+
sd s4, 40(sp)
43+
sd s5, 48(sp)
44+
sd s6, 56(sp)
45+
sd s7, 64(sp)
46+
sd s8, 72(sp)
47+
sd s9, 80(sp)
48+
sd s10, 88(sp)
49+
sd s11, 96(sp)
50+
51+
# Save non-volatile floating point registers (fs0-fs11)
52+
fsd fs0, 104(sp)
53+
fsd fs1, 112(sp)
54+
fsd fs2, 120(sp)
55+
fsd fs3, 128(sp)
56+
fsd fs4, 136(sp)
57+
fsd fs5, 144(sp)
58+
fsd fs6, 152(sp)
59+
fsd fs7, 160(sp)
60+
fsd fs8, 168(sp)
61+
fsd fs9, 176(sp)
62+
fsd fs10, 184(sp)
63+
fsd fs11, 192(sp)
64+
65+
# Call our helper function to save the old stack in memory
66+
mv t0, a0 # Save our qt_helper_t* h from arg0
67+
mv a0, sp # arg0: old thread's stack pointer
68+
mv sp, a3 # we run this already on the new stack
69+
jalr t0
70+
71+
# Restore non-volatile floating-point registers (fs0-fs11)
72+
fld fs11, 192(sp)
73+
fld fs10, 184(sp)
74+
fld fs9, 176(sp)
75+
fld fs8, 168(sp)
76+
fld fs7, 160(sp)
77+
fld fs6, 152(sp)
78+
fld fs5, 144(sp)
79+
fld fs4, 136(sp)
80+
fld fs3, 128(sp)
81+
fld fs2, 120(sp)
82+
fld fs1, 112(sp)
83+
fld fs0, 104(sp)
84+
85+
# Restore non-volatile integer registers (ra, fp, s1-s11)
86+
ld s11, 96(sp)
87+
ld s10, 88(sp)
88+
ld s9, 80(sp)
89+
ld s8, 72(sp)
90+
ld s7, 64(sp)
91+
ld s6, 56(sp)
92+
ld s5, 48(sp)
93+
ld s4, 40(sp)
94+
ld s3, 32(sp)
95+
ld s2, 24(sp)
96+
ld s1, 16(sp)
97+
ld fp, 8(sp) # s0 / frame pointer
98+
ld ra, 0(sp)
99+
100+
# Deallocate the stack frame and return to new stack
101+
addi sp, sp, 208
102+
ret
103+
104+
105+
# qt_start will be used as the return address (in ra) of our initial stack
106+
# frame, so we have something to return to in the beginning; it then
107+
# collects the thread init func and its arguments from the restored stack
108+
# frame (from whichever registers those ended up in) and then jumps there
109+
# see QUICKTHREAD_ARGS in riscv64.h
110+
.globl _qt_start
111+
.globl qt_start
112+
_qt_start:
113+
qt_start:
114+
mv a0, s4
115+
mv a1, s3
116+
mv a2, s2
117+
jalr s1
118+
call qt_error
119+
120+
121+
.globl _qt_abort
122+
.globl qt_abort
123+
_qt_abort:
124+
qt_abort:
125+
call qt_block

src/sysc/packages/qt/qtmd.h

+4
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,8 @@
1212
#include "sysc/packages/qt/md/powerpc_sys5.h"
1313
#elif defined( __aarch64__ )
1414
#include "sysc/packages/qt/md/aarch64.h"
15+
#elif defined( __riscv ) && ( __riscv_xlen == 64 )
16+
#include "sysc/packages/qt/md/riscv64.h"
17+
#else
18+
#error "Unknown architecture!"
1519
#endif

0 commit comments

Comments
 (0)