feat(asm): emit the loong64 stack-split guard for big frames

This commit is contained in:
2026-09-14 22:38:58 +02:00
parent db50b98179
commit 70218e84ba
7 changed files with 294 additions and 67 deletions
+11 -4
View File
@@ -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))