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) {
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")

View File

@@ -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,16 +60,14 @@ 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)
}
sort.Strings(conds)
m.Printf("case %s:\n", strings.Join(conds, " && "))
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)
}
}
}
// ismov decides whether the given instruction is a plain move instruction.
func ismov(i inst.Instruction) bool {
@@ -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
case strings.Contains(i.Summary, "Zero-Extend"):
f["types.IsInteger"] = true
f["types.IsUnsigned"] = true
case strings.Contains(i.Summary, "Sign-Extension"):
f["types.IsInteger"] = true
f["types.IsUnsigned"] = false
default:
f["types.IsInteger"] = true
return []typecase{
{"types.IsFloat", "!=", "0"},
}
case strings.Contains(i.Summary, "Zero-Extend"):
return []typecase{
{"(types.IsInteger|types.IsUnsigned)", "==", "(types.IsInteger|types.IsUnsigned)"},
{"types.IsBoolean", "!=", "0"},
}
case strings.Contains(i.Summary, "Sign-Extension"):
return []typecase{
{"(types.IsInteger|types.IsUnsigned)", "==", "types.IsInteger"},
}
default:
return []typecase{
{"(types.IsInteger|types.IsBoolean)", "!=", "0"},
}
}
return f
}
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