@@ -282,6 +282,12 @@ static uptr riscv64_get_abs(void *address);
282
282
static void riscv64_set_jump (void * address , uptr item );
283
283
static uptr riscv64_get_jump (void * address );
284
284
#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 */
285
291
#ifdef PORTABLE_BYTECODE_SWAPENDIAN
286
292
static void swap_code_endian (octet * code , uptr len );
287
293
#endif
@@ -1486,6 +1492,17 @@ void S_set_code_obj(char *who, IFASLCODE typ, ptr p, iptr n, ptr x, iptr o) {
1486
1492
riscv64_set_jump (address , item );
1487
1493
break ;
1488
1494
#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 */
1489
1506
default :
1490
1507
S_error1 (who , "invalid relocation type ~s" , FIX (typ ));
1491
1508
}
@@ -1575,6 +1592,15 @@ ptr S_get_code_obj(IFASLCODE typ, ptr p, iptr n, iptr o) {
1575
1592
item = riscv64_get_jump (address );
1576
1593
break ;
1577
1594
#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 */
1578
1604
default :
1579
1605
S_error1 ("" , "invalid relocation type ~s" , FIX (typ ));
1580
1606
return (ptr )0 /* not reached */ ;
@@ -2042,6 +2068,52 @@ static void riscv64_set_jump(void* address, uptr item)
2042
2068
}
2043
2069
#endif /* RISCV64 */
2044
2070
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
+
2045
2117
#ifdef PORTABLE_BYTECODE_SWAPENDIAN
2046
2118
typedef struct {
2047
2119
octet * code ;
0 commit comments