diff --git a/build/zmov.go b/build/zmov.go index 2bb9d4c..ff97308 100644 --- a/build/zmov.go +++ b/build/zmov.go @@ -10,261 +10,283 @@ import ( func (c *Context) mov(a, b operand.Op, an, bn int, t *types.Basic) { switch { - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsK(a) && operand.IsK(b): + case an == 8 && operand.IsK(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVB(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 1 && operand.IsK(a) && operand.IsM8(b): + case an == 8 && operand.IsK(a) && bn == 1 && operand.IsM8(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVB(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 4 && operand.IsK(a) && operand.IsR32(b): + case an == 8 && operand.IsK(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVB(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 1 && bn == 8 && operand.IsK(b) && operand.IsM8(a): + case an == 1 && operand.IsM8(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVB(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 8 && operand.IsK(b) && operand.IsR32(a): + case an == 4 && operand.IsR32(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVB(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsK(a) && operand.IsK(b): + case an == 8 && operand.IsK(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVD(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 4 && operand.IsK(a) && operand.IsM32(b): + case an == 8 && operand.IsK(a) && bn == 4 && operand.IsM32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVD(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 4 && operand.IsK(a) && operand.IsR32(b): + case an == 8 && operand.IsK(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVD(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 8 && operand.IsK(b) && operand.IsM32(a): + case an == 4 && operand.IsM32(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVD(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 8 && operand.IsK(b) && operand.IsR32(a): + case an == 4 && operand.IsR32(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVD(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsK(a) && operand.IsK(b): + case an == 8 && operand.IsK(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsK(a) && operand.IsM64(b): + case an == 8 && operand.IsK(a) && bn == 8 && operand.IsM64(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsK(a) && operand.IsR64(b): + case an == 8 && operand.IsK(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsK(b) && operand.IsM64(a): + case an == 8 && operand.IsM64(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsK(b) && operand.IsR64(a): + case an == 8 && operand.IsR64(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsK(a) && operand.IsK(b): + case an == 8 && operand.IsK(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVW(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 2 && operand.IsK(a) && operand.IsM16(b): + case an == 8 && operand.IsK(a) && bn == 2 && operand.IsM16(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVW(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 4 && operand.IsK(a) && operand.IsR32(b): + case an == 8 && operand.IsK(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVW(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 2 && bn == 8 && operand.IsK(b) && operand.IsM16(a): + case an == 2 && operand.IsM16(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVW(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 8 && operand.IsK(b) && operand.IsR32(a): + case an == 4 && operand.IsR32(a) && bn == 8 && operand.IsK(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.KMOVW(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 1 && bn == 1 && operand.IsM8(a) && operand.IsR8(b): + case an == 1 && operand.IsM8(a) && bn == 1 && operand.IsR8(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVB(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 1 && bn == 1 && operand.IsM8(b) && operand.IsR8(a): + case an == 1 && operand.IsR8(a) && bn == 1 && operand.IsM8(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVB(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 1 && bn == 1 && operand.IsR8(a) && operand.IsR8(b): + case an == 1 && operand.IsR8(a) && bn == 1 && operand.IsR8(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVB(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 4 && operand.IsM8(a) && operand.IsR32(b): + case an == 1 && operand.IsM8(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVBLSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 4 && operand.IsR32(b) && operand.IsR8(a): + case an == 1 && operand.IsR8(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVBLSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 4 && operand.IsM8(a) && operand.IsR32(b): + case an == 1 && operand.IsM8(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): c.MOVBLZX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 4 && operand.IsR32(b) && operand.IsR8(a): + case an == 1 && operand.IsM8(a) && bn == 4 && operand.IsR32(b) && (t.Info()&types.IsBoolean) != 0: c.MOVBLZX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 8 && operand.IsM8(a) && operand.IsR64(b): + case an == 1 && operand.IsR8(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): + c.MOVBLZX(a, b) + case an == 1 && operand.IsR8(a) && bn == 4 && operand.IsR32(b) && (t.Info()&types.IsBoolean) != 0: + c.MOVBLZX(a, b) + case an == 1 && operand.IsM8(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVBQSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 8 && operand.IsR64(b) && operand.IsR8(a): + case an == 1 && operand.IsR8(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVBQSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 8 && operand.IsM8(a) && operand.IsR64(b): + case an == 1 && operand.IsM8(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): c.MOVBQZX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 8 && operand.IsR64(b) && operand.IsR8(a): + case an == 1 && operand.IsM8(a) && bn == 8 && operand.IsR64(b) && (t.Info()&types.IsBoolean) != 0: c.MOVBQZX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 2 && operand.IsM8(a) && operand.IsR16(b): + case an == 1 && operand.IsR8(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): + c.MOVBQZX(a, b) + case an == 1 && operand.IsR8(a) && bn == 8 && operand.IsR64(b) && (t.Info()&types.IsBoolean) != 0: + c.MOVBQZX(a, b) + case an == 1 && operand.IsM8(a) && bn == 2 && operand.IsR16(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVBWSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 1 && bn == 2 && operand.IsR16(b) && operand.IsR8(a): + case an == 1 && operand.IsR8(a) && bn == 2 && operand.IsR16(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVBWSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 2 && operand.IsM8(a) && operand.IsR16(b): + case an == 1 && operand.IsM8(a) && bn == 2 && operand.IsR16(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): c.MOVBWZX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 1 && bn == 2 && operand.IsR16(b) && operand.IsR8(a): + case an == 1 && operand.IsM8(a) && bn == 2 && operand.IsR16(b) && (t.Info()&types.IsBoolean) != 0: c.MOVBWZX(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 4 && operand.IsM32(a) && operand.IsR32(b): + case an == 1 && operand.IsR8(a) && bn == 2 && operand.IsR16(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): + c.MOVBWZX(a, b) + case an == 1 && operand.IsR8(a) && bn == 2 && operand.IsR16(b) && (t.Info()&types.IsBoolean) != 0: + c.MOVBWZX(a, b) + case an == 4 && operand.IsM32(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVL(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 4 && operand.IsM32(b) && operand.IsR32(a): + case an == 4 && operand.IsR32(a) && bn == 4 && operand.IsM32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVL(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 4 && operand.IsR32(a) && operand.IsR32(b): + case an == 4 && operand.IsR32(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVL(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 4 && bn == 8 && operand.IsM32(a) && operand.IsR64(b): + case an == 4 && operand.IsM32(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVLQSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 4 && bn == 8 && operand.IsR32(a) && operand.IsR64(b): + case an == 4 && operand.IsR32(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVLQSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 4 && bn == 8 && operand.IsM32(a) && operand.IsR64(b): + case an == 4 && operand.IsM32(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): c.MOVLQZX(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(a) && operand.IsXMM(b): + case an == 4 && operand.IsM32(a) && bn == 8 && operand.IsR64(b) && (t.Info()&types.IsBoolean) != 0: + c.MOVLQZX(a, b) + case an == 16 && operand.IsM128(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVOU(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsM128(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVOU(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsXMM(a) && operand.IsXMM(b): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVOU(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 16 && operand.IsM32(a) && operand.IsXMM(b): + case an == 4 && operand.IsM32(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 16 && operand.IsM64(a) && operand.IsXMM(b): + case an == 8 && operand.IsM64(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 16 && operand.IsR32(a) && operand.IsXMM(b): + case an == 4 && operand.IsR32(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 16 && operand.IsR64(a) && operand.IsXMM(b): + case an == 8 && operand.IsR64(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 4 && operand.IsM32(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 4 && operand.IsM32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 8 && operand.IsM64(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 8 && operand.IsM64(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 4 && operand.IsR32(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 8 && operand.IsR64(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsXMM(a) && operand.IsXMM(b): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsM64(a) && operand.IsR64(b): + case an == 8 && operand.IsM64(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsM64(b) && operand.IsR64(a): + case an == 8 && operand.IsR64(a) && bn == 8 && operand.IsM64(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 8 && operand.IsR64(a) && operand.IsR64(b): + case an == 8 && operand.IsR64(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVQ(a, b) - case (t.Info()&types.IsFloat) != 0 && an == 8 && bn == 16 && operand.IsM64(a) && operand.IsXMM(b): + case an == 8 && operand.IsM64(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&types.IsFloat) != 0: c.MOVSD(a, b) - case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 8 && operand.IsM64(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 8 && operand.IsM64(b) && (t.Info()&types.IsFloat) != 0: c.MOVSD(a, b) - case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 16 && operand.IsXMM(a) && operand.IsXMM(b): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&types.IsFloat) != 0: c.MOVSD(a, b) - case (t.Info()&types.IsFloat) != 0 && an == 4 && bn == 16 && operand.IsM32(a) && operand.IsXMM(b): + case an == 4 && operand.IsM32(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&types.IsFloat) != 0: c.MOVSS(a, b) - case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 4 && operand.IsM32(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 4 && operand.IsM32(b) && (t.Info()&types.IsFloat) != 0: c.MOVSS(a, b) - case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 16 && operand.IsXMM(a) && operand.IsXMM(b): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&types.IsFloat) != 0: c.MOVSS(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 2 && bn == 2 && operand.IsM16(a) && operand.IsR16(b): + case an == 2 && operand.IsM16(a) && bn == 2 && operand.IsR16(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVW(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 2 && bn == 2 && operand.IsM16(b) && operand.IsR16(a): + case an == 2 && operand.IsR16(a) && bn == 2 && operand.IsM16(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVW(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 2 && bn == 2 && operand.IsR16(a) && operand.IsR16(b): + case an == 2 && operand.IsR16(a) && bn == 2 && operand.IsR16(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.MOVW(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 2 && bn == 4 && operand.IsM16(a) && operand.IsR32(b): + case an == 2 && operand.IsM16(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVWLSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 2 && bn == 4 && operand.IsR16(a) && operand.IsR32(b): + case an == 2 && operand.IsR16(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVWLSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 2 && bn == 4 && operand.IsM16(a) && operand.IsR32(b): + case an == 2 && operand.IsM16(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): c.MOVWLZX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 2 && bn == 4 && operand.IsR16(a) && operand.IsR32(b): + case an == 2 && operand.IsM16(a) && bn == 4 && operand.IsR32(b) && (t.Info()&types.IsBoolean) != 0: c.MOVWLZX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 2 && bn == 8 && operand.IsM16(a) && operand.IsR64(b): + case an == 2 && operand.IsR16(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): + c.MOVWLZX(a, b) + case an == 2 && operand.IsR16(a) && bn == 4 && operand.IsR32(b) && (t.Info()&types.IsBoolean) != 0: + c.MOVWLZX(a, b) + case an == 2 && operand.IsM16(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVWQSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) == 0 && an == 2 && bn == 8 && operand.IsR16(a) && operand.IsR64(b): + case an == 2 && operand.IsR16(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == types.IsInteger: c.MOVWQSX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 2 && bn == 8 && operand.IsM16(a) && operand.IsR64(b): + case an == 2 && operand.IsM16(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): c.MOVWQZX(a, b) - case (t.Info()&types.IsInteger) != 0 && (t.Info()&types.IsUnsigned) != 0 && an == 2 && bn == 8 && operand.IsR16(a) && operand.IsR64(b): + case an == 2 && operand.IsM16(a) && bn == 8 && operand.IsR64(b) && (t.Info()&types.IsBoolean) != 0: c.MOVWQZX(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 16 && operand.IsM32(a) && operand.IsXMM(b): + case an == 2 && operand.IsR16(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsUnsigned)) == (types.IsInteger|types.IsUnsigned): + c.MOVWQZX(a, b) + case an == 2 && operand.IsR16(a) && bn == 8 && operand.IsR64(b) && (t.Info()&types.IsBoolean) != 0: + c.MOVWQZX(a, b) + case an == 4 && operand.IsM32(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVD(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 4 && bn == 16 && operand.IsR32(a) && operand.IsXMM(b): + case an == 4 && operand.IsR32(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVD(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 4 && operand.IsM32(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 4 && operand.IsM32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVD(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 4 && operand.IsR32(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 4 && operand.IsR32(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVD(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(a) && operand.IsXMM(b): + case an == 16 && operand.IsM128(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsM256(a) && operand.IsYMM(b): + case an == 32 && operand.IsM256(a) && bn == 32 && operand.IsYMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsM128(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsXMM(a) && operand.IsXMM(b): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsM256(b) && operand.IsYMM(a): + case an == 32 && operand.IsYMM(a) && bn == 32 && operand.IsM256(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsYMM(a) && operand.IsYMM(b): + case an == 32 && operand.IsYMM(a) && bn == 32 && operand.IsYMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(a) && operand.IsXMM(b): + case an == 16 && operand.IsM128(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU16(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsM256(a) && operand.IsYMM(b): + case an == 32 && operand.IsM256(a) && bn == 32 && operand.IsYMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU16(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsM128(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU16(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsXMM(a) && operand.IsXMM(b): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU16(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsM256(b) && operand.IsYMM(a): + case an == 32 && operand.IsYMM(a) && bn == 32 && operand.IsM256(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU16(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsYMM(a) && operand.IsYMM(b): + case an == 32 && operand.IsYMM(a) && bn == 32 && operand.IsYMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU16(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsM512(a) && operand.IsZMM(b): + case an == 64 && operand.IsM512(a) && bn == 64 && operand.IsZMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU16(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsM512(b) && operand.IsZMM(a): + case an == 64 && operand.IsZMM(a) && bn == 64 && operand.IsM512(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU16(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsZMM(a) && operand.IsZMM(b): + case an == 64 && operand.IsZMM(a) && bn == 64 && operand.IsZMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU16(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(a) && operand.IsXMM(b): + case an == 16 && operand.IsM128(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU32(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsM256(a) && operand.IsYMM(b): + case an == 32 && operand.IsM256(a) && bn == 32 && operand.IsYMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU32(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsM128(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU32(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsXMM(a) && operand.IsXMM(b): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU32(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsM256(b) && operand.IsYMM(a): + case an == 32 && operand.IsYMM(a) && bn == 32 && operand.IsM256(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU32(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsYMM(a) && operand.IsYMM(b): + case an == 32 && operand.IsYMM(a) && bn == 32 && operand.IsYMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU32(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsM512(a) && operand.IsZMM(b): + case an == 64 && operand.IsM512(a) && bn == 64 && operand.IsZMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU32(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsM512(b) && operand.IsZMM(a): + case an == 64 && operand.IsZMM(a) && bn == 64 && operand.IsM512(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU32(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsZMM(a) && operand.IsZMM(b): + case an == 64 && operand.IsZMM(a) && bn == 64 && operand.IsZMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU32(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(a) && operand.IsXMM(b): + case an == 16 && operand.IsM128(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU64(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsM256(a) && operand.IsYMM(b): + case an == 32 && operand.IsM256(a) && bn == 32 && operand.IsYMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU64(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsM128(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU64(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsXMM(a) && operand.IsXMM(b): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU64(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsM256(b) && operand.IsYMM(a): + case an == 32 && operand.IsYMM(a) && bn == 32 && operand.IsM256(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU64(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsYMM(a) && operand.IsYMM(b): + case an == 32 && operand.IsYMM(a) && bn == 32 && operand.IsYMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU64(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsM512(a) && operand.IsZMM(b): + case an == 64 && operand.IsM512(a) && bn == 64 && operand.IsZMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU64(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsM512(b) && operand.IsZMM(a): + case an == 64 && operand.IsZMM(a) && bn == 64 && operand.IsM512(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU64(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsZMM(a) && operand.IsZMM(b): + case an == 64 && operand.IsZMM(a) && bn == 64 && operand.IsZMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU64(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(a) && operand.IsXMM(b): + case an == 16 && operand.IsM128(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU8(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsM256(a) && operand.IsYMM(b): + case an == 32 && operand.IsM256(a) && bn == 32 && operand.IsYMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU8(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsM128(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsM128(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU8(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsXMM(a) && operand.IsXMM(b): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU8(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsM256(b) && operand.IsYMM(a): + case an == 32 && operand.IsYMM(a) && bn == 32 && operand.IsM256(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU8(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 32 && bn == 32 && operand.IsYMM(a) && operand.IsYMM(b): + case an == 32 && operand.IsYMM(a) && bn == 32 && operand.IsYMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU8(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsM512(a) && operand.IsZMM(b): + case an == 64 && operand.IsM512(a) && bn == 64 && operand.IsZMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU8(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsM512(b) && operand.IsZMM(a): + case an == 64 && operand.IsZMM(a) && bn == 64 && operand.IsM512(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU8(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 64 && bn == 64 && operand.IsZMM(a) && operand.IsZMM(b): + case an == 64 && operand.IsZMM(a) && bn == 64 && operand.IsZMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVDQU8(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 16 && operand.IsM64(a) && operand.IsXMM(b): + case an == 8 && operand.IsM64(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 8 && bn == 16 && operand.IsR64(a) && operand.IsXMM(b): + case an == 8 && operand.IsR64(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 8 && operand.IsM64(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 8 && operand.IsM64(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 8 && operand.IsR64(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 8 && operand.IsR64(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVQ(a, b) - case (t.Info()&types.IsInteger) != 0 && an == 16 && bn == 16 && operand.IsXMM(a) && operand.IsXMM(b): + case an == 16 && operand.IsXMM(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&(types.IsInteger|types.IsBoolean)) != 0: c.VMOVQ(a, b) - case (t.Info()&types.IsFloat) != 0 && an == 8 && bn == 16 && operand.IsM64(a) && operand.IsXMM(b): + case an == 8 && operand.IsM64(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&types.IsFloat) != 0: c.VMOVSD(a, b) - case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 8 && operand.IsM64(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 8 && operand.IsM64(b) && (t.Info()&types.IsFloat) != 0: c.VMOVSD(a, b) - case (t.Info()&types.IsFloat) != 0 && an == 4 && bn == 16 && operand.IsM32(a) && operand.IsXMM(b): + case an == 4 && operand.IsM32(a) && bn == 16 && operand.IsXMM(b) && (t.Info()&types.IsFloat) != 0: c.VMOVSS(a, b) - case (t.Info()&types.IsFloat) != 0 && an == 16 && bn == 4 && operand.IsM32(b) && operand.IsXMM(a): + case an == 16 && operand.IsXMM(a) && bn == 4 && operand.IsM32(b) && (t.Info()&types.IsFloat) != 0: c.VMOVSS(a, b) default: c.adderrormessage("could not deduce mov instruction") diff --git a/internal/gen/mov.go b/internal/gen/mov.go index a281add..c4e3cd0 100644 --- a/internal/gen/mov.go +++ b/internal/gen/mov.go @@ -3,7 +3,6 @@ package gen import ( "errors" "fmt" - "sort" "strings" "github.com/mmcloughlin/avo/internal/api" @@ -48,7 +47,7 @@ func (m *mov) Generate(is []inst.Instruction) ([]byte, error) { } func (m *mov) instruction(i inst.Instruction) { - f := flags(i) + tcs := typecases(i) mfs, err := movforms(i) if err != nil { m.AddError(err) @@ -61,14 +60,12 @@ func (m *mov) instruction(i inst.Instruction) { fmt.Sprintf("bn == %d", opsize[mf.B]), fmt.Sprintf("%s(b)", api.CheckerName(mf.B)), } - for c, on := range f { - cmp := map[bool]string{true: "!=", false: "=="} - cond := fmt.Sprintf("(t.Info() & %s) %s 0", c, cmp[on]) - conds = append(conds, cond) + + for _, tc := range tcs { + typecase := fmt.Sprintf("(t.Info() & %s) %s %s", tc.Mask, tc.Op, tc.Value) + m.Printf("case %s && %s:\n", strings.Join(conds, " && "), typecase) + m.Printf("c.%s(a, b)\n", i.Opcode) } - sort.Strings(conds) - m.Printf("case %s:\n", strings.Join(conds, " && ")) - m.Printf("c.%s(a, b)\n", i.Opcode) } } @@ -100,21 +97,32 @@ func ismov(i inst.Instruction) bool { return true } -func flags(i inst.Instruction) map[string]bool { - f := map[string]bool{} +type typecase struct { + Mask string + Op string + Value string +} + +func typecases(i inst.Instruction) []typecase { switch { case strings.Contains(i.Summary, "Floating-Point"): - f["types.IsFloat"] = true + return []typecase{ + {"types.IsFloat", "!=", "0"}, + } case strings.Contains(i.Summary, "Zero-Extend"): - f["types.IsInteger"] = true - f["types.IsUnsigned"] = true + return []typecase{ + {"(types.IsInteger|types.IsUnsigned)", "==", "(types.IsInteger|types.IsUnsigned)"}, + {"types.IsBoolean", "!=", "0"}, + } case strings.Contains(i.Summary, "Sign-Extension"): - f["types.IsInteger"] = true - f["types.IsUnsigned"] = false + return []typecase{ + {"(types.IsInteger|types.IsUnsigned)", "==", "types.IsInteger"}, + } default: - f["types.IsInteger"] = true + return []typecase{ + {"(types.IsInteger|types.IsBoolean)", "!=", "0"}, + } } - return f } type movform struct{ A, B string } diff --git a/tests/fixedbugs/issue336/asm.go b/tests/fixedbugs/issue336/asm.go new file mode 100644 index 0000000..ff60018 --- /dev/null +++ b/tests/fixedbugs/issue336/asm.go @@ -0,0 +1,38 @@ +//go:build ignore +// +build ignore + +package main + +import ( + "fmt" + + . "github.com/mmcloughlin/avo/build" + . "github.com/mmcloughlin/avo/operand" + . "github.com/mmcloughlin/avo/reg" +) + +func main() { + variants := []struct { + Size int + Register func() GPVirtual + XOR func(Op, Op) + }{ + {8, GP8L, XORB}, + {16, GP16, XORW}, + {32, GP32, XORL}, + {64, GP64, XORQ}, + } + + for _, v := range variants { + name := fmt.Sprintf("Not%d", v.Size) + TEXT(name, NOSPLIT, "func(x bool) bool") + Doc(fmt.Sprintf("%s returns the boolean negation of x using a %d-bit intermediate.", name, v.Size)) + x := v.Register() + Load(Param("x"), x) + v.XOR(U8(1), x) + Store(x.As8L(), ReturnIndex(0)) + RET() + } + + Generate() +} diff --git a/tests/fixedbugs/issue336/doc.go b/tests/fixedbugs/issue336/doc.go new file mode 100644 index 0000000..fdcaab8 --- /dev/null +++ b/tests/fixedbugs/issue336/doc.go @@ -0,0 +1,4 @@ +// Package issue336 tests boolean arguments and return values. +// +// Issue #336 pointed out that move deduction for boolean types was not present. +package issue336 diff --git a/tests/fixedbugs/issue336/issue336.s b/tests/fixedbugs/issue336/issue336.s new file mode 100644 index 0000000..512a9e1 --- /dev/null +++ b/tests/fixedbugs/issue336/issue336.s @@ -0,0 +1,31 @@ +// Code generated by command: go run asm.go -out issue336.s -stubs stub.go. DO NOT EDIT. + +#include "textflag.h" + +// func Not8(x bool) bool +TEXT ·Not8(SB), NOSPLIT, $0-9 + MOVB x+0(FP), AL + XORB $0x01, AL + MOVB AL, ret+8(FP) + RET + +// func Not16(x bool) bool +TEXT ·Not16(SB), NOSPLIT, $0-9 + MOVBWZX x+0(FP), AX + XORW $0x01, AX + MOVB AL, ret+8(FP) + RET + +// func Not32(x bool) bool +TEXT ·Not32(SB), NOSPLIT, $0-9 + MOVBLZX x+0(FP), AX + XORL $0x01, AX + MOVB AL, ret+8(FP) + RET + +// func Not64(x bool) bool +TEXT ·Not64(SB), NOSPLIT, $0-9 + MOVBQZX x+0(FP), AX + XORQ $0x01, AX + MOVB AL, ret+8(FP) + RET diff --git a/tests/fixedbugs/issue336/issue336_test.go b/tests/fixedbugs/issue336/issue336_test.go new file mode 100644 index 0000000..f7dca40 --- /dev/null +++ b/tests/fixedbugs/issue336/issue336_test.go @@ -0,0 +1,16 @@ +package issue336 + +import "testing" + +//go:generate go run asm.go -out issue336.s -stubs stub.go + +func TestNot(t *testing.T) { + nots := []func(bool) bool{Not8, Not16, Not32, Not64} + for _, not := range nots { + for _, x := range []bool{true, false} { + if not(x) != !x { + t.Fail() + } + } + } +} diff --git a/tests/fixedbugs/issue336/stub.go b/tests/fixedbugs/issue336/stub.go new file mode 100644 index 0000000..ec201c9 --- /dev/null +++ b/tests/fixedbugs/issue336/stub.go @@ -0,0 +1,15 @@ +// Code generated by command: go run asm.go -out issue336.s -stubs stub.go. DO NOT EDIT. + +package issue336 + +// Not8 returns the boolean negation of x using a 8-bit intermediate. +func Not8(x bool) bool + +// Not16 returns the boolean negation of x using a 16-bit intermediate. +func Not16(x bool) bool + +// Not32 returns the boolean negation of x using a 32-bit intermediate. +func Not32(x bool) bool + +// Not64 returns the boolean negation of x using a 64-bit intermediate. +func Not64(x bool) bool