1
0
mirror of https://github.com/golang/go synced 2024-11-18 11:14:39 -07:00

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 <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
Cherry Zhang 2019-10-26 22:48:15 -04:00
parent 97592b3c14
commit ba0bab7b4f
3 changed files with 37 additions and 18 deletions

View File

@ -130,27 +130,27 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
// { // {
// outcode(int($1), &$2, 0, &$4); // outcode(int($1), &$2, 0, &$4);
// } // }
MOVW FCR0, R1 MOVW FCR31, R1 // 4441f800
// LMOVW freg ',' fpscr // LMOVW freg ',' fpscr
// { // {
// outcode(int($1), &$2, 0, &$4); // outcode(int($1), &$2, 0, &$4);
// } // }
MOVW R1, FCR0 MOVW R1, FCR31 // 44c1f800
// LMOVW rreg ',' mreg // LMOVW rreg ',' mreg
// { // {
// outcode(int($1), &$2, 0, &$4); // outcode(int($1), &$2, 0, &$4);
// } // }
MOVW R1, M1 MOVW R1, M1 // 40810800
MOVV R1, M1 MOVV R1, M1 // 40a10800
// LMOVW mreg ',' rreg // LMOVW mreg ',' rreg
// { // {
// outcode(int($1), &$2, 0, &$4); // outcode(int($1), &$2, 0, &$4);
// } // }
MOVW M1, R1 MOVW M1, R1 // 40010800
MOVV M1, R1 MOVV M1, R1 // 40210800
// //
@ -406,6 +406,7 @@ label4:
NEGW R1, R2 // 00011023 NEGW R1, R2 // 00011023
NEGV R1, R2 // 0001102f NEGV R1, R2 // 0001102f
RET
// END // END
// //

View File

@ -46,7 +46,7 @@ const (
) )
const ( const (
REG_R0 = obj.RBaseMIPS + iota REG_R0 = obj.RBaseMIPS + iota // must be a multiple of 32
REG_R1 REG_R1
REG_R2 REG_R2
REG_R3 REG_R3
@ -79,7 +79,7 @@ const (
REG_R30 REG_R30
REG_R31 REG_R31
REG_F0 REG_F0 // must be a multiple of 32
REG_F1 REG_F1
REG_F2 REG_F2
REG_F3 REG_F3
@ -112,11 +112,8 @@ const (
REG_F30 REG_F30
REG_F31 REG_F31
REG_HI
REG_LO
// co-processor 0 control registers // co-processor 0 control registers
REG_M0 REG_M0 // must be a multiple of 32
REG_M1 REG_M1
REG_M2 REG_M2
REG_M3 REG_M3
@ -150,7 +147,7 @@ const (
REG_M31 REG_M31
// FPU control registers // FPU control registers
REG_FCR0 REG_FCR0 // must be a multiple of 32
REG_FCR1 REG_FCR1
REG_FCR2 REG_FCR2
REG_FCR3 REG_FCR3
@ -183,7 +180,10 @@ const (
REG_FCR30 REG_FCR30
REG_FCR31 REG_FCR31
REG_LAST = REG_FCR31 // the last defined register REG_HI
REG_LO
REG_LAST = REG_LO // the last defined register
REG_SPECIAL = REG_M0 REG_SPECIAL = REG_M0
@ -412,3 +412,22 @@ const (
AJAL = obj.ACALL AJAL = obj.ACALL
ARET = obj.ARET ARET = obj.ARET
) )
func init() {
// 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.
// Check this here.
if REG_R0%32 != 0 {
panic("REG_R0 is not a multiple of 32")
}
if REG_F0%32 != 0 {
panic("REG_F0 is not a multiple of 32")
}
if REG_M0%32 != 0 {
panic("REG_M0 is not a multiple of 32")
}
if REG_FCR0%32 != 0 {
panic("REG_FCR0 is not a multiple of 32")
}
}

View File

@ -362,8 +362,8 @@ var optab = []Optab{
{AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0, 0}, {AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0, 0},
{AMOVW, C_REG, C_NONE, C_FCREG, 41, 8, 0, 0}, {AMOVW, C_REG, C_NONE, C_FCREG, 41, 4, 0, 0},
{AMOVV, C_REG, C_NONE, C_FCREG, 41, 8, 0, sys.MIPS64}, {AMOVV, C_REG, C_NONE, C_FCREG, 41, 4, 0, sys.MIPS64},
{AMOVW, C_FCREG, C_NONE, C_REG, 42, 4, 0, 0}, {AMOVW, C_FCREG, C_NONE, C_REG, 42, 4, 0, 0},
{AMOVV, C_FCREG, C_NONE, C_REG, 42, 4, 0, sys.MIPS64}, {AMOVV, C_FCREG, C_NONE, C_REG, 42, 4, 0, sys.MIPS64},
@ -1476,8 +1476,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
o1 = uint32(c.regoff(&p.From)) o1 = uint32(c.regoff(&p.From))
case 41: /* movw f,fcr */ case 41: /* movw f,fcr */
o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(REGZERO), uint32(0), uint32(p.To.Reg)) /* mfcc1 */ o1 = OP_RRR(SP(2, 1)|(6<<21), uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) /* mtcc1 */
o2 = OP_RRR(SP(2, 1)|(6<<21), uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) /* mtcc1 */
case 42: /* movw fcr,r */ case 42: /* movw fcr,r */
o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) /* mfcc1 */ o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) /* mfcc1 */