style: put the repository assembly in gasm fmt canonical form

Assisted-by: GLM 5.3 Flash
This commit is contained in:
2026-09-17 20:33:18 +02:00
parent 0b42ce7952
commit 03d6d4da54
26 changed files with 583 additions and 542 deletions
+5 -5
View File
@@ -5,8 +5,8 @@
// func add(a, b int64) int64 // func add(a, b int64) int64
TEXT ·add(SB), NOSPLIT, $0-24 TEXT ·add(SB), NOSPLIT, $0-24
MOV a+0(FP), X10 MOV a+0(FP), X10
MOV b+8(FP), X11 MOV b+8(FP), X11
ADD X11, X10, X10 ADD X11, X10, X10
MOV X10, ret+16(FP) MOV X10, ret+16(FP)
RET RET
+10 -10
View File
@@ -5,16 +5,16 @@
// func atomicAdd(ptr *int64, val int64) int64 // func atomicAdd(ptr *int64, val int64) int64
TEXT ·atomicAdd(SB), NOSPLIT, $0-24 TEXT ·atomicAdd(SB), NOSPLIT, $0-24
MOV a+0(FP), X10 MOV a+0(FP), X10
MOV b+8(FP), X11 MOV b+8(FP), X11
AMOADDD X11, (X10), X12 AMOADDD X11, (X10), X12
MOV X12, ret+16(FP) MOV X12, ret+16(FP)
RET RET
// func fpAdd(a, b float64) float64 // func fpAdd(a, b float64) float64
TEXT ·fpAdd(SB), NOSPLIT, $0-24 TEXT ·fpAdd(SB), NOSPLIT, $0-24
FLD a+0(FP), F10 FLD a+0(FP), F10
FLD b+8(FP), F11 FLD b+8(FP), F11
FADDD F10, F11, F12 FADDD F10, F11, F12
FSD F12, ret+16(FP) FSD F12, ret+16(FP)
RET RET
+13 -13
View File
@@ -5,22 +5,22 @@
// func readCSR(csr int64) int64 // func readCSR(csr int64) int64
TEXT ·readCSR(SB), NOSPLIT, $0-16 TEXT ·readCSR(SB), NOSPLIT, $0-16
MOV a+0(FP), X10 MOV a+0(FP), X10
CSRRS $0x300, X0, X11 CSRRS $0x300, X0, X11
MOV X11, ret+8(FP) MOV X11, ret+8(FP)
RET RET
// func setCSRBit(csr, bit int64) int64 // func setCSRBit(csr, bit int64) int64
TEXT ·setCSRBit(SB), NOSPLIT, $0-24 TEXT ·setCSRBit(SB), NOSPLIT, $0-24
MOV a+0(FP), X10 MOV a+0(FP), X10
MOV b+8(FP), X11 MOV b+8(FP), X11
CSRRS $0x304, X11, X12 CSRRS $0x304, X11, X12
MOV X12, ret+16(FP) MOV X12, ret+16(FP)
RET RET
// func writeCSR(val int64) int64 // func writeCSR(val int64) int64
TEXT ·writeCSR(SB), NOSPLIT, $0-16 TEXT ·writeCSR(SB), NOSPLIT, $0-16
MOV a+0(FP), X10 MOV a+0(FP), X10
CSRRW $0x305, X10, X11 CSRRW $0x305, X10, X11
MOV X11, ret+8(FP) MOV X11, ret+8(FP)
RET RET
+12 -12
View File
@@ -5,18 +5,18 @@
// func fma(a, b, c float64) float64 // func fma(a, b, c float64) float64
TEXT ·fma(SB), NOSPLIT, $0-32 TEXT ·fma(SB), NOSPLIT, $0-32
FLD a+0(FP), F10 FLD a+0(FP), F10
FLD b+8(FP), F11 FLD b+8(FP), F11
FLD c+16(FP), F12 FLD c+16(FP), F12
FMADDD F10, F11, F12, F13 FMADDD F10, F11, F12, F13
FSD F13, ret+24(FP) FSD F13, ret+24(FP)
RET RET
// func fms(a, b, c float64) float64 // func fms(a, b, c float64) float64
TEXT ·fms(SB), NOSPLIT, $0-32 TEXT ·fms(SB), NOSPLIT, $0-32
FLD a+0(FP), F10 FLD a+0(FP), F10
FLD b+8(FP), F11 FLD b+8(FP), F11
FLD c+16(FP), F12 FLD c+16(FP), F12
FMSUBD F10, F11, F12, F13 FMSUBD F10, F11, F12, F13
FSD F13, ret+24(FP) FSD F13, ret+24(FP)
RET RET
+22 -21
View File
@@ -6,31 +6,32 @@
// func casLoop(ptr *int64, old, new int64) bool // func casLoop(ptr *int64, old, new int64) bool
TEXT ·casLoop(SB), NOSPLIT, $0-32 TEXT ·casLoop(SB), NOSPLIT, $0-32
cas_retry: cas_retry:
MOV a+0(FP), X10 MOV a+0(FP), X10
LRD (X10), X11 LRD (X10), X11
MOV b+8(FP), X12 MOV b+8(FP), X12
BNE X11, X12, cas_fail BNE X11, X12, cas_fail
MOV c+16(FP), X13 MOV c+16(FP), X13
SCD X13, (X10), X14 SCD X13, (X10), X14
BNE X14, X0, cas_retry BNE X14, X0, cas_retry
ADDI X0, $1, X15 ADDI X0, $1, X15
MOV X15, ret+24(FP) MOV X15, ret+24(FP)
RET RET
cas_fail: cas_fail:
MOV X0, ret+24(FP) MOV X0, ret+24(FP)
RET RET
// func intToFloat(x int64) float64 // func intToFloat(x int64) float64
TEXT ·intToFloat(SB), NOSPLIT, $0-16 TEXT ·intToFloat(SB), NOSPLIT, $0-16
MOV a+0(FP), X10 MOV a+0(FP), X10
FCVTDL X10, F10 FCVTDL X10, F10
FSD F10, ret+8(FP) FSD F10, ret+8(FP)
RET RET
// func compare(a, b float64) bool // func compare(a, b float64) bool
TEXT ·compare(SB), NOSPLIT, $0-24 TEXT ·compare(SB), NOSPLIT, $0-24
FLD a+0(FP), F10 FLD a+0(FP), F10
FLD b+8(FP), F11 FLD b+8(FP), F11
FLTD F10, F11, X10 FLTD F10, F11, X10
MOV X10, ret+16(FP) MOV X10, ret+16(FP)
RET RET
+28 -27
View File
@@ -15,43 +15,44 @@ DATA mask24<>+4(SB)/4, $0x80050403
// func analyzeO1RangeAVX2(swin []int32, dstP []uint32, hist *[32]uint16) (partSum uint64, overflow bool) // func analyzeO1RangeAVX2(swin []int32, dstP []uint32, hist *[32]uint16) (partSum uint64, overflow bool)
TEXT ·analyzeO1RangeAVX2(SB), NOSPLIT, $0-65 TEXT ·analyzeO1RangeAVX2(SB), NOSPLIT, $0-65
MOVQ swin_base+0(FP), SI MOVQ swin_base+0(FP), SI
MOVQ dstP_base+24(FP), DI MOVQ dstP_base+24(FP), DI
MOVQ dstP_len+32(FP), BX MOVQ dstP_len+32(FP), BX
MOVQ hist+48(FP), R13 MOVQ hist+48(FP), R13
VPCMPEQD Y0, Y0, Y0 VPCMPEQD Y0, Y0, Y0
VPSLLD $31, Y0, Y0 VPSLLD $31, Y0, Y0
LEAQ (SI)(BX*4), R9 LEAQ (SI)(BX*4), R9
MOVQ BX, R10 MOVQ BX, R10
ANDQ $-8, R10 ANDQ $-8, R10
vec1: vec1:
CMPQ SI, R10 CMPQ SI, R10
JGE vec1done JGE vec1done
VMOVDQU (SI), Y1 VMOVDQU (SI), Y1
VMOVDQU 4(SI), Y2 VMOVDQU 4(SI), Y2
VPSUBD Y1, Y2, Y3 VPSUBD Y1, Y2, Y3
ADDQ $32, SI ADDQ $32, SI
JMP vec1 JMP vec1
vec1done: vec1done:
MOVQ AX, partSum+56(FP) MOVQ AX, partSum+56(FP)
MOVB AL, overflow+64(FP) MOVB AL, overflow+64(FP)
VZEROUPPER VZEROUPPER
RET RET
// func decodeFixedO1AVX512(samples []int32, residual []int32) // func decodeFixedO1AVX512(samples []int32, residual []int32)
TEXT ·decodeFixedO1AVX512(SB), NOSPLIT, $0-48 TEXT ·decodeFixedO1AVX512(SB), NOSPLIT, $0-48
MOVQ samples_base+0(FP), SI MOVQ samples_base+0(FP), SI
MOVQ residual_base+16(FP), DI MOVQ residual_base+16(FP), DI
VPBROADCASTD AX, Z15 VPBROADCASTD AX, Z15
VMOVDQU32 (DI)(AX*1), Z0 VMOVDQU32 (DI)(AX*1), Z0
VALIGND $15, Z9, Z0, Z1 VALIGND $15, Z9, Z0, Z1
VFMADD231PD Z14, Z12, Z10 VFMADD231PD Z14, Z12, Z10
VPCMPEQD Z0, Z3, K1 VPCMPEQD Z0, Z3, K1
KTESTW K1, K1 KTESTW K1, K1
VPSRAQ X31, Z8, Z8 VPSRAQ X31, Z8, Z8
VMOVDQU32 Z0, 4(SI)(AX*1) VMOVDQU32 Z0, 4(SI)(AX*1)
RET RET
+30 -30
View File
@@ -13,55 +13,55 @@ TEXT ·add(SB), NOSPLIT, $0-24
// func sum(data []int64) int64 // func sum(data []int64) int64
// Sums all elements of the slice. // Sums all elements of the slice.
TEXT ·sum(SB), NOSPLIT, $0-32 TEXT ·sum(SB), NOSPLIT, $0-32
MOVQ data_base+0(FP), SI MOVQ data_base+0(FP), SI
MOVQ data_len+8(FP), CX MOVQ data_len+8(FP), CX
XORQ AX, AX XORQ AX, AX
TESTQ CX, CX TESTQ CX, CX
JZ sum_done JZ sum_done
sum_loop: sum_loop:
ADDQ (SI), AX ADDQ (SI), AX
ADDQ $8, SI ADDQ $8, SI
DECQ CX DECQ CX
JNZ sum_loop JNZ sum_loop
sum_done: sum_done:
MOVQ AX, ret+24(FP) MOVQ AX, ret+24(FP)
RET RET
// func wideCopy(dst, src []byte) // func wideCopy(dst, src []byte)
// Non-overlapping copy of min(len(dst), len(src)) bytes using 32-byte moves. // Non-overlapping copy of min(len(dst), len(src)) bytes using 32-byte moves.
TEXT ·wideCopy(SB), NOSPLIT, $0-48 TEXT ·wideCopy(SB), NOSPLIT, $0-48
MOVQ dst_base+0(FP), DI MOVQ dst_base+0(FP), DI
MOVQ dst_len+8(FP), BX MOVQ dst_len+8(FP), BX
MOVQ src_base+24(FP), SI MOVQ src_base+24(FP), SI
MOVQ src_len+32(FP), R8 MOVQ src_len+32(FP), R8
CMPQ BX, R8 CMPQ BX, R8
JLE wc_have_n JLE wc_have_n
MOVQ R8, BX MOVQ R8, BX
wc_have_n: wc_have_n:
CMPQ BX, $32 CMPQ BX, $32
JB wc_small JB wc_small
VMOVDQU (SI), Y0 VMOVDQU (SI), Y0
VMOVDQU Y0, (DI) VMOVDQU Y0, (DI)
VMOVDQU -32(SI)(BX*1), Y0 VMOVDQU -32(SI)(BX*1), Y0
VMOVDQU Y0, -32(DI)(BX*1) VMOVDQU Y0,-32(DI)(BX*1)
VZEROUPPER VZEROUPPER
RET RET
wc_small: wc_small:
TESTQ BX, BX TESTQ BX, BX
JZ wc_done JZ wc_done
wc_byte: wc_byte:
MOVB (SI), R8B MOVB (SI), R8B
MOVB R8B, (DI) MOVB R8B, (DI)
INCQ SI INCQ SI
INCQ DI INCQ DI
DECQ BX DECQ BX
JNZ wc_byte JNZ wc_byte
wc_done: wc_done:
RET RET
+32 -29
View File
@@ -5,53 +5,56 @@
// add returns a + b. // add returns a + b.
TEXT ·add(SB), NOSPLIT, $0-24 TEXT ·add(SB), NOSPLIT, $0-24
MOVD a+0(FP), R4 MOVD a+0(FP), R4
MOVD b+8(FP), R5 MOVD b+8(FP), R5
ADD R5, R4, R4 ADD R5, R4, R4
MOVD R4, ret+16(FP) MOVD R4, ret+16(FP)
RET RET
// arith exercises the register-register integer set. // arith exercises the register-register integer set.
TEXT ·arith(SB), NOSPLIT, $0-0 TEXT ·arith(SB), NOSPLIT, $0-0
ADD R4, R5, R6 ADD R4, R5, R6
SUB R7, R8, R9 SUB R7, R8, R9
AND R10, R11, R12 AND R10, R11, R12
ORR R12, R13, R14 ORR R12, R13, R14
EOR R14, R15, R16 EOR R14, R15, R16
CMP R16, R17 CMP R16, R17
ADD R4, R5 ADD R4, R5
SUB R6, R7 SUB R6, R7
RET RET
// branch exercises conditional and unconditional control flow. // branch exercises conditional and unconditional control flow.
TEXT ·branch(SB), NOSPLIT, $0-0 TEXT ·branch(SB), NOSPLIT, $0-0
BEQ done BEQ done
BNE skip BNE skip
BGE done BGE done
BLT done BLT done
BGT done BGT done
BLE done BLE done
skip: skip:
B loop B loop
loop: loop:
ADD R4, R5 ADD R4, R5
RET RET
done: done:
RET RET
// mov exercises the MOV pseudo-instruction. // mov exercises the MOV pseudo-instruction.
TEXT ·mov(SB), NOSPLIT, $0-16 TEXT ·mov(SB), NOSPLIT, $0-16
MOVD $0, R4 MOVD $0, R4
MOVD $1, R5 MOVD $1, R5
MOVD $42, R6 MOVD $42, R6
MOVD a+0(FP), R7 MOVD a+0(FP), R7
MOVD R7, ret+0(FP) MOVD R7, ret+0(FP)
MOVW $100, R8 MOVW $100, R8
RET RET
// frame exercises the prologue/epilogue of a function with a real frame. // frame exercises the prologue/epilogue of a function with a real frame.
TEXT ·frame(SB), NOSPLIT, $32-8 TEXT ·frame(SB), NOSPLIT, $32-8
MOVD arg+0(FP), R4 MOVD arg+0(FP), R4
ADD $1, R4, R4 ADD $1, R4, R4
MOVD R4, ret+0(FP) MOVD R4, ret+0(FP)
RET RET
+33 -30
View File
@@ -5,50 +5,53 @@
// add returns a + b. // add returns a + b.
TEXT ·add(SB), NOSPLIT, $0-24 TEXT ·add(SB), NOSPLIT, $0-24
MOVV a+0(FP), R4 MOVV a+0(FP), R4
MOVV b+8(FP), R5 MOVV b+8(FP), R5
ADDV R5, R4, R4 ADDV R5, R4, R4
MOVV R4, ret+16(FP) MOVV R4, ret+16(FP)
RET RET
// arith exercises the 3R integer and FP set. // arith exercises the 3R integer and FP set.
TEXT ·arith(SB), NOSPLIT, $0-0 TEXT ·arith(SB), NOSPLIT, $0-0
ADDV R4, R5, R6 ADDV R4, R5, R6
SUBV R7, R8, R9 SUBV R7, R8, R9
MULV R10, R11, R12 MULV R10, R11, R12
DIVV R13, R14, R15 DIVV R13, R14, R15
AND R16, R17, R18 AND R16, R17, R18
OR R18, R19, R20 OR R18, R19, R20
XOR R20, R21, R2 XOR R20, R21, R2
SLLV R2, R23, R24 SLLV R2, R23, R24
SRLV R24, R25, R26 SRLV R24, R25, R26
SRAV R26, R27, R28 SRAV R26, R27, R28
RET RET
// imm exercises the immediate forms. // imm exercises the immediate forms.
TEXT ·imm(SB), NOSPLIT, $0-0 TEXT ·imm(SB), NOSPLIT, $0-0
ADDV $42, R4, R5 ADDV $42, R4, R5
ADDV $-8, R6 ADDV $-8, R6
AND $0xff, R7, R8 AND $0xff, R7, R8
OR $1, R9, R10 OR $1, R9, R10
XOR $0, R11, R12 XOR $0, R11, R12
SGT $100, R13, R14 SGT $100, R13, R14
SLLV $4, R15, R16 SLLV $4, R15, R16
MOVV $0x12345, R17 MOVV $0x12345, R17
RET RET
// branch exercises conditional and unconditional control flow. // branch exercises conditional and unconditional control flow.
TEXT ·branch(SB), NOSPLIT, $0-0 TEXT ·branch(SB), NOSPLIT, $0-0
BEQ R4, R5, done BEQ R4, R5, done
BNE R6, R7, skip BNE R6, R7, skip
BLT R8, R9, done BLT R8, R9, done
BGE R10, R11, done BGE R10, R11, done
BLTU R12, R13, done BLTU R12, R13, done
BGEU R14, R15, done BGEU R14, R15, done
skip: skip:
JMP loop JMP loop
loop: loop:
JAL skip JAL skip
RET RET
done: done:
RET RET
+19 -16
View File
@@ -5,23 +5,26 @@
// branch exercises all conditional branch forms and jump chain folding. // branch exercises all conditional branch forms and jump chain folding.
TEXT ·branch(SB), NOSPLIT, $0-0 TEXT ·branch(SB), NOSPLIT, $0-0
BEQ done BEQ done
BNE skip BNE skip
BGE done BGE done
BLT done BLT done
BGT done BGT done
BLE done BLE done
BCS done BCS done
BCC done BCC done
BMI done BMI done
BPL done BPL done
BVS done BVS done
BVC done BVC done
BHI done BHI done
BLS done BLS done
skip: skip:
B loop B loop
loop: loop:
ADD R4, R5 ADD R4, R5
done: done:
RET RET
+14 -6
View File
@@ -5,31 +5,39 @@
TEXT ·branches(SB), NOSPLIT, $0 TEXT ·branches(SB), NOSPLIT, $0
ADDI $1, X10, X10 ADDI $1, X10, X10
BEQ X10, X11, beq_done BEQ X10, X11, beq_done
ADDI $2, X10, X10 ADDI $2, X10, X10
beq_done: beq_done:
BNE X10, X11, bne_done BNE X10, X11, bne_done
ADDI $3, X10, X10 ADDI $3, X10, X10
bne_done: bne_done:
BLT X10, X11, blt_done BLT X10, X11, blt_done
ADDI $4, X10, X10 ADDI $4, X10, X10
blt_done: blt_done:
BGE X10, X11, bge_done BGE X10, X11, bge_done
ADDI $5, X10, X10 ADDI $5, X10, X10
bge_done: bge_done:
BLTU X10, X11, bltu_done BLTU X10, X11, bltu_done
ADDI $6, X10, X10 ADDI $6, X10, X10
bltu_done: bltu_done:
BGEU X10, X11, bgeu_done BGEU X10, X11, bgeu_done
ADDI $7, X10, X10 ADDI $7, X10, X10
bgeu_done: bgeu_done:
RET RET
TEXT ·jumps(SB), NOSPLIT, $0 TEXT ·jumps(SB), NOSPLIT, $0
JMP done JMP done
ADDI $1, X10, X10 ADDI $1, X10, X10
done: done:
JAL X11, skip JAL X11, skip
ADDI $2, X10, X10 ADDI $2, X10, X10
skip: skip:
RET RET
+2 -2
View File
@@ -5,6 +5,6 @@
// caller exercises BL to an external symbol (produces a relocation). // caller exercises BL to an external symbol (produces a relocation).
TEXT ·caller(SB), NOSPLIT, $0-0 TEXT ·caller(SB), NOSPLIT, $0-0
BL other(SB) BL other(SB)
ADD R4, R5 ADD R4, R5
RET RET
+87 -87
View File
@@ -5,115 +5,115 @@
// fparith exercises the FP arithmetic set. // fparith exercises the FP arithmetic set.
TEXT ·fparith(SB), NOSPLIT, $0-0 TEXT ·fparith(SB), NOSPLIT, $0-0
FADDD F0, F1, F2 FADDD F0, F1, F2
FSUBD F3, F4, F5 FSUBD F3, F4, F5
FMULD F6, F7, F8 FMULD F6, F7, F8
FDIVD F9, F10, F11 FDIVD F9, F10, F11
FADDS F12, F13, F14 FADDS F12, F13, F14
FSUBS F15, F16, F17 FSUBS F15, F16, F17
FMULS F18, F19, F20 FMULS F18, F19, F20
FDIVS F21, F22, F23 FDIVS F21, F22, F23
FSQRTD F24, F25 FSQRTD F24, F25
FSQRTS F26, F27 FSQRTS F26, F27
FNEGD F28, F29 FNEGD F28, F29
FNEGS F30, F31 FNEGS F30, F31
FABSD F0, F1 FABSD F0, F1
FABSS F2, F3 FABSS F2, F3
FNMULD F4, F5, F6 FNMULD F4, F5, F6
FNMULS F7, F8, F9 FNMULS F7, F8, F9
FMIND F10, F11, F12 FMIND F10, F11, F12
FMAXD F13, F14, F15 FMAXD F13, F14, F15
FMINS F16, F17, F18 FMINS F16, F17, F18
FMAXS F19, F20, F21 FMAXS F19, F20, F21
RET RET
// fpfma exercises fused multiply-add. // fpfma exercises fused multiply-add.
TEXT ·fpfma(SB), NOSPLIT, $0-0 TEXT ·fpfma(SB), NOSPLIT, $0-0
FMADDD F0, F1, F2, F3 FMADDD F0, F1, F2, F3
FMSUBD F4, F5, F6, F7 FMSUBD F4, F5, F6, F7
FNMADDD F8, F9, F10, F11 FNMADDD F8, F9, F10, F11
FNMSUBD F12, F13, F14, F15 FNMSUBD F12, F13, F14, F15
FMADDS F16, F17, F18, F19 FMADDS F16, F17, F18, F19
FMSUBS F20, F21, F22, F23 FMSUBS F20, F21, F22, F23
FNMADDS F24, F25, F26, F27 FNMADDS F24, F25, F26, F27
FNMSUBS F28, F29, F30, F0 FNMSUBS F28, F29, F30, F0
RET RET
// fpconv exercises FP↔integer conversion and cross-precision. // fpconv exercises FP↔integer conversion and cross-precision.
// Syntax: FCVTZSD Fd, Rn (float→int: FP source first, int dest second) // Syntax: FCVTZSD Fd, Rn (float→int: FP source first, int dest second)
// SCVTFD Rn, Fd (int→float: int source first, FP dest second) // SCVTFD Rn, Fd (int→float: int source first, FP dest second)
TEXT ·fpconv(SB), NOSPLIT, $0-0 TEXT ·fpconv(SB), NOSPLIT, $0-0
FCVTSD F0, F1 FCVTSD F0, F1
FCVTDS F2, F3 FCVTDS F2, F3
FCVTZSD F4, R0 FCVTZSD F4, R0
FCVTZSS F5, R1 FCVTZSS F5, R1
FCVTZUD F6, R2 FCVTZUD F6, R2
FCVTZUS F7, R3 FCVTZUS F7, R3
SCVTFD R4, F8 SCVTFD R4, F8
SCVTFS R5, F9 SCVTFS R5, F9
UCVTFD R6, F10 UCVTFD R6, F10
UCVTFS R7, F11 UCVTFS R7, F11
SCVTFWD R0, F12 SCVTFWD R0, F12
SCVTFWS R1, F13 SCVTFWS R1, F13
UCVTFWD R2, F14 UCVTFWD R2, F14
UCVTFWS R3, F15 UCVTFWS R3, F15
FMOVS F14, R20 FMOVS F14, R20
FMOVS R21, F15 FMOVS R21, F15
FMOVD F16, R22 FMOVD F16, R22
FMOVD R23, F17 FMOVD R23, F17
RET RET
// fpcmp exercises FP compare and conditional compare. // fpcmp exercises FP compare and conditional compare.
// FCCMP syntax: FCCMP cond, Fn, Fm, $nzcv // FCCMP syntax: FCCMP cond, Fn, Fm, $nzcv
// FCSEL syntax: FCSEL cond, Fn, Fm, Fd // FCSEL syntax: FCSEL cond, Fn, Fm, Fd
TEXT ·fpcmp(SB), NOSPLIT, $0-0 TEXT ·fpcmp(SB), NOSPLIT, $0-0
FCMPS F0, F1 FCMPS F0, F1
FCMPD F2, F3 FCMPD F2, F3
FCMPS $0.0, F4 FCMPS $0.0, F4
FCMPD $0.0, F5 FCMPD $0.0, F5
FCCMPS EQ, F6, F7, $0 FCCMPS EQ, F6, F7, $0
FCCMPD NE, F8, F9, $0 FCCMPD NE, F8, F9, $0
FCSELS GE, F10, F11, F12 FCSELS GE, F10, F11, F12
FCSELD LT, F13, F14, F15 FCSELD LT, F13, F14, F15
RET RET
// frint exercises FP rounding. // frint exercises FP rounding.
TEXT ·frint(SB), NOSPLIT, $0-0 TEXT ·frint(SB), NOSPLIT, $0-0
FRINTND F0, F1 FRINTND F0, F1
FRINTNS F2, F3 FRINTNS F2, F3
FRINTPD F4, F5 FRINTPD F4, F5
FRINTPS F6, F7 FRINTPS F6, F7
FRINTMD F8, F9 FRINTMD F8, F9
FRINTMS F10, F11 FRINTMS F10, F11
FRINTZD F12, F13 FRINTZD F12, F13
FRINTZS F14, F15 FRINTZS F14, F15
FRINTAD F16, F17 FRINTAD F16, F17
FRINTAS F18, F19 FRINTAS F18, F19
FRINTXD F20, F21 FRINTXD F20, F21
FRINTXS F22, F23 FRINTXS F22, F23
FRINTID F24, F25 FRINTID F24, F25
FRINTIS F26, F27 FRINTIS F26, F27
FMOVD F0, F1 FMOVD F0, F1
FMOVS F2, F3 FMOVS F2, F3
RET RET
// condsel exercises conditional select and CRC32. // condsel exercises conditional select and CRC32.
TEXT ·condsel(SB), NOSPLIT, $0-0 TEXT ·condsel(SB), NOSPLIT, $0-0
CSEL EQ, R0, R1, R2 CSEL EQ, R0, R1, R2
CSINC NE, R3, R4, R5 CSINC NE, R3, R4, R5
CSINV GE, R6, R7, R8 CSINV GE, R6, R7, R8
CSNEG LT, R9, R10, R11 CSNEG LT, R9, R10, R11
CSET EQ, R12 CSET EQ, R12
CSETM NE, R13 CSETM NE, R13
CINC EQ, R14, R15 CINC EQ, R14, R15
CINV NE, R16, R17 CINV NE, R16, R17
CNEG GE, R19, R20 CNEG GE, R19, R20
CRC32B R0, R2 CRC32B R0, R2
CRC32H R3, R5 CRC32H R3, R5
CRC32W R6, R8 CRC32W R6, R8
CRC32X R9, R11 CRC32X R9, R11
CRC32CB R12, R14 CRC32CB R12, R14
CRC32CH R15, R0 CRC32CH R15, R0
CRC32CW R1, R3 CRC32CW R1, R3
CRC32CX R4, R6 CRC32CX R4, R6
RET RET
+106 -90
View File
@@ -6,138 +6,154 @@
// fp exercises the floating-point set: 3R arithmetic, 2R unary, compares // fp exercises the floating-point set: 3R arithmetic, 2R unary, compares
// into FCC, fused multiply-add and the register moves. // into FCC, fused multiply-add and the register moves.
TEXT ·fp(SB), NOSPLIT, $0-0 TEXT ·fp(SB), NOSPLIT, $0-0
ADDD F4, F5, F6 ADDD F4, F5, F6
SUBD F7, F8, F9 SUBD F7, F8, F9
MULD F9, F10, F11 MULD F9, F10, F11
DIVD F11, F12, F13 DIVD F11, F12, F13
MULF F13, F14, F15 MULF F13, F14, F15
ADDF F15, F16, F17 ADDF F15, F16, F17
SQRTD F17, F18 SQRTD F17, F18
SQRTF F18, F19 SQRTF F18, F19
ABSD F19, F20 ABSD F19, F20
NEGD F20, F21 NEGD F20, F21
MOVD F21, F22 MOVD F21, F22
CMPEQD F22, F23, FCC0 CMPEQD F22, F23, FCC0
CMPGTF F23, F24, FCC1 CMPGTF F23, F24, FCC1
CMPGED F24, F25, FCC2 CMPGED F24, F25, FCC2
FMADDD F0, F1, F2, F3 FMADDD F0, F1, F2, F3
FMSUBF F3, F4, F5, F6 FMSUBF F3, F4, F5, F6
FNMADDD F6, F7, F8, F9 FNMADDD F6, F7, F8, F9
FNMSUBF F9, F10, F11, F12 FNMSUBF F9, F10, F11, F12
FMAXD F12, F13, F14 FMAXD F12, F13, F14
FMINF F14, F15, F16 FMINF F14, F15, F16
FMAXAD F16, F17, F18 FMAXAD F16, F17, F18
FMINAF F18, F19, F20 FMINAF F18, F19, F20
FSCALEBF F20, F21, F22 FSCALEBF F20, F21, F22
FCOPYSGD F22, F23, F24 FCOPYSGD F22, F23, F24
MOVV F25, R25 MOVV F25, R25
MOVV R26, F27 MOVV R26, F27
MOVW R28, F29 MOVW R28, F29
MOVW F30, R31 MOVW F30, R31
RET RET
// mov forms: register moves, immediates (12/32/64-bit), memory with FP/SP // mov forms: register moves, immediates (12/32/64-bit), memory with FP/SP
// pseudo-registers and the register-indexed forms. // pseudo-registers and the register-indexed forms.
TEXT ·mov(SB), NOSPLIT, $0-16 TEXT ·mov(SB), NOSPLIT, $0-16
MOVV R4, R5 MOVV R4, R5
MOVW R6, R7 MOVW R6, R7
MOVB R8, R9 MOVB R8, R9
MOVBU R10, R11 MOVBU R10, R11
MOVHU R12, R13 MOVHU R12, R13
MOVWU R14, R15 MOVWU R14, R15
MOVV $42, R16 MOVV $42, R16
MOVV $0x12345, R17 MOVV $0x12345, R17
MOVV $0x100000, R18 MOVV $0x100000, R18
MOVW $-100, R19 MOVW $-100, R19
MOVV $0x123456789, R20 MOVV $0x123456789, R20
MOVV a+0(FP), R21 MOVV a+0(FP), R21
MOVV R23, b+8(FP) MOVV R23, b+8(FP)
MOVW c+16(FP), R24 MOVW c+16(FP), R24
MOVV (R24)(R25), R26 MOVV (R24)(R25), R26
MOVV R27, (R28)(R29) MOVV R27, (R28)(R29)
RET RET
// frame exercises the prologue/epilogue of a function with a real frame. // frame exercises the prologue/epilogue of a function with a real frame.
TEXT ·frame(SB), NOSPLIT, $32-8 TEXT ·frame(SB), NOSPLIT, $32-8
MOVV R4, R5 MOVV R4, R5
MOVV arg+0(FP), R6 MOVV arg+0(FP), R6
MOVV R7, local-8(SP) MOVV R7, local-8(SP)
MOVV local-8(SP), R8 MOVV local-8(SP), R8
MOVV R9, ret+0(FP) MOVV R9, ret+0(FP)
RET RET
// branches21 exercises the single-register and zero-register branch forms // branches21 exercises the single-register and zero-register branch forms
// with 21-bit offsets. // with 21-bit offsets.
TEXT ·branches21(SB), NOSPLIT, $0-0 TEXT ·branches21(SB), NOSPLIT, $0-0
BEQ R0, R4, l1 BEQ R0, R4, l1
BEQ R5, R0, l2 BEQ R5, R0, l2
BNE R0, R6, l3 BNE R0, R6, l3
BNE R7, R0, l4 BNE R7, R0, l4
BLTZ R8, l5 BLTZ R8, l5
BGEZ R9, l6 BGEZ R9, l6
BLEZ R10, l7 BLEZ R10, l7
BGTZ R11, l8 BGTZ R11, l8
JMP l9 JMP l9
l1: l1:
JMP l10 JMP l10
l2: l2:
JMP l11 JMP l11
l3: l3:
JMP l12 JMP l12
l4: l4:
JMP l13 JMP l13
l5: l5:
JMP l14 JMP l14
l6: l6:
JMP l15 JMP l15
l7: l7:
JMP l16 JMP l16
l8: l8:
JMP l16 JMP l16
l9: l9:
MOVV R1, R2 MOVV R1, R2
l10: l10:
LL (R12), R13 LL (R12), R13
LLV (R14), R15 LLV (R14), R15
SC R16, (R17) SC R16, (R17)
SCV R18, (R19) SCV R18, (R19)
RDTIMED R20, R21 RDTIMED R20, R21
SYSCALL SYSCALL
DBAR DBAR
RET RET
l11: l11:
JAL (R30) JAL (R30)
RET RET
l12: l12:
BSTRINSV $7, R4, $0, R5 BSTRINSV $7, R4, $0, R5
BSTRPICKV $63, R6, $32, R7 BSTRPICKV $63, R6, $32, R7
ALSLV $2, R8, R9, R10 ALSLV $2, R8, R9, R10
ADDV16 $65536, R11, R12 ADDV16 $65536, R11, R12
RET RET
l13: l13:
MOVV $0xffffffffffffffff, R13 MOVV $0xffffffffffffffff, R13
RET RET
l14: l14:
CPUCFG R14, R14 CPUCFG R14, R14
RET RET
l15: l15:
NOR R15, R16, R17 NOR R15, R16, R17
ORN R18, R19, R20 ORN R18, R19, R20
ANDN R21, R24, R25 ANDN R21, R24, R25
RET RET
l16: l16:
MOVB R26, (R27) MOVB R26, (R27)
MOVB (R28), R29 MOVB (R28), R29
RET RET
// sbdata loads and stores a static symbol with relocations (the relocation // sbdata loads and stores a static symbol with relocations (the relocation
// fields are masked before comparison). // fields are masked before comparison).
GLOBL ·table(SB), RODATA, $16 GLOBL ·table(SB), RODATA, $16
DATA ·table+0(SB)/8, $0x1122334455667788 DATA ·table+0(SB)/8, $0x1122334455667788
DATA ·table+8(SB)/8, $0x8877665544332211 DATA ·table+8(SB)/8, $0x8877665544332211
TEXT ·sbdata(SB), NOSPLIT, $0-0 TEXT ·sbdata(SB), NOSPLIT, $0-0
MOVV $·table(SB), R4 MOVV $·table(SB), R4
MOVV ·table(SB), R5 MOVV ·table(SB), R5
MOVV R6, ·table+8(SB) MOVV R6, ·table+8(SB)
RET RET
+1 -1
View File
@@ -7,6 +7,6 @@ TEXT ·largeimm(SB), NOSPLIT, $0
ADDI $2048, X5 ADDI $2048, X5
ADDI $4095, X5, X6 ADDI $4095, X5, X6
ANDI $4095, X5, X6 ANDI $4095, X5, X6
ORI $-4096, X5, X6 ORI $-4096, X5, X6
XORI $0x12345, X5, X6 XORI $0x12345, X5, X6
RET RET
+8 -8
View File
@@ -4,14 +4,14 @@
#include "textflag.h" #include "textflag.h"
TEXT ·ldst(SB), NOSPLIT, $0 TEXT ·ldst(SB), NOSPLIT, $0
LD (X8), X9 LD (X8), X9
SD X9, (X8) SD X9, (X8)
LW (X8), X9 LW (X8), X9
SW X9, (X8) SW X9, (X8)
LD 8(X2), X10 LD 8(X2), X10
SD X10, 16(X2) SD X10, 16(X2)
LW 4(X2), X11 LW 4(X2), X11
SW X11, 8(X2) SW X11, 8(X2)
RET RET
TEXT ·addi4spn(SB), NOSPLIT, $0 TEXT ·addi4spn(SB), NOSPLIT, $0
+13 -13
View File
@@ -5,17 +5,17 @@
// movimm exercises MOV with various immediate values. // movimm exercises MOV with various immediate values.
TEXT ·movimm(SB), NOSPLIT, $0-0 TEXT ·movimm(SB), NOSPLIT, $0-0
MOVD $0, R0 MOVD $0, R0
MOVD $1, R1 MOVD $1, R1
MOVD $42, R2 MOVD $42, R2
MOVD $255, R3 MOVD $255, R3
MOVD $256, R4 MOVD $256, R4
MOVD $0xFFFF, R5 MOVD $0xFFFF, R5
MOVD $0x12345678, R6 MOVD $0x12345678, R6
MOVD $0x123456789ABCDEF0, R7 MOVD $0x123456789ABCDEF0, R7
MOVD $-1, R8 MOVD $-1, R8
MOVD $-2, R9 MOVD $-2, R9
MOVW $0, R10 MOVW $0, R10
MOVW $100, R11 MOVW $100, R11
MOVW $0x12345, R12 MOVW $0x12345, R12
RET RET
+3 -3
View File
@@ -10,9 +10,9 @@ TEXT ·shifts(SB), NOSPLIT, $0
RET RET
TEXT ·logic(SB), NOSPLIT, $0 TEXT ·logic(SB), NOSPLIT, $0
AND X11, X10, X10 AND X11, X10, X10
OR X11, X10, X10 OR X11, X10, X10
XOR X11, X10, X10 XOR X11, X10, X10
ANDI $7, X10, X10 ANDI $7, X10, X10
RET RET
+19 -19
View File
@@ -17,32 +17,32 @@
// - R14 holds the goroutine pointer and must survive across any call. // - R14 holds the goroutine pointer and must survive across any call.
// Sentinel values chosen to be unlikely in normal execution. // Sentinel values chosen to be unlikely in normal execution.
#define SENTINEL_BP 0xDEADBEEFCAFEF00D #define SENTINEL_BP 0xDEADBEEFCAFEF00D
#define SENTINEL_R14 0x0BADF00DDEADBEEF #define SENTINEL_R14 0x0BADF00DDEADBEEF
// GLOBL holding the raw address of the leave trampoline, read by Go. // GLOBL holding the raw address of the leave trampoline, read by Go.
GLOBL ·leaveCheckedPtr(SB), NOPTR, $8 GLOBL ·leaveCheckedPtr(SB), NOPTR, $8
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB) DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
// func enterJITChecked(fn uintptr, stack uintptr) // func enterJITChecked(fn uintptr, stack uintptr)
// Sets sentinels in BP and R14, switches to the prepared stack and jumps // Sets sentinels in BP and R14, switches to the prepared stack and jumps
// to fn. The prepared stack's return address must be leaveJITCheckedRaw // to fn. The prepared stack's return address must be leaveJITCheckedRaw
// (read from leaveCheckedPtr). // (read from leaveCheckedPtr).
TEXT ·enterJITChecked(SB), NOSPLIT, $0-16 TEXT ·enterJITChecked(SB), NOSPLIT, $0-16
MOVQ fn+0(FP), AX // target (before SP switch) MOVQ fn+0(FP), AX // target (before SP switch)
MOVQ SP, ·savedSP(SB) // preserve Go stack MOVQ SP, ·savedSP(SB) // preserve Go stack
MOVQ BP, ·savedBP(SB) // preserve frame pointer (vet requires save before clobber) MOVQ BP, ·savedBP(SB) // preserve frame pointer (vet requires save before clobber)
MOVQ R14, ·savedR14(SB) // preserve the goroutine pointer MOVQ R14, ·savedR14(SB) // preserve the goroutine pointer
MOVQ $SENTINEL_BP, BP // sentinel in BP MOVQ $SENTINEL_BP, BP // sentinel in BP
MOVQ $SENTINEL_R14, R14 // sentinel in R14 MOVQ $SENTINEL_R14, R14 // sentinel in R14
MOVQ stack+8(FP), SP // switch to prepared stack MOVQ stack+8(FP), SP // switch to prepared stack
JMP AX JMP AX
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function // leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
// declaration, so no ABIInternal wrapper is generated; the JIT function's // declaration, so no ABIInternal wrapper is generated; the JIT function's
// RET lands here directly, seeing BP and R14 exactly as the function left // RET lands here directly, seeing BP and R14 exactly as the function left
// them. It checks the sentinels, records violations in abiResult, then // them. It checks the sentinels, records violations in abiResult, then
// restores the Go stack and returns. // restores the Go stack and returns.
TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0 TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
// Check BP against the sentinel. // Check BP against the sentinel.
MOVQ $SENTINEL_BP, CX MOVQ $SENTINEL_BP, CX
@@ -58,10 +58,10 @@ bp_ok:
ORQ $2, ·abiResult(SB) ORQ $2, ·abiResult(SB)
r14_ok: r14_ok:
MOVQ ·savedR14(SB), R14 // restore the goroutine pointer: the runtime MOVQ ·savedR14(SB), R14 // restore the goroutine pointer: the runtime
// needs it the moment Go code resumes, whether // needs it the moment Go code resumes, whether
// or not the kernel violated it (the violation // or not the kernel violated it (the violation
// is already recorded in abiResult) // is already recorded in abiResult)
MOVQ ·savedBP(SB), BP // restore the frame pointer MOVQ ·savedBP(SB), BP // restore the frame pointer
MOVQ ·savedSP(SB), SP MOVQ ·savedSP(SB), SP
RET RET
+30 -27
View File
@@ -21,12 +21,12 @@
// cannot cover it. // cannot cover it.
// Sentinel values chosen to be unlikely in normal execution. // Sentinel values chosen to be unlikely in normal execution.
#define SENTINEL_FP 0xDEADBEEFCAFEF00D #define SENTINEL_FP 0xDEADBEEFCAFEF00D
#define SENTINEL_G 0x0BADF00DDEADBEEF #define SENTINEL_G 0x0BADF00DDEADBEEF
// GLOBL holding the raw address of the leave trampoline, read by Go. // GLOBL holding the raw address of the leave trampoline, read by Go.
GLOBL ·leaveCheckedPtr(SB), NOPTR, $8 GLOBL ·leaveCheckedPtr(SB), NOPTR, $8
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB) DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
// func enterJITChecked(fn uintptr, stack uintptr) // func enterJITChecked(fn uintptr, stack uintptr)
// Sets sentinels in R29, R28 and R18, switches to the prepared stack and // 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 // leaveJITCheckedRaw (read from leaveCheckedPtr). Only R0 and R3 are used
// as scratch: caller-saved, and not among the checked registers. // as scratch: caller-saved, and not among the checked registers.
TEXT ·enterJITChecked(SB), NOSPLIT, $0-16 TEXT ·enterJITChecked(SB), NOSPLIT, $0-16
MOVD fn+0(FP), R0 // target (before SP switch) MOVD fn+0(FP), R0 // target (before SP switch)
MOVD R30, savedLR(SB) // save link register MOVD R30, savedLR(SB) // save link register
MOVD R3, savedSP(SB) // save Go stack pointer MOVD R3, savedSP(SB) // save Go stack pointer
MOVD R29, savedFP(SB) // save frame pointer (vet requires save before clobber) MOVD R29, savedFP(SB) // save frame pointer (vet requires save before clobber)
MOVD g, savedG(SB) // save g MOVD g, savedG(SB) // save g
MOVD $SENTINEL_FP, R29 // sentinel in the frame pointer MOVD $SENTINEL_FP, R29 // sentinel in the frame pointer
MOVD $SENTINEL_G, g // sentinel in g MOVD $SENTINEL_G, g // sentinel in g
MOVD stack+8(FP), R3 // load prepared stack pointer MOVD stack+8(FP), R3 // load prepared stack pointer
MOVD 0(R3), R30 // load leaveJITCheckedRaw into LR MOVD 0(R3), R30 // load leaveJITCheckedRaw into LR
MOVD R3, RSP // SP stays on the leave slot: the kernel MOVD R3, RSP // SP stays on the leave slot: the kernel
// reads its first argument at SP+8 // reads its first argument at SP+8
JMP (R0) // branch to JIT function JMP (R0) // branch to JIT function
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function // leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
// declaration, so no ABIInternal wrapper is generated; the JIT function's // declaration, so no ABIInternal wrapper is generated; the JIT function's
// RET lands here directly, seeing R29 and g exactly as the function left // RET lands here directly, seeing R29 and g exactly as the function left
// them. It checks the sentinels, records violations in abiResult, then // them. It checks the sentinels, records violations in abiResult, then
// restores the Go stack and returns. // restores the Go stack and returns.
TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0 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. // Check the frame pointer against the sentinel.
MOVD $SENTINEL_FP, R3 MOVD $SENTINEL_FP, R3
@@ -61,6 +61,7 @@ TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
BEQ fp_ok BEQ fp_ok
MOVD $1, R5 MOVD $1, R5
ORR R5, R4, R4 ORR R5, R4, R4
fp_ok: fp_ok:
// Check g against the sentinel. // Check g against the sentinel.
MOVD $SENTINEL_G, R3 MOVD $SENTINEL_G, R3
@@ -68,22 +69,24 @@ fp_ok:
BEQ g_ok BEQ g_ok
MOVD $2, R5 MOVD $2, R5
ORR R5, R4, R4 ORR R5, R4, R4
g_ok: g_ok:
CBZ R4, restore CBZ R4, restore
MOVD R4, ·abiResult(SB) MOVD R4, ·abiResult(SB)
restore: restore:
MOVD savedSP(SB), R3 // restore Go stack pointer MOVD savedSP(SB), R3 // restore Go stack pointer
MOVD R3, RSP MOVD R3, RSP
MOVD savedLR(SB), R30 // restore link register MOVD savedLR(SB), R30 // restore link register
MOVD savedFP(SB), R29 // restore frame pointer: Go code needs it the MOVD savedFP(SB), R29 // restore frame pointer: Go code needs it the
// moment it resumes, violation or not // moment it resumes, violation or not
MOVD savedG(SB), g // restore g MOVD savedG(SB), g // restore g
RET // return to Go caller RET // return to Go caller
// Package-level storage for the saved frame pointer. Like savedSP and // Package-level storage for the saved frame pointer. Like savedSP and
// savedLR in trampoline_arm64.s, this is assembly-side state: the amd64 // 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 // checked trampoline saves the caller's frame pointer for vet's sake and
// never restores it, and this file mirrors that. // never restores it, and this file mirrors that.
GLOBL savedFP(SB), NOPTR, $8 GLOBL savedFP(SB), NOPTR, $8
GLOBL savedG(SB), NOPTR, $8 GLOBL savedG(SB), NOPTR, $8
+22 -22
View File
@@ -18,11 +18,11 @@
// spells this register "g"; R22 is not accepted. // spells this register "g"; R22 is not accepted.
// Sentinel value chosen to be unlikely in normal execution. // 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 holding the raw address of the leave trampoline, read by Go.
GLOBL ·leaveCheckedPtr(SB), NOPTR, $8 GLOBL ·leaveCheckedPtr(SB), NOPTR, $8
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB) DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
// func enterJITChecked(fn uintptr, stack uintptr) // func enterJITChecked(fn uintptr, stack uintptr)
// Sets a sentinel in g (R22), switches to the prepared stack and jumps to // 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 // leaveJITCheckedRaw (read from leaveCheckedPtr). Only R4 and R5 are used
// as scratch: caller-saved, and R22 is not among them. // as scratch: caller-saved, and R22 is not among them.
TEXT ·enterJITChecked(SB), NOSPLIT, $0-16 TEXT ·enterJITChecked(SB), NOSPLIT, $0-16
MOVV fn+0(FP), R4 // target function address (A0) MOVV fn+0(FP), R4 // target function address (A0)
MOVV R1, savedRA(SB) // save return address (RA) MOVV R1, savedRA(SB) // save return address (RA)
MOVV R3, savedSP(SB) // save Go stack pointer (SP) MOVV R3, savedSP(SB) // save Go stack pointer (SP)
MOVV g, savedG(SB) // save g MOVV g, savedG(SB) // save g
MOVV $SENTINEL_G, g // sentinel in g MOVV $SENTINEL_G, g // sentinel in g
MOVV stack+8(FP), R5 // load prepared stack pointer (A1) MOVV stack+8(FP), R5 // load prepared stack pointer (A1)
MOVV 0(R5), R1 // load leaveJITCheckedRaw into RA MOVV 0(R5), R1 // load leaveJITCheckedRaw into RA
MOVV R5, R3 // SP stays on the leave slot: the kernel MOVV R5, R3 // SP stays on the leave slot: the kernel
// reads its first argument at SP+8 // reads its first argument at SP+8
JIRL R0, R4, 0 // jump to JIT function JIRL R0, R4, 0 // jump to JIT function
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function // leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
// declaration, so no ABIInternal wrapper is generated; the JIT function's // declaration, so no ABIInternal wrapper is generated; the JIT function's
// RET lands here directly, seeing g exactly as the function left it. It // RET lands here directly, seeing g exactly as the function left it. It
// checks the sentinel, records violations in abiResult, then restores the // checks the sentinel, records violations in abiResult, then restores the
// Go stack and returns. // Go stack and returns.
TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0 TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
// Check g against the sentinel. // Check g against the sentinel.
MOVV $SENTINEL_G, R5 MOVV $SENTINEL_G, R5
@@ -56,11 +56,11 @@ TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
MOVV R4, ·abiResult(SB) MOVV R4, ·abiResult(SB)
g_ok: g_ok:
MOVV savedSP(SB), R5 // restore Go stack pointer MOVV savedSP(SB), R5 // restore Go stack pointer
MOVV R5, R3 MOVV R5, R3
MOVV savedRA(SB), R1 // restore return address MOVV savedRA(SB), R1 // restore return address
MOVV savedG(SB), g // restore g: Go code needs it the moment it MOVV savedG(SB), g // restore g: Go code needs it the moment it
// resumes, violation or not // resumes, violation or not
JIRL R0, R1, 0 // return to Go caller JIRL R0, R1, 0 // return to Go caller
GLOBL savedG(SB), NOPTR, $8 GLOBL savedG(SB), NOPTR, $8
+22 -22
View File
@@ -18,11 +18,11 @@
// spells this register "g"; X27 is not accepted. // spells this register "g"; X27 is not accepted.
// Sentinel value chosen to be unlikely in normal execution. // 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 holding the raw address of the leave trampoline, read by Go.
GLOBL ·leaveCheckedPtr(SB), NOPTR, $8 GLOBL ·leaveCheckedPtr(SB), NOPTR, $8
DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB) DATA ·leaveCheckedPtr(SB)/8, $·leaveJITCheckedRaw(SB)
// func enterJITChecked(fn uintptr, stack uintptr) // func enterJITChecked(fn uintptr, stack uintptr)
// Sets a sentinel in g (X27), switches to the prepared stack and jumps to // 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 // leaveJITCheckedRaw (read from leaveCheckedPtr). Only X5 and X6 are used
// as scratch: caller-saved, and X27 is not among them. // as scratch: caller-saved, and X27 is not among them.
TEXT ·enterJITChecked(SB), NOSPLIT, $0-16 TEXT ·enterJITChecked(SB), NOSPLIT, $0-16
MOV fn+0(FP), X5 // target function address (T0) MOV fn+0(FP), X5 // target function address (T0)
MOV X1, savedRA(SB) // save return address MOV X1, savedRA(SB) // save return address
MOV X2, savedSP(SB) // save Go stack pointer MOV X2, savedSP(SB) // save Go stack pointer
MOV g, savedG(SB) // save g MOV g, savedG(SB) // save g
MOV $SENTINEL_G, g // sentinel in g MOV $SENTINEL_G, g // sentinel in g
MOV stack+8(FP), X6 // load prepared stack pointer (T1) MOV stack+8(FP), X6 // load prepared stack pointer (T1)
LD 0(X6), X1 // load leaveJITCheckedRaw into RA LD 0(X6), X1 // load leaveJITCheckedRaw into RA
MOV X6, X2 // SP stays on the leave slot: the kernel MOV X6, X2 // SP stays on the leave slot: the kernel
// reads its first argument at SP+8 // reads its first argument at SP+8
JALR X0, 0(X5) // jump to JIT function JALR X0, 0(X5) // jump to JIT function
// leaveJITCheckedRaw is the raw return trampoline. It has NO Go function // leaveJITCheckedRaw is the raw return trampoline. It has NO Go function
// declaration, so no ABIInternal wrapper is generated; the JIT function's // declaration, so no ABIInternal wrapper is generated; the JIT function's
// RET lands here directly, seeing g exactly as the function left it. It // RET lands here directly, seeing g exactly as the function left it. It
// checks the sentinel, records violations in abiResult, then restores the // checks the sentinel, records violations in abiResult, then restores the
// Go stack and returns. // Go stack and returns.
TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0 TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
// Check g against the sentinel. // Check g against the sentinel.
MOV $SENTINEL_G, X6 MOV $SENTINEL_G, X6
@@ -56,11 +56,11 @@ TEXT ·leaveJITCheckedRaw(SB), NOSPLIT, $0-0
MOV X7, ·abiResult(SB) MOV X7, ·abiResult(SB)
g_ok: g_ok:
MOV savedSP(SB), X6 // restore Go stack pointer MOV savedSP(SB), X6 // restore Go stack pointer
MOV X6, X2 MOV X6, X2
MOV savedRA(SB), X1 // restore return address MOV savedRA(SB), X1 // restore return address
MOV savedG(SB), g // restore g: Go code needs it the moment it MOV savedG(SB), g // restore g: Go code needs it the moment it
// resumes, violation or not // resumes, violation or not
JALR X0, 0(X1) // return to Go caller JALR X0, 0(X1) // return to Go caller
GLOBL savedG(SB), NOPTR, $8 GLOBL savedG(SB), NOPTR, $8
+5 -5
View File
@@ -18,13 +18,13 @@
// Switches to the prepared stack and jumps to fn. Does not return normally; // Switches to the prepared stack and jumps to fn. Does not return normally;
// the JIT function's RET transfers control to leaveJIT. // the JIT function's RET transfers control to leaveJIT.
TEXT ·enterJIT(SB), NOSPLIT, $0-16 TEXT ·enterJIT(SB), NOSPLIT, $0-16
MOVQ fn+0(FP), AX // target function address (before SP switch) MOVQ fn+0(FP), AX // target function address (before SP switch)
MOVQ SP, ·savedSP(SB) // preserve the Go stack pointer MOVQ SP, ·savedSP(SB) // preserve the Go stack pointer
MOVQ stack+8(FP), SP // switch to the prepared stack MOVQ stack+8(FP), SP // switch to the prepared stack
JMP AX JMP AX
// func leaveJIT() // func leaveJIT()
// Restores the Go stack pointer and returns to enterJIT's caller. // Restores the Go stack pointer and returns to enterJIT's caller.
TEXT ·leaveJIT(SB), NOSPLIT, $0-0 TEXT ·leaveJIT(SB), NOSPLIT, $0-0
MOVQ ·savedSP(SB), SP MOVQ ·savedSP(SB), SP
RET RET
+17 -16
View File
@@ -15,32 +15,33 @@
// func enterJIT(fn uintptr, stack uintptr) // func enterJIT(fn uintptr, stack uintptr)
TEXT ·enterJIT(SB), NOSPLIT, $0-16 TEXT ·enterJIT(SB), NOSPLIT, $0-16
MOVD fn+0(FP), R0 // target function address MOVD fn+0(FP), R0 // target function address
MOVD R30, savedLR(SB) // save link register MOVD R30, savedLR(SB) // save link register
MOVD R3, savedSP(SB) // save Go stack pointer MOVD R3, savedSP(SB) // save Go stack pointer
MOVD stack+8(FP), R3 // load prepared stack pointer MOVD stack+8(FP), R3 // load prepared stack pointer
MOVD 0(R3), R30 // load leaveJIT address into LR MOVD 0(R3), R30 // load leaveJIT address into LR
MOVD R3, RSP // switch to the prepared stack: SP stays on MOVD R3, RSP // switch to the prepared stack: SP stays on
// the leave slot, so the kernel reads its // the leave slot, so the kernel reads its
// first argument at SP+8 per the frame // first argument at SP+8 per the frame
// convention (amd64 lays the stack out the // convention (amd64 lays the stack out the
// same way) // same way)
JMP (R0) // branch to JIT function JMP (R0) // branch to JIT function
// func leaveJIT() // func leaveJIT()
TEXT ·leaveJIT(SB), NOSPLIT, $0-0 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 R3, RSP
MOVD savedLR(SB), R30 // restore link register MOVD savedLR(SB), R30 // restore link register
RET // return to Go caller RET // return to Go caller
// leaveRawAddr holds the raw .abi0 address of leaveJIT, read by call_arm64.go // 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 // in preference to reflect.ValueOf(leaveJIT), which returns the address of the
// ABIInternal wrapper the linker interposes: the wrapper's prologue clobbers // ABIInternal wrapper the linker interposes: the wrapper's prologue clobbers
// the saved-register window the JIT call depends on. // the saved-register window the JIT call depends on.
GLOBL ·leaveRawAddr(SB), NOPTR, $8 GLOBL ·leaveRawAddr(SB), NOPTR, $8
DATA ·leaveRawAddr(SB)/8, $·leaveJIT(SB) DATA ·leaveRawAddr(SB)/8, $·leaveJIT(SB)
// Package-level storage for saved registers. // Package-level storage for saved registers.
GLOBL savedLR(SB), NOPTR, $8 GLOBL savedLR(SB), NOPTR, $8
GLOBL savedSP(SB), NOPTR, $8 GLOBL savedSP(SB), NOPTR, $8
+15 -14
View File
@@ -11,22 +11,23 @@
// func enterJIT(fn uintptr, stack uintptr) // func enterJIT(fn uintptr, stack uintptr)
TEXT ·enterJIT(SB), NOSPLIT, $0-16 TEXT ·enterJIT(SB), NOSPLIT, $0-16
MOVV fn+0(FP), R4 // target function address (A0) MOVV fn+0(FP), R4 // target function address (A0)
MOVV R1, savedRA(SB) // save return address (RA) MOVV R1, savedRA(SB) // save return address (RA)
MOVV R3, savedSP(SB) // save Go stack pointer (SP) MOVV R3, savedSP(SB) // save Go stack pointer (SP)
MOVV stack+8(FP), R5 // load prepared stack pointer (A1) MOVV stack+8(FP), R5 // load prepared stack pointer (A1)
MOVV 0(R5), R1 // load leaveJIT address into RA MOVV 0(R5), R1 // load leaveJIT address into RA
MOVV R5, R3 // switch to the prepared stack: SP stays on MOVV R5, R3 // switch to the prepared stack: SP stays on
// the leave slot, so the kernel reads its // the leave slot, so the kernel reads its
// first argument at SP+8 // first argument at SP+8
JIRL R0, R4, 0 // jump to JIT function JIRL R0, R4, 0 // jump to JIT function
// func leaveJIT() // func leaveJIT()
TEXT ·leaveJIT(SB), NOSPLIT, $0-0 TEXT ·leaveJIT(SB), NOSPLIT, $0-0
MOVV savedSP(SB), R5 // restore Go stack pointer MOVV savedSP(SB), R5 // restore Go stack pointer
MOVV R5, R3 // restore SP MOVV R5, R3 // restore SP
MOVV savedRA(SB), R1 // restore return address MOVV savedRA(SB), R1 // restore return address
JIRL R0, R1, 0 // return to Go caller JIRL R0, R1, 0 // return to Go caller
GLOBL savedRA(SB), NOPTR, $8 GLOBL savedRA(SB), NOPTR, $8
GLOBL savedSP(SB), NOPTR, $8 GLOBL savedSP(SB), NOPTR, $8
+15 -14
View File
@@ -11,22 +11,23 @@
// func enterJIT(fn uintptr, stack uintptr) // func enterJIT(fn uintptr, stack uintptr)
TEXT ·enterJIT(SB), NOSPLIT, $0-16 TEXT ·enterJIT(SB), NOSPLIT, $0-16
MOV fn+0(FP), X5 // target function address (T0) MOV fn+0(FP), X5 // target function address (T0)
MOV X1, savedRA(SB) // save return address MOV X1, savedRA(SB) // save return address
MOV X2, savedSP(SB) // save Go stack pointer MOV X2, savedSP(SB) // save Go stack pointer
MOV stack+8(FP), X6 // load prepared stack pointer (T1) MOV stack+8(FP), X6 // load prepared stack pointer (T1)
LD 0(X6), X1 // load leaveJIT address into RA LD 0(X6), X1 // load leaveJIT address into RA
MOV X6, X2 // switch to the prepared stack: SP stays on MOV X6, X2 // switch to the prepared stack: SP stays on
// the leave slot, so the kernel reads its // the leave slot, so the kernel reads its
// first argument at SP+8 // first argument at SP+8
JALR X0, 0(X5) // jump to JIT function JALR X0, 0(X5) // jump to JIT function
// func leaveJIT() // func leaveJIT()
TEXT ·leaveJIT(SB), NOSPLIT, $0-0 TEXT ·leaveJIT(SB), NOSPLIT, $0-0
MOV savedSP(SB), X6 // restore Go stack pointer MOV savedSP(SB), X6 // restore Go stack pointer
MOV X6, X2 // restore SP MOV X6, X2 // restore SP
MOV savedRA(SB), X1 // restore return address MOV savedRA(SB), X1 // restore return address
JALR X0, 0(X1) // return to Go caller JALR X0, 0(X1) // return to Go caller
GLOBL savedRA(SB), NOPTR, $8 GLOBL savedRA(SB), NOPTR, $8
GLOBL savedSP(SB), NOPTR, $8 GLOBL savedSP(SB), NOPTR, $8