]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/riscv64: add initial spill support
authorMeng Zhuo <mzh@golangcn.org>
Sun, 31 Oct 2021 13:12:45 +0000 (21:12 +0800)
committermzh <mzh@golangcn.org>
Sun, 20 Mar 2022 03:01:15 +0000 (03:01 +0000)
This CL adds some initial support for spilling and reloading
registers in the new ABI for RISCV64.

Change-Id: I5e2b4d93c33c528809d569e5a442bb302074be78
Reviewed-on: https://go-review.googlesource.com/c/go/+/360215
Reviewed-by: Cherry Mui <cherryyz@google.com>
Trust: mzh <mzh@golangcn.org>
Run-TryBot: mzh <mzh@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/riscv64/galign.go
src/cmd/compile/internal/riscv64/ssa.go

index 846ed8fb3802e43d603abe6bb0de2617a177dca8..4244afba3e19689286c03633849890e449facb32 100644 (file)
@@ -21,4 +21,6 @@ func Init(arch *ssagen.ArchInfo) {
        arch.SSAMarkMoves = ssaMarkMoves
        arch.SSAGenValue = ssaGenValue
        arch.SSAGenBlock = ssaGenBlock
+       arch.LoadRegResult = loadRegResult
+       arch.SpillArgReg = spillArgReg
 }
index d4faee9ee3424427f8a758f73667349b4956e5be..b6e6dc1a03d3bcf79667cb39f055e79b19fd2b06 100644 (file)
@@ -7,6 +7,7 @@ package riscv64
 import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/ir"
+       "cmd/compile/internal/objw"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/ssagen"
        "cmd/compile/internal/types"
@@ -231,6 +232,17 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                p.From.Reg = v.Args[0].Reg()
                ssagen.AddrAuto(&p.To, v)
        case ssa.OpArgIntReg, ssa.OpArgFloatReg:
+               // The assembler needs to wrap the entry safepoint/stack growth code with spill/unspill
+               // The loop only runs once.
+               for _, a := range v.Block.Func.RegArgs {
+                       // Pass the spill/unspill information along to the assembler, offset by size of
+                       // the saved LR slot.
+                       addr := ssagen.SpillSlotAddr(a, riscv.REG_SP, base.Ctxt.FixedFrameSize())
+                       s.FuncInfo().AddSpill(
+                               obj.RegSpill{Reg: a.Reg, Addr: addr, Unspill: loadByType(a.Type), Spill: storeByType(a.Type)})
+               }
+               v.Block.Func.RegArgs = nil
+
                ssagen.CheckArgReg(v)
        case ssa.OpSP, ssa.OpSB, ssa.OpGetG:
                // nothing to do
@@ -775,3 +787,22 @@ func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
                b.Fatalf("Unhandled block: %s", b.LongString())
        }
 }
+
+func loadRegResult(s *ssagen.State, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog {
+       p := s.Prog(loadByType(t))
+       p.From.Type = obj.TYPE_MEM
+       p.From.Name = obj.NAME_AUTO
+       p.From.Sym = n.Linksym()
+       p.From.Offset = n.FrameOffset() + off
+       p.To.Type = obj.TYPE_REG
+       p.To.Reg = reg
+       return p
+}
+
+func spillArgReg(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog {
+       p = pp.Append(p, storeByType(t), obj.TYPE_REG, reg, 0, obj.TYPE_MEM, 0, n.FrameOffset()+off)
+       p.To.Name = obj.NAME_PARAM
+       p.To.Sym = n.Linksym()
+       p.Pos = p.Pos.WithNotStmt()
+       return p
+}