style: put the repository assembly in gasm fmt canonical form
Assisted-by: GLM 5.3 Flash
This commit is contained in:
Vendored
+5
-5
@@ -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
|
||||||
|
|||||||
Vendored
+10
-10
@@ -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
|
||||||
|
|||||||
Vendored
+13
-13
@@ -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
|
||||||
|
|||||||
Vendored
+12
-12
@@ -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
|
||||||
|
|||||||
Vendored
+22
-21
@@ -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
|
||||||
|
|||||||
Vendored
+28
-27
@@ -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
|
||||||
|
|||||||
Vendored
+30
-30
@@ -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
|
||||||
|
|||||||
Vendored
+32
-29
@@ -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
|
||||||
|
|||||||
Vendored
+33
-30
@@ -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
|
||||||
|
|||||||
Vendored
+19
-16
@@ -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
|
||||||
|
|||||||
Vendored
+14
-6
@@ -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
|
||||||
|
|||||||
Vendored
+2
-2
@@ -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
|
||||||
|
|||||||
Vendored
+87
-87
@@ -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
|
||||||
|
|||||||
Vendored
+106
-90
@@ -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
|
||||||
|
|||||||
Vendored
+1
-1
@@ -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
|
||||||
|
|||||||
Vendored
+8
-8
@@ -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
|
||||||
|
|||||||
Vendored
+13
-13
@@ -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
|
||||||
|
|||||||
Vendored
+3
-3
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user