diff options
| author | limeidan <limeidan@loongson.cn> | 2025-12-03 10:25:15 +0800 |
|---|---|---|
| committer | abner chenc <chenguoqi@loongson.cn> | 2026-03-18 18:08:52 -0700 |
| commit | 1e994e0a486afc976116e2d7a6ca7517fe150304 (patch) | |
| tree | 7c39b6354369d35f3177a116d92ad663ea5f5811 /src/cmd | |
| parent | 9def4acb06bf9167441caa8af37e27b3cdbf8cf0 (diff) | |
| download | go-1e994e0a486afc976116e2d7a6ca7517fe150304.tar.xz | |
cmd/link: modify the register used in trampoline
R30 is the callee's saved register; using it requires saving and then restoring.
Therefore, we replace it with a register saved by the caller.
R4~R19 are argument registers on loong64, and R20 is the only remaining usable
caller saved register. To use R20 in trampoline, we modified the registers used
by the LoweredMove/LoweredMoveLoop operations (originally using r20 and r21,
now changed to R23 and R24).
Change-Id: Ie7bba0caa30a764a45bcb47635c35c829036c5a2
Reviewed-on: https://go-review.googlesource.com/c/go/+/726140
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/compile/internal/loong64/ssa.go | 6 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go | 8 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/opGen.go | 12 | ||||
| -rw-r--r-- | src/cmd/internal/obj/loong64/doc.go | 12 | ||||
| -rw-r--r-- | src/cmd/link/internal/loong64/asm.go | 19 |
5 files changed, 31 insertions, 26 deletions
diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go index 7b3d314a15..326574b15f 100644 --- a/src/cmd/compile/internal/loong64/ssa.go +++ b/src/cmd/compile/internal/loong64/ssa.go @@ -706,7 +706,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { if dstReg == srcReg { break } - tmpReg := int16(loong64.REG_R20) + tmpReg := int16(loong64.REG_R23) n := v.AuxInt if n < 16 { v.Fatalf("Move too small %d", n) @@ -732,8 +732,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { if dstReg == srcReg { break } - countReg := int16(loong64.REG_R20) - tmpReg := int16(loong64.REG_R21) + countReg := int16(loong64.REG_R23) + tmpReg := int16(loong64.REG_R24) var off int64 n := v.AuxInt loopSize := int64(64) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index ee9a2cb3f2..1128f47e67 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -410,8 +410,8 @@ func init() { aux: "Int64", argLength: 3, reg: regInfo{ - inputs: []regMask{gp &^ buildReg("R20"), gp &^ buildReg("R20")}, - clobbers: buildReg("R20"), + inputs: []regMask{gp &^ buildReg("R23"), gp &^ buildReg("R23")}, + clobbers: buildReg("R23"), }, faultOnNilArg0: true, faultOnNilArg1: true, @@ -428,8 +428,8 @@ func init() { aux: "Int64", argLength: 3, reg: regInfo{ - inputs: []regMask{gp &^ buildReg("R20 R21"), gp &^ buildReg("R20 R21")}, - clobbers: buildReg("R20 R21"), + inputs: []regMask{gp &^ buildReg("R23 R24"), gp &^ buildReg("R23 R24")}, + clobbers: buildReg("R23 R24"), clobbersArg0: true, clobbersArg1: true, }, diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index a8f99f6a76..28b09a58d4 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -72101,10 +72101,10 @@ var opcodeTable = [...]opInfo{ faultOnNilArg1: true, reg: regInfo{ inputs: []inputInfo{ - {0, 1071120376}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R21 R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1071120376}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R21 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1067450360}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R24 R25 R26 R27 R28 R29 R31 + {1, 1067450360}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R24 R25 R26 R27 R28 R29 R31 }, - clobbers: 524288, // R20 + clobbers: 4194304, // R23 }, }, { @@ -72115,10 +72115,10 @@ var opcodeTable = [...]opInfo{ faultOnNilArg1: true, reg: regInfo{ inputs: []inputInfo{ - {0, 1070071800}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1070071800}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1059061752}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R25 R26 R27 R28 R29 R31 + {1, 1059061752}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R25 R26 R27 R28 R29 R31 }, - clobbers: 1572864, // R20 R21 + clobbers: 12582912, // R23 R24 clobbersArg0: true, clobbersArg1: true, }, diff --git a/src/cmd/internal/obj/loong64/doc.go b/src/cmd/internal/obj/loong64/doc.go index 19c9e05590..1cf83223f1 100644 --- a/src/cmd/internal/obj/loong64/doc.go +++ b/src/cmd/internal/obj/loong64/doc.go @@ -6,6 +6,18 @@ Package loong64 implements an LoongArch64 assembler. Go assembly syntax is different from GNU LoongArch64 syntax, but we can still follow the general rules to map between them. +# Register Convention + + Name | Alias | Meaning + ----------------------------------------------------------------------------------------------------------------------- + R0 | REGZERO | Constant zero + R1 | REGLINK | Return address + R3 | REGSP | Stack pointer + R12,R13,R14,R15,R20 | | For plt and trampoline, use with caution in assembly code, save before calling function + R22 | REGG | Goroutine pointer + R29 | REGCTXT | Context for closures + R30 | REGTMP | Tmp register used by assembler + # Instructions mnemonics mapping rules 1. Bit widths represented by various instruction suffixes and prefixes diff --git a/src/cmd/link/internal/loong64/asm.go b/src/cmd/link/internal/loong64/asm.go index 0ebdc61936..8100b4ed25 100644 --- a/src/cmd/link/internal/loong64/asm.go +++ b/src/cmd/link/internal/loong64/asm.go @@ -760,13 +760,6 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) { r := relocs.At(ri) switch r.Type() { case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_B26), objabi.R_CALLLOONG64: - if ldr.SymType(rs) == sym.SDYNIMPORT { - // Nothing to do. - // The plt symbol has not been added. If we add tramp - // here, plt will not work. - return - } - var t int64 // ldr.SymValue(rs) == 0 indicates a cross-package jump to a function that is not yet // laid out. Conservatively use a trampoline. This should be rare, as we lay out packages @@ -835,7 +828,7 @@ func gentramp(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, ta tramp.SetSize(12) // 3 instructions P := make([]byte, tramp.Size()) - o1 := uint32(0x1a00001e) // pcalau12i $r30, 0 + o1 := uint32(0x1a000014) // pcalau12i $r20, 0 ctxt.Arch.ByteOrder.PutUint32(P, o1) r1, _ := tramp.AddRel(objabi.R_LOONG64_ADDR_HI) r1.SetOff(0) @@ -843,7 +836,7 @@ func gentramp(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, ta r1.SetSym(target) r1.SetAdd(offset) - o2 := uint32(0x02c003de) // addi.d $r30, $r30, 0 + o2 := uint32(0x02c00294) // addi.d $r20, $r20, 0 ctxt.Arch.ByteOrder.PutUint32(P[4:], o2) r2, _ := tramp.AddRel(objabi.R_LOONG64_ADDR_LO) r2.SetOff(4) @@ -851,7 +844,7 @@ func gentramp(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, ta r2.SetSym(target) r2.SetAdd(offset) - o3 := uint32(0x4c0003c0) // jirl $r0, $r30, 0 + o3 := uint32(0x4c000280) // jirl $r0, $r20, 0 ctxt.Arch.ByteOrder.PutUint32(P[8:], o3) tramp.SetData(P) @@ -861,21 +854,21 @@ func gentrampgot(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, tramp.SetSize(12) // 3 instructions P := make([]byte, tramp.Size()) - o1 := uint32(0x1a00001e) // pcalau12i $r30, 0 + o1 := uint32(0x1a000014) // pcalau12i $r20, 0 ctxt.Arch.ByteOrder.PutUint32(P, o1) r1, _ := tramp.AddRel(objabi.R_LOONG64_GOT_HI) r1.SetOff(0) r1.SetSiz(4) r1.SetSym(target) - o2 := uint32(0x28c003de) // ld.d $r30, $r30, 0 + o2 := uint32(0x28c00294) // ld.d $r20, $r20, 0 ctxt.Arch.ByteOrder.PutUint32(P[4:], o2) r2, _ := tramp.AddRel(objabi.R_LOONG64_GOT_LO) r2.SetOff(4) r2.SetSiz(4) r2.SetSym(target) - o3 := uint32(0x4c0003c0) // jirl $r0, $r30, 0 + o3 := uint32(0x4c000280) // jirl $r0, $r20, 0 ctxt.Arch.ByteOrder.PutUint32(P[8:], o3) tramp.SetData(P) |
