]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj: stop using as+ALAST as an opcode
authorMatthew Dempsky <mdempsky@google.com>
Mon, 7 Mar 2016 23:15:57 +0000 (15:15 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 8 Mar 2016 00:11:15 +0000 (00:11 +0000)
Currently, package obj reserves a range of 1<<12 opcodes for each
target architecture.  E.g., mips64 has [6<<12, 7<<12).

However, because mips.ABEQ and mips.ALAST are both within that range,
the expression mips.ABEQ+mips.ALAST in turn falls (far) outside that
range around 12<<12, meaning it could theoretically collide with
another arch's opcodes.

More practically, it's a problem because 12<<12 overflows an int16,
which hampers fixing #14692.  (We could also just switch to uint16 to
avoid the overflow, but that still leaves the first problem.)

As a workaround, use Michael Hudson-Doyle's solution from
https://golang.org/cl/20182 and use negative values for these variant
instructions.

Passes toolstash -cmp for GOARCH=arm and GOARCH=mips64.

Updates #14692.

Change-Id: Iad797d10652360109fa4db19d4d1edb6529fc2c0
Reviewed-on: https://go-review.googlesource.com/20345
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

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

index 8536e7628bbc1ca1a5e293ced67822a36ef7343b..e84b332b62d21c5aa8a2dfc672e8630e07af3626 100644 (file)
@@ -2276,13 +2276,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
 
                o1 |= (uint32(p.From.Reg) & 15) << 0
                o1 |= (FREGTMP & 15) << 12
-               o2 = oprrr(ctxt, AMOVFW+ALAST, int(p.Scond))
+               o2 = oprrr(ctxt, -AMOVFW, int(p.Scond))
                o2 |= (FREGTMP & 15) << 16
                o2 |= (uint32(p.To.Reg) & 15) << 12
 
                // macro for movw reg,FTMP; movwf FTMP,freg
        case 87: /* movwf reg,freg - fix-to-float */
-               o1 = oprrr(ctxt, AMOVWF+ALAST, int(p.Scond))
+               o1 = oprrr(ctxt, -AMOVWF, int(p.Scond))
 
                o1 |= (uint32(p.From.Reg) & 15) << 12
                o1 |= (FREGTMP & 15) << 16
@@ -2291,19 +2291,19 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
                o2 |= (uint32(p.To.Reg) & 15) << 12
 
        case 88: /* movw reg,freg  */
-               o1 = oprrr(ctxt, AMOVWF+ALAST, int(p.Scond))
+               o1 = oprrr(ctxt, -AMOVWF, int(p.Scond))
 
                o1 |= (uint32(p.From.Reg) & 15) << 12
                o1 |= (uint32(p.To.Reg) & 15) << 16
 
        case 89: /* movw freg,reg  */
-               o1 = oprrr(ctxt, AMOVFW+ALAST, int(p.Scond))
+               o1 = oprrr(ctxt, -AMOVFW, int(p.Scond))
 
                o1 |= (uint32(p.From.Reg) & 15) << 16
                o1 |= (uint32(p.To.Reg) & 15) << 12
 
        case 90: /* tst reg  */
-               o1 = oprrr(ctxt, ACMP+ALAST, int(p.Scond))
+               o1 = oprrr(ctxt, -ACMP, int(p.Scond))
 
                o1 |= (uint32(p.From.Reg) & 15) << 16
 
@@ -2560,13 +2560,13 @@ func oprrr(ctxt *obj.Link, a int, sc int) uint32 {
                }
                return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 1<<18 | 1<<8 | 1<<7 // toint, double, trunc
 
-       case AMOVWF + ALAST: // copy WtoF
+       case -AMOVWF: // copy WtoF
                return o | 0xe<<24 | 0x0<<20 | 0xb<<8 | 1<<4
 
-       case AMOVFW + ALAST: // copy FtoW
+       case -AMOVFW: // copy FtoW
                return o | 0xe<<24 | 0x1<<20 | 0xb<<8 | 1<<4
 
-       case ACMP + ALAST: // cmp imm
+       case -ACMP: // cmp imm
                return o | 0x3<<24 | 0x5<<20
 
                // CLZ doesn't support .nil
index 601f35b0684820a14879d31019e5ff5552d0d271..5d9a41e928e7d6aa9f56bcd0a8138dbc8f94684c 100644 (file)
@@ -1072,7 +1072,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
                        r = int(o.param)
                }
                v := regoff(ctxt, &p.From)
-               o1 = OP_IRR(opirr(ctxt, int(p.As)+ALAST), uint32(v), uint32(r), uint32(p.To.Reg))
+               o1 = OP_IRR(opirr(ctxt, -int(p.As)), uint32(v), uint32(r), uint32(p.To.Reg))
 
        case 9: /* sll r1,[r2],r3 */
                r := int(p.Reg)
@@ -1147,11 +1147,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
                }
 
        case 14: /* movwu r,r */
-               o1 = OP_SRR(opirr(ctxt, ASLLV+ALAST), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
+               o1 = OP_SRR(opirr(ctxt, -ASLLV), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
                if p.As == AMOVWU {
-                       o2 = OP_SRR(opirr(ctxt, ASRLV+ALAST), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
+                       o2 = OP_SRR(opirr(ctxt, -ASRLV), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
                } else {
-                       o2 = OP_SRR(opirr(ctxt, ASRAV+ALAST), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
+                       o2 = OP_SRR(opirr(ctxt, -ASRAV), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
                }
 
        case 16: /* sll $c,[r1],r2 */
@@ -1163,7 +1163,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
 
                /* OP_SRR will use only the low 5 bits of the shift value */
                if v >= 32 && vshift(p.As) {
-                       o1 = OP_SRR(opirr(ctxt, int(p.As)+ALAST), uint32(v-32), uint32(r), uint32(p.To.Reg))
+                       o1 = OP_SRR(opirr(ctxt, -int(p.As)), uint32(v-32), uint32(r), uint32(p.To.Reg))
                } else {
                        o1 = OP_SRR(opirr(ctxt, int(p.As)), uint32(v), uint32(r), uint32(p.To.Reg))
                }
@@ -1248,9 +1248,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
                if r == 0 {
                        r = int(o.param)
                }
-               a := AMOVF + ALAST
+               a := -AMOVF
                if p.As == AMOVD {
-                       a = AMOVD + ALAST
+                       a = -AMOVD
                }
                switch o.size {
                case 16:
@@ -1331,7 +1331,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
                o1 = OP_IRR(opirr(ctxt, ALUI), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
                o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
                o3 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
-               o4 = OP_IRR(opirr(ctxt, int(p.As)+ALAST), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
+               o4 = OP_IRR(opirr(ctxt, -int(p.As)), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
 
        case 37: /* movw r,mr */
                a := SP(2, 0) | (4 << 21) /* mtc0 */
@@ -1389,7 +1389,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
                rel.Sym = p.From.Sym
                rel.Add = p.From.Offset
                rel.Type = obj.R_ADDRMIPS
-               o3 = OP_IRR(opirr(ctxt, int(p.As)+ALAST), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
+               o3 = OP_IRR(opirr(ctxt, -int(p.As)), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
        }
 
        out[0] = o1
@@ -1562,8 +1562,8 @@ func oprrr(ctxt *obj.Link, a int) uint32 {
                return FPD(7, 6)
        }
 
-       if a >= ALAST {
-               ctxt.Diag("bad rrr opcode %v+ALAST", obj.Aconv(a-ALAST))
+       if a < 0 {
+               ctxt.Diag("bad rrr opcode -%v", obj.Aconv(-a))
        } else {
                ctxt.Diag("bad rrr opcode %v", obj.Aconv(a))
        }
@@ -1607,43 +1607,43 @@ func opirr(ctxt *obj.Link, a int) uint32 {
                return SP(0, 3)
        case ABEQ:
                return SP(0, 4)
-       case ABEQ + ALAST:
+       case -ABEQ:
                return SP(2, 4) /* likely */
        case ABNE:
                return SP(0, 5)
-       case ABNE + ALAST:
+       case -ABNE:
                return SP(2, 5) /* likely */
        case ABGEZ:
                return SP(0, 1) | BCOND(0, 1)
-       case ABGEZ + ALAST:
+       case -ABGEZ:
                return SP(0, 1) | BCOND(0, 3) /* likely */
        case ABGEZAL:
                return SP(0, 1) | BCOND(2, 1)
-       case ABGEZAL + ALAST:
+       case -ABGEZAL:
                return SP(0, 1) | BCOND(2, 3) /* likely */
        case ABGTZ:
                return SP(0, 7)
-       case ABGTZ + ALAST:
+       case -ABGTZ:
                return SP(2, 7) /* likely */
        case ABLEZ:
                return SP(0, 6)
-       case ABLEZ + ALAST:
+       case -ABLEZ:
                return SP(2, 6) /* likely */
        case ABLTZ:
                return SP(0, 1) | BCOND(0, 0)
-       case ABLTZ + ALAST:
+       case -ABLTZ:
                return SP(0, 1) | BCOND(0, 2) /* likely */
        case ABLTZAL:
                return SP(0, 1) | BCOND(2, 0)
-       case ABLTZAL + ALAST:
+       case -ABLTZAL:
                return SP(0, 1) | BCOND(2, 2) /* likely */
        case ABFPT:
                return SP(2, 1) | (257 << 16)
-       case ABFPT + ALAST:
+       case -ABFPT:
                return SP(2, 1) | (259 << 16) /* likely */
        case ABFPF:
                return SP(2, 1) | (256 << 16)
-       case ABFPF + ALAST:
+       case -ABFPF:
                return SP(2, 1) | (258 << 16) /* likely */
 
        case AMOVB,
@@ -1673,31 +1673,31 @@ func opirr(ctxt *obj.Link, a int) uint32 {
        case ABREAK:
                return SP(5, 7)
 
-       case AMOVWL + ALAST:
+       case -AMOVWL:
                return SP(4, 2)
-       case AMOVWR + ALAST:
+       case -AMOVWR:
                return SP(4, 6)
-       case AMOVVL + ALAST:
+       case -AMOVVL:
                return SP(3, 2)
-       case AMOVVR + ALAST:
+       case -AMOVVR:
                return SP(3, 3)
-       case AMOVB + ALAST:
+       case -AMOVB:
                return SP(4, 0)
-       case AMOVBU + ALAST:
+       case -AMOVBU:
                return SP(4, 4)
-       case AMOVH + ALAST:
+       case -AMOVH:
                return SP(4, 1)
-       case AMOVHU + ALAST:
+       case -AMOVHU:
                return SP(4, 5)
-       case AMOVW + ALAST:
+       case -AMOVW:
                return SP(4, 3)
-       case AMOVWU + ALAST:
+       case -AMOVWU:
                return SP(4, 7)
-       case AMOVV + ALAST:
+       case -AMOVV:
                return SP(6, 7)
-       case AMOVF + ALAST:
+       case -AMOVF:
                return SP(6, 1)
-       case AMOVD + ALAST:
+       case -AMOVD:
                return SP(6, 5)
 
        case ASLLV:
@@ -1706,16 +1706,16 @@ func opirr(ctxt *obj.Link, a int) uint32 {
                return OP(7, 2)
        case ASRAV:
                return OP(7, 3)
-       case ASLLV + ALAST:
+       case -ASLLV:
                return OP(7, 4)
-       case ASRLV + ALAST:
+       case -ASRLV:
                return OP(7, 6)
-       case ASRAV + ALAST:
+       case -ASRAV:
                return OP(7, 7)
        }
 
-       if a >= ALAST {
-               ctxt.Diag("bad irr opcode %v+ALAST", obj.Aconv(a-ALAST))
+       if a < 0 {
+               ctxt.Diag("bad irr opcode -%v", obj.Aconv(-a))
        } else {
                ctxt.Diag("bad irr opcode %v", obj.Aconv(a))
        }