r := regnum(v)
a := regnum(v.Args[0])
if r == a {
- if v.AuxInt == 1 {
+ if v.AuxInt2Int64() == 1 {
var asm int
switch v.Op {
// Software optimization manual recommends add $1,reg.
p.To.Type = obj.TYPE_REG
p.To.Reg = r
return
- } else if v.AuxInt == -1 {
+ } else if v.AuxInt2Int64() == -1 {
var asm int
switch v.Op {
case ssa.OpAMD64ADDQconst:
} else {
p := Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
- p.From.Offset = v.AuxInt
+ p.From.Offset = v.AuxInt2Int64()
p.To.Type = obj.TYPE_REG
p.To.Reg = r
return
p := Prog(asm)
p.From.Type = obj.TYPE_MEM
p.From.Reg = a
- p.From.Offset = v.AuxInt
+ p.From.Offset = v.AuxInt2Int64()
p.To.Type = obj.TYPE_REG
p.To.Reg = r
case ssa.OpAMD64MULQconst, ssa.OpAMD64MULLconst, ssa.OpAMD64MULWconst, ssa.OpAMD64MULBconst:
}
p := Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
- p.From.Offset = v.AuxInt
+ p.From.Offset = v.AuxInt2Int64()
p.To.Type = obj.TYPE_REG
p.To.Reg = r
// TODO: Teach doasm to compile the three-address multiply imul $c, r1, r2
// a = b + (- const), saves us 1 instruction. We can't fit
// - (-1 << 31) into 4 bytes offset in lea.
// We handle 2-address just fine below.
- if v.AuxInt == -1<<31 || x == r {
+ if v.AuxInt2Int64() == -1<<31 || x == r {
if x != r {
// This code compensates for the fact that the register allocator
// doesn't understand 2-address instructions yet. TODO: fix that.
}
p := Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
- p.From.Offset = v.AuxInt
+ p.From.Offset = v.AuxInt2Int64()
p.To.Type = obj.TYPE_REG
p.To.Reg = r
- } else if x == r && v.AuxInt == -1 {
+ } else if x == r && v.AuxInt2Int64() == -1 {
var asm int
// x = x - (-1) is the same as x++
// See OpAMD64ADDQconst comments about inc vs add $1,reg
p := Prog(asm)
p.To.Type = obj.TYPE_REG
p.To.Reg = r
- } else if x == r && v.AuxInt == 1 {
+ } else if x == r && v.AuxInt2Int64() == 1 {
var asm int
switch v.Op {
case ssa.OpAMD64SUBQconst:
p := Prog(asm)
p.From.Type = obj.TYPE_MEM
p.From.Reg = x
- p.From.Offset = -v.AuxInt
+ p.From.Offset = -v.AuxInt2Int64()
p.To.Type = obj.TYPE_REG
p.To.Reg = r
}
}
p := Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
- p.From.Offset = v.AuxInt
+ p.From.Offset = v.AuxInt2Int64()
p.To.Type = obj.TYPE_REG
p.To.Reg = r
case ssa.OpAMD64SBBQcarrymask, ssa.OpAMD64SBBLcarrymask:
p.From.Type = obj.TYPE_REG
p.From.Reg = regnum(v.Args[0])
p.To.Type = obj.TYPE_CONST
- p.To.Offset = v.AuxInt
+ p.To.Offset = v.AuxInt2Int64()
case ssa.OpAMD64TESTQconst, ssa.OpAMD64TESTLconst, ssa.OpAMD64TESTWconst, ssa.OpAMD64TESTBconst:
p := Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
- p.From.Offset = v.AuxInt
+ p.From.Offset = v.AuxInt2Int64()
p.To.Type = obj.TYPE_REG
p.To.Reg = regnum(v.Args[0])
case ssa.OpAMD64MOVBconst, ssa.OpAMD64MOVWconst, ssa.OpAMD64MOVLconst, ssa.OpAMD64MOVQconst:
x := regnum(v)
p := Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
- var i int64
- switch v.Op {
- case ssa.OpAMD64MOVBconst:
- i = int64(v.AuxInt8())
- case ssa.OpAMD64MOVWconst:
- i = int64(v.AuxInt16())
- case ssa.OpAMD64MOVLconst:
- i = int64(v.AuxInt32())
- case ssa.OpAMD64MOVQconst:
- i = v.AuxInt
- }
- p.From.Offset = i
+ p.From.Offset = v.AuxInt2Int64()
p.To.Type = obj.TYPE_REG
p.To.Reg = x
// If flags are live at this instruction, suppress the
import "fmt"
+const (
+ y = 0x0fffFFFF
+)
+
+//go:noinline
+func invalidAdd_ssa(x uint32) uint32 {
+ return x + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y + y
+}
+
+//go:noinline
+func invalidSub_ssa(x uint32) uint32 {
+ return x - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y - y
+}
+
+//go:noinline
+func invalidMul_ssa(x uint32) uint32 {
+ return x * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y * y
+}
+
+// testLargeConst tests a situation where larger than 32 bit consts were passed to ADDL
+// causing an invalid instruction error.
+func testLargeConst() {
+ if want, got := uint32(268435440), invalidAdd_ssa(1); want != got {
+ println("testLargeConst add failed, wanted", want, "got", got)
+ failed = true
+ }
+ if want, got := uint32(4026531858), invalidSub_ssa(1); want != got {
+ println("testLargeConst sub failed, wanted", want, "got", got)
+ failed = true
+ }
+ if want, got := uint32(268435455), invalidMul_ssa(1); want != got {
+ println("testLargeConst mul failed, wanted", want, "got", got)
+ failed = true
+ }
+}
+
// testArithRshConst ensures that "const >> const" right shifts correctly perform
// sign extension on the lhs constant
func testArithRshConst() {
testOverflowConstShift()
testArithConstShift()
testArithRshConst()
+ testLargeConst()
if failed {
panic("failed")