1
0
mirror of https://github.com/golang/go synced 2024-10-04 23:11:21 -06:00

cmd/compile: get rid of most byte and word insns for amd64

Now that we're using 32-bit ops for 8/16-bit logical operations
(to avoid partial register stalls), there's really no need to
keep track of the 8/16-bit ops at all.  Convert everything we
can to 32-bit ops.

This CL is the obvious stuff.  I might think a bit more about
whether we can get rid of weirder stuff like HMULWU.

The only downside to this CL is that we lose some information
about constants.  If we had source like:
  var a byte = ...
  a += 128
  a += 128
We will convert that to a += 256, when we could get rid of the
add altogether.  This seems like a fairly unusual scenario and
I'm happy with forgoing that optimization.

Change-Id: Ia7c1e5203d0d110807da69ed646535194a3efba1
Reviewed-on: https://go-review.googlesource.com/22382
Reviewed-by: Todd Neal <todd@tneal.org>
This commit is contained in:
Keith Randall 2016-04-22 13:09:18 -07:00
parent 217c284995
commit 9e3c68f1e0
6 changed files with 535 additions and 3069 deletions

View File

@ -62,7 +62,7 @@ func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) {
} }
for i := len(b.Values) - 1; i >= 0; i-- { for i := len(b.Values) - 1; i >= 0; i-- {
v := b.Values[i] v := b.Values[i]
if flive && (v.Op == ssa.OpAMD64MOVBconst || v.Op == ssa.OpAMD64MOVWconst || v.Op == ssa.OpAMD64MOVLconst || v.Op == ssa.OpAMD64MOVQconst) { if flive && (v.Op == ssa.OpAMD64MOVLconst || v.Op == ssa.OpAMD64MOVQconst) {
// The "mark" is any non-nil Aux value. // The "mark" is any non-nil Aux value.
v.Aux = v v.Aux = v
} }
@ -160,7 +160,7 @@ func opregreg(op obj.As, dest, src int16) *obj.Prog {
func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
s.SetLineno(v.Line) s.SetLineno(v.Line)
switch v.Op { switch v.Op {
case ssa.OpAMD64ADDQ, ssa.OpAMD64ADDL, ssa.OpAMD64ADDW, ssa.OpAMD64ADDB: case ssa.OpAMD64ADDQ, ssa.OpAMD64ADDL:
r := gc.SSARegNum(v) r := gc.SSARegNum(v)
r1 := gc.SSARegNum(v.Args[0]) r1 := gc.SSARegNum(v.Args[0])
r2 := gc.SSARegNum(v.Args[1]) r2 := gc.SSARegNum(v.Args[1])
@ -193,12 +193,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Reg = r p.To.Reg = r
} }
// 2-address opcode arithmetic // 2-address opcode arithmetic
case ssa.OpAMD64SUBQ, ssa.OpAMD64SUBL, ssa.OpAMD64SUBW, ssa.OpAMD64SUBB, case ssa.OpAMD64SUBQ, ssa.OpAMD64SUBL,
ssa.OpAMD64MULQ, ssa.OpAMD64MULL, ssa.OpAMD64MULW, ssa.OpAMD64MULB, ssa.OpAMD64MULQ, ssa.OpAMD64MULL,
ssa.OpAMD64ANDQ, ssa.OpAMD64ANDL, ssa.OpAMD64ANDW, ssa.OpAMD64ANDB, ssa.OpAMD64ANDQ, ssa.OpAMD64ANDL,
ssa.OpAMD64ORQ, ssa.OpAMD64ORL, ssa.OpAMD64ORW, ssa.OpAMD64ORB, ssa.OpAMD64ORQ, ssa.OpAMD64ORL,
ssa.OpAMD64XORQ, ssa.OpAMD64XORL, ssa.OpAMD64XORW, ssa.OpAMD64XORB, ssa.OpAMD64XORQ, ssa.OpAMD64XORL,
ssa.OpAMD64SHLQ, ssa.OpAMD64SHLL, ssa.OpAMD64SHLW, ssa.OpAMD64SHLB, ssa.OpAMD64SHLQ, ssa.OpAMD64SHLL,
ssa.OpAMD64SHRQ, ssa.OpAMD64SHRL, ssa.OpAMD64SHRW, ssa.OpAMD64SHRB, ssa.OpAMD64SHRQ, ssa.OpAMD64SHRL, ssa.OpAMD64SHRW, ssa.OpAMD64SHRB,
ssa.OpAMD64SARQ, ssa.OpAMD64SARL, ssa.OpAMD64SARW, ssa.OpAMD64SARB, ssa.OpAMD64SARQ, ssa.OpAMD64SARL, ssa.OpAMD64SARW, ssa.OpAMD64SARB,
ssa.OpAMD64ADDSS, ssa.OpAMD64ADDSD, ssa.OpAMD64SUBSS, ssa.OpAMD64SUBSD, ssa.OpAMD64ADDSS, ssa.OpAMD64ADDSD, ssa.OpAMD64SUBSS, ssa.OpAMD64SUBSD,
@ -335,7 +335,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = r
case ssa.OpAMD64ADDQconst, ssa.OpAMD64ADDLconst, ssa.OpAMD64ADDWconst, ssa.OpAMD64ADDBconst: case ssa.OpAMD64ADDQconst, ssa.OpAMD64ADDLconst:
r := gc.SSARegNum(v) r := gc.SSARegNum(v)
a := gc.SSARegNum(v.Args[0]) a := gc.SSARegNum(v.Args[0])
if r == a { if r == a {
@ -408,7 +408,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = r p.To.Reg = r
case ssa.OpAMD64MULQconst, ssa.OpAMD64MULLconst, ssa.OpAMD64MULWconst, ssa.OpAMD64MULBconst: case ssa.OpAMD64MULQconst, ssa.OpAMD64MULLconst:
r := gc.SSARegNum(v) r := gc.SSARegNum(v)
if r != gc.SSARegNum(v.Args[0]) { if r != gc.SSARegNum(v.Args[0]) {
v.Fatalf("input[0] and output not in same register %s", v.LongString()) v.Fatalf("input[0] and output not in same register %s", v.LongString())
@ -424,11 +424,11 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
//p.From3.Type = obj.TYPE_REG //p.From3.Type = obj.TYPE_REG
//p.From3.Reg = gc.SSARegNum(v.Args[0]) //p.From3.Reg = gc.SSARegNum(v.Args[0])
case ssa.OpAMD64SUBQconst, ssa.OpAMD64SUBLconst, ssa.OpAMD64SUBWconst, ssa.OpAMD64SUBBconst, case ssa.OpAMD64SUBQconst, ssa.OpAMD64SUBLconst,
ssa.OpAMD64ANDQconst, ssa.OpAMD64ANDLconst, ssa.OpAMD64ANDWconst, ssa.OpAMD64ANDBconst, ssa.OpAMD64ANDQconst, ssa.OpAMD64ANDLconst,
ssa.OpAMD64ORQconst, ssa.OpAMD64ORLconst, ssa.OpAMD64ORWconst, ssa.OpAMD64ORBconst, ssa.OpAMD64ORQconst, ssa.OpAMD64ORLconst,
ssa.OpAMD64XORQconst, ssa.OpAMD64XORLconst, ssa.OpAMD64XORWconst, ssa.OpAMD64XORBconst, ssa.OpAMD64XORQconst, ssa.OpAMD64XORLconst,
ssa.OpAMD64SHLQconst, ssa.OpAMD64SHLLconst, ssa.OpAMD64SHLWconst, ssa.OpAMD64SHLBconst, ssa.OpAMD64SHLQconst, ssa.OpAMD64SHLLconst,
ssa.OpAMD64SHRQconst, ssa.OpAMD64SHRLconst, ssa.OpAMD64SHRWconst, ssa.OpAMD64SHRBconst, ssa.OpAMD64SHRQconst, ssa.OpAMD64SHRLconst, ssa.OpAMD64SHRWconst, ssa.OpAMD64SHRBconst,
ssa.OpAMD64SARQconst, ssa.OpAMD64SARLconst, ssa.OpAMD64SARWconst, ssa.OpAMD64SARBconst, ssa.OpAMD64SARQconst, ssa.OpAMD64SARLconst, ssa.OpAMD64SARWconst, ssa.OpAMD64SARBconst,
ssa.OpAMD64ROLQconst, ssa.OpAMD64ROLLconst, ssa.OpAMD64ROLWconst, ssa.OpAMD64ROLBconst: ssa.OpAMD64ROLQconst, ssa.OpAMD64ROLLconst, ssa.OpAMD64ROLWconst, ssa.OpAMD64ROLBconst:
@ -497,7 +497,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.From.Offset = v.AuxInt p.From.Offset = v.AuxInt
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = gc.SSARegNum(v.Args[0]) p.To.Reg = gc.SSARegNum(v.Args[0])
case ssa.OpAMD64MOVBconst, ssa.OpAMD64MOVWconst, ssa.OpAMD64MOVLconst, ssa.OpAMD64MOVQconst: case ssa.OpAMD64MOVLconst, ssa.OpAMD64MOVQconst:
x := gc.SSARegNum(v) x := gc.SSARegNum(v)
p := gc.Prog(v.Op.Asm()) p := gc.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
@ -812,9 +812,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
if gc.Maxarg < v.AuxInt { if gc.Maxarg < v.AuxInt {
gc.Maxarg = v.AuxInt gc.Maxarg = v.AuxInt
} }
case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL, ssa.OpAMD64NEGW, ssa.OpAMD64NEGB, case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL,
ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL, ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL,
ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL, ssa.OpAMD64NOTW, ssa.OpAMD64NOTB: ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL:
r := gc.SSARegNum(v) r := gc.SSARegNum(v)
if r != gc.SSARegNum(v.Args[0]) { if r != gc.SSARegNum(v.Args[0]) {
v.Fatalf("input[0] and output not in same register %s", v.LongString()) v.Fatalf("input[0] and output not in same register %s", v.LongString())

View File

@ -6,23 +6,23 @@
(Add64 x y) -> (ADDQ x y) (Add64 x y) -> (ADDQ x y)
(AddPtr x y) -> (ADDQ x y) (AddPtr x y) -> (ADDQ x y)
(Add32 x y) -> (ADDL x y) (Add32 x y) -> (ADDL x y)
(Add16 x y) -> (ADDW x y) (Add16 x y) -> (ADDL x y)
(Add8 x y) -> (ADDB x y) (Add8 x y) -> (ADDL x y)
(Add32F x y) -> (ADDSS x y) (Add32F x y) -> (ADDSS x y)
(Add64F x y) -> (ADDSD x y) (Add64F x y) -> (ADDSD x y)
(Sub64 x y) -> (SUBQ x y) (Sub64 x y) -> (SUBQ x y)
(SubPtr x y) -> (SUBQ x y) (SubPtr x y) -> (SUBQ x y)
(Sub32 x y) -> (SUBL x y) (Sub32 x y) -> (SUBL x y)
(Sub16 x y) -> (SUBW x y) (Sub16 x y) -> (SUBL x y)
(Sub8 x y) -> (SUBB x y) (Sub8 x y) -> (SUBL x y)
(Sub32F x y) -> (SUBSS x y) (Sub32F x y) -> (SUBSS x y)
(Sub64F x y) -> (SUBSD x y) (Sub64F x y) -> (SUBSD x y)
(Mul64 x y) -> (MULQ x y) (Mul64 x y) -> (MULQ x y)
(Mul32 x y) -> (MULL x y) (Mul32 x y) -> (MULL x y)
(Mul16 x y) -> (MULW x y) (Mul16 x y) -> (MULL x y)
(Mul8 x y) -> (MULB x y) (Mul8 x y) -> (MULL x y)
(Mul32F x y) -> (MULSS x y) (Mul32F x y) -> (MULSS x y)
(Mul64F x y) -> (MULSD x y) (Mul64F x y) -> (MULSD x y)
@ -60,30 +60,30 @@
(And64 x y) -> (ANDQ x y) (And64 x y) -> (ANDQ x y)
(And32 x y) -> (ANDL x y) (And32 x y) -> (ANDL x y)
(And16 x y) -> (ANDW x y) (And16 x y) -> (ANDL x y)
(And8 x y) -> (ANDB x y) (And8 x y) -> (ANDL x y)
(Or64 x y) -> (ORQ x y) (Or64 x y) -> (ORQ x y)
(Or32 x y) -> (ORL x y) (Or32 x y) -> (ORL x y)
(Or16 x y) -> (ORW x y) (Or16 x y) -> (ORL x y)
(Or8 x y) -> (ORB x y) (Or8 x y) -> (ORL x y)
(Xor64 x y) -> (XORQ x y) (Xor64 x y) -> (XORQ x y)
(Xor32 x y) -> (XORL x y) (Xor32 x y) -> (XORL x y)
(Xor16 x y) -> (XORW x y) (Xor16 x y) -> (XORL x y)
(Xor8 x y) -> (XORB x y) (Xor8 x y) -> (XORL x y)
(Neg64 x) -> (NEGQ x) (Neg64 x) -> (NEGQ x)
(Neg32 x) -> (NEGL x) (Neg32 x) -> (NEGL x)
(Neg16 x) -> (NEGW x) (Neg16 x) -> (NEGL x)
(Neg8 x) -> (NEGB x) (Neg8 x) -> (NEGL x)
(Neg32F x) -> (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> [f2i(math.Copysign(0, -1))])) (Neg32F x) -> (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> [f2i(math.Copysign(0, -1))]))
(Neg64F x) -> (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> [f2i(math.Copysign(0, -1))])) (Neg64F x) -> (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> [f2i(math.Copysign(0, -1))]))
(Com64 x) -> (NOTQ x) (Com64 x) -> (NOTQ x)
(Com32 x) -> (NOTL x) (Com32 x) -> (NOTL x)
(Com16 x) -> (NOTW x) (Com16 x) -> (NOTL x)
(Com8 x) -> (NOTB x) (Com8 x) -> (NOTL x)
// CMPQconst 0 below is redundant because BSF sets Z but how to remove? // CMPQconst 0 below is redundant because BSF sets Z but how to remove?
(Ctz64 <t> x) -> (CMOVQEQconst (BSFQ <t> x) (CMPQconst x [0]) [64]) (Ctz64 <t> x) -> (CMOVQEQconst (BSFQ <t> x) (CMPQconst x [0]) [64])
@ -169,15 +169,15 @@
(Lsh32x16 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst y [32]))) (Lsh32x16 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst y [32])))
(Lsh32x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32]))) (Lsh32x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
(Lsh16x64 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPQconst y [16]))) (Lsh16x64 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPQconst y [32])))
(Lsh16x32 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPLconst y [16]))) (Lsh16x32 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPLconst y [32])))
(Lsh16x16 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPWconst y [16]))) (Lsh16x16 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst y [32])))
(Lsh16x8 <t> x y) -> (ANDW (SHLW <t> x y) (SBBLcarrymask <t> (CMPBconst y [16]))) (Lsh16x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
(Lsh8x64 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPQconst y [8]))) (Lsh8x64 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPQconst y [32])))
(Lsh8x32 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPLconst y [8]))) (Lsh8x32 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPLconst y [32])))
(Lsh8x16 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPWconst y [8]))) (Lsh8x16 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPWconst y [32])))
(Lsh8x8 <t> x y) -> (ANDB (SHLB <t> x y) (SBBLcarrymask <t> (CMPBconst y [8]))) (Lsh8x8 <t> x y) -> (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
(Lrot64 <t> x [c]) -> (ROLQconst <t> [c&63] x) (Lrot64 <t> x [c]) -> (ROLQconst <t> [c&63] x)
(Lrot32 <t> x [c]) -> (ROLLconst <t> [c&31] x) (Lrot32 <t> x [c]) -> (ROLLconst <t> [c&31] x)
@ -194,38 +194,38 @@
(Rsh32Ux16 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPWconst y [32]))) (Rsh32Ux16 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPWconst y [32])))
(Rsh32Ux8 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32]))) (Rsh32Ux8 <t> x y) -> (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMPBconst y [32])))
(Rsh16Ux64 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPQconst y [16]))) (Rsh16Ux64 <t> x y) -> (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMPQconst y [16])))
(Rsh16Ux32 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPLconst y [16]))) (Rsh16Ux32 <t> x y) -> (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMPLconst y [16])))
(Rsh16Ux16 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPWconst y [16]))) (Rsh16Ux16 <t> x y) -> (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMPWconst y [16])))
(Rsh16Ux8 <t> x y) -> (ANDW (SHRW <t> x y) (SBBLcarrymask <t> (CMPBconst y [16]))) (Rsh16Ux8 <t> x y) -> (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMPBconst y [16])))
(Rsh8Ux64 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPQconst y [8]))) (Rsh8Ux64 <t> x y) -> (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMPQconst y [8])))
(Rsh8Ux32 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPLconst y [8]))) (Rsh8Ux32 <t> x y) -> (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMPLconst y [8])))
(Rsh8Ux16 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPWconst y [8]))) (Rsh8Ux16 <t> x y) -> (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMPWconst y [8])))
(Rsh8Ux8 <t> x y) -> (ANDB (SHRB <t> x y) (SBBLcarrymask <t> (CMPBconst y [8]))) (Rsh8Ux8 <t> x y) -> (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMPBconst y [8])))
// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value. // Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
// We implement this by setting the shift value to -1 (all ones) if the shift value is >= width. // We implement this by setting the shift value to -1 (all ones) if the shift value is >= width.
// Note: for small shift widths we generate 32 bits of mask even when we don't need it all. // Note: for small shift widths we generate 32 bits of mask even when we don't need it all.
(Rsh64x64 <t> x y) -> (SARQ <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [64]))))) (Rsh64x64 <t> x y) -> (SARQ <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [64])))))
(Rsh64x32 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [64]))))) (Rsh64x32 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [64])))))
(Rsh64x16 <t> x y) -> (SARQ <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [64]))))) (Rsh64x16 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [64])))))
(Rsh64x8 <t> x y) -> (SARQ <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [64]))))) (Rsh64x8 <t> x y) -> (SARQ <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [64])))))
(Rsh32x64 <t> x y) -> (SARL <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [32]))))) (Rsh32x64 <t> x y) -> (SARL <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [32])))))
(Rsh32x32 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [32]))))) (Rsh32x32 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [32])))))
(Rsh32x16 <t> x y) -> (SARL <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [32]))))) (Rsh32x16 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [32])))))
(Rsh32x8 <t> x y) -> (SARL <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [32]))))) (Rsh32x8 <t> x y) -> (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [32])))))
(Rsh16x64 <t> x y) -> (SARW <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [16]))))) (Rsh16x64 <t> x y) -> (SARW <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [16])))))
(Rsh16x32 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [16]))))) (Rsh16x32 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [16])))))
(Rsh16x16 <t> x y) -> (SARW <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [16]))))) (Rsh16x16 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [16])))))
(Rsh16x8 <t> x y) -> (SARW <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [16]))))) (Rsh16x8 <t> x y) -> (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [16])))))
(Rsh8x64 <t> x y) -> (SARB <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [8]))))) (Rsh8x64 <t> x y) -> (SARB <t> x (ORQ <y.Type> y (NOTQ <y.Type> (SBBQcarrymask <y.Type> (CMPQconst y [8])))))
(Rsh8x32 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [8]))))) (Rsh8x32 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPLconst y [8])))))
(Rsh8x16 <t> x y) -> (SARB <t> x (ORW <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [8]))))) (Rsh8x16 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPWconst y [8])))))
(Rsh8x8 <t> x y) -> (SARB <t> x (ORB <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [8]))))) (Rsh8x8 <t> x y) -> (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMPBconst y [8])))))
(Less64 x y) -> (SETL (CMPQ x y)) (Less64 x y) -> (SETL (CMPQ x y))
(Less32 x y) -> (SETL (CMPL x y)) (Less32 x y) -> (SETL (CMPL x y))
@ -366,19 +366,19 @@
(Move [size] dst src mem) && (size > 16*64 || config.noDuffDevice) && size%8 == 0 -> (Move [size] dst src mem) && (size > 16*64 || config.noDuffDevice) && size%8 == 0 ->
(REPMOVSQ dst src (MOVQconst [size/8]) mem) (REPMOVSQ dst src (MOVQconst [size/8]) mem)
(Not x) -> (XORBconst [1] x) (Not x) -> (XORLconst [1] x)
(OffPtr [off] ptr) && is32Bit(off) -> (ADDQconst [off] ptr) (OffPtr [off] ptr) && is32Bit(off) -> (ADDQconst [off] ptr)
(OffPtr [off] ptr) -> (ADDQ (MOVQconst [off]) ptr) (OffPtr [off] ptr) -> (ADDQ (MOVQconst [off]) ptr)
(Const8 [val]) -> (MOVBconst [val]) (Const8 [val]) -> (MOVLconst [val])
(Const16 [val]) -> (MOVWconst [val]) (Const16 [val]) -> (MOVLconst [val])
(Const32 [val]) -> (MOVLconst [val]) (Const32 [val]) -> (MOVLconst [val])
(Const64 [val]) -> (MOVQconst [val]) (Const64 [val]) -> (MOVQconst [val])
(Const32F [val]) -> (MOVSSconst [val]) (Const32F [val]) -> (MOVSSconst [val])
(Const64F [val]) -> (MOVSDconst [val]) (Const64F [val]) -> (MOVSDconst [val])
(ConstNil) -> (MOVQconst [0]) (ConstNil) -> (MOVQconst [0])
(ConstBool [b]) -> (MOVBconst [b]) (ConstBool [b]) -> (MOVLconst [b])
(Addr {sym} base) -> (LEAQ {sym} base) (Addr {sym} base) -> (LEAQ {sym} base)
@ -439,44 +439,22 @@
(ADDQ (MOVQconst [c]) x) && is32Bit(c) -> (ADDQconst [c] x) (ADDQ (MOVQconst [c]) x) && is32Bit(c) -> (ADDQconst [c] x)
(ADDL x (MOVLconst [c])) -> (ADDLconst [c] x) (ADDL x (MOVLconst [c])) -> (ADDLconst [c] x)
(ADDL (MOVLconst [c]) x) -> (ADDLconst [c] x) (ADDL (MOVLconst [c]) x) -> (ADDLconst [c] x)
(ADDW x (MOVWconst [c])) -> (ADDWconst [c] x)
(ADDW (MOVWconst [c]) x) -> (ADDWconst [c] x)
(ADDB x (MOVBconst [c])) -> (ADDBconst [c] x)
(ADDB (MOVBconst [c]) x) -> (ADDBconst [c] x)
(SUBQ x (MOVQconst [c])) && is32Bit(c) -> (SUBQconst x [c]) (SUBQ x (MOVQconst [c])) && is32Bit(c) -> (SUBQconst x [c])
(SUBQ (MOVQconst [c]) x) && is32Bit(c) -> (NEGQ (SUBQconst <v.Type> x [c])) (SUBQ (MOVQconst [c]) x) && is32Bit(c) -> (NEGQ (SUBQconst <v.Type> x [c]))
(SUBL x (MOVLconst [c])) -> (SUBLconst x [c]) (SUBL x (MOVLconst [c])) -> (SUBLconst x [c])
(SUBL (MOVLconst [c]) x) -> (NEGL (SUBLconst <v.Type> x [c])) (SUBL (MOVLconst [c]) x) -> (NEGL (SUBLconst <v.Type> x [c]))
(SUBW x (MOVWconst [c])) -> (SUBWconst x [c])
(SUBW (MOVWconst [c]) x) -> (NEGW (SUBWconst <v.Type> x [c]))
(SUBB x (MOVBconst [c])) -> (SUBBconst x [c])
(SUBB (MOVBconst [c]) x) -> (NEGB (SUBBconst <v.Type> x [c]))
(MULQ x (MOVQconst [c])) && is32Bit(c) -> (MULQconst [c] x) (MULQ x (MOVQconst [c])) && is32Bit(c) -> (MULQconst [c] x)
(MULQ (MOVQconst [c]) x) && is32Bit(c) -> (MULQconst [c] x) (MULQ (MOVQconst [c]) x) && is32Bit(c) -> (MULQconst [c] x)
(MULL x (MOVLconst [c])) -> (MULLconst [c] x) (MULL x (MOVLconst [c])) -> (MULLconst [c] x)
(MULL (MOVLconst [c]) x) -> (MULLconst [c] x) (MULL (MOVLconst [c]) x) -> (MULLconst [c] x)
(MULW x (MOVWconst [c])) -> (MULWconst [c] x)
(MULW (MOVWconst [c]) x) -> (MULWconst [c] x)
(MULB x (MOVBconst [c])) -> (MULBconst [c] x)
(MULB (MOVBconst [c]) x) -> (MULBconst [c] x)
(ANDQ x (MOVQconst [c])) && is32Bit(c) -> (ANDQconst [c] x) (ANDQ x (MOVQconst [c])) && is32Bit(c) -> (ANDQconst [c] x)
(ANDQ (MOVQconst [c]) x) && is32Bit(c) -> (ANDQconst [c] x) (ANDQ (MOVQconst [c]) x) && is32Bit(c) -> (ANDQconst [c] x)
(ANDL x (MOVLconst [c])) -> (ANDLconst [c] x) (ANDL x (MOVLconst [c])) -> (ANDLconst [c] x)
(ANDL (MOVLconst [c]) x) -> (ANDLconst [c] x) (ANDL (MOVLconst [c]) x) -> (ANDLconst [c] x)
(ANDW x (MOVLconst [c])) -> (ANDWconst [c] x)
(ANDW (MOVLconst [c]) x) -> (ANDWconst [c] x)
(ANDW x (MOVWconst [c])) -> (ANDWconst [c] x)
(ANDW (MOVWconst [c]) x) -> (ANDWconst [c] x)
(ANDB x (MOVLconst [c])) -> (ANDBconst [c] x)
(ANDB (MOVLconst [c]) x) -> (ANDBconst [c] x)
(ANDB x (MOVBconst [c])) -> (ANDBconst [c] x)
(ANDB (MOVBconst [c]) x) -> (ANDBconst [c] x)
(ANDBconst [c] (ANDBconst [d] x)) -> (ANDBconst [c & d] x)
(ANDWconst [c] (ANDWconst [d] x)) -> (ANDWconst [c & d] x)
(ANDLconst [c] (ANDLconst [d] x)) -> (ANDLconst [c & d] x) (ANDLconst [c] (ANDLconst [d] x)) -> (ANDLconst [c & d] x)
(ANDQconst [c] (ANDQconst [d] x)) -> (ANDQconst [c & d] x) (ANDQconst [c] (ANDQconst [d] x)) -> (ANDQconst [c & d] x)
@ -484,108 +462,64 @@
(ORQ (MOVQconst [c]) x) && is32Bit(c) -> (ORQconst [c] x) (ORQ (MOVQconst [c]) x) && is32Bit(c) -> (ORQconst [c] x)
(ORL x (MOVLconst [c])) -> (ORLconst [c] x) (ORL x (MOVLconst [c])) -> (ORLconst [c] x)
(ORL (MOVLconst [c]) x) -> (ORLconst [c] x) (ORL (MOVLconst [c]) x) -> (ORLconst [c] x)
(ORW x (MOVWconst [c])) -> (ORWconst [c] x)
(ORW (MOVWconst [c]) x) -> (ORWconst [c] x)
(ORB x (MOVBconst [c])) -> (ORBconst [c] x)
(ORB (MOVBconst [c]) x) -> (ORBconst [c] x)
(XORQ x (MOVQconst [c])) && is32Bit(c) -> (XORQconst [c] x) (XORQ x (MOVQconst [c])) && is32Bit(c) -> (XORQconst [c] x)
(XORQ (MOVQconst [c]) x) && is32Bit(c) -> (XORQconst [c] x) (XORQ (MOVQconst [c]) x) && is32Bit(c) -> (XORQconst [c] x)
(XORL x (MOVLconst [c])) -> (XORLconst [c] x) (XORL x (MOVLconst [c])) -> (XORLconst [c] x)
(XORL (MOVLconst [c]) x) -> (XORLconst [c] x) (XORL (MOVLconst [c]) x) -> (XORLconst [c] x)
(XORW x (MOVWconst [c])) -> (XORWconst [c] x)
(XORW (MOVWconst [c]) x) -> (XORWconst [c] x)
(XORB x (MOVBconst [c])) -> (XORBconst [c] x)
(XORB (MOVBconst [c]) x) -> (XORBconst [c] x)
(SHLQ x (MOVQconst [c])) -> (SHLQconst [c&63] x) (SHLQ x (MOVQconst [c])) -> (SHLQconst [c&63] x)
(SHLQ x (MOVLconst [c])) -> (SHLQconst [c&63] x) (SHLQ x (MOVLconst [c])) -> (SHLQconst [c&63] x)
(SHLQ x (MOVWconst [c])) -> (SHLQconst [c&63] x)
(SHLQ x (MOVBconst [c])) -> (SHLQconst [c&63] x)
(SHLL x (MOVQconst [c])) -> (SHLLconst [c&31] x) (SHLL x (MOVQconst [c])) -> (SHLLconst [c&31] x)
(SHLL x (MOVLconst [c])) -> (SHLLconst [c&31] x) (SHLL x (MOVLconst [c])) -> (SHLLconst [c&31] x)
(SHLL x (MOVWconst [c])) -> (SHLLconst [c&31] x)
(SHLL x (MOVBconst [c])) -> (SHLLconst [c&31] x)
(SHLW x (MOVQconst [c])) -> (SHLWconst [c&31] x)
(SHLW x (MOVLconst [c])) -> (SHLWconst [c&31] x)
(SHLW x (MOVWconst [c])) -> (SHLWconst [c&31] x)
(SHLW x (MOVBconst [c])) -> (SHLWconst [c&31] x)
(SHLB x (MOVQconst [c])) -> (SHLBconst [c&31] x)
(SHLB x (MOVLconst [c])) -> (SHLBconst [c&31] x)
(SHLB x (MOVWconst [c])) -> (SHLBconst [c&31] x)
(SHLB x (MOVBconst [c])) -> (SHLBconst [c&31] x)
(SHRQ x (MOVQconst [c])) -> (SHRQconst [c&63] x) (SHRQ x (MOVQconst [c])) -> (SHRQconst [c&63] x)
(SHRQ x (MOVLconst [c])) -> (SHRQconst [c&63] x) (SHRQ x (MOVLconst [c])) -> (SHRQconst [c&63] x)
(SHRQ x (MOVWconst [c])) -> (SHRQconst [c&63] x)
(SHRQ x (MOVBconst [c])) -> (SHRQconst [c&63] x)
(SHRL x (MOVQconst [c])) -> (SHRLconst [c&31] x) (SHRL x (MOVQconst [c])) -> (SHRLconst [c&31] x)
(SHRL x (MOVLconst [c])) -> (SHRLconst [c&31] x) (SHRL x (MOVLconst [c])) -> (SHRLconst [c&31] x)
(SHRL x (MOVWconst [c])) -> (SHRLconst [c&31] x)
(SHRL x (MOVBconst [c])) -> (SHRLconst [c&31] x)
(SHRW x (MOVQconst [c])) -> (SHRWconst [c&31] x) (SHRW x (MOVQconst [c])) -> (SHRWconst [c&31] x)
(SHRW x (MOVLconst [c])) -> (SHRWconst [c&31] x) (SHRW x (MOVLconst [c])) -> (SHRWconst [c&31] x)
(SHRW x (MOVWconst [c])) -> (SHRWconst [c&31] x)
(SHRW x (MOVBconst [c])) -> (SHRWconst [c&31] x)
(SHRB x (MOVQconst [c])) -> (SHRBconst [c&31] x) (SHRB x (MOVQconst [c])) -> (SHRBconst [c&31] x)
(SHRB x (MOVLconst [c])) -> (SHRBconst [c&31] x) (SHRB x (MOVLconst [c])) -> (SHRBconst [c&31] x)
(SHRB x (MOVWconst [c])) -> (SHRBconst [c&31] x)
(SHRB x (MOVBconst [c])) -> (SHRBconst [c&31] x)
(SARQ x (MOVQconst [c])) -> (SARQconst [c&63] x) (SARQ x (MOVQconst [c])) -> (SARQconst [c&63] x)
(SARQ x (MOVLconst [c])) -> (SARQconst [c&63] x) (SARQ x (MOVLconst [c])) -> (SARQconst [c&63] x)
(SARQ x (MOVWconst [c])) -> (SARQconst [c&63] x)
(SARQ x (MOVBconst [c])) -> (SARQconst [c&63] x)
(SARL x (MOVQconst [c])) -> (SARLconst [c&31] x) (SARL x (MOVQconst [c])) -> (SARLconst [c&31] x)
(SARL x (MOVLconst [c])) -> (SARLconst [c&31] x) (SARL x (MOVLconst [c])) -> (SARLconst [c&31] x)
(SARL x (MOVWconst [c])) -> (SARLconst [c&31] x)
(SARL x (MOVBconst [c])) -> (SARLconst [c&31] x)
(SARW x (MOVQconst [c])) -> (SARWconst [c&31] x) (SARW x (MOVQconst [c])) -> (SARWconst [c&31] x)
(SARW x (MOVLconst [c])) -> (SARWconst [c&31] x) (SARW x (MOVLconst [c])) -> (SARWconst [c&31] x)
(SARW x (MOVWconst [c])) -> (SARWconst [c&31] x)
(SARW x (MOVBconst [c])) -> (SARWconst [c&31] x)
(SARB x (MOVQconst [c])) -> (SARBconst [c&31] x) (SARB x (MOVQconst [c])) -> (SARBconst [c&31] x)
(SARB x (MOVLconst [c])) -> (SARBconst [c&31] x) (SARB x (MOVLconst [c])) -> (SARBconst [c&31] x)
(SARB x (MOVWconst [c])) -> (SARBconst [c&31] x)
(SARB x (MOVBconst [c])) -> (SARBconst [c&31] x)
(SARB x (ANDBconst [31] y)) -> (SARB x y)
(SARW x (ANDWconst [31] y)) -> (SARW x y)
(SARL x (ANDLconst [31] y)) -> (SARL x y) (SARL x (ANDLconst [31] y)) -> (SARL x y)
(SARQ x (ANDQconst [63] y)) -> (SARQ x y) (SARQ x (ANDQconst [63] y)) -> (SARQ x y)
(SHLB x (ANDBconst [31] y)) -> (SHLB x y)
(SHLW x (ANDWconst [31] y)) -> (SHLW x y)
(SHLL x (ANDLconst [31] y)) -> (SHLL x y) (SHLL x (ANDLconst [31] y)) -> (SHLL x y)
(SHLQ x (ANDQconst [63] y)) -> (SHLQ x y) (SHLQ x (ANDQconst [63] y)) -> (SHLQ x y)
(SHRB x (ANDBconst [31] y)) -> (SHRB x y)
(SHRW x (ANDWconst [31] y)) -> (SHRW x y)
(SHRL x (ANDLconst [31] y)) -> (SHRL x y) (SHRL x (ANDLconst [31] y)) -> (SHRL x y)
(SHRQ x (ANDQconst [63] y)) -> (SHRQ x y) (SHRQ x (ANDQconst [63] y)) -> (SHRQ x y)
// Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits) // Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits)
// because the x86 instructions are defined to use all 5 bits of the shift even // because the x86 instructions are defined to use all 5 bits of the shift even
// for the small shifts. I don't think we'll ever generate a weird shift (e.g. // for the small shifts. I don't think we'll ever generate a weird shift (e.g.
// (SHLW x (MOVWconst [24])), but just in case. // (SHRW x (MOVLconst [24])), but just in case.
(CMPQ x (MOVQconst [c])) && is32Bit(c) -> (CMPQconst x [c]) (CMPQ x (MOVQconst [c])) && is32Bit(c) -> (CMPQconst x [c])
(CMPQ (MOVQconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPQconst x [c])) (CMPQ (MOVQconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPQconst x [c]))
(CMPL x (MOVLconst [c])) -> (CMPLconst x [c]) (CMPL x (MOVLconst [c])) -> (CMPLconst x [c])
(CMPL (MOVLconst [c]) x) -> (InvertFlags (CMPLconst x [c])) (CMPL (MOVLconst [c]) x) -> (InvertFlags (CMPLconst x [c]))
(CMPW x (MOVWconst [c])) -> (CMPWconst x [c]) (CMPW x (MOVLconst [c])) -> (CMPWconst x [int64(int16(c))])
(CMPW (MOVWconst [c]) x) -> (InvertFlags (CMPWconst x [c])) (CMPW (MOVLconst [c]) x) -> (InvertFlags (CMPWconst x [int64(int16(c))]))
(CMPB x (MOVBconst [c])) -> (CMPBconst x [c]) (CMPB x (MOVLconst [c])) -> (CMPBconst x [int64(int8(c))])
(CMPB (MOVBconst [c]) x) -> (InvertFlags (CMPBconst x [c])) (CMPB (MOVLconst [c]) x) -> (InvertFlags (CMPBconst x [int64(int8(c))]))
// Using MOVBQZX instead of ANDQ is cheaper. // Using MOVBQZX instead of ANDQ is cheaper.
(ANDQconst [0xFF] x) -> (MOVBQZX x) (ANDQconst [0xFF] x) -> (MOVBQZX x)
@ -709,12 +643,12 @@
(MOVQload [off] {sym} ptr (MOVQstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x (MOVQload [off] {sym} ptr (MOVQstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
// Fold extensions and ANDs together. // Fold extensions and ANDs together.
(MOVBQZX (ANDBconst [c] x)) -> (ANDQconst [c & 0xff] x) (MOVBQZX (ANDLconst [c] x)) -> (ANDLconst [c & 0xff] x)
(MOVWQZX (ANDWconst [c] x)) -> (ANDQconst [c & 0xffff] x) (MOVWQZX (ANDLconst [c] x)) -> (ANDLconst [c & 0xffff] x)
(MOVLQZX (ANDLconst [c] x)) && c & 0x80000000 == 0 -> (ANDQconst [c & 0x7fffffff] x) (MOVLQZX (ANDLconst [c] x)) -> (ANDLconst [c] x)
(MOVBQSX (ANDBconst [c] x)) && c & 0x80 == 0 -> (ANDQconst [c & 0x7f] x) (MOVBQSX (ANDLconst [c] x)) && c & 0x80 == 0 -> (ANDLconst [c & 0x7f] x)
(MOVWQSX (ANDWconst [c] x)) && c & 0x8000 == 0 -> (ANDQconst [c & 0x7fff] x) (MOVWQSX (ANDLconst [c] x)) && c & 0x8000 == 0 -> (ANDLconst [c & 0x7fff] x)
(MOVLQSX (ANDLconst [c] x)) && c & 0x80000000 == 0 -> (ANDQconst [c & 0x7fffffff] x) (MOVLQSX (ANDLconst [c] x)) && c & 0x80000000 == 0 -> (ANDLconst [c & 0x7fffffff] x)
// Don't extend before storing // Don't extend before storing
(MOVLstore [off] {sym} ptr (MOVLQSX x) mem) -> (MOVLstore [off] {sym} ptr x mem) (MOVLstore [off] {sym} ptr (MOVLQSX x) mem) -> (MOVLstore [off] {sym} ptr x mem)
@ -750,9 +684,9 @@
(MOVQstoreconst [makeValAndOff(c,off)] {sym} ptr mem) (MOVQstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
(MOVLstore [off] {sym} ptr (MOVLconst [c]) mem) && validOff(off) -> (MOVLstore [off] {sym} ptr (MOVLconst [c]) mem) && validOff(off) ->
(MOVLstoreconst [makeValAndOff(int64(int32(c)),off)] {sym} ptr mem) (MOVLstoreconst [makeValAndOff(int64(int32(c)),off)] {sym} ptr mem)
(MOVWstore [off] {sym} ptr (MOVWconst [c]) mem) && validOff(off) -> (MOVWstore [off] {sym} ptr (MOVLconst [c]) mem) && validOff(off) ->
(MOVWstoreconst [makeValAndOff(int64(int16(c)),off)] {sym} ptr mem) (MOVWstoreconst [makeValAndOff(int64(int16(c)),off)] {sym} ptr mem)
(MOVBstore [off] {sym} ptr (MOVBconst [c]) mem) && validOff(off) -> (MOVBstore [off] {sym} ptr (MOVLconst [c]) mem) && validOff(off) ->
(MOVBstoreconst [makeValAndOff(int64(int8(c)),off)] {sym} ptr mem) (MOVBstoreconst [makeValAndOff(int64(int8(c)),off)] {sym} ptr mem)
// Fold address offsets into constant stores. // Fold address offsets into constant stores.
@ -1086,16 +1020,16 @@
(CMPLconst (MOVLconst [x]) [y]) && int32(x)<int32(y) && uint32(x)>uint32(y) -> (FlagLT_UGT) (CMPLconst (MOVLconst [x]) [y]) && int32(x)<int32(y) && uint32(x)>uint32(y) -> (FlagLT_UGT)
(CMPLconst (MOVLconst [x]) [y]) && int32(x)>int32(y) && uint32(x)<uint32(y) -> (FlagGT_ULT) (CMPLconst (MOVLconst [x]) [y]) && int32(x)>int32(y) && uint32(x)<uint32(y) -> (FlagGT_ULT)
(CMPLconst (MOVLconst [x]) [y]) && int32(x)>int32(y) && uint32(x)>uint32(y) -> (FlagGT_UGT) (CMPLconst (MOVLconst [x]) [y]) && int32(x)>int32(y) && uint32(x)>uint32(y) -> (FlagGT_UGT)
(CMPWconst (MOVWconst [x]) [y]) && int16(x)==int16(y) -> (FlagEQ) (CMPWconst (MOVLconst [x]) [y]) && int16(x)==int16(y) -> (FlagEQ)
(CMPWconst (MOVWconst [x]) [y]) && int16(x)<int16(y) && uint16(x)<uint16(y) -> (FlagLT_ULT) (CMPWconst (MOVLconst [x]) [y]) && int16(x)<int16(y) && uint16(x)<uint16(y) -> (FlagLT_ULT)
(CMPWconst (MOVWconst [x]) [y]) && int16(x)<int16(y) && uint16(x)>uint16(y) -> (FlagLT_UGT) (CMPWconst (MOVLconst [x]) [y]) && int16(x)<int16(y) && uint16(x)>uint16(y) -> (FlagLT_UGT)
(CMPWconst (MOVWconst [x]) [y]) && int16(x)>int16(y) && uint16(x)<uint16(y) -> (FlagGT_ULT) (CMPWconst (MOVLconst [x]) [y]) && int16(x)>int16(y) && uint16(x)<uint16(y) -> (FlagGT_ULT)
(CMPWconst (MOVWconst [x]) [y]) && int16(x)>int16(y) && uint16(x)>uint16(y) -> (FlagGT_UGT) (CMPWconst (MOVLconst [x]) [y]) && int16(x)>int16(y) && uint16(x)>uint16(y) -> (FlagGT_UGT)
(CMPBconst (MOVBconst [x]) [y]) && int8(x)==int8(y) -> (FlagEQ) (CMPBconst (MOVLconst [x]) [y]) && int8(x)==int8(y) -> (FlagEQ)
(CMPBconst (MOVBconst [x]) [y]) && int8(x)<int8(y) && uint8(x)<uint8(y) -> (FlagLT_ULT) (CMPBconst (MOVLconst [x]) [y]) && int8(x)<int8(y) && uint8(x)<uint8(y) -> (FlagLT_ULT)
(CMPBconst (MOVBconst [x]) [y]) && int8(x)<int8(y) && uint8(x)>uint8(y) -> (FlagLT_UGT) (CMPBconst (MOVLconst [x]) [y]) && int8(x)<int8(y) && uint8(x)>uint8(y) -> (FlagLT_UGT)
(CMPBconst (MOVBconst [x]) [y]) && int8(x)>int8(y) && uint8(x)<uint8(y) -> (FlagGT_ULT) (CMPBconst (MOVLconst [x]) [y]) && int8(x)>int8(y) && uint8(x)<uint8(y) -> (FlagGT_ULT)
(CMPBconst (MOVBconst [x]) [y]) && int8(x)>int8(y) && uint8(x)>uint8(y) -> (FlagGT_UGT) (CMPBconst (MOVLconst [x]) [y]) && int8(x)>int8(y) && uint8(x)>uint8(y) -> (FlagGT_UGT)
// Other known comparisons. // Other known comparisons.
(CMPQconst (MOVBQZX _) [c]) && 0xFF < c -> (FlagLT_ULT) (CMPQconst (MOVBQZX _) [c]) && 0xFF < c -> (FlagLT_ULT)
@ -1105,8 +1039,8 @@
(CMPQconst (SHRQconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n) -> (FlagLT_ULT) (CMPQconst (SHRQconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n) -> (FlagLT_ULT)
(CMPQconst (ANDQconst _ [m]) [n]) && 0 <= m && m < n -> (FlagLT_ULT) (CMPQconst (ANDQconst _ [m]) [n]) && 0 <= m && m < n -> (FlagLT_ULT)
(CMPLconst (ANDLconst _ [m]) [n]) && 0 <= int32(m) && int32(m) < int32(n) -> (FlagLT_ULT) (CMPLconst (ANDLconst _ [m]) [n]) && 0 <= int32(m) && int32(m) < int32(n) -> (FlagLT_ULT)
(CMPWconst (ANDWconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < int16(n) -> (FlagLT_ULT) (CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < int16(n) -> (FlagLT_ULT)
(CMPBconst (ANDBconst _ [m]) [n]) && 0 <= int8(m) && int8(m) < int8(n) -> (FlagLT_ULT) (CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m) && int8(m) < int8(n) -> (FlagLT_ULT)
// TODO: DIVxU also. // TODO: DIVxU also.
// Absorb flag constants into SBB ops. // Absorb flag constants into SBB ops.
@ -1183,181 +1117,140 @@
(UGE (FlagGT_UGT) yes no) -> (First nil yes no) (UGE (FlagGT_UGT) yes no) -> (First nil yes no)
// Absorb flag constants into SETxx ops. // Absorb flag constants into SETxx ops.
(SETEQ (FlagEQ)) -> (MOVBconst [1]) (SETEQ (FlagEQ)) -> (MOVLconst [1])
(SETEQ (FlagLT_ULT)) -> (MOVBconst [0]) (SETEQ (FlagLT_ULT)) -> (MOVLconst [0])
(SETEQ (FlagLT_UGT)) -> (MOVBconst [0]) (SETEQ (FlagLT_UGT)) -> (MOVLconst [0])
(SETEQ (FlagGT_ULT)) -> (MOVBconst [0]) (SETEQ (FlagGT_ULT)) -> (MOVLconst [0])
(SETEQ (FlagGT_UGT)) -> (MOVBconst [0]) (SETEQ (FlagGT_UGT)) -> (MOVLconst [0])
(SETNE (FlagEQ)) -> (MOVBconst [0]) (SETNE (FlagEQ)) -> (MOVLconst [0])
(SETNE (FlagLT_ULT)) -> (MOVBconst [1]) (SETNE (FlagLT_ULT)) -> (MOVLconst [1])
(SETNE (FlagLT_UGT)) -> (MOVBconst [1]) (SETNE (FlagLT_UGT)) -> (MOVLconst [1])
(SETNE (FlagGT_ULT)) -> (MOVBconst [1]) (SETNE (FlagGT_ULT)) -> (MOVLconst [1])
(SETNE (FlagGT_UGT)) -> (MOVBconst [1]) (SETNE (FlagGT_UGT)) -> (MOVLconst [1])
(SETL (FlagEQ)) -> (MOVBconst [0]) (SETL (FlagEQ)) -> (MOVLconst [0])
(SETL (FlagLT_ULT)) -> (MOVBconst [1]) (SETL (FlagLT_ULT)) -> (MOVLconst [1])
(SETL (FlagLT_UGT)) -> (MOVBconst [1]) (SETL (FlagLT_UGT)) -> (MOVLconst [1])
(SETL (FlagGT_ULT)) -> (MOVBconst [0]) (SETL (FlagGT_ULT)) -> (MOVLconst [0])
(SETL (FlagGT_UGT)) -> (MOVBconst [0]) (SETL (FlagGT_UGT)) -> (MOVLconst [0])
(SETLE (FlagEQ)) -> (MOVBconst [1]) (SETLE (FlagEQ)) -> (MOVLconst [1])
(SETLE (FlagLT_ULT)) -> (MOVBconst [1]) (SETLE (FlagLT_ULT)) -> (MOVLconst [1])
(SETLE (FlagLT_UGT)) -> (MOVBconst [1]) (SETLE (FlagLT_UGT)) -> (MOVLconst [1])
(SETLE (FlagGT_ULT)) -> (MOVBconst [0]) (SETLE (FlagGT_ULT)) -> (MOVLconst [0])
(SETLE (FlagGT_UGT)) -> (MOVBconst [0]) (SETLE (FlagGT_UGT)) -> (MOVLconst [0])
(SETG (FlagEQ)) -> (MOVBconst [0]) (SETG (FlagEQ)) -> (MOVLconst [0])
(SETG (FlagLT_ULT)) -> (MOVBconst [0]) (SETG (FlagLT_ULT)) -> (MOVLconst [0])
(SETG (FlagLT_UGT)) -> (MOVBconst [0]) (SETG (FlagLT_UGT)) -> (MOVLconst [0])
(SETG (FlagGT_ULT)) -> (MOVBconst [1]) (SETG (FlagGT_ULT)) -> (MOVLconst [1])
(SETG (FlagGT_UGT)) -> (MOVBconst [1]) (SETG (FlagGT_UGT)) -> (MOVLconst [1])
(SETGE (FlagEQ)) -> (MOVBconst [1]) (SETGE (FlagEQ)) -> (MOVLconst [1])
(SETGE (FlagLT_ULT)) -> (MOVBconst [0]) (SETGE (FlagLT_ULT)) -> (MOVLconst [0])
(SETGE (FlagLT_UGT)) -> (MOVBconst [0]) (SETGE (FlagLT_UGT)) -> (MOVLconst [0])
(SETGE (FlagGT_ULT)) -> (MOVBconst [1]) (SETGE (FlagGT_ULT)) -> (MOVLconst [1])
(SETGE (FlagGT_UGT)) -> (MOVBconst [1]) (SETGE (FlagGT_UGT)) -> (MOVLconst [1])
(SETB (FlagEQ)) -> (MOVBconst [0]) (SETB (FlagEQ)) -> (MOVLconst [0])
(SETB (FlagLT_ULT)) -> (MOVBconst [1]) (SETB (FlagLT_ULT)) -> (MOVLconst [1])
(SETB (FlagLT_UGT)) -> (MOVBconst [0]) (SETB (FlagLT_UGT)) -> (MOVLconst [0])
(SETB (FlagGT_ULT)) -> (MOVBconst [1]) (SETB (FlagGT_ULT)) -> (MOVLconst [1])
(SETB (FlagGT_UGT)) -> (MOVBconst [0]) (SETB (FlagGT_UGT)) -> (MOVLconst [0])
(SETBE (FlagEQ)) -> (MOVBconst [1]) (SETBE (FlagEQ)) -> (MOVLconst [1])
(SETBE (FlagLT_ULT)) -> (MOVBconst [1]) (SETBE (FlagLT_ULT)) -> (MOVLconst [1])
(SETBE (FlagLT_UGT)) -> (MOVBconst [0]) (SETBE (FlagLT_UGT)) -> (MOVLconst [0])
(SETBE (FlagGT_ULT)) -> (MOVBconst [1]) (SETBE (FlagGT_ULT)) -> (MOVLconst [1])
(SETBE (FlagGT_UGT)) -> (MOVBconst [0]) (SETBE (FlagGT_UGT)) -> (MOVLconst [0])
(SETA (FlagEQ)) -> (MOVBconst [0]) (SETA (FlagEQ)) -> (MOVLconst [0])
(SETA (FlagLT_ULT)) -> (MOVBconst [0]) (SETA (FlagLT_ULT)) -> (MOVLconst [0])
(SETA (FlagLT_UGT)) -> (MOVBconst [1]) (SETA (FlagLT_UGT)) -> (MOVLconst [1])
(SETA (FlagGT_ULT)) -> (MOVBconst [0]) (SETA (FlagGT_ULT)) -> (MOVLconst [0])
(SETA (FlagGT_UGT)) -> (MOVBconst [1]) (SETA (FlagGT_UGT)) -> (MOVLconst [1])
(SETAE (FlagEQ)) -> (MOVBconst [1]) (SETAE (FlagEQ)) -> (MOVLconst [1])
(SETAE (FlagLT_ULT)) -> (MOVBconst [0]) (SETAE (FlagLT_ULT)) -> (MOVLconst [0])
(SETAE (FlagLT_UGT)) -> (MOVBconst [1]) (SETAE (FlagLT_UGT)) -> (MOVLconst [1])
(SETAE (FlagGT_ULT)) -> (MOVBconst [0]) (SETAE (FlagGT_ULT)) -> (MOVLconst [0])
(SETAE (FlagGT_UGT)) -> (MOVBconst [1]) (SETAE (FlagGT_UGT)) -> (MOVLconst [1])
// Remove redundant *const ops // Remove redundant *const ops
(ADDQconst [0] x) -> x (ADDQconst [0] x) -> x
(ADDLconst [c] x) && int32(c)==0 -> x (ADDLconst [c] x) && int32(c)==0 -> x
(ADDWconst [c] x) && int16(c)==0 -> x
(ADDBconst [c] x) && int8(c)==0 -> x
(SUBQconst [0] x) -> x (SUBQconst [0] x) -> x
(SUBLconst [c] x) && int32(c) == 0 -> x (SUBLconst [c] x) && int32(c) == 0 -> x
(SUBWconst [c] x) && int16(c) == 0 -> x
(SUBBconst [c] x) && int8(c) == 0 -> x
(ANDQconst [0] _) -> (MOVQconst [0]) (ANDQconst [0] _) -> (MOVQconst [0])
(ANDLconst [c] _) && int32(c)==0 -> (MOVLconst [0]) (ANDLconst [c] _) && int32(c)==0 -> (MOVLconst [0])
(ANDWconst [c] _) && int16(c)==0 -> (MOVWconst [0])
(ANDBconst [c] _) && int8(c)==0 -> (MOVBconst [0])
(ANDQconst [-1] x) -> x (ANDQconst [-1] x) -> x
(ANDLconst [c] x) && int32(c)==-1 -> x (ANDLconst [c] x) && int32(c)==-1 -> x
(ANDWconst [c] x) && int16(c)==-1 -> x
(ANDBconst [c] x) && int8(c)==-1 -> x
(ORQconst [0] x) -> x (ORQconst [0] x) -> x
(ORLconst [c] x) && int32(c)==0 -> x (ORLconst [c] x) && int32(c)==0 -> x
(ORWconst [c] x) && int16(c)==0 -> x
(ORBconst [c] x) && int8(c)==0 -> x
(ORQconst [-1] _) -> (MOVQconst [-1]) (ORQconst [-1] _) -> (MOVQconst [-1])
(ORLconst [c] _) && int32(c)==-1 -> (MOVLconst [-1]) (ORLconst [c] _) && int32(c)==-1 -> (MOVLconst [-1])
(ORWconst [c] _) && int16(c)==-1 -> (MOVWconst [-1])
(ORBconst [c] _) && int8(c)==-1 -> (MOVBconst [-1])
(XORQconst [0] x) -> x (XORQconst [0] x) -> x
(XORLconst [c] x) && int32(c)==0 -> x (XORLconst [c] x) && int32(c)==0 -> x
(XORWconst [c] x) && int16(c)==0 -> x // TODO: since we got rid of the W/B versions, we might miss
(XORBconst [c] x) && int8(c)==0 -> x // things like (ANDLconst [0x100] x) which were formerly
// (ANDBconst [0] x). Probably doesn't happen very often.
// If we cared, we might do:
// (ANDLconst <t> [c] x) && t.Size()==1 && int8(x)==0 -> (MOVLconst [0])
// Convert constant subtracts to constant adds // Convert constant subtracts to constant adds
(SUBQconst [c] x) && c != -(1<<31) -> (ADDQconst [-c] x) (SUBQconst [c] x) && c != -(1<<31) -> (ADDQconst [-c] x)
(SUBLconst [c] x) -> (ADDLconst [int64(int32(-c))] x) (SUBLconst [c] x) -> (ADDLconst [int64(int32(-c))] x)
(SUBWconst [c] x) -> (ADDWconst [int64(int16(-c))] x)
(SUBBconst [c] x) -> (ADDBconst [int64(int8(-c))] x)
// generic constant folding // generic constant folding
// TODO: more of this // TODO: more of this
(ADDQconst [c] (MOVQconst [d])) -> (MOVQconst [c+d]) (ADDQconst [c] (MOVQconst [d])) -> (MOVQconst [c+d])
(ADDLconst [c] (MOVLconst [d])) -> (MOVLconst [int64(int32(c+d))]) (ADDLconst [c] (MOVLconst [d])) -> (MOVLconst [int64(int32(c+d))])
(ADDWconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int16(c+d))])
(ADDBconst [c] (MOVBconst [d])) -> (MOVBconst [int64(int8(c+d))])
(ADDQconst [c] (ADDQconst [d] x)) && is32Bit(c+d) -> (ADDQconst [c+d] x) (ADDQconst [c] (ADDQconst [d] x)) && is32Bit(c+d) -> (ADDQconst [c+d] x)
(ADDLconst [c] (ADDLconst [d] x)) -> (ADDLconst [int64(int32(c+d))] x) (ADDLconst [c] (ADDLconst [d] x)) -> (ADDLconst [int64(int32(c+d))] x)
(ADDWconst [c] (ADDWconst [d] x)) -> (ADDWconst [int64(int16(c+d))] x)
(ADDBconst [c] (ADDBconst [d] x)) -> (ADDBconst [int64(int8(c+d))] x)
(SUBQconst (MOVQconst [d]) [c]) -> (MOVQconst [d-c]) (SUBQconst (MOVQconst [d]) [c]) -> (MOVQconst [d-c])
(SUBLconst (MOVLconst [d]) [c]) -> (MOVLconst [int64(int32(d-c))]) (SUBLconst (MOVLconst [d]) [c]) -> (MOVLconst [int64(int32(d-c))])
(SUBWconst (MOVWconst [d]) [c]) -> (MOVWconst [int64(int16(d-c))])
(SUBBconst (MOVBconst [d]) [c]) -> (MOVBconst [int64(int8(d-c))])
(SUBQconst (SUBQconst x [d]) [c]) && is32Bit(-c-d) -> (ADDQconst [-c-d] x) (SUBQconst (SUBQconst x [d]) [c]) && is32Bit(-c-d) -> (ADDQconst [-c-d] x)
(SUBLconst (SUBLconst x [d]) [c]) -> (ADDLconst [int64(int32(-c-d))] x) (SUBLconst (SUBLconst x [d]) [c]) -> (ADDLconst [int64(int32(-c-d))] x)
(SUBWconst (SUBWconst x [d]) [c]) -> (ADDWconst [int64(int16(-c-d))] x)
(SUBBconst (SUBBconst x [d]) [c]) -> (ADDBconst [int64(int8(-c-d))] x)
(SARQconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)]) (SARQconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
(SARLconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)]) (SARLconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
(SARWconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)]) (SARWconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
(SARBconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)]) (SARBconst [c] (MOVQconst [d])) -> (MOVQconst [d>>uint64(c)])
(NEGQ (MOVQconst [c])) -> (MOVQconst [-c]) (NEGQ (MOVQconst [c])) -> (MOVQconst [-c])
(NEGL (MOVLconst [c])) -> (MOVLconst [int64(int32(-c))]) (NEGL (MOVLconst [c])) -> (MOVLconst [int64(int32(-c))])
(NEGW (MOVWconst [c])) -> (MOVWconst [int64(int16(-c))])
(NEGB (MOVBconst [c])) -> (MOVBconst [int64(int8(-c))])
(MULQconst [c] (MOVQconst [d])) -> (MOVQconst [c*d]) (MULQconst [c] (MOVQconst [d])) -> (MOVQconst [c*d])
(MULLconst [c] (MOVLconst [d])) -> (MOVLconst [int64(int32(c*d))]) (MULLconst [c] (MOVLconst [d])) -> (MOVLconst [int64(int32(c*d))])
(MULWconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int16(c*d))])
(MULBconst [c] (MOVBconst [d])) -> (MOVBconst [int64(int8(c*d))])
(ANDQconst [c] (MOVQconst [d])) -> (MOVQconst [c&d]) (ANDQconst [c] (MOVQconst [d])) -> (MOVQconst [c&d])
(ANDLconst [c] (MOVLconst [d])) -> (MOVLconst [c&d]) (ANDLconst [c] (MOVLconst [d])) -> (MOVLconst [c&d])
(ANDWconst [c] (MOVWconst [d])) -> (MOVWconst [c&d])
(ANDBconst [c] (MOVBconst [d])) -> (MOVBconst [c&d])
(ORQconst [c] (MOVQconst [d])) -> (MOVQconst [c|d]) (ORQconst [c] (MOVQconst [d])) -> (MOVQconst [c|d])
(ORLconst [c] (MOVLconst [d])) -> (MOVLconst [c|d]) (ORLconst [c] (MOVLconst [d])) -> (MOVLconst [c|d])
(ORWconst [c] (MOVWconst [d])) -> (MOVWconst [c|d])
(ORBconst [c] (MOVBconst [d])) -> (MOVBconst [c|d])
(XORQconst [c] (MOVQconst [d])) -> (MOVQconst [c^d]) (XORQconst [c] (MOVQconst [d])) -> (MOVQconst [c^d])
(XORLconst [c] (MOVLconst [d])) -> (MOVLconst [c^d]) (XORLconst [c] (MOVLconst [d])) -> (MOVLconst [c^d])
(XORWconst [c] (MOVWconst [d])) -> (MOVWconst [c^d])
(XORBconst [c] (MOVBconst [d])) -> (MOVBconst [c^d])
(NOTQ (MOVQconst [c])) -> (MOVQconst [^c]) (NOTQ (MOVQconst [c])) -> (MOVQconst [^c])
(NOTL (MOVLconst [c])) -> (MOVLconst [^c]) (NOTL (MOVLconst [c])) -> (MOVLconst [^c])
(NOTW (MOVWconst [c])) -> (MOVWconst [^c])
(NOTB (MOVBconst [c])) -> (MOVBconst [^c])
// generic simplifications // generic simplifications
// TODO: more of this // TODO: more of this
(ADDQ x (NEGQ y)) -> (SUBQ x y) (ADDQ x (NEGQ y)) -> (SUBQ x y)
(ADDL x (NEGL y)) -> (SUBL x y) (ADDL x (NEGL y)) -> (SUBL x y)
(ADDW x (NEGW y)) -> (SUBW x y)
(ADDB x (NEGB y)) -> (SUBB x y)
(SUBQ x x) -> (MOVQconst [0]) (SUBQ x x) -> (MOVQconst [0])
(SUBL x x) -> (MOVLconst [0]) (SUBL x x) -> (MOVLconst [0])
(SUBW x x) -> (MOVWconst [0])
(SUBB x x) -> (MOVBconst [0])
(ANDQ x x) -> x (ANDQ x x) -> x
(ANDL x x) -> x (ANDL x x) -> x
(ANDW x x) -> x
(ANDB x x) -> x
(ORQ x x) -> x (ORQ x x) -> x
(ORL x x) -> x (ORL x x) -> x
(ORW x x) -> x
(ORB x x) -> x
(XORQ x x) -> (MOVQconst [0]) (XORQ x x) -> (MOVQconst [0])
(XORL x x) -> (MOVLconst [0]) (XORL x x) -> (MOVLconst [0])
(XORW x x) -> (MOVWconst [0])
(XORB x x) -> (MOVBconst [0])
// checking AND against 0. // checking AND against 0.
(CMPQconst (ANDQ x y) [0]) -> (TESTQ x y) (CMPQconst (ANDQ x y) [0]) -> (TESTQ x y)
(CMPLconst (ANDL x y) [0]) -> (TESTL x y) (CMPLconst (ANDL x y) [0]) -> (TESTL x y)
(CMPWconst (ANDW x y) [0]) -> (TESTW x y) (CMPWconst (ANDL x y) [0]) -> (TESTW x y)
(CMPBconst (ANDB x y) [0]) -> (TESTB x y) (CMPBconst (ANDL x y) [0]) -> (TESTB x y)
(CMPQconst (ANDQconst [c] x) [0]) -> (TESTQconst [c] x) (CMPQconst (ANDQconst [c] x) [0]) -> (TESTQconst [c] x)
(CMPLconst (ANDLconst [c] x) [0]) -> (TESTLconst [c] x) (CMPLconst (ANDLconst [c] x) [0]) -> (TESTLconst [c] x)
(CMPWconst (ANDWconst [c] x) [0]) -> (TESTWconst [c] x) (CMPWconst (ANDLconst [c] x) [0]) -> (TESTWconst [int64(int16(c))] x)
(CMPBconst (ANDBconst [c] x) [0]) -> (TESTBconst [c] x) (CMPBconst (ANDLconst [c] x) [0]) -> (TESTBconst [int64(int8(c))] x)
// TEST %reg,%reg is shorter than CMP // TEST %reg,%reg is shorter than CMP
(CMPQconst x [0]) -> (TESTQ x x) (CMPQconst x [0]) -> (TESTQ x x)
@ -1368,8 +1261,8 @@
// Combining byte loads into larger (unaligned) loads. // Combining byte loads into larger (unaligned) loads.
// There are many ways these combinations could occur. This is // There are many ways these combinations could occur. This is
// designed to match the way encoding/binary.LittleEndian does it. // designed to match the way encoding/binary.LittleEndian does it.
(ORW x0:(MOVBload [i] {s} p mem) (ORL x0:(MOVBload [i] {s} p mem)
s0:(SHLWconst [8] x1:(MOVBload [i+1] {s} p mem))) s0:(SHLLconst [8] x1:(MOVBload [i+1] {s} p mem)))
&& x0.Uses == 1 && x0.Uses == 1
&& x1.Uses == 1 && x1.Uses == 1
&& s0.Uses == 1 && s0.Uses == 1
@ -1459,8 +1352,8 @@
&& clobber(o5) && clobber(o5)
-> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVQload [i] {s} p mem) -> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVQload [i] {s} p mem)
(ORW x0:(MOVBloadidx1 [i] {s} p idx mem) (ORL x0:(MOVBloadidx1 [i] {s} p idx mem)
s0:(SHLWconst [8] x1:(MOVBloadidx1 [i+1] {s} p idx mem))) s0:(SHLLconst [8] x1:(MOVBloadidx1 [i+1] {s} p idx mem)))
&& x0.Uses == 1 && x0.Uses == 1
&& x1.Uses == 1 && x1.Uses == 1
&& s0.Uses == 1 && s0.Uses == 1

View File

@ -190,30 +190,18 @@ func init() {
// binary ops // binary ops
{name: "ADDQ", argLength: 2, reg: gp21sp, asm: "ADDQ", commutative: true}, // arg0 + arg1 {name: "ADDQ", argLength: 2, reg: gp21sp, asm: "ADDQ", commutative: true}, // arg0 + arg1
{name: "ADDL", argLength: 2, reg: gp21sp, asm: "ADDL", commutative: true}, // arg0 + arg1 {name: "ADDL", argLength: 2, reg: gp21sp, asm: "ADDL", commutative: true}, // arg0 + arg1
{name: "ADDW", argLength: 2, reg: gp21sp, asm: "ADDL", commutative: true}, // arg0 + arg1
{name: "ADDB", argLength: 2, reg: gp21sp, asm: "ADDL", commutative: true}, // arg0 + arg1
{name: "ADDQconst", argLength: 1, reg: gp11sp, asm: "ADDQ", aux: "Int64", typ: "UInt64"}, // arg0 + auxint {name: "ADDQconst", argLength: 1, reg: gp11sp, asm: "ADDQ", aux: "Int64", typ: "UInt64"}, // arg0 + auxint
{name: "ADDLconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int32"}, // arg0 + auxint {name: "ADDLconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int32"}, // arg0 + auxint
{name: "ADDWconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int16"}, // arg0 + auxint
{name: "ADDBconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int8"}, // arg0 + auxint
{name: "SUBQ", argLength: 2, reg: gp21, asm: "SUBQ", resultInArg0: true}, // arg0 - arg1 {name: "SUBQ", argLength: 2, reg: gp21, asm: "SUBQ", resultInArg0: true}, // arg0 - arg1
{name: "SUBL", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true}, // arg0 - arg1 {name: "SUBL", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true}, // arg0 - arg1
{name: "SUBW", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true}, // arg0 - arg1
{name: "SUBB", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true}, // arg0 - arg1
{name: "SUBQconst", argLength: 1, reg: gp11, asm: "SUBQ", aux: "Int64", resultInArg0: true}, // arg0 - auxint {name: "SUBQconst", argLength: 1, reg: gp11, asm: "SUBQ", aux: "Int64", resultInArg0: true}, // arg0 - auxint
{name: "SUBLconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int32", resultInArg0: true}, // arg0 - auxint {name: "SUBLconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int32", resultInArg0: true}, // arg0 - auxint
{name: "SUBWconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int16", resultInArg0: true}, // arg0 - auxint
{name: "SUBBconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int8", resultInArg0: true}, // arg0 - auxint
{name: "MULQ", argLength: 2, reg: gp21, asm: "IMULQ", commutative: true, resultInArg0: true}, // arg0 * arg1 {name: "MULQ", argLength: 2, reg: gp21, asm: "IMULQ", commutative: true, resultInArg0: true}, // arg0 * arg1
{name: "MULL", argLength: 2, reg: gp21, asm: "IMULL", commutative: true, resultInArg0: true}, // arg0 * arg1 {name: "MULL", argLength: 2, reg: gp21, asm: "IMULL", commutative: true, resultInArg0: true}, // arg0 * arg1
{name: "MULW", argLength: 2, reg: gp21, asm: "IMULW", commutative: true, resultInArg0: true}, // arg0 * arg1
{name: "MULB", argLength: 2, reg: gp21, asm: "IMULW", commutative: true, resultInArg0: true}, // arg0 * arg1
{name: "MULQconst", argLength: 1, reg: gp11, asm: "IMULQ", aux: "Int64", resultInArg0: true}, // arg0 * auxint {name: "MULQconst", argLength: 1, reg: gp11, asm: "IMULQ", aux: "Int64", resultInArg0: true}, // arg0 * auxint
{name: "MULLconst", argLength: 1, reg: gp11, asm: "IMULL", aux: "Int32", resultInArg0: true}, // arg0 * auxint {name: "MULLconst", argLength: 1, reg: gp11, asm: "IMULL", aux: "Int32", resultInArg0: true}, // arg0 * auxint
{name: "MULWconst", argLength: 1, reg: gp11, asm: "IMULW", aux: "Int16", resultInArg0: true}, // arg0 * auxint
{name: "MULBconst", argLength: 1, reg: gp11, asm: "IMULW", aux: "Int8", resultInArg0: true}, // arg0 * auxint
{name: "HMULQ", argLength: 2, reg: gp11hmul, asm: "IMULQ"}, // (arg0 * arg1) >> width {name: "HMULQ", argLength: 2, reg: gp11hmul, asm: "IMULQ"}, // (arg0 * arg1) >> width
{name: "HMULL", argLength: 2, reg: gp11hmul, asm: "IMULL"}, // (arg0 * arg1) >> width {name: "HMULL", argLength: 2, reg: gp11hmul, asm: "IMULL"}, // (arg0 * arg1) >> width
@ -242,30 +230,18 @@ func init() {
{name: "ANDQ", argLength: 2, reg: gp21, asm: "ANDQ", commutative: true, resultInArg0: true}, // arg0 & arg1 {name: "ANDQ", argLength: 2, reg: gp21, asm: "ANDQ", commutative: true, resultInArg0: true}, // arg0 & arg1
{name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true}, // arg0 & arg1 {name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true}, // arg0 & arg1
{name: "ANDW", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true}, // arg0 & arg1
{name: "ANDB", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true}, // arg0 & arg1
{name: "ANDQconst", argLength: 1, reg: gp11, asm: "ANDQ", aux: "Int64", resultInArg0: true}, // arg0 & auxint {name: "ANDQconst", argLength: 1, reg: gp11, asm: "ANDQ", aux: "Int64", resultInArg0: true}, // arg0 & auxint
{name: "ANDLconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int32", resultInArg0: true}, // arg0 & auxint {name: "ANDLconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int32", resultInArg0: true}, // arg0 & auxint
{name: "ANDWconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int16", resultInArg0: true}, // arg0 & auxint
{name: "ANDBconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int8", resultInArg0: true}, // arg0 & auxint
{name: "ORQ", argLength: 2, reg: gp21, asm: "ORQ", commutative: true, resultInArg0: true}, // arg0 | arg1 {name: "ORQ", argLength: 2, reg: gp21, asm: "ORQ", commutative: true, resultInArg0: true}, // arg0 | arg1
{name: "ORL", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true}, // arg0 | arg1 {name: "ORL", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true}, // arg0 | arg1
{name: "ORW", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true}, // arg0 | arg1
{name: "ORB", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true}, // arg0 | arg1
{name: "ORQconst", argLength: 1, reg: gp11, asm: "ORQ", aux: "Int64", resultInArg0: true}, // arg0 | auxint {name: "ORQconst", argLength: 1, reg: gp11, asm: "ORQ", aux: "Int64", resultInArg0: true}, // arg0 | auxint
{name: "ORLconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int32", resultInArg0: true}, // arg0 | auxint {name: "ORLconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int32", resultInArg0: true}, // arg0 | auxint
{name: "ORWconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int16", resultInArg0: true}, // arg0 | auxint
{name: "ORBconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int8", resultInArg0: true}, // arg0 | auxint
{name: "XORQ", argLength: 2, reg: gp21, asm: "XORQ", commutative: true, resultInArg0: true}, // arg0 ^ arg1 {name: "XORQ", argLength: 2, reg: gp21, asm: "XORQ", commutative: true, resultInArg0: true}, // arg0 ^ arg1
{name: "XORL", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true}, // arg0 ^ arg1 {name: "XORL", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true}, // arg0 ^ arg1
{name: "XORW", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true}, // arg0 ^ arg1
{name: "XORB", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true}, // arg0 ^ arg1
{name: "XORQconst", argLength: 1, reg: gp11, asm: "XORQ", aux: "Int64", resultInArg0: true}, // arg0 ^ auxint {name: "XORQconst", argLength: 1, reg: gp11, asm: "XORQ", aux: "Int64", resultInArg0: true}, // arg0 ^ auxint
{name: "XORLconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int32", resultInArg0: true}, // arg0 ^ auxint {name: "XORLconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int32", resultInArg0: true}, // arg0 ^ auxint
{name: "XORWconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int16", resultInArg0: true}, // arg0 ^ auxint
{name: "XORBconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int8", resultInArg0: true}, // arg0 ^ auxint
{name: "CMPQ", argLength: 2, reg: gp2flags, asm: "CMPQ", typ: "Flags"}, // arg0 compare to arg1 {name: "CMPQ", argLength: 2, reg: gp2flags, asm: "CMPQ", typ: "Flags"}, // arg0 compare to arg1
{name: "CMPL", argLength: 2, reg: gp2flags, asm: "CMPL", typ: "Flags"}, // arg0 compare to arg1 {name: "CMPL", argLength: 2, reg: gp2flags, asm: "CMPL", typ: "Flags"}, // arg0 compare to arg1
@ -290,12 +266,8 @@ func init() {
{name: "SHLQ", argLength: 2, reg: gp21shift, asm: "SHLQ", resultInArg0: true}, // arg0 << arg1, shift amount is mod 64 {name: "SHLQ", argLength: 2, reg: gp21shift, asm: "SHLQ", resultInArg0: true}, // arg0 << arg1, shift amount is mod 64
{name: "SHLL", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true}, // arg0 << arg1, shift amount is mod 32 {name: "SHLL", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true}, // arg0 << arg1, shift amount is mod 32
{name: "SHLW", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true}, // arg0 << arg1, shift amount is mod 32
{name: "SHLB", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true}, // arg0 << arg1, shift amount is mod 32
{name: "SHLQconst", argLength: 1, reg: gp11, asm: "SHLQ", aux: "Int64", resultInArg0: true}, // arg0 << auxint, shift amount 0-63 {name: "SHLQconst", argLength: 1, reg: gp11, asm: "SHLQ", aux: "Int64", resultInArg0: true}, // arg0 << auxint, shift amount 0-63
{name: "SHLLconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int32", resultInArg0: true}, // arg0 << auxint, shift amount 0-31 {name: "SHLLconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int32", resultInArg0: true}, // arg0 << auxint, shift amount 0-31
{name: "SHLWconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int16", resultInArg0: true}, // arg0 << auxint, shift amount 0-31
{name: "SHLBconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int8", resultInArg0: true}, // arg0 << auxint, shift amount 0-31
// Note: x86 is weird, the 16 and 8 byte shifts still use all 5 bits of shift amount! // Note: x86 is weird, the 16 and 8 byte shifts still use all 5 bits of shift amount!
{name: "SHRQ", argLength: 2, reg: gp21shift, asm: "SHRQ", resultInArg0: true}, // unsigned arg0 >> arg1, shift amount is mod 64 {name: "SHRQ", argLength: 2, reg: gp21shift, asm: "SHRQ", resultInArg0: true}, // unsigned arg0 >> arg1, shift amount is mod 64
@ -324,13 +296,9 @@ func init() {
// unary ops // unary ops
{name: "NEGQ", argLength: 1, reg: gp11, asm: "NEGQ", resultInArg0: true}, // -arg0 {name: "NEGQ", argLength: 1, reg: gp11, asm: "NEGQ", resultInArg0: true}, // -arg0
{name: "NEGL", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true}, // -arg0 {name: "NEGL", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true}, // -arg0
{name: "NEGW", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true}, // -arg0
{name: "NEGB", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true}, // -arg0
{name: "NOTQ", argLength: 1, reg: gp11, asm: "NOTQ", resultInArg0: true}, // ^arg0 {name: "NOTQ", argLength: 1, reg: gp11, asm: "NOTQ", resultInArg0: true}, // ^arg0
{name: "NOTL", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true}, // ^arg0 {name: "NOTL", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true}, // ^arg0
{name: "NOTW", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true}, // ^arg0
{name: "NOTB", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true}, // ^arg0
{name: "BSFQ", argLength: 1, reg: gp11, asm: "BSFQ"}, // arg0 # of low-order zeroes ; undef if zero {name: "BSFQ", argLength: 1, reg: gp11, asm: "BSFQ"}, // arg0 # of low-order zeroes ; undef if zero
{name: "BSFL", argLength: 1, reg: gp11, asm: "BSFL"}, // arg0 # of low-order zeroes ; undef if zero {name: "BSFL", argLength: 1, reg: gp11, asm: "BSFL"}, // arg0 # of low-order zeroes ; undef if zero
@ -385,8 +353,6 @@ func init() {
{name: "MOVLQSX", argLength: 1, reg: gp11nf, asm: "MOVLQSX"}, // sign extend arg0 from int32 to int64 {name: "MOVLQSX", argLength: 1, reg: gp11nf, asm: "MOVLQSX"}, // sign extend arg0 from int32 to int64
{name: "MOVLQZX", argLength: 1, reg: gp11nf, asm: "MOVLQZX"}, // zero extend arg0 from int32 to int64 {name: "MOVLQZX", argLength: 1, reg: gp11nf, asm: "MOVLQZX"}, // zero extend arg0 from int32 to int64
{name: "MOVBconst", reg: gp01, asm: "MOVB", typ: "UInt8", aux: "Int8", rematerializeable: true}, // 8 low bits of auxint
{name: "MOVWconst", reg: gp01, asm: "MOVW", typ: "UInt16", aux: "Int16", rematerializeable: true}, // 16 low bits of auxint
{name: "MOVLconst", reg: gp01, asm: "MOVL", typ: "UInt32", aux: "Int32", rematerializeable: true}, // 32 low bits of auxint {name: "MOVLconst", reg: gp01, asm: "MOVL", typ: "UInt32", aux: "Int32", rematerializeable: true}, // 32 low bits of auxint
{name: "MOVQconst", reg: gp01, asm: "MOVQ", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint {name: "MOVQconst", reg: gp01, asm: "MOVQ", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint

View File

@ -120,28 +120,16 @@ const (
OpAMD64MOVSDstoreidx8 OpAMD64MOVSDstoreidx8
OpAMD64ADDQ OpAMD64ADDQ
OpAMD64ADDL OpAMD64ADDL
OpAMD64ADDW
OpAMD64ADDB
OpAMD64ADDQconst OpAMD64ADDQconst
OpAMD64ADDLconst OpAMD64ADDLconst
OpAMD64ADDWconst
OpAMD64ADDBconst
OpAMD64SUBQ OpAMD64SUBQ
OpAMD64SUBL OpAMD64SUBL
OpAMD64SUBW
OpAMD64SUBB
OpAMD64SUBQconst OpAMD64SUBQconst
OpAMD64SUBLconst OpAMD64SUBLconst
OpAMD64SUBWconst
OpAMD64SUBBconst
OpAMD64MULQ OpAMD64MULQ
OpAMD64MULL OpAMD64MULL
OpAMD64MULW
OpAMD64MULB
OpAMD64MULQconst OpAMD64MULQconst
OpAMD64MULLconst OpAMD64MULLconst
OpAMD64MULWconst
OpAMD64MULBconst
OpAMD64HMULQ OpAMD64HMULQ
OpAMD64HMULL OpAMD64HMULL
OpAMD64HMULW OpAMD64HMULW
@ -165,28 +153,16 @@ const (
OpAMD64MODWU OpAMD64MODWU
OpAMD64ANDQ OpAMD64ANDQ
OpAMD64ANDL OpAMD64ANDL
OpAMD64ANDW
OpAMD64ANDB
OpAMD64ANDQconst OpAMD64ANDQconst
OpAMD64ANDLconst OpAMD64ANDLconst
OpAMD64ANDWconst
OpAMD64ANDBconst
OpAMD64ORQ OpAMD64ORQ
OpAMD64ORL OpAMD64ORL
OpAMD64ORW
OpAMD64ORB
OpAMD64ORQconst OpAMD64ORQconst
OpAMD64ORLconst OpAMD64ORLconst
OpAMD64ORWconst
OpAMD64ORBconst
OpAMD64XORQ OpAMD64XORQ
OpAMD64XORL OpAMD64XORL
OpAMD64XORW
OpAMD64XORB
OpAMD64XORQconst OpAMD64XORQconst
OpAMD64XORLconst OpAMD64XORLconst
OpAMD64XORWconst
OpAMD64XORBconst
OpAMD64CMPQ OpAMD64CMPQ
OpAMD64CMPL OpAMD64CMPL
OpAMD64CMPW OpAMD64CMPW
@ -207,12 +183,8 @@ const (
OpAMD64TESTBconst OpAMD64TESTBconst
OpAMD64SHLQ OpAMD64SHLQ
OpAMD64SHLL OpAMD64SHLL
OpAMD64SHLW
OpAMD64SHLB
OpAMD64SHLQconst OpAMD64SHLQconst
OpAMD64SHLLconst OpAMD64SHLLconst
OpAMD64SHLWconst
OpAMD64SHLBconst
OpAMD64SHRQ OpAMD64SHRQ
OpAMD64SHRL OpAMD64SHRL
OpAMD64SHRW OpAMD64SHRW
@ -235,12 +207,8 @@ const (
OpAMD64ROLBconst OpAMD64ROLBconst
OpAMD64NEGQ OpAMD64NEGQ
OpAMD64NEGL OpAMD64NEGL
OpAMD64NEGW
OpAMD64NEGB
OpAMD64NOTQ OpAMD64NOTQ
OpAMD64NOTL OpAMD64NOTL
OpAMD64NOTW
OpAMD64NOTB
OpAMD64BSFQ OpAMD64BSFQ
OpAMD64BSFL OpAMD64BSFL
OpAMD64BSFW OpAMD64BSFW
@ -280,8 +248,6 @@ const (
OpAMD64MOVWQZX OpAMD64MOVWQZX
OpAMD64MOVLQSX OpAMD64MOVLQSX
OpAMD64MOVLQZX OpAMD64MOVLQZX
OpAMD64MOVBconst
OpAMD64MOVWconst
OpAMD64MOVLconst OpAMD64MOVLconst
OpAMD64MOVQconst OpAMD64MOVQconst
OpAMD64CVTTSD2SL OpAMD64CVTTSD2SL
@ -1002,38 +968,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "ADDW",
argLen: 2,
commutative: true,
asm: x86.AADDL,
reg: regInfo{
inputs: []inputInfo{
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "ADDB",
argLen: 2,
commutative: true,
asm: x86.AADDL,
reg: regInfo{
inputs: []inputInfo{
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "ADDQconst", name: "ADDQconst",
auxType: auxInt64, auxType: auxInt64,
@ -1064,36 +998,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "ADDWconst",
auxType: auxInt16,
argLen: 1,
asm: x86.AADDL,
reg: regInfo{
inputs: []inputInfo{
{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "ADDBconst",
auxType: auxInt8,
argLen: 1,
asm: x86.AADDL,
reg: regInfo{
inputs: []inputInfo{
{0, 65535}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "SUBQ", name: "SUBQ",
argLen: 2, argLen: 2,
@ -1126,38 +1030,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "SUBW",
argLen: 2,
resultInArg0: true,
asm: x86.ASUBL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "SUBB",
argLen: 2,
resultInArg0: true,
asm: x86.ASUBL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "SUBQconst", name: "SUBQconst",
auxType: auxInt64, auxType: auxInt64,
@ -1190,38 +1062,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "SUBWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.ASUBL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "SUBBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.ASUBL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "MULQ", name: "MULQ",
argLen: 2, argLen: 2,
@ -1256,40 +1096,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "MULW",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AIMULW,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "MULB",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AIMULW,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "MULQconst", name: "MULQconst",
auxType: auxInt64, auxType: auxInt64,
@ -1322,38 +1128,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "MULWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.AIMULW,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "MULBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.AIMULW,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "HMULQ", name: "HMULQ",
argLen: 2, argLen: 2,
@ -1704,40 +1478,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "ANDW",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AANDL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "ANDB",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AANDL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "ANDQconst", name: "ANDQconst",
auxType: auxInt64, auxType: auxInt64,
@ -1770,38 +1510,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "ANDWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.AANDL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "ANDBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.AANDL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "ORQ", name: "ORQ",
argLen: 2, argLen: 2,
@ -1836,40 +1544,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "ORW",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AORL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "ORB",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AORL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "ORQconst", name: "ORQconst",
auxType: auxInt64, auxType: auxInt64,
@ -1902,38 +1576,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "ORWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.AORL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "ORBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.AORL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "XORQ", name: "XORQ",
argLen: 2, argLen: 2,
@ -1968,40 +1610,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "XORW",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AXORL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "XORB",
argLen: 2,
commutative: true,
resultInArg0: true,
asm: x86.AXORL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
{1, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "XORQconst", name: "XORQconst",
auxType: auxInt64, auxType: auxInt64,
@ -2034,38 +1642,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "XORWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.AXORL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "XORBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.AXORL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "CMPQ", name: "CMPQ",
argLen: 2, argLen: 2,
@ -2350,38 +1926,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "SHLW",
argLen: 2,
resultInArg0: true,
asm: x86.ASHLL,
reg: regInfo{
inputs: []inputInfo{
{1, 2}, // CX
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "SHLB",
argLen: 2,
resultInArg0: true,
asm: x86.ASHLL,
reg: regInfo{
inputs: []inputInfo{
{1, 2}, // CX
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "SHLQconst", name: "SHLQconst",
auxType: auxInt64, auxType: auxInt64,
@ -2414,38 +1958,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "SHLWconst",
auxType: auxInt16,
argLen: 1,
resultInArg0: true,
asm: x86.ASHLL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "SHLBconst",
auxType: auxInt8,
argLen: 1,
resultInArg0: true,
asm: x86.ASHLL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "SHRQ", name: "SHRQ",
argLen: 2, argLen: 2,
@ -2796,36 +2308,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "NEGW",
argLen: 1,
resultInArg0: true,
asm: x86.ANEGL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "NEGB",
argLen: 1,
resultInArg0: true,
asm: x86.ANEGL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "NOTQ", name: "NOTQ",
argLen: 1, argLen: 1,
@ -2856,36 +2338,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "NOTW",
argLen: 1,
resultInArg0: true,
asm: x86.ANOTL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "NOTB",
argLen: 1,
resultInArg0: true,
asm: x86.ANOTL,
reg: regInfo{
inputs: []inputInfo{
{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
clobbers: 8589934592, // FLAGS
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "BSFQ", name: "BSFQ",
argLen: 1, argLen: 1,
@ -3429,30 +2881,6 @@ var opcodeTable = [...]opInfo{
}, },
}, },
}, },
{
name: "MOVBconst",
auxType: auxInt8,
argLen: 0,
rematerializeable: true,
asm: x86.AMOVB,
reg: regInfo{
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{
name: "MOVWconst",
auxType: auxInt16,
argLen: 0,
rematerializeable: true,
asm: x86.AMOVW,
reg: regInfo{
outputs: []regMask{
65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
},
},
},
{ {
name: "MOVLconst", name: "MOVLconst",
auxType: auxInt32, auxType: auxInt32,

View File

@ -11,8 +11,8 @@ func TestLiveControlOps(t *testing.T) {
f := Fun(c, "entry", f := Fun(c, "entry",
Bloc("entry", Bloc("entry",
Valu("mem", OpInitMem, TypeMem, 0, nil), Valu("mem", OpInitMem, TypeMem, 0, nil),
Valu("x", OpAMD64MOVBconst, TypeInt8, 1, nil), Valu("x", OpAMD64MOVLconst, TypeInt8, 1, nil),
Valu("y", OpAMD64MOVBconst, TypeInt8, 2, nil), Valu("y", OpAMD64MOVLconst, TypeInt8, 2, nil),
Valu("a", OpAMD64TESTB, TypeFlags, 0, nil, "x", "y"), Valu("a", OpAMD64TESTB, TypeFlags, 0, nil, "x", "y"),
Valu("b", OpAMD64TESTB, TypeFlags, 0, nil, "y", "x"), Valu("b", OpAMD64TESTB, TypeFlags, 0, nil, "y", "x"),
Eq("a", "if", "exit"), Eq("a", "if", "exit"),

File diff suppressed because it is too large Load Diff