diff options
| author | Matthew Dempsky <mdempsky@google.com> | 2016-03-07 15:15:57 -0800 |
|---|---|---|
| committer | Matthew Dempsky <mdempsky@google.com> | 2016-03-08 00:11:15 +0000 |
| commit | e853131699680c875d2d4e6cf82d959272dacd00 (patch) | |
| tree | e3d952bc7da2fdd912e312162ea7eb834ce75518 /src/cmd/internal/obj/arm | |
| parent | 399f0f5fe8029e31e742e0341c7ddfd2097f3926 (diff) | |
| download | go-e853131699680c875d2d4e6cf82d959272dacd00.tar.xz | |
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 <mdempsky@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/cmd/internal/obj/arm')
| -rw-r--r-- | src/cmd/internal/obj/arm/asm5.go | 16 |
1 files changed, 8 insertions, 8 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 |
