Commit ba0bab7b authored by Cherry Zhang's avatar Cherry Zhang

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: default avatarAustin Clements <austin@google.com>
parent 97592b3c
......@@ -130,27 +130,27 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
// {
// outcode(int($1), &$2, 0, &$4);
// }
MOVW FCR0, R1
MOVW FCR31, R1 // 4441f800
// LMOVW freg ',' fpscr
// {
// outcode(int($1), &$2, 0, &$4);
// }
MOVW R1, FCR0
MOVW R1, FCR31 // 44c1f800
// LMOVW rreg ',' mreg
// {
// outcode(int($1), &$2, 0, &$4);
// }
MOVW R1, M1
MOVV R1, M1
MOVW R1, M1 // 40810800
MOVV R1, M1 // 40a10800
// LMOVW mreg ',' rreg
// {
// outcode(int($1), &$2, 0, &$4);
// }
MOVW M1, R1
MOVV M1, R1
MOVW M1, R1 // 40010800
MOVV M1, R1 // 40210800
//
......@@ -406,6 +406,7 @@ label4:
NEGW R1, R2 // 00011023
NEGV R1, R2 // 0001102f
RET
// END
//
......
......@@ -46,7 +46,7 @@ const (
)
const (
REG_R0 = obj.RBaseMIPS + iota
REG_R0 = obj.RBaseMIPS + iota // must be a multiple of 32
REG_R1
REG_R2
REG_R3
......@@ -79,7 +79,7 @@ const (
REG_R30
REG_R31
REG_F0
REG_F0 // must be a multiple of 32
REG_F1
REG_F2
REG_F3
......@@ -112,11 +112,8 @@ const (
REG_F30
REG_F31
REG_HI
REG_LO
// co-processor 0 control registers
REG_M0
REG_M0 // must be a multiple of 32
REG_M1
REG_M2
REG_M3
......@@ -150,7 +147,7 @@ const (
REG_M31
// FPU control registers
REG_FCR0
REG_FCR0 // must be a multiple of 32
REG_FCR1
REG_FCR2
REG_FCR3
......@@ -183,7 +180,10 @@ const (
REG_FCR30
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
......@@ -412,3 +412,22 @@ const (
AJAL = obj.ACALL
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")
}
}
......@@ -362,8 +362,8 @@ var optab = []Optab{
{AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0, 0},
{AMOVW, C_REG, C_NONE, C_FCREG, 41, 8, 0, 0},
{AMOVV, C_REG, C_NONE, C_FCREG, 41, 8, 0, sys.MIPS64},
{AMOVW, C_REG, C_NONE, C_FCREG, 41, 4, 0, 0},
{AMOVV, C_REG, C_NONE, C_FCREG, 41, 4, 0, sys.MIPS64},
{AMOVW, C_FCREG, C_NONE, C_REG, 42, 4, 0, 0},
{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))
case 41: /* movw f,fcr */
o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(REGZERO), uint32(0), uint32(p.To.Reg)) /* mfcc1 */
o2 = OP_RRR(SP(2, 1)|(6<<21), uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) /* mtcc1 */
o1 = OP_RRR(SP(2, 1)|(6<<21), uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) /* mtcc1 */
case 42: /* movw fcr,r */
o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) /* mfcc1 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment