]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/mips: fix encoding of FCR registers
authorCherry Zhang <cherryyz@google.com>
Sun, 27 Oct 2019 02:48:15 +0000 (22:48 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 29 Oct 2019 03:45:36 +0000 (03:45 +0000)
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>
src/cmd/asm/internal/asm/testdata/mips64.s
src/cmd/internal/obj/mips/a.out.go
src/cmd/internal/obj/mips/asm0.go

index 2d1bc18cec9d3d8ea0d05d813438f5fed9008540..e80f4d83d1e5af6ffcaad724d2c43eafd23043d1 100644 (file)
@@ -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
 //
index 026e8db76a122bb07fa4c1cf1ce93c833039ee19..b0205ec11a8e64f8f40e616f0a246a259846f1d3 100644 (file)
@@ -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")
+       }
+}
index 77aa24a4f657d2f07e37a4a48787b44ea78eedf2..76a3eec6bfb580508531b6f0c67fefab7f796e9f 100644 (file)
@@ -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 */