@@ -256,12 +256,15 @@ var optab = []Optab{
256
256
{AMOVD , C_FREG , C_NONE , C_NONE , C_ADDR , C_NONE , 50 , 8 , 0 , 0 },
257
257
258
258
{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 },
265
268
266
269
{AMOVW , C_ADDCON , C_NONE , C_NONE , C_FREG , C_NONE , 34 , 8 , 0 , 0 },
267
270
{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 {
607
610
return C_NONE
608
611
609
612
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 )
623
614
624
615
case obj .TYPE_MEM :
625
616
switch a .Name {
@@ -778,21 +769,27 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
778
769
return C_GOK
779
770
}
780
771
772
+ // In Loong64,there are 8 CFRs, denoted as fcc0-fcc7.
773
+ // There are 4 FCSRs, denoted as fcsr0-fcsr3.
781
774
func (c * ctxt0 ) rclass (r int16 ) int {
782
775
switch {
783
776
case REG_R0 <= r && r <= REG_R31 :
784
777
return C_REG
785
778
case REG_F0 <= r && r <= REG_F31 :
786
779
return C_FREG
787
- case REG_FCC0 <= r && r <= REG_FCC31 :
780
+ case REG_FCC0 <= r && r <= REG_FCC7 :
788
781
return C_FCCREG
789
- case REG_FCSR0 <= r && r <= REG_FCSR31 :
782
+ case REG_FCSR0 <= r && r <= REG_FCSR3 :
790
783
return C_FCSRREG
791
784
}
792
785
793
786
return C_GOK
794
787
}
795
788
789
+ func oclass (a * obj.Addr ) int {
790
+ return int (a .Class ) - 1
791
+ }
792
+
796
793
func prasm (p * obj.Prog ) {
797
794
fmt .Printf ("%v\n " , p )
798
795
}
@@ -1179,10 +1176,6 @@ func buildop(ctxt *obj.Link) {
1179
1176
}
1180
1177
}
1181
1178
1182
- func OP_TEN (x uint32 , y uint32 ) uint32 {
1183
- return x << 21 | y << 10
1184
- }
1185
-
1186
1179
// r1 -> rk
1187
1180
// r2 -> rj
1188
1181
// r3 -> rd
@@ -1514,12 +1507,8 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
1514
1507
o1 = OP_12IRR (c .opirr (p .As ), uint32 (v ), uint32 (r ), uint32 (p .From .Reg ))
1515
1508
}
1516
1509
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 ))
1523
1512
o1 = OP_RR (a , uint32 (p .From .Reg ), uint32 (p .To .Reg ))
1524
1513
1525
1514
case 34 : // mov $con,fr
@@ -1528,8 +1517,9 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
1528
1517
if o .from1 == C_ANDCON {
1529
1518
a = AOR
1530
1519
}
1520
+ a2 := c .specailFpMovInst (p .As , C_REG , oclass (& p .To ))
1531
1521
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 ))
1533
1523
1534
1524
case 35 : // mov r,lext/auto/oreg
1535
1525
v := c .regoff (& p .To )
@@ -1554,14 +1544,6 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
1554
1544
case 40 : // word
1555
1545
o1 = uint32 (c .regoff (& p .From ))
1556
1546
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
-
1565
1547
case 49 :
1566
1548
if p .As == ANOOP {
1567
1549
// andi r0, r0, 0
@@ -1570,6 +1552,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
1570
1552
// undef
1571
1553
o1 = OP_15I (c .opi (ABREAK ), 0 )
1572
1554
}
1555
+
1573
1556
// relocation operations
1574
1557
case 50 : // mov r,addr ==> pcalau12i + sw
1575
1558
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) {
1726
1709
case 62 : // rdtimex rd, rj
1727
1710
o1 = OP_RR (c .oprr (p .As ), uint32 (p .To .Reg ), uint32 (p .RegTo2 ))
1728
1711
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
-
1737
1712
case 65 : // mov sym@GOT, r ==> pcalau12i + ld.d
1738
1713
o1 = OP_IR (c .opir (APCALAU12I ), uint32 (0 ), uint32 (p .To .Reg ))
1739
1714
rel := obj .Addrel (c .cursym )
@@ -2119,6 +2094,60 @@ func (c *ctxt0) opirr(a obj.As) uint32 {
2119
2094
return 0
2120
2095
}
2121
2096
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
+
2122
2151
func vshift (a obj.As ) bool {
2123
2152
switch a {
2124
2153
case ASLLV ,
0 commit comments