feat(asm): emit the loong64 stack-split guard for big frames
This commit is contained in:
+11
-4
@@ -182,7 +182,7 @@ func arm64Prologue(fi arm64FrameInfo) []byte {
|
||||
|
||||
// arm64SubImmWords emits SUB $imm, SP, Rd: the immediate form when the value
|
||||
// fits the imm12 field, otherwise the toolchain materialises it into REGTMP
|
||||
// (R27) and subtracts the register.
|
||||
// (R27) and subtracts the register in the extended-register form.
|
||||
func arm64SubImmWords(imm uint32, rd uint32) []uint32 {
|
||||
if imm <= 0xFFF {
|
||||
return []uint32{a64AddSub(1, 1, 0, 0, imm, 31, rd)}
|
||||
@@ -191,7 +191,7 @@ func arm64SubImmWords(imm uint32, rd uint32) []uint32 {
|
||||
if err != nil {
|
||||
mov = nil
|
||||
}
|
||||
return append(wordsOf(mov), arm64DPSRWords(arm64OpSub, 27, 31, rd))
|
||||
return append(wordsOf(mov), arm64DPExtWords(arm64OpSub, 27, 31, rd))
|
||||
}
|
||||
|
||||
// arm64AddImmWords emits ADD $imm, SP, Rd with the same REGTMP fallback.
|
||||
@@ -203,7 +203,7 @@ func arm64AddImmWords(imm uint32, rd uint32) []uint32 {
|
||||
if err != nil {
|
||||
mov = nil
|
||||
}
|
||||
return append(wordsOf(mov), arm64DPSRWords(arm64OpAdd, 27, 31, rd))
|
||||
return append(wordsOf(mov), arm64DPExtWords(arm64OpAdd, 27, 31, rd))
|
||||
}
|
||||
|
||||
// arm64Return returns the bytes for a RET: the epilogue (restore FP/LR and
|
||||
@@ -326,6 +326,13 @@ func arm64DPSRWords(base uint32, rm, rn, rd uint32) uint32 {
|
||||
return base | rm<<16 | rn<<5 | rd
|
||||
}
|
||||
|
||||
// arm64DPExtWords builds one data-processing (extended register) word, the
|
||||
// form the toolchain picks when a large immediate was materialised into
|
||||
// REGTMP before the operation: base | 1<<21 | Rm<<16 | UXTX<<13 | Rn<<5 | Rd.
|
||||
func arm64DPExtWords(base, rm, rn, rd uint32) uint32 {
|
||||
return base | 1<<21 | rm<<16 | 3<<13 | rn<<5 | rd
|
||||
}
|
||||
|
||||
// wordsOf converts little-endian instruction bytes back to words.
|
||||
func wordsOf(b []byte) []uint32 {
|
||||
ws := make([]uint32, 0, len(b)/4)
|
||||
@@ -359,7 +366,7 @@ func arm64GuardBytes(fi arm64FrameInfo, blockStart int) []byte {
|
||||
}
|
||||
ws = append(ws, wordsOf(mov)...)
|
||||
ml := len(mov) / 4
|
||||
ws = append(ws, arm64DPSRWords(arm64OpSubs, 27, 31, 17)) // SUBS R27, RSP, R17
|
||||
ws = append(ws, arm64DPExtWords(arm64OpSubs, 27, 31, 17)) // SUBS R17, RSP, R27
|
||||
ws = append(ws, br(8+ml, a64CondLO))
|
||||
ws = append(ws, arm64DPSRWords(arm64OpSubs, 16, 17, 31)) // CMP R16, R17
|
||||
ws = append(ws, br(8+ml+8, a64CondLS))
|
||||
|
||||
Reference in New Issue
Block a user