build: mov deduction for booleans (#341)

Updates #336
This commit is contained in:
Michael McLoughlin
2022-11-26 19:30:55 -08:00
committed by GitHub
parent ef60a33bf0
commit 127528d117
7 changed files with 280 additions and 146 deletions

View File

@@ -10,261 +10,283 @@ import (
func (c *Context) mov(a, b operand.Op, an, bn int, t *types.Basic) { func (c *Context) mov(a, b operand.Op, an, bn int, t *types.Basic) {
switch { 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) c.VMOVSS(a, b)
default: default:
c.adderrormessage("could not deduce mov instruction") c.adderrormessage("could not deduce mov instruction")

View File

@@ -3,7 +3,6 @@ package gen
import ( import (
"errors" "errors"
"fmt" "fmt"
"sort"
"strings" "strings"
"github.com/mmcloughlin/avo/internal/api" "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) { func (m *mov) instruction(i inst.Instruction) {
f := flags(i) tcs := typecases(i)
mfs, err := movforms(i) mfs, err := movforms(i)
if err != nil { if err != nil {
m.AddError(err) m.AddError(err)
@@ -61,14 +60,12 @@ func (m *mov) instruction(i inst.Instruction) {
fmt.Sprintf("bn == %d", opsize[mf.B]), fmt.Sprintf("bn == %d", opsize[mf.B]),
fmt.Sprintf("%s(b)", api.CheckerName(mf.B)), fmt.Sprintf("%s(b)", api.CheckerName(mf.B)),
} }
for c, on := range f {
cmp := map[bool]string{true: "!=", false: "=="} for _, tc := range tcs {
cond := fmt.Sprintf("(t.Info() & %s) %s 0", c, cmp[on]) typecase := fmt.Sprintf("(t.Info() & %s) %s %s", tc.Mask, tc.Op, tc.Value)
conds = append(conds, cond) 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 return true
} }
func flags(i inst.Instruction) map[string]bool { type typecase struct {
f := map[string]bool{} Mask string
Op string
Value string
}
func typecases(i inst.Instruction) []typecase {
switch { switch {
case strings.Contains(i.Summary, "Floating-Point"): case strings.Contains(i.Summary, "Floating-Point"):
f["types.IsFloat"] = true return []typecase{
{"types.IsFloat", "!=", "0"},
}
case strings.Contains(i.Summary, "Zero-Extend"): case strings.Contains(i.Summary, "Zero-Extend"):
f["types.IsInteger"] = true return []typecase{
f["types.IsUnsigned"] = true {"(types.IsInteger|types.IsUnsigned)", "==", "(types.IsInteger|types.IsUnsigned)"},
{"types.IsBoolean", "!=", "0"},
}
case strings.Contains(i.Summary, "Sign-Extension"): case strings.Contains(i.Summary, "Sign-Extension"):
f["types.IsInteger"] = true return []typecase{
f["types.IsUnsigned"] = false {"(types.IsInteger|types.IsUnsigned)", "==", "types.IsInteger"},
}
default: default:
f["types.IsInteger"] = true return []typecase{
{"(types.IsInteger|types.IsBoolean)", "!=", "0"},
}
} }
return f
} }
type movform struct{ A, B string } type movform struct{ A, B string }

View File

@@ -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()
}

View File

@@ -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

View File

@@ -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

View File

@@ -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()
}
}
}
}

View File

@@ -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