From e853131699680c875d2d4e6cf82d959272dacd00 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Mon, 7 Mar 2016 15:15:57 -0800 Subject: [PATCH] cmd/internal/obj: stop using as+ALAST as an opcode 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 Reviewed-by: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/cmd/internal/obj/arm/asm5.go | 16 +++---- src/cmd/internal/obj/mips/asm0.go | 78 +++++++++++++++---------------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go index 8536e7628b..e84b332b62 100644 --- a/src/cmd/internal/obj/arm/asm5.go +++ b/src/cmd/internal/obj/arm/asm5.go @@ -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 diff --git a/src/cmd/internal/obj/mips/asm0.go b/src/cmd/internal/obj/mips/asm0.go index 601f35b068..5d9a41e928 100644 --- a/src/cmd/internal/obj/mips/asm0.go +++ b/src/cmd/internal/obj/mips/asm0.go @@ -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)) } -- 2.48.1