feat(asm): emit the loong64 stack-split guard for small and medium frames
This commit is contained in:
+28
-5
@@ -27,6 +27,7 @@ import (
|
||||
func assembleLOONG64(t *ast.Text) ([]byte, map[string]int, []Reloc, []LineEntry, []SpadjStep, error) {
|
||||
fi := loong64ComputeFrame(t)
|
||||
prologue := loong64Prologue(fi)
|
||||
guardLen := loong64GuardLen(fi)
|
||||
chain := loong64JumpChain(t)
|
||||
resolve := func(name string) string {
|
||||
if r, ok := chain[name]; ok {
|
||||
@@ -42,12 +43,12 @@ func assembleLOONG64(t *ast.Text) ([]byte, map[string]int, []Reloc, []LineEntry,
|
||||
// delta by autosize; the boundary is reported at the third instruction's
|
||||
// pc, exactly as the toolchain's pctospadj does.
|
||||
if fi.autosize != 0 {
|
||||
spadj = append(spadj, SpadjStep{PC: 8, Value: fi.autosize})
|
||||
spadj = append(spadj, SpadjStep{PC: guardLen + 8, Value: fi.autosize})
|
||||
}
|
||||
|
||||
// Pass 1: label offsets from the instruction sizes.
|
||||
offsets := map[string]int{}
|
||||
pos := len(prologue)
|
||||
pos := guardLen + len(prologue)
|
||||
for _, stmt := range t.Body {
|
||||
switch s := stmt.(type) {
|
||||
case *ast.Label:
|
||||
@@ -57,9 +58,25 @@ func assembleLOONG64(t *ast.Text) ([]byte, map[string]int, []Reloc, []LineEntry,
|
||||
}
|
||||
}
|
||||
|
||||
// Pass 2: encode. Relocation offsets are recorded function-relative.
|
||||
out := append([]byte(nil), prologue...)
|
||||
pc := len(prologue)
|
||||
// Pass 2: encode. The guard prefix precedes the prologue; its branches
|
||||
// target the morestack block at the end of the function, which the first
|
||||
// pass has sized.
|
||||
bodyLen := 0
|
||||
{
|
||||
p := guardLen + len(prologue)
|
||||
for _, stmt := range t.Body {
|
||||
if in, ok := stmt.(*ast.Instr); ok {
|
||||
p += loong64InstrSize(in, fi)
|
||||
}
|
||||
}
|
||||
bodyLen = p - (guardLen + len(prologue))
|
||||
}
|
||||
var out []byte
|
||||
if fi.needSplit {
|
||||
out = append(out, loong64GuardBytes(fi, guardLen+len(prologue)+bodyLen)...)
|
||||
}
|
||||
out = append(out, prologue...)
|
||||
pc := guardLen + len(prologue)
|
||||
preCount := len(relocs)
|
||||
var lines []LineEntry
|
||||
for _, stmt := range t.Body {
|
||||
@@ -94,6 +111,12 @@ func assembleLOONG64(t *ast.Text) ([]byte, map[string]int, []Reloc, []LineEntry,
|
||||
out = append(out, code...)
|
||||
pc += len(code)
|
||||
}
|
||||
if fi.needSplit {
|
||||
block, blReloc := loong64MoreStackBlock(pc)
|
||||
out = append(out, block...)
|
||||
relocs = append(relocs, blReloc)
|
||||
pc += len(block)
|
||||
}
|
||||
return out, offsets, relocs, lines, spadj, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user