Skip to content

Commit 0654a2d

Browse files
authored
LoongArch64 Support (#754)
* Fix riscv64 asm-indirect-jump. * Add loongarch64 support. * Fix the `cas` primitive in riscv and loongarch backend to allow for offset value bigger than 12 bits.
1 parent 0274e27 commit 0654a2d

20 files changed

+2849
-28
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
/ti3*/
1616
/arm*/
1717
/tarm*/
18+
/rv64*/
19+
/trv64*/
20+
/la64*/
21+
/tla64*/
1822
/ppc*/
1923
/tppc*/
2024
/xc-*/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Supported platforms (bytecode interpreter may work for others):
1010

1111
* Windows: x86, x86_64, AArch64
1212
* Mac OS: x86, x86_64, AArch64, PowerPC32
13-
* Linux: x86, x86_64, ARMv6, AArch64, RV64G, PowerPC32
13+
* Linux: x86, x86_64, ARMv6, AArch64, RV64G, LoongArch64, PowerPC32
1414
* FreeBSD: x86, x86_64, ARMv6, AArch64, PowerPC32
1515
* OpenBSD: x86, x86_64, ARMv6, AArch64, PowerPC32
1616
* NetBSD: x86, x86_64, ARMv6, AArch64, PowerPC32

c/atomic.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
# define STORE_FENCE() __asm__ __volatile__ ("fence w,rw" : : : "memory")
3131
# define ACQUIRE_FENCE() __asm__ __volatile__ ("fence r,rw" : : : "memory")
3232
# define RELEASE_FENCE() __asm__ __volatile__ ("fence rw,r" : : : "memory")
33+
#elif defined(__loongarch64)
34+
# define STORE_FENCE() __asm__ __volatile__ ("dbar 0" : : : "memory")
35+
# define ACQUIRE_FENCE() __asm__ __volatile__ ("dbar 0" : : : "memory")
36+
# define RELEASE_FENCE() __asm__ __volatile__ ("dbar 0" : : : "memory")
3337
#else
3438
# define STORE_FENCE() do { } while (0)
3539
#endif
@@ -147,6 +151,8 @@ FORCEINLINE int S_cas_any_fence(volatile void *addr, void *old_val, void *new_va
147151
# define CAS_ANY_FENCE(a, old, new) S_cas_any_fence(a, old, new)
148152
#elif defined(__riscv)
149153
# error expected a compiler with a CS intrinsic for RISC-V
154+
#elif defined(__loongarch64)
155+
# error TODO
150156
#else
151157
# define CAS_ANY_FENCE(a, old, new) ((*(ptr *)(a) == TO_PTR(old)) ? (*(ptr *)(a) = TO_PTR(new), 1) : 0)
152158
#endif

c/build.zuo

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
[(string=? arch "rv64")
6060
(cons "RISCV64"
6161
"clearcache.c")]
62+
[(string=? arch "la64")
63+
(cons "LOONGARCH64"
64+
"clearcache.c")]
6265
[(glob-match? "pb*" arch)
6366
(cons "PORTABLE_BYTECODE"
6467
"pb.c")]

c/fasl.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,12 @@ static uptr riscv64_get_abs(void *address);
282282
static void riscv64_set_jump(void *address, uptr item);
283283
static uptr riscv64_get_jump(void *address);
284284
#endif /* RISCV64 */
285+
#ifdef LOONGARCH64
286+
static void loongarch64_set_abs(void *address, uptr item);
287+
static uptr loongarch64_get_abs(void *address);
288+
static void loongarch64_set_jump(void *address, uptr item);
289+
static uptr loongarch64_get_jump(void *address);
290+
#endif /* LOONGARCH64 */
285291
#ifdef PORTABLE_BYTECODE_SWAPENDIAN
286292
static void swap_code_endian(octet *code, uptr len);
287293
#endif
@@ -1486,6 +1492,17 @@ void S_set_code_obj(char *who, IFASLCODE typ, ptr p, iptr n, ptr x, iptr o) {
14861492
riscv64_set_jump(address, item);
14871493
break;
14881494
#endif /* RISCV64 */
1495+
#ifdef LOONGARCH64
1496+
case reloc_loongarch64_abs:
1497+
loongarch64_set_abs(address, item);
1498+
break;
1499+
case reloc_loongarch64_jump:
1500+
loongarch64_set_jump(address, item);
1501+
break;
1502+
case reloc_loongarch64_call:
1503+
loongarch64_set_jump(address, item);
1504+
break;
1505+
#endif /* LOONGARCH64 */
14891506
default:
14901507
S_error1(who, "invalid relocation type ~s", FIX(typ));
14911508
}
@@ -1575,6 +1592,15 @@ ptr S_get_code_obj(IFASLCODE typ, ptr p, iptr n, iptr o) {
15751592
item = riscv64_get_jump(address);
15761593
break;
15771594
#endif /* RISCV64 */
1595+
#ifdef LOONGARCH64
1596+
case reloc_loongarch64_abs:
1597+
item = loongarch64_get_abs(address);
1598+
break;
1599+
case reloc_loongarch64_jump:
1600+
case reloc_loongarch64_call:
1601+
item = loongarch64_get_jump(address);
1602+
break;
1603+
#endif /* LOONGARCH64 */
15781604
default:
15791605
S_error1("", "invalid relocation type ~s", FIX(typ));
15801606
return (ptr)0 /* not reached */;
@@ -2042,6 +2068,52 @@ static void riscv64_set_jump(void* address, uptr item)
20422068
}
20432069
#endif /* RISCV64 */
20442070

2071+
#ifdef LOONGARCH64
2072+
#define PCADDI_INSTR(dest, offset) ((0b1100 << 25) | ((offset) << 5) | (dest))
2073+
#define EXTRACT_LD_INSTR_DEST(instr) (instr & 0b11111)
2074+
#define JUMP_REG 12
2075+
2076+
static uptr loongarch64_get_abs(void* address)
2077+
{
2078+
return *((I64 *)((I32 *)address + 3));
2079+
}
2080+
2081+
static uptr loongarch64_get_jump(void* address)
2082+
{
2083+
return *((I64 *)((I32 *)address + 3));
2084+
}
2085+
2086+
static void loongarch64_set_abs(void* address, uptr item)
2087+
{
2088+
/*
2089+
[0] pcaddi dest 0
2090+
[1] ld.d dest dest 12
2091+
[2] b 12
2092+
[3-4] 8-bytes of addr
2093+
*/
2094+
2095+
// same as riscv64
2096+
int dest = EXTRACT_LD_INSTR_DEST(((I32 *)address)[1]);
2097+
((I32 *)address)[0] = PCADDI_INSTR(dest, 0);
2098+
(*((I64 *)((I32 *)address + 3))) = item;
2099+
}
2100+
2101+
static void loongarch64_set_jump(void* address, uptr item)
2102+
{
2103+
/*
2104+
[0] pcaddi dest 0
2105+
[1] ld.d dest dest 12
2106+
[2] b 12
2107+
[3-4] 8-bytes of addr
2108+
[5] jirl %real-zero dest 0
2109+
*/
2110+
2111+
int dest = EXTRACT_LD_INSTR_DEST(((I32 *)address)[1]);
2112+
((I32 *)address)[0] = PCADDI_INSTR(dest, 0);
2113+
(*((I64 *)((I32 *)address + 3))) = item;
2114+
}
2115+
#endif /* LOONGARCH64 */
2116+
20452117
#ifdef PORTABLE_BYTECODE_SWAPENDIAN
20462118
typedef struct {
20472119
octet *code;

c/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
# define FLUSHCACHE
4545
#endif
4646

47-
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(__riscv)
47+
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(__riscv) || defined(__loongarch64)
4848
# define FLUSHCACHE
4949
#endif
5050

configure

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ if [ "$unixsuffix" != "" ] ; then
209209
m64=rv64${unixsuffix}
210210
tm32=""
211211
tm64=trv64${unixsuffix}
212+
elif uname -m | grep 'loongarch64' > /dev/null 2>&1 ; then
213+
m32=""
214+
m64=la64${unixsuffix}
215+
tm32=""
216+
tm64=tla64${unixsuffix}
212217
else
213218
# using "unknown" helps at least select OS-based flags
214219
m32=unknown32${unixsuffix}
@@ -443,7 +448,7 @@ esac
443448

444449
if [ "$bits" = "" ] ; then
445450
# infer default bits; this will be irrelevant if a machine is specified
446-
if uname -m | egrep 'amd64|x86_64|aarch64|arm64|ppc64|powerpc64|riscv64' > /dev/null 2>&1 ; then
451+
if uname -m | egrep 'amd64|x86_64|aarch64|arm64|ppc64|powerpc64|riscv64|loongarch64' > /dev/null 2>&1 ; then
447452
bits=64
448453
# NetBSD `uname -m` produces "evbarm" for AArch64
449454
elif uname -p | egrep 'aarch64' > /dev/null 2>&1 ; then

makefiles/lib.zuo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
(and (>= (string-length uni) (string-length arch))
4646
(string=? (substring uni 0 (string-length arch)) arch)
4747
arch))
48-
'("a6" "i3" "arm64" "arm32" "ppc32" "rv64" "pb"))
48+
'("a6" "i3" "arm64" "arm32" "ppc32" "rv64" "la64" "pb"))
4949
(error "could not extract architecture from machine name" m))))
5050

5151
(define (hash-set* ht . keys+vals)

mats/bytevector.ms

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
[(i3le ti3le i3nt ti3nt a6nt ta6nt arm64nt tarm64nt i3ob ti3ob i3fb ti3fb i3nb ti3nb
3636
i3osx ti3osx a6le ta6le a6nb ta6nb
3737
a6osx ta6osx a6fb ta6fb a6ob ta6ob a6s2 ta6s2 i3s2 ti3s2 i3qnx ti3qnx
38-
arm32le tarm32le arm64le tarm64le arm64osx tarm64osx rv64le trv64le)
38+
arm32le tarm32le arm64le tarm64le arm64osx tarm64osx rv64le trv64le
39+
la64le tla64le)
3940
'little]
4041
[(ppc32le tppc32le ppc32osx tppc32osx) 'big]
4142
[(pb tpb) (native-endianness)]

mats/foreign.ms

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@
199199
(error? (load-shared-object 3))
200200
)
201201
]
202-
[(i3le ti3le a6le ta6le arm32le tarm32le arm64le tarm64le ppc32le tppc32le rv64le trv64le)
202+
[(i3le ti3le a6le ta6le arm32le tarm32le arm64le tarm64le ppc32le tppc32le rv64le trv64le la64le tla64le)
203203
(mat load-shared-object
204204
(file-exists? foreign1.so)
205205
(begin (load-shared-object foreign1.so) #t)
@@ -3085,7 +3085,7 @@
30853085
(machine-case
30863086
[(i3ob ti3ob a6ob ta6ob a6s2 ta6s2 i3s2 ti3s2 i3qnx ti3qnx i3nb ti3nb a6nb ta6nb)
30873087
'(load-shared-object "libc.so")]
3088-
[(i3le ti3le a6le ta6le arm32le tarm32le arm64le tarm64le ppc32le tppc32le rv64le trv64le)
3088+
[(i3le ti3le a6le ta6le arm32le tarm32le arm64le tarm64le ppc32le tppc32le rv64le trv64le la64le tla64le)
30893089
'(load-shared-object "libc.so.6")]
30903090
[(i3fb ti3fb a6fb ta6fb)
30913091
'(load-shared-object "libc.so.7")]

0 commit comments

Comments
 (0)