style: put the repository assembly in gasm fmt canonical form
Assisted-by: GLM 5.3 Flash
This commit is contained in:
+19
-19
@@ -17,32 +17,32 @@
|
||||
// - R14 holds the goroutine pointer and must survive across any call.
|
||||
|
||||
// Sentinel values chosen to be unlikely in normal execution.
|
||||
#define SENTINEL_BP 0xDEADBEEFCAFEF00D
|
||||
#define SENTINEL_BP 0xDEADBEEFCAFEF00D
|
||||
#define SENTINEL_R14 0x0BADF00DDEADBEEF
|
||||
|
||||
// GLOBL holding the raw address of the leave trampoline, read by Go.
|
||||
GLOBL ·leaveCheckedPtr(SB), NOPTR, $8
|
||||
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
|
||||
// func enterJITChecked(fn uintptr, stack uintptr)
|
||||
// Sets sentinels in BP and R14, switches to the prepared stack and jumps
|
||||
// to fn. The prepared stack's return address must be leaveJITCheckedRaw
|
||||
// (read from leaveCheckedPtr).
|
||||
TEXT ·enterJITChecked(SB), NOSPLIT, $0-16
|
||||
MOVQ fn+0(FP), AX // target (before SP switch)
|
||||
MOVQ SP, ·savedSP(SB) // preserve Go stack
|
||||
MOVQ BP, ·savedBP(SB) // preserve frame pointer (vet requires save before clobber)
|
||||
MOVQ R14, ·savedR14(SB) // preserve the goroutine pointer
|
||||
MOVQ $SENTINEL_BP, BP // sentinel in BP
|
||||
MOVQ $SENTINEL_R14, R14 // sentinel in R14
|
||||
MOVQ stack+8(FP), SP // switch to prepared stack
|
||||
MOVQ fn+0(FP), AX // target (before SP switch)
|
||||
MOVQ SP, ·savedSP(SB) // preserve Go stack
|
||||
MOVQ BP, ·savedBP(SB) // preserve frame pointer (vet requires save before clobber)
|
||||
MOVQ R14, ·savedR14(SB) // preserve the goroutine pointer
|
||||
MOVQ $SENTINEL_BP, BP // sentinel in BP
|
||||
MOVQ $SENTINEL_R14, R14 // sentinel in R14
|
||||
MOVQ stack+8(FP), SP // switch to prepared stack
|
||||
JMP AX
|
||||
|
||||
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
|
||||
// declaration, so no ABIInternal wrapper is generated; the JIT function's
|
||||
// RET lands here directly, seeing BP and R14 exactly as the function left
|
||||
// them. It checks the sentinels, records violations in abiResult, then
|
||||
// restores the Go stack and returns.
|
||||
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
|
||||
// declaration, so no ABIInternal wrapper is generated; the JIT function's
|
||||
// RET lands here directly, seeing BP and R14 exactly as the function left
|
||||
// them. It checks the sentinels, records violations in abiResult, then
|
||||
// restores the Go stack and returns.
|
||||
TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
|
||||
// Check BP against the sentinel.
|
||||
MOVQ $SENTINEL_BP, CX
|
||||
@@ -58,10 +58,10 @@ bp_ok:
|
||||
ORQ $2, ·abiResult(SB)
|
||||
|
||||
r14_ok:
|
||||
MOVQ ·savedR14(SB), R14 // restore the goroutine pointer: the runtime
|
||||
// needs it the moment Go code resumes, whether
|
||||
// or not the kernel violated it (the violation
|
||||
// is already recorded in abiResult)
|
||||
MOVQ ·savedBP(SB), BP // restore the frame pointer
|
||||
MOVQ ·savedR14(SB), R14 // restore the goroutine pointer: the runtime
|
||||
// needs it the moment Go code resumes, whether
|
||||
// or not the kernel violated it (the violation
|
||||
// is already recorded in abiResult)
|
||||
MOVQ ·savedBP(SB), BP // restore the frame pointer
|
||||
MOVQ ·savedSP(SB), SP
|
||||
RET
|
||||
|
||||
+30
-27
@@ -21,12 +21,12 @@
|
||||
// cannot cover it.
|
||||
|
||||
// Sentinel values chosen to be unlikely in normal execution.
|
||||
#define SENTINEL_FP 0xDEADBEEFCAFEF00D
|
||||
#define SENTINEL_G 0x0BADF00DDEADBEEF
|
||||
#define SENTINEL_FP 0xDEADBEEFCAFEF00D
|
||||
#define SENTINEL_G 0x0BADF00DDEADBEEF
|
||||
|
||||
// GLOBL holding the raw address of the leave trampoline, read by Go.
|
||||
GLOBL ·leaveCheckedPtr(SB), NOPTR, $8
|
||||
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
|
||||
// func enterJITChecked(fn uintptr, stack uintptr)
|
||||
// Sets sentinels in R29, R28 and R18, switches to the prepared stack and
|
||||
@@ -34,26 +34,26 @@ DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
// leaveJITCheckedRaw (read from leaveCheckedPtr). Only R0 and R3 are used
|
||||
// as scratch: caller-saved, and not among the checked registers.
|
||||
TEXT ·enterJITChecked(SB), NOSPLIT, $0-16
|
||||
MOVD fn+0(FP), R0 // target (before SP switch)
|
||||
MOVD R30, savedLR(SB) // save link register
|
||||
MOVD R3, savedSP(SB) // save Go stack pointer
|
||||
MOVD R29, savedFP(SB) // save frame pointer (vet requires save before clobber)
|
||||
MOVD g, savedG(SB) // save g
|
||||
MOVD $SENTINEL_FP, R29 // sentinel in the frame pointer
|
||||
MOVD $SENTINEL_G, g // sentinel in g
|
||||
MOVD stack+8(FP), R3 // load prepared stack pointer
|
||||
MOVD 0(R3), R30 // load leaveJITCheckedRaw into LR
|
||||
MOVD R3, RSP // SP stays on the leave slot: the kernel
|
||||
// reads its first argument at SP+8
|
||||
JMP (R0) // branch to JIT function
|
||||
MOVD fn+0(FP), R0 // target (before SP switch)
|
||||
MOVD R30, savedLR(SB) // save link register
|
||||
MOVD R3, savedSP(SB) // save Go stack pointer
|
||||
MOVD R29, savedFP(SB) // save frame pointer (vet requires save before clobber)
|
||||
MOVD g, savedG(SB) // save g
|
||||
MOVD $SENTINEL_FP, R29 // sentinel in the frame pointer
|
||||
MOVD $SENTINEL_G, g // sentinel in g
|
||||
MOVD stack+8(FP), R3 // load prepared stack pointer
|
||||
MOVD 0(R3), R30 // load leaveJITCheckedRaw into LR
|
||||
MOVD R3, RSP // SP stays on the leave slot: the kernel
|
||||
// reads its first argument at SP+8
|
||||
JMP (R0) // branch 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
|
||||
// RET lands here directly, seeing R29 and g exactly as the function left
|
||||
// them. It checks the sentinels, records violations in abiResult, then
|
||||
// restores the Go stack and returns.
|
||||
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
|
||||
// declaration, so no ABIInternal wrapper is generated; the JIT function's
|
||||
// RET lands here directly, seeing R29 and g exactly as the function left
|
||||
// them. It checks the sentinels, records violations in abiResult, then
|
||||
// restores the Go stack and returns.
|
||||
TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
|
||||
MOVD $0, R4 // accumulated violation bits
|
||||
MOVD $0, R4 // accumulated violation bits
|
||||
|
||||
// Check the frame pointer against the sentinel.
|
||||
MOVD $SENTINEL_FP, R3
|
||||
@@ -61,6 +61,7 @@ TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
|
||||
BEQ fp_ok
|
||||
MOVD $1, R5
|
||||
ORR R5, R4, R4
|
||||
|
||||
fp_ok:
|
||||
// Check g against the sentinel.
|
||||
MOVD $SENTINEL_G, R3
|
||||
@@ -68,22 +69,24 @@ fp_ok:
|
||||
BEQ g_ok
|
||||
MOVD $2, R5
|
||||
ORR R5, R4, R4
|
||||
|
||||
g_ok:
|
||||
CBZ R4, restore
|
||||
MOVD R4, ·abiResult(SB)
|
||||
|
||||
restore:
|
||||
MOVD savedSP(SB), R3 // restore Go stack pointer
|
||||
MOVD savedSP(SB), R3 // restore Go stack pointer
|
||||
MOVD R3, RSP
|
||||
MOVD savedLR(SB), R30 // restore link register
|
||||
MOVD savedFP(SB), R29 // restore frame pointer: Go code needs it the
|
||||
// moment it resumes, violation or not
|
||||
MOVD savedG(SB), g // restore g
|
||||
RET // return to Go caller
|
||||
MOVD savedLR(SB), R30 // restore link register
|
||||
MOVD savedFP(SB), R29 // restore frame pointer: Go code needs it the
|
||||
// moment it resumes, violation or not
|
||||
MOVD savedG(SB), g // restore g
|
||||
RET // return to Go caller
|
||||
|
||||
// Package-level storage for the saved frame pointer. Like savedSP and
|
||||
// savedLR in trampoline_arm64.s, this is assembly-side state: the amd64
|
||||
// checked trampoline saves the caller's frame pointer for vet's sake and
|
||||
// never restores it, and this file mirrors that.
|
||||
GLOBL savedFP(SB), NOPTR, $8
|
||||
|
||||
GLOBL savedG(SB), NOPTR, $8
|
||||
|
||||
+22
-22
@@ -18,11 +18,11 @@
|
||||
// spells this register "g"; R22 is not accepted.
|
||||
|
||||
// Sentinel value chosen to be unlikely in normal execution.
|
||||
#define SENTINEL_G 0x0BADF00DDEADBEEF
|
||||
#define SENTINEL_G 0x0BADF00DDEADBEEF
|
||||
|
||||
// GLOBL holding the raw address of the leave trampoline, read by Go.
|
||||
GLOBL ·leaveCheckedPtr(SB), NOPTR, $8
|
||||
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
|
||||
// func enterJITChecked(fn uintptr, stack uintptr)
|
||||
// Sets a sentinel in g (R22), switches to the prepared stack and jumps to
|
||||
@@ -30,22 +30,22 @@ DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
// leaveJITCheckedRaw (read from leaveCheckedPtr). Only R4 and R5 are used
|
||||
// as scratch: caller-saved, and R22 is not among them.
|
||||
TEXT ·enterJITChecked(SB), NOSPLIT, $0-16
|
||||
MOVV fn+0(FP), R4 // target function address (A0)
|
||||
MOVV R1, savedRA(SB) // save return address (RA)
|
||||
MOVV R3, savedSP(SB) // save Go stack pointer (SP)
|
||||
MOVV g, savedG(SB) // save g
|
||||
MOVV $SENTINEL_G, g // sentinel in g
|
||||
MOVV stack+8(FP), R5 // load prepared stack pointer (A1)
|
||||
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
|
||||
MOVV fn+0(FP), R4 // target function address (A0)
|
||||
MOVV R1, savedRA(SB) // save return address (RA)
|
||||
MOVV R3, savedSP(SB) // save Go stack pointer (SP)
|
||||
MOVV g, savedG(SB) // save g
|
||||
MOVV $SENTINEL_G, g // sentinel in g
|
||||
MOVV stack+8(FP), R5 // load prepared stack pointer (A1)
|
||||
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
|
||||
|
||||
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
|
||||
// declaration, so no ABIInternal wrapper is generated; the JIT function's
|
||||
// RET lands here directly, seeing g exactly as the function left it. It
|
||||
// checks the sentinel, records violations in abiResult, then restores the
|
||||
// Go stack and returns.
|
||||
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
|
||||
// declaration, so no ABIInternal wrapper is generated; the JIT function's
|
||||
// RET lands here directly, seeing g exactly as the function left it. It
|
||||
// checks the sentinel, records violations in abiResult, then restores the
|
||||
// Go stack and returns.
|
||||
TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
|
||||
// Check g against the sentinel.
|
||||
MOVV $SENTINEL_G, R5
|
||||
@@ -56,11 +56,11 @@ TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
|
||||
MOVV R4, ·abiResult(SB)
|
||||
|
||||
g_ok:
|
||||
MOVV savedSP(SB), R5 // restore Go stack pointer
|
||||
MOVV savedSP(SB), R5 // restore Go stack pointer
|
||||
MOVV R5, R3
|
||||
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
|
||||
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
|
||||
|
||||
GLOBL savedG(SB), NOPTR, $8
|
||||
|
||||
+22
-22
@@ -18,11 +18,11 @@
|
||||
// spells this register "g"; X27 is not accepted.
|
||||
|
||||
// Sentinel value chosen to be unlikely in normal execution.
|
||||
#define SENTINEL_G 0x0BADF00DDEADBEEF
|
||||
#define SENTINEL_G 0x0BADF00DDEADBEEF
|
||||
|
||||
// GLOBL holding the raw address of the leave trampoline, read by Go.
|
||||
GLOBL ·leaveCheckedPtr(SB), NOPTR, $8
|
||||
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
|
||||
// func enterJITChecked(fn uintptr, stack uintptr)
|
||||
// Sets a sentinel in g (X27), switches to the prepared stack and jumps to
|
||||
@@ -30,22 +30,22 @@ DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
|
||||
// leaveJITCheckedRaw (read from leaveCheckedPtr). Only X5 and X6 are used
|
||||
// as scratch: caller-saved, and X27 is not among them.
|
||||
TEXT ·enterJITChecked(SB), NOSPLIT, $0-16
|
||||
MOV fn+0(FP), X5 // target function address (T0)
|
||||
MOV X1, savedRA(SB) // save return address
|
||||
MOV X2, savedSP(SB) // save Go stack pointer
|
||||
MOV g, savedG(SB) // save g
|
||||
MOV $SENTINEL_G, g // sentinel in g
|
||||
MOV stack+8(FP), X6 // load prepared stack pointer (T1)
|
||||
LD 0(X6), X1 // load leaveJITCheckedRaw into RA
|
||||
MOV X6, X2 // SP stays on the leave slot: the kernel
|
||||
// reads its first argument at SP+8
|
||||
JALR X0, 0(X5) // jump to JIT function
|
||||
MOV fn+0(FP), X5 // target function address (T0)
|
||||
MOV X1, savedRA(SB) // save return address
|
||||
MOV X2, savedSP(SB) // save Go stack pointer
|
||||
MOV g, savedG(SB) // save g
|
||||
MOV $SENTINEL_G, g // sentinel in g
|
||||
MOV stack+8(FP), X6 // load prepared stack pointer (T1)
|
||||
LD 0(X6), X1 // load leaveJITCheckedRaw into RA
|
||||
MOV X6, X2 // SP stays on the leave slot: the kernel
|
||||
// reads its first argument at SP+8
|
||||
JALR X0, 0(X5) // 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
|
||||
// RET lands here directly, seeing g exactly as the function left it. It
|
||||
// checks the sentinel, records violations in abiResult, then restores the
|
||||
// Go stack and returns.
|
||||
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
|
||||
// declaration, so no ABIInternal wrapper is generated; the JIT function's
|
||||
// RET lands here directly, seeing g exactly as the function left it. It
|
||||
// checks the sentinel, records violations in abiResult, then restores the
|
||||
// Go stack and returns.
|
||||
TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
|
||||
// Check g against the sentinel.
|
||||
MOV $SENTINEL_G, X6
|
||||
@@ -56,11 +56,11 @@ TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
|
||||
MOV X7, ·abiResult(SB)
|
||||
|
||||
g_ok:
|
||||
MOV savedSP(SB), X6 // restore Go stack pointer
|
||||
MOV savedSP(SB), X6 // restore Go stack pointer
|
||||
MOV X6, X2
|
||||
MOV savedRA(SB), X1 // restore return address
|
||||
MOV savedG(SB), g // restore g: Go code needs it the moment it
|
||||
// resumes, violation or not
|
||||
JALR X0, 0(X1) // return to Go caller
|
||||
MOV savedRA(SB), X1 // restore return address
|
||||
MOV savedG(SB), g // restore g: Go code needs it the moment it
|
||||
// resumes, violation or not
|
||||
JALR X0, 0(X1) // return to Go caller
|
||||
|
||||
GLOBL savedG(SB), NOPTR, $8
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
// Switches to the prepared stack and jumps to fn. Does not return normally;
|
||||
// the JIT function's RET transfers control to leaveJIT.
|
||||
TEXT ·enterJIT(SB), NOSPLIT, $0-16
|
||||
MOVQ fn+0(FP), AX // target function address (before SP switch)
|
||||
MOVQ SP, ·savedSP(SB) // preserve the Go stack pointer
|
||||
MOVQ stack+8(FP), SP // switch to the prepared stack
|
||||
MOVQ fn+0(FP), AX // target function address (before SP switch)
|
||||
MOVQ SP, ·savedSP(SB) // preserve the Go stack pointer
|
||||
MOVQ stack+8(FP), SP // switch to the prepared stack
|
||||
JMP AX
|
||||
|
||||
// func leaveJIT()
|
||||
// Restores the Go stack pointer and returns to enterJIT's caller.
|
||||
// func leaveJIT()
|
||||
// Restores the Go stack pointer and returns to enterJIT's caller.
|
||||
TEXT ·leaveJIT(SB), NOSPLIT, $0-0
|
||||
MOVQ ·savedSP(SB), SP
|
||||
RET
|
||||
|
||||
+17
-16
@@ -15,32 +15,33 @@
|
||||
|
||||
// func enterJIT(fn uintptr, stack uintptr)
|
||||
TEXT ·enterJIT(SB), NOSPLIT, $0-16
|
||||
MOVD fn+0(FP), R0 // target function address
|
||||
MOVD R30, savedLR(SB) // save link register
|
||||
MOVD R3, savedSP(SB) // save Go stack pointer
|
||||
MOVD stack+8(FP), R3 // load prepared stack pointer
|
||||
MOVD 0(R3), R30 // load leaveJIT address into LR
|
||||
MOVD R3, RSP // switch to the prepared stack: SP stays on
|
||||
// the leave slot, so the kernel reads its
|
||||
// first argument at SP+8 per the frame
|
||||
// convention (amd64 lays the stack out the
|
||||
// same way)
|
||||
JMP (R0) // branch to JIT function
|
||||
MOVD fn+0(FP), R0 // target function address
|
||||
MOVD R30, savedLR(SB) // save link register
|
||||
MOVD R3, savedSP(SB) // save Go stack pointer
|
||||
MOVD stack+8(FP), R3 // load prepared stack pointer
|
||||
MOVD 0(R3), R30 // load leaveJIT address into LR
|
||||
MOVD R3, RSP // switch to the prepared stack: SP stays on
|
||||
// the leave slot, so the kernel reads its
|
||||
// first argument at SP+8 per the frame
|
||||
// convention (amd64 lays the stack out the
|
||||
// same way)
|
||||
JMP (R0) // branch to JIT function
|
||||
|
||||
// func leaveJIT()
|
||||
// func leaveJIT()
|
||||
TEXT ·leaveJIT(SB), NOSPLIT, $0-0
|
||||
MOVD savedSP(SB), R3 // restore Go stack pointer
|
||||
MOVD savedSP(SB), R3 // restore Go stack pointer
|
||||
MOVD R3, RSP
|
||||
MOVD savedLR(SB), R30 // restore link register
|
||||
RET // return to Go caller
|
||||
MOVD savedLR(SB), R30 // restore link register
|
||||
RET // return to Go caller
|
||||
|
||||
// leaveRawAddr holds the raw .abi0 address of leaveJIT, read by call_arm64.go
|
||||
// in preference to reflect.ValueOf(leaveJIT), which returns the address of the
|
||||
// ABIInternal wrapper the linker interposes: the wrapper's prologue clobbers
|
||||
// the saved-register window the JIT call depends on.
|
||||
GLOBL ·leaveRawAddr(SB), NOPTR, $8
|
||||
DATA ·leaveRawAddr(SB)/8, $·leaveJIT(SB)
|
||||
DATA ·leaveRawAddr(SB)/8, $·leaveJIT(SB)
|
||||
|
||||
// Package-level storage for saved registers.
|
||||
GLOBL savedLR(SB), NOPTR, $8
|
||||
|
||||
GLOBL savedSP(SB), NOPTR, $8
|
||||
|
||||
+15
-14
@@ -11,22 +11,23 @@
|
||||
|
||||
// func enterJIT(fn uintptr, stack uintptr)
|
||||
TEXT ·enterJIT(SB), NOSPLIT, $0-16
|
||||
MOVV fn+0(FP), R4 // target function address (A0)
|
||||
MOVV R1, savedRA(SB) // save return address (RA)
|
||||
MOVV R3, savedSP(SB) // save Go stack pointer (SP)
|
||||
MOVV stack+8(FP), R5 // load prepared stack pointer (A1)
|
||||
MOVV 0(R5), R1 // load leaveJIT address into RA
|
||||
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
|
||||
MOVV fn+0(FP), R4 // target function address (A0)
|
||||
MOVV R1, savedRA(SB) // save return address (RA)
|
||||
MOVV R3, savedSP(SB) // save Go stack pointer (SP)
|
||||
MOVV stack+8(FP), R5 // load prepared stack pointer (A1)
|
||||
MOVV 0(R5), R1 // load leaveJIT address into RA
|
||||
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
|
||||
|
||||
// func leaveJIT()
|
||||
// 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
|
||||
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
|
||||
|
||||
GLOBL savedRA(SB), NOPTR, $8
|
||||
|
||||
GLOBL savedSP(SB), NOPTR, $8
|
||||
|
||||
+15
-14
@@ -11,22 +11,23 @@
|
||||
|
||||
// func enterJIT(fn uintptr, stack uintptr)
|
||||
TEXT ·enterJIT(SB), NOSPLIT, $0-16
|
||||
MOV fn+0(FP), X5 // target function address (T0)
|
||||
MOV X1, savedRA(SB) // save return address
|
||||
MOV X2, savedSP(SB) // save Go stack pointer
|
||||
MOV stack+8(FP), X6 // load prepared stack pointer (T1)
|
||||
LD 0(X6), X1 // load leaveJIT address into RA
|
||||
MOV X6, X2 // switch to the prepared stack: SP stays on
|
||||
// the leave slot, so the kernel reads its
|
||||
// first argument at SP+8
|
||||
JALR X0, 0(X5) // jump to JIT function
|
||||
MOV fn+0(FP), X5 // target function address (T0)
|
||||
MOV X1, savedRA(SB) // save return address
|
||||
MOV X2, savedSP(SB) // save Go stack pointer
|
||||
MOV stack+8(FP), X6 // load prepared stack pointer (T1)
|
||||
LD 0(X6), X1 // load leaveJIT address into RA
|
||||
MOV X6, X2 // switch to the prepared stack: SP stays on
|
||||
// the leave slot, so the kernel reads its
|
||||
// first argument at SP+8
|
||||
JALR X0, 0(X5) // jump to JIT function
|
||||
|
||||
// func leaveJIT()
|
||||
// func leaveJIT()
|
||||
TEXT ·leaveJIT(SB), NOSPLIT, $0-0
|
||||
MOV savedSP(SB), X6 // restore Go stack pointer
|
||||
MOV X6, X2 // restore SP
|
||||
MOV savedRA(SB), X1 // restore return address
|
||||
JALR X0, 0(X1) // return to Go caller
|
||||
MOV savedSP(SB), X6 // restore Go stack pointer
|
||||
MOV X6, X2 // restore SP
|
||||
MOV savedRA(SB), X1 // restore return address
|
||||
JALR X0, 0(X1) // return to Go caller
|
||||
|
||||
GLOBL savedRA(SB), NOPTR, $8
|
||||
|
||||
GLOBL savedSP(SB), NOPTR, $8
|
||||
|
||||
Reference in New Issue
Block a user