Skip to content

Commit 11dbbaf

Browse files
sophie-zhaoabner-chenc
authored andcommitted
cmd/internal/obj/loong64: add support for MOV{GR2FCSR/FCSR2GR/FR2CF/CF2FR} instructions
Go asm syntax example: MOVV R4, FCSR0 MOVV FCSR1, R5 MOVV F4, FCC0 MOVV FCC1, F5 Equivalent platform assembler syntax: movgr2fcsr fcsr0, r4 movfcsr2gr r5, fcsr1 movfr2cf fcc0, f4 movcf2fr f5, fcc1 Ref: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html This change also merges the case of floating point move instructions and add checks for the range of special registers. Change-Id: Ib08fbce83e7a31dc0ab4857bf9ba959855241d1c Reviewed-on: https://go-review.googlesource.com/c/go/+/580279 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: abner chenc <chenguoqi@loongson.cn> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
1 parent 67c3f01 commit 11dbbaf

File tree

2 files changed

+81
-48
lines changed

2 files changed

+81
-48
lines changed

src/cmd/asm/internal/asm/testdata/loong64enc1.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,10 @@ lable2:
213213
RDTIMEHW R4, R0 // 80640000
214214
RDTIMED R4, R5 // 85680000
215215

216+
MOVV R4, FCSR3 // 83c01401
217+
MOVV FCSR3, R4 // 64c81401
218+
MOVV F4, FCC0 // 80d01401
219+
MOVV FCC0, F4 // 04d41401
216220
MOVV FCC0, R4 // 04dc1401
217221
MOVV R4, FCC0 // 80d81401
218222

src/cmd/internal/obj/loong64/asm.go

Lines changed: 77 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,15 @@ var optab = []Optab{
256256
{AMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
257257

258258
{AMOVW, C_REG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
259-
{AMOVW, C_FREG, C_NONE, C_NONE, C_REG, C_NONE, 31, 4, 0, 0},
260-
{AMOVV, C_REG, C_NONE, C_NONE, C_FREG, C_NONE, 47, 4, 0, 0},
261-
{AMOVV, C_FREG, C_NONE, C_NONE, C_REG, C_NONE, 48, 4, 0, 0},
262-
263-
{AMOVV, C_FCCREG, C_NONE, C_NONE, C_REG, C_NONE, 63, 4, 0, 0},
264-
{AMOVV, C_REG, C_NONE, C_NONE, C_FCCREG, C_NONE, 64, 4, 0, 0},
259+
{AMOVV, C_REG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
260+
{AMOVW, C_FREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
261+
{AMOVV, C_FREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
262+
{AMOVV, C_FCCREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
263+
{AMOVV, C_FCSRREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
264+
{AMOVV, C_REG, C_NONE, C_NONE, C_FCCREG, C_NONE, 30, 4, 0, 0},
265+
{AMOVV, C_REG, C_NONE, C_NONE, C_FCSRREG, C_NONE, 30, 4, 0, 0},
266+
{AMOVV, C_FREG, C_NONE, C_NONE, C_FCCREG, C_NONE, 30, 4, 0, 0},
267+
{AMOVV, C_FCCREG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
265268

266269
{AMOVW, C_ADDCON, C_NONE, C_NONE, C_FREG, C_NONE, 34, 8, 0, 0},
267270
{AMOVW, C_ANDCON, C_NONE, C_NONE, C_FREG, C_NONE, 34, 8, 0, 0},
@@ -607,19 +610,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
607610
return C_NONE
608611

609612
case obj.TYPE_REG:
610-
if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
611-
return C_REG
612-
}
613-
if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
614-
return C_FREG
615-
}
616-
if REG_FCSR0 <= a.Reg && a.Reg <= REG_FCSR31 {
617-
return C_FCSRREG
618-
}
619-
if REG_FCC0 <= a.Reg && a.Reg <= REG_FCC31 {
620-
return C_FCCREG
621-
}
622-
return C_GOK
613+
return c.rclass(a.Reg)
623614

624615
case obj.TYPE_MEM:
625616
switch a.Name {
@@ -778,21 +769,27 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
778769
return C_GOK
779770
}
780771

772+
// In Loong64,there are 8 CFRs, denoted as fcc0-fcc7.
773+
// There are 4 FCSRs, denoted as fcsr0-fcsr3.
781774
func (c *ctxt0) rclass(r int16) int {
782775
switch {
783776
case REG_R0 <= r && r <= REG_R31:
784777
return C_REG
785778
case REG_F0 <= r && r <= REG_F31:
786779
return C_FREG
787-
case REG_FCC0 <= r && r <= REG_FCC31:
780+
case REG_FCC0 <= r && r <= REG_FCC7:
788781
return C_FCCREG
789-
case REG_FCSR0 <= r && r <= REG_FCSR31:
782+
case REG_FCSR0 <= r && r <= REG_FCSR3:
790783
return C_FCSRREG
791784
}
792785

793786
return C_GOK
794787
}
795788

789+
func oclass(a *obj.Addr) int {
790+
return int(a.Class) - 1
791+
}
792+
796793
func prasm(p *obj.Prog) {
797794
fmt.Printf("%v\n", p)
798795
}
@@ -1179,10 +1176,6 @@ func buildop(ctxt *obj.Link) {
11791176
}
11801177
}
11811178

1182-
func OP_TEN(x uint32, y uint32) uint32 {
1183-
return x<<21 | y<<10
1184-
}
1185-
11861179
// r1 -> rk
11871180
// r2 -> rj
11881181
// r3 -> rd
@@ -1514,12 +1507,8 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
15141507
o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.From.Reg))
15151508
}
15161509

1517-
case 30: // movw r,fr
1518-
a := OP_TEN(8, 1321) // movgr2fr.w
1519-
o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
1520-
1521-
case 31: // movw fr,r
1522-
a := OP_TEN(8, 1325) // movfr2gr.s
1510+
case 30: // mov gr/fr/fcc/fcsr, fr/fcc/fcsr/gr
1511+
a := c.specailFpMovInst(p.As, oclass(&p.From), oclass(&p.To))
15231512
o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
15241513

15251514
case 34: // mov $con,fr
@@ -1528,8 +1517,9 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
15281517
if o.from1 == C_ANDCON {
15291518
a = AOR
15301519
}
1520+
a2 := c.specailFpMovInst(p.As, C_REG, oclass(&p.To))
15311521
o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
1532-
o2 = OP_RR(OP_TEN(8, 1321), uint32(REGTMP), uint32(p.To.Reg)) // movgr2fr.w
1522+
o2 = OP_RR(a2, uint32(REGTMP), uint32(p.To.Reg))
15331523

15341524
case 35: // mov r,lext/auto/oreg
15351525
v := c.regoff(&p.To)
@@ -1554,14 +1544,6 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
15541544
case 40: // word
15551545
o1 = uint32(c.regoff(&p.From))
15561546

1557-
case 47: // movv r,fr
1558-
a := OP_TEN(8, 1322) // movgr2fr.d
1559-
o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
1560-
1561-
case 48: // movv fr,r
1562-
a := OP_TEN(8, 1326) // movfr2gr.d
1563-
o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
1564-
15651547
case 49:
15661548
if p.As == ANOOP {
15671549
// andi r0, r0, 0
@@ -1570,6 +1552,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
15701552
// undef
15711553
o1 = OP_15I(c.opi(ABREAK), 0)
15721554
}
1555+
15731556
// relocation operations
15741557
case 50: // mov r,addr ==> pcalau12i + sw
15751558
o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
@@ -1726,14 +1709,6 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
17261709
case 62: // rdtimex rd, rj
17271710
o1 = OP_RR(c.oprr(p.As), uint32(p.To.Reg), uint32(p.RegTo2))
17281711

1729-
case 63: // movv c_fcc0, c_reg ==> movcf2gr rd, cj
1730-
a := OP_TEN(8, 1335)
1731-
o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
1732-
1733-
case 64: // movv c_reg, c_fcc0 ==> movgr2cf cd, rj
1734-
a := OP_TEN(8, 1334)
1735-
o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
1736-
17371712
case 65: // mov sym@GOT, r ==> pcalau12i + ld.d
17381713
o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
17391714
rel := obj.Addrel(c.cursym)
@@ -2119,6 +2094,60 @@ func (c *ctxt0) opirr(a obj.As) uint32 {
21192094
return 0
21202095
}
21212096

2097+
func (c *ctxt0) specailFpMovInst(a obj.As, fclass int, tclass int) uint32 {
2098+
switch a {
2099+
case AMOVV:
2100+
switch fclass {
2101+
case C_REG:
2102+
switch tclass {
2103+
case C_FREG:
2104+
return 0x452a << 10 // movgr2fr.d
2105+
case C_FCCREG:
2106+
return 0x4536 << 10 // movgr2cf
2107+
case C_FCSRREG:
2108+
return 0x4530 << 10 // movgr2fcsr
2109+
}
2110+
case C_FREG:
2111+
switch tclass {
2112+
case C_REG:
2113+
return 0x452e << 10 // movfr2gr.d
2114+
case C_FCCREG:
2115+
return 0x4534 << 10 // movfr2cf
2116+
}
2117+
case C_FCCREG:
2118+
switch tclass {
2119+
case C_REG:
2120+
return 0x4537 << 10 // movcf2gr
2121+
case C_FREG:
2122+
return 0x4535 << 10 // movcf2fr
2123+
}
2124+
case C_FCSRREG:
2125+
switch tclass {
2126+
case C_REG:
2127+
return 0x4532 << 10 // movfcsr2gr
2128+
}
2129+
}
2130+
2131+
case AMOVW:
2132+
switch fclass {
2133+
case C_REG:
2134+
switch tclass {
2135+
case C_FREG:
2136+
return 0x4529 << 10 // movgr2fr.w
2137+
}
2138+
case C_FREG:
2139+
switch tclass {
2140+
case C_REG:
2141+
return 0x452d << 10 // movfr2gr.s
2142+
}
2143+
}
2144+
}
2145+
2146+
c.ctxt.Diag("bad class combination: %s %s,%s\n", a, fclass, tclass)
2147+
2148+
return 0
2149+
}
2150+
21222151
func vshift(a obj.As) bool {
21232152
switch a {
21242153
case ASLLV,

0 commit comments

Comments
 (0)