aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorlimeidan <limeidan@loongson.cn>2025-12-03 10:25:15 +0800
committerabner chenc <chenguoqi@loongson.cn>2026-03-18 18:08:52 -0700
commit1e994e0a486afc976116e2d7a6ca7517fe150304 (patch)
tree7c39b6354369d35f3177a116d92ad663ea5f5811 /src/cmd
parent9def4acb06bf9167441caa8af37e27b3cdbf8cf0 (diff)
downloadgo-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.go6
-rw-r--r--src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go8
-rw-r--r--src/cmd/compile/internal/ssa/opGen.go12
-rw-r--r--src/cmd/internal/obj/loong64/doc.go12
-rw-r--r--src/cmd/link/internal/loong64/asm.go19
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)