Skip to content

Commit ba0bab7

Browse files
committed
cmd/internal/obj/mips: fix encoding of FCR registers
The asm encoder generally assumes that the lowest 5 bits of the REG_XX constants match the machine instruction encoding, i.e. the lowest 5 bits is the register number. This was not true for FCR registers and M registers. Make it so. MOV Rx, FCRy was encoded as two machine instructions. The first is unnecessary. Remove. Change-Id: Ib988e6b109ba8f564337cdd31019c1a6f1881f5b Reviewed-on: https://go-review.googlesource.com/c/go/+/203717 Run-TryBot: Cherry Zhang <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Austin Clements <[email protected]>
1 parent 97592b3 commit ba0bab7

File tree

3 files changed

+37
-18
lines changed

3 files changed

+37
-18
lines changed

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,27 +130,27 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
130130
// {
131131
// outcode(int($1), &$2, 0, &$4);
132132
// }
133-
MOVW FCR0, R1
133+
MOVW FCR31, R1 // 4441f800
134134

135135
// LMOVW freg ',' fpscr
136136
// {
137137
// outcode(int($1), &$2, 0, &$4);
138138
// }
139-
MOVW R1, FCR0
139+
MOVW R1, FCR31 // 44c1f800
140140

141141
// LMOVW rreg ',' mreg
142142
// {
143143
// outcode(int($1), &$2, 0, &$4);
144144
// }
145-
MOVW R1, M1
146-
MOVV R1, M1
145+
MOVW R1, M1 // 40810800
146+
MOVV R1, M1 // 40a10800
147147

148148
// LMOVW mreg ',' rreg
149149
// {
150150
// outcode(int($1), &$2, 0, &$4);
151151
// }
152-
MOVW M1, R1
153-
MOVV M1, R1
152+
MOVW M1, R1 // 40010800
153+
MOVV M1, R1 // 40210800
154154

155155

156156
//
@@ -406,6 +406,7 @@ label4:
406406

407407
NEGW R1, R2 // 00011023
408408
NEGV R1, R2 // 0001102f
409+
RET
409410

410411
// END
411412
//

src/cmd/internal/obj/mips/a.out.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const (
4646
)
4747

4848
const (
49-
REG_R0 = obj.RBaseMIPS + iota
49+
REG_R0 = obj.RBaseMIPS + iota // must be a multiple of 32
5050
REG_R1
5151
REG_R2
5252
REG_R3
@@ -79,7 +79,7 @@ const (
7979
REG_R30
8080
REG_R31
8181

82-
REG_F0
82+
REG_F0 // must be a multiple of 32
8383
REG_F1
8484
REG_F2
8585
REG_F3
@@ -112,11 +112,8 @@ const (
112112
REG_F30
113113
REG_F31
114114

115-
REG_HI
116-
REG_LO
117-
118115
// co-processor 0 control registers
119-
REG_M0
116+
REG_M0 // must be a multiple of 32
120117
REG_M1
121118
REG_M2
122119
REG_M3
@@ -150,7 +147,7 @@ const (
150147
REG_M31
151148

152149
// FPU control registers
153-
REG_FCR0
150+
REG_FCR0 // must be a multiple of 32
154151
REG_FCR1
155152
REG_FCR2
156153
REG_FCR3
@@ -183,7 +180,10 @@ const (
183180
REG_FCR30
184181
REG_FCR31
185182

186-
REG_LAST = REG_FCR31 // the last defined register
183+
REG_HI
184+
REG_LO
185+
186+
REG_LAST = REG_LO // the last defined register
187187

188188
REG_SPECIAL = REG_M0
189189

@@ -412,3 +412,22 @@ const (
412412
AJAL = obj.ACALL
413413
ARET = obj.ARET
414414
)
415+
416+
func init() {
417+
// The asm encoder generally assumes that the lowest 5 bits of the
418+
// REG_XX constants match the machine instruction encoding, i.e.
419+
// the lowest 5 bits is the register number.
420+
// Check this here.
421+
if REG_R0%32 != 0 {
422+
panic("REG_R0 is not a multiple of 32")
423+
}
424+
if REG_F0%32 != 0 {
425+
panic("REG_F0 is not a multiple of 32")
426+
}
427+
if REG_M0%32 != 0 {
428+
panic("REG_M0 is not a multiple of 32")
429+
}
430+
if REG_FCR0%32 != 0 {
431+
panic("REG_FCR0 is not a multiple of 32")
432+
}
433+
}

src/cmd/internal/obj/mips/asm0.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,8 @@ var optab = []Optab{
362362

363363
{AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0, 0},
364364

365-
{AMOVW, C_REG, C_NONE, C_FCREG, 41, 8, 0, 0},
366-
{AMOVV, C_REG, C_NONE, C_FCREG, 41, 8, 0, sys.MIPS64},
365+
{AMOVW, C_REG, C_NONE, C_FCREG, 41, 4, 0, 0},
366+
{AMOVV, C_REG, C_NONE, C_FCREG, 41, 4, 0, sys.MIPS64},
367367
{AMOVW, C_FCREG, C_NONE, C_REG, 42, 4, 0, 0},
368368
{AMOVV, C_FCREG, C_NONE, C_REG, 42, 4, 0, sys.MIPS64},
369369

@@ -1476,8 +1476,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
14761476
o1 = uint32(c.regoff(&p.From))
14771477

14781478
case 41: /* movw f,fcr */
1479-
o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(REGZERO), uint32(0), uint32(p.To.Reg)) /* mfcc1 */
1480-
o2 = OP_RRR(SP(2, 1)|(6<<21), uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) /* mtcc1 */
1479+
o1 = OP_RRR(SP(2, 1)|(6<<21), uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) /* mtcc1 */
14811480

14821481
case 42: /* movw fcr,r */
14831482
o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) /* mfcc1 */

0 commit comments

Comments
 (0)