feat(asm): encode indirect JMP and CALL on all four architectures
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -39,7 +39,7 @@ TEXT ·enterJITChecked(SB), NOSPLIT, $0-16
|
||||
MOVV 0(R5), R1 // load leaveJITCheckedRaw into RA
|
||||
MOVV R5, R3 // SP stays on the leave slot: the kernel
|
||||
// reads its first argument at SP+8
|
||||
JIRL R0, R4, 0 // jump to JIT function
|
||||
JMP (R4) // jump to JIT function
|
||||
|
||||
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
|
||||
// declaration, so no ABIInternal wrapper is generated; the JIT function's
|
||||
@@ -61,6 +61,6 @@ g_ok:
|
||||
MOVV savedRA(SB), R1 // restore return address
|
||||
MOVV savedG(SB), g // restore g: Go code needs it the moment it
|
||||
// resumes, violation or not
|
||||
JIRL R0, R1, 0 // return to Go caller
|
||||
JMP (R1) // return to Go caller
|
||||
|
||||
GLOBL savedG(SB), NOPTR, $8
|
||||
|
||||
@@ -25,6 +25,7 @@ func TestGroundTruthARM64(t *testing.T) {
|
||||
"../testdata/verify/call_arm64.s",
|
||||
"../testdata/verify/bigframe_arm64.s",
|
||||
"../testdata/verify/guard_arm64.s",
|
||||
"../testdata/verify/indirect_arm64.s",
|
||||
} {
|
||||
t.Run(path, func(t *testing.T) {
|
||||
src, err := os.ReadFile(path)
|
||||
|
||||
@@ -98,6 +98,7 @@ func TestGroundTruthAMD64(t *testing.T) {
|
||||
"../testdata/verify/basic_amd64.s",
|
||||
"../testdata/verify/bigframe_amd64.s",
|
||||
"../testdata/verify/guard_amd64.s",
|
||||
"../testdata/verify/indirect_amd64.s",
|
||||
} {
|
||||
t.Run(path, func(t *testing.T) {
|
||||
f, errs := parser.Parse(path, mustRead(t, path))
|
||||
|
||||
@@ -24,6 +24,8 @@ func TestGroundTruthLOONG64(t *testing.T) {
|
||||
"../testdata/verify/fp_loong64.s",
|
||||
"../testdata/verify/bigframe_loong64.s",
|
||||
"../testdata/verify/guard_loong64.s",
|
||||
"../testdata/verify/indirect_loong64.s",
|
||||
"trampoline_loong64.s",
|
||||
} {
|
||||
t.Run(path, func(t *testing.T) {
|
||||
src, err := os.ReadFile(path)
|
||||
|
||||
@@ -27,6 +27,8 @@ func TestGroundTruthRISCV(t *testing.T) {
|
||||
"../testdata/verify/call_riscv64.s",
|
||||
"../testdata/verify/bigframe_riscv64.s",
|
||||
"../testdata/verify/guard_riscv64.s",
|
||||
"../testdata/verify/indirect_riscv64.s",
|
||||
"trampoline_riscv64.s",
|
||||
} {
|
||||
t.Run(path, func(t *testing.T) {
|
||||
testGroundTruthRISCVFile(t, path)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// ABI0 JIT trampoline for LoongArch 64.
|
||||
//
|
||||
// enterJIT saves Go SP and RA (R1), switches to the prepared stack, and
|
||||
// jumps to the JIT function. When the function RETs (JIRL zero, ra, 0),
|
||||
// jumps to the JIT function. When the function RETs (JMP (R1), the toolchain's spelling for jirl zero, ra, 0),
|
||||
// control lands in leaveJIT.
|
||||
|
||||
// func enterJIT(fn uintptr, stack uintptr)
|
||||
@@ -19,14 +19,14 @@ TEXT ·enterJIT(SB), NOSPLIT, $0-16
|
||||
MOVV R5, R3 // switch to the prepared stack: SP stays on
|
||||
// the leave slot, so the kernel reads its
|
||||
// first argument at SP+8
|
||||
JIRL R0, R4, 0 // jump to JIT function
|
||||
JMP (R4) // jump to JIT function
|
||||
|
||||
// func leaveJIT()
|
||||
TEXT ·leaveJIT(SB), NOSPLIT, $0-0
|
||||
MOVV savedSP(SB), R5 // restore Go stack pointer
|
||||
MOVV R5, R3 // restore SP
|
||||
MOVV savedRA(SB), R1 // restore return address
|
||||
JIRL R0, R1, 0 // return to Go caller
|
||||
JMP (R1) // return to Go caller
|
||||
|
||||
GLOBL savedRA(SB), NOPTR, $8
|
||||
|
||||
|
||||
Reference in New Issue
Block a user