blob: cdee0870647f01c9ad11499af5541d0baa6fa6ae [file]
!sum
# Add
- go: Add
asm: "VPADD[BWDQ]|VADDP[SD]"
in:
- &any
go: $t
- *any
out:
- *any
# Add Saturated
- go: AddSaturated
asm: "VPADDS[BWDQ]"
in:
- &int
go: $t
base: int
- *int
out:
- *int
- go: AddSaturated
asm: "VPADDS[BWDQ]"
in:
- &uint
go: $t
base: uint
- *uint
out:
- *uint
# Sub
- go: Sub
asm: "VPSUB[BWDQ]|VSUBP[SD]"
in: &2any
- *any
- *any
out: &1any
- *any
# Sub Saturated
- go: SubSaturated
asm: "VPSUBS[BWDQ]"
in: &2int
- *int
- *int
out: &1int
- *int
- go: SubSaturated
asm: "VPSUBS[BWDQ]"
in:
- *uint
- *uint
out:
- *uint
- go: AddPairs
asm: "VPHADD[DW]"
in: *2any
out: *1any
- go: SubPairs
asm: "VPHSUB[DW]"
in: *2any
out: *1any
- go: AddPairs
asm: "VHADDP[SD]" # floats
in: *2any
out: *1any
- go: SubPairs
asm: "VHSUBP[SD]" # floats
in: *2any
out: *1any
- go: AddPairsSaturated
asm: "VPHADDS[DW]"
in: *2int
out: *1int
- go: SubPairsSaturated
asm: "VPHSUBS[DW]"
in: *2int
out: *1int
# In the XED data, *all* floating point bitwise logic operation has their
# operand type marked as uint. We are not trying to understand why Intel
# decided that they want FP bit-wise logic operations, but this irregularity
# has to be dealed with in separate rules with some overwrites.
# For many bit-wise operations, we have the following non-orthogonal
# choices:
#
# - Non-masked AVX operations have no element width (because it
# doesn't matter), but only cover 128 and 256 bit vectors.
#
# - Masked AVX-512 operations have an element width (because it needs
# to know how to interpret the mask), and cover 128, 256, and 512 bit
# vectors. These only cover 32- and 64-bit element widths.
#
# - Non-masked AVX-512 operations still have an element width (because
# they're just the masked operations with an implicit K0 mask) but it
# doesn't matter! This is the only option for non-masked 512 bit
# operations, and we can pick any of the element widths.
#
# We unify with ALL of these operations and the compiler generator
# picks when there are multiple options.
# TODO: We don't currently generate unmasked bit-wise operations on 512 bit
# vectors of 8- or 16-bit elements. AVX-512 only has *masked* bit-wise
# operations for 32- and 64-bit elements; while the element width doesn't matter
# for unmasked operations, right now we don't realize that we can just use the
# 32- or 64-bit version for the unmasked form. Maybe in the XED decoder we
# should recognize bit-wise operations when generating unmasked versions and
# omit the element width.
# For binary operations, we constrain their two inputs and one output to the
# same Go type using a variable.
- go: And
asm: "VPAND[DQ]?"
in:
- &any
go: $t
- *any
out:
- *any
- go: And
asm: "VPANDD" # Fill in the gap, And is missing for Uint8x64 and Int8x64
inVariant: []
in: &twoI8x64
- &i8x64
go: $t
overwriteElementBits: 8
- *i8x64
out: &oneI8x64
- *i8x64
- go: And
asm: "VPANDD" # Fill in the gap, And is missing for Uint16x32 and Int16x32
inVariant: []
in: &twoI16x32
- &i16x32
go: $t
overwriteElementBits: 16
- *i16x32
out: &oneI16x32
- *i16x32
- go: AndNot
asm: "VPANDN[DQ]?"
operandOrder: "21" # switch the arg order
in:
- *any
- *any
out:
- *any
- go: AndNot
asm: "VPANDND" # Fill in the gap, AndNot is missing for Uint8x64 and Int8x64
operandOrder: "21" # switch the arg order
inVariant: []
in: *twoI8x64
out: *oneI8x64
- go: AndNot
asm: "VPANDND" # Fill in the gap, AndNot is missing for Uint16x32 and Int16x32
operandOrder: "21" # switch the arg order
inVariant: []
in: *twoI16x32
out: *oneI16x32
- go: Or
asm: "VPOR[DQ]?"
in:
- *any
- *any
out:
- *any
- go: Or
asm: "VPORD" # Fill in the gap, Or is missing for Uint8x64 and Int8x64
inVariant: []
in: *twoI8x64
out: *oneI8x64
- go: Or
asm: "VPORD" # Fill in the gap, Or is missing for Uint16x32 and Int16x32
inVariant: []
in: *twoI16x32
out: *oneI16x32
- go: Xor
asm: "VPXOR[DQ]?"
in:
- *any
- *any
out:
- *any
- go: Xor
asm: "VPXORD" # Fill in the gap, Or is missing for Uint8x64 and Int8x64
inVariant: []
in: *twoI8x64
out: *oneI8x64
- go: Xor
asm: "VPXORD" # Fill in the gap, Or is missing for Uint16x32 and Int16x32
inVariant: []
in: *twoI16x32
out: *oneI16x32
# Ints
- go: Equal
asm: "V?PCMPEQ[BWDQ]"
in:
- &any
go: $t
- *any
out:
- &anyvregToMask
go: $t
overwriteBase: int
overwriteClass: mask
- go: Greater
asm: "V?PCMPGT[BWDQ]"
in:
- &int
go: $t
base: int
- *int
out:
- *anyvregToMask
# 256-bit VCMPGTQ's output elemBits is marked 32-bit in the XED data, we
# believe this is an error, so add this definition to overwrite.
- go: Greater
asm: "VPCMPGTQ"
in:
- &int64
go: $t
base: int
elemBits: 64
- *int64
out:
- base: int
elemBits: 32
overwriteElementBits: 64
overwriteClass: mask
overwriteBase: int
# AVX-512 compares produce masks.
- go: Equal
asm: "V?PCMPEQ[BWDQ]"
in:
- *any
- *any
out:
- class: mask
- go: Greater
asm: "V?PCMPGT[BWDQ]"
in:
- *int
- *int
out:
- class: mask
# The const imm predicated compares after AVX512, please see categories.yaml
# for const imm specification.
- go: (Equal|Greater|Less|LessEqual|GreaterEqual|NotEqual)
asm: "VPCMP[BWDQ]"
in:
- *int
- *int
- class: immediate
const: 0 # Just a placeholder, will be overwritten by const imm porting.
out:
- class: mask
- go: (Equal|Greater|Less|LessEqual|GreaterEqual|NotEqual)
asm: "VPCMPU[BWDQ]"
in:
- &uint
go: $t
base: uint
- *uint
- class: immediate
const: 0
out:
- class: mask
# Floats
- go: Equal|Greater|Less|LessEqual|GreaterEqual|NotEqual|IsNan
asm: "VCMPP[SD]"
in:
- &float
go: $t
base: float
- *float
- class: immediate
const: 0
out:
- go: $t
overwriteBase: int
overwriteClass: mask
- go: (Equal|Greater|Less|LessEqual|GreaterEqual|NotEqual|IsNan)
asm: "VCMPP[SD]"
in:
- *float
- *float
- class: immediate
const: 0
out:
- class: mask
- go: ConvertToInt32
asm: "VCVTTPS2DQ"
in:
- &fp
go: $t
base: float
out:
- &i32
go: $u
base: int
elemBits: 32
- go: ConvertToUint32
asm: "VCVTPS2UDQ"
in:
- *fp
out:
- &u32
go: $u
base: uint
elemBits: 32
- go: Div
asm: "V?DIVP[SD]"
in: &2fp
- &fp
go: $t
base: float
- *fp
out: &1fp
- *fp
- go: Sqrt
asm: "V?SQRTP[SD]"
in: *1fp
out: *1fp
# TODO: Provide separate methods for 12-bit precision and 14-bit precision?
- go: ApproximateReciprocal
asm: "VRCP(14)?P[SD]"
in: *1fp
out: *1fp
- go: ApproximateReciprocalOfSqrt
asm: "V?RSQRT(14)?P[SD]"
in: *1fp
out: *1fp
- go: Scale
asm: "VSCALEFP[SD]"
in: *2fp
out: *1fp
- go: "Round|Ceil|Floor|Trunc"
asm: "VROUNDP[SD]"
in:
- *fp
- class: immediate
const: 0 # place holder
out: *1fp
- go: "(Round|Ceil|Floor|Trunc)Scaled"
asm: "VRNDSCALEP[SD]"
in:
- *fp
- class: immediate
const: 0 # place holder
immOffset: 4 # "M", round to numbers with M digits after dot(by means of binary number).
name: prec
out: *1fp
- go: "(Round|Ceil|Floor|Trunc)ScaledResidue"
asm: "VREDUCEP[SD]"
in:
- *fp
- class: immediate
const: 0 # place holder
immOffset: 4 # "M", round to numbers with M digits after dot(by means of binary number).
name: prec
out: *1fp
- go: "AddSub"
asm: "VADDSUBP[SD]"
in:
- *fp
- *fp
out:
- *fp
- go: GaloisFieldAffineTransform
asm: VGF2P8AFFINEQB
operandOrder: 2I # 2nd operand, then immediate
in: &AffineArgs
- &uint8
go: $t
base: uint
- &uint8x8
go: $t2
base: uint
- &pureImmVar
class: immediate
immOffset: 0
name: b
out:
- *uint8
- go: GaloisFieldAffineTransformInverse
asm: VGF2P8AFFINEINVQB
operandOrder: 2I # 2nd operand, then immediate
in: *AffineArgs
out:
- *uint8
- go: GaloisFieldMul
asm: VGF2P8MULB
in:
- *uint8
- *uint8
out:
- *uint8
# Average (unsigned byte, unsigned word)
# Instructions: VPAVGB, VPAVGW
- go: Average
asm: "VPAVG[BW]" # Matches VPAVGB (byte) and VPAVGW (word)
in:
- &uint_t # $t will be Uint8xN for VPAVGB, Uint16xN for VPAVGW
go: $t
base: uint
- *uint_t
out:
- *uint_t
# Absolute Value (signed byte, word, dword, qword)
# Instructions: VPABSB, VPABSW, VPABSD, VPABSQ
- go: Absolute
asm: "VPABS[BWDQ]" # Matches VPABSB, VPABSW, VPABSD, VPABSQ
in:
- &int_t # $t will be Int8xN, Int16xN, Int32xN, Int64xN
go: $t
base: int
out:
- *int_t # Output is magnitude, fits in the same signed type
# Sign Operation (signed byte, word, dword)
# Applies sign of second operand to the first.
# Instructions: VPSIGNB, VPSIGNW, VPSIGND
- go: Sign
asm: "VPSIGN[BWD]" # Matches VPSIGNB, VPSIGNW, VPSIGND
in:
- *int_t # value to apply sign to
- *int_t # value from which to take the sign
out:
- *int_t
# Population Count (count set bits in each element)
# Instructions: VPOPCNTB, VPOPCNTW (AVX512_BITALG)
# VPOPCNTD, VPOPCNTQ (AVX512_VPOPCNTDQ)
- go: PopCount
asm: "VPOPCNT[BWDQ]"
in:
- &any
go: $t
out:
- *any
- go: PairDotProd
asm: VPMADDWD
in:
- &int
go: $t
base: int
- *int
out:
- &int2 # The elemBits are different
go: $t2
base: int
- go: SaturatedUnsignedSignedPairDotProd
asm: VPMADDUBSW
in:
- &uint
go: $t
base: uint
overwriteElementBits: 8
- &int3
go: $t3
base: int
overwriteElementBits: 8
out:
- *int2
- go: DotProdBroadcast
asm: VDPP[SD]
in:
- &dpb_src
go: $t
- *dpb_src
- class: immediate
const: 127
out:
- *dpb_src
- go: UnsignedSignedQuadDotProdAccumulate
asm: "VPDPBUSD"
operandOrder: "31" # switch operand 3 and 1
in:
- &qdpa_acc
go: $t_acc
base: int
elemBits: 32
- &qdpa_src1
go: $t_src1
base: uint
overwriteElementBits: 8
- &qdpa_src2
go: $t_src2
base: int
overwriteElementBits: 8
out:
- *qdpa_acc
- go: SaturatedUnsignedSignedQuadDotProdAccumulate
asm: "VPDPBUSDS"
operandOrder: "31" # switch operand 3 and 1
in:
- *qdpa_acc
- *qdpa_src1
- *qdpa_src2
out:
- *qdpa_acc
- go: AddDotProd
asm: "VPDPWSSD"
in:
- &pdpa_acc
go: $t_acc
base: int
elemBits: 32
- &pdpa_src1
go: $t_src1
base: int
overwriteElementBits: 16
- &pdpa_src2
go: $t_src2
base: int
overwriteElementBits: 16
out:
- *pdpa_acc
- go: SaturatedAddDotProd
asm: "VPDPWSSDS"
in:
- *pdpa_acc
- *pdpa_src1
- *pdpa_src2
out:
- *pdpa_acc
- go: FusedMultiplyAdd
asm: "VFMADD213PS|VFMADD213PD"
in:
- &fma_op
go: $t
base: float
- *fma_op
- *fma_op
out:
- *fma_op
- go: FusedMultiplyAddSub
asm: "VFMADDSUB213PS|VFMADDSUB213PD"
in:
- *fma_op
- *fma_op
- *fma_op
out:
- *fma_op
- go: FusedMultiplySubAdd
asm: "VFMSUBADD213PS|VFMSUBADD213PD"
in:
- *fma_op
- *fma_op
- *fma_op
out:
- *fma_op
- go: Max
asm: "V?PMAXS[BWDQ]"
in: &2int
- &int
go: $t
base: int
- *int
out: &1int
- *int
- go: Max
asm: "V?PMAXU[BWDQ]"
in: &2uint
- &uint
go: $t
base: uint
- *uint
out: &1uint
- *uint
- go: Min
asm: "V?PMINS[BWDQ]"
in: *2int
out: *1int
- go: Min
asm: "V?PMINU[BWDQ]"
in: *2uint
out: *1uint
- go: Max
asm: "V?MAXP[SD]"
in: &2float
- &float
go: $t
base: float
- *float
out: &1float
- *float
- go: Min
asm: "V?MINP[SD]"
in: *2float
out: *1float
- go: SetElem
asm: "VPINSR[BWDQ]"
in:
- &t
class: vreg
base: $b
- class: greg
base: $b
lanes: 1 # Scalar, darn it!
- &imm
class: immediate
immOffset: 0
name: index
out:
- *t
- go: GetElem
asm: "VPEXTR[BWDQ]"
in:
- class: vreg
base: $b
elemBits: $e
- *imm
out:
- class: greg
base: $b
bits: $e
- go: Set128
asm: "VINSERTI128"
in:
- &i8x32
class: vreg
base: $t
bits: 256
OverwriteElementBits: 8
- &i8x16
class: vreg
base: $t
bits: 128
OverwriteElementBits: 8
- &imm01 # This immediate should be only 0 or 1
class: immediate
immOffset: 0
name: index
out:
- *i8x32
- go: Get128
asm: "VEXTRACTI128"
in:
- *i8x32
- *imm01
out:
- *i8x16
- go: Set128
asm: "VINSERTI128"
in:
- &i16x16
class: vreg
base: $t
bits: 256
OverwriteElementBits: 16
- &i16x8
class: vreg
base: $t
bits: 128
OverwriteElementBits: 16
- *imm01
out:
- *i16x16
- go: Get128
asm: "VEXTRACTI128"
in:
- *i16x16
- *imm01
out:
- *i16x8
- go: Set128
asm: "VINSERTI128"
in:
- &i32x8
class: vreg
base: $t
bits: 256
OverwriteElementBits: 32
- &i32x4
class: vreg
base: $t
bits: 128
OverwriteElementBits: 32
- *imm01
out:
- *i32x8
- go: Get128
asm: "VEXTRACTI128"
in:
- *i32x8
- *imm01
out:
- *i32x4
- go: Set128
asm: "VINSERTI128"
in:
- &i64x4
class: vreg
base: $t
bits: 256
OverwriteElementBits: 64
- &i64x2
class: vreg
base: $t
bits: 128
OverwriteElementBits: 64
- *imm01
out:
- *i64x4
- go: Get128
asm: "VEXTRACTI128"
in:
- *i64x4
- *imm01
out:
- *i64x2
- go: Set128
asm: "VINSERTF128"
in:
- &f32x8
class: vreg
base: $t
bits: 256
OverwriteElementBits: 32
- &f32x4
class: vreg
base: $t
bits: 128
OverwriteElementBits: 32
- *imm01
out:
- *f32x8
- go: Get128
asm: "VEXTRACTF128"
in:
- *f32x8
- *imm01
out:
- *f32x4
- go: Set128
asm: "VINSERTF128"
in:
- &f64x4
class: vreg
base: $t
bits: 256
- &f64x2
class: vreg
base: $t
bits: 128
- *imm01
out:
- *f64x4
- go: Get128
asm: "VEXTRACTF128"
in:
- *f64x4
- *imm01
out:
- *f64x2
- go: Permute
asm: "VPERM[BWDQ]|VPERMP[SD]"
operandOrder: "21Type1"
in:
- &anyindices
go: $t
name: indices
overwriteBase: uint
- &any
go: $t
out:
- *any
- go: Permute2
asm: "VPERMI2[BWDQ]|VPERMI2P[SD]"
# Because we are overwriting the receiver's type, we
# have to move the receiver to be a parameter so that
# we can have no duplication.
operandOrder: "231Type1"
in:
- *anyindices # result in arg 0
- *any
- *any
out:
- *any
- go: Compress
asm: "VPCOMPRESS[BWDQ]|VCOMPRESSP[SD]"
in:
# The mask in Compress is a control mask rather than a write mask, so it's not optional.
- class: mask
- *any
out:
- *any
# For now a non-public method because
# (1) [OverwriteClass] must be set together with [OverwriteBase]
# (2) "simdgen does not support [OverwriteClass] in inputs".
# That means the signature is wrong.
- go: blend
asm: VPBLENDVB
in:
- &v
go: $t
class: vreg
base: int
- *v
-
class: vreg
base: int
name: mask
out:
- *v
# For AVX512
- go: blend
asm: VPBLENDM[BWDQ]
in:
- &v
go: $t
bits: 512
class: vreg
base: int
- *v
inVariant:
-
class: mask
out:
- *v
# "Normal" multiplication is only available for floats.
# This only covers the single and double precision.
- go: Mul
asm: "VMULP[SD]"
in:
- &fp
go: $t
base: float
- *fp
out:
- *fp
# Integer multiplications.
# MulEvenWiden
# Dword only.
- go: MulEvenWiden
asm: "VPMULDQ"
in:
- &int
go: $t
base: int
- *int
out:
- &int2
go: $t2
base: int
- go: MulEvenWiden
asm: "VPMULUDQ"
in:
- &uint
go: $t
base: uint
- *uint
out:
- &uint2
go: $t2
base: uint
# MulHigh
# Word only.
- go: MulHigh
asm: "VPMULHW"
in:
- *int
- *int
out:
- *int2
- go: MulHigh
asm: "VPMULHUW"
in:
- *uint
- *uint
out:
- *uint2
# MulLow
# Signed int only.
- go: Mul
asm: "VPMULL[WDQ]"
in:
- *int
- *int
out:
- *int2
# Integers
# ShiftAll*
- go: ShiftAllLeft
asm: "VPSLL[WDQ]"
in:
- &any
go: $t
- &vecAsScalar64
go: "Uint.*"
treatLikeAScalarOfSize: 64
out:
- *any
- go: ShiftAllRight
signed: false
asm: "VPSRL[WDQ]"
in:
- &uint
go: $t
base: uint
- *vecAsScalar64
out:
- *uint
- go: ShiftAllRight
signed: true
asm: "VPSRA[WDQ]"
in:
- &int
go: $t
base: int
- *vecAsScalar64
out:
- *int
- go: shiftAllLeftConst
asm: "VPSLL[WDQ]"
in:
- *any
- &imm
class: immediate
immOffset: 0
out:
- *any
- go: shiftAllRightConst
asm: "VPSRL[WDQ]"
in:
- *int
- *imm
out:
- *int
- go: shiftAllRightConst
asm: "VPSRA[WDQ]"
in:
- *uint
- *imm
out:
- *uint
# Shift* (variable)
- go: ShiftLeft
asm: "VPSLLV[WD]"
in:
- *any
- *any
out:
- *any
# XED data of VPSLLVQ marks the element bits 32 which is off to the actual semantic, we need to overwrite
# it to 64.
- go: ShiftLeft
asm: "VPSLLVQ"
in:
- &anyOverwriteElemBits
go: $t
overwriteElementBits: 64
- *anyOverwriteElemBits
out:
- *anyOverwriteElemBits
- go: ShiftRight
signed: false
asm: "VPSRLV[WD]"
in:
- *uint
- *uint
out:
- *uint
# XED data of VPSRLVQ needs the same overwrite as VPSLLVQ.
- go: ShiftRight
signed: false
asm: "VPSRLVQ"
in:
- &uintOverwriteElemBits
go: $t
base: uint
overwriteElementBits: 64
- *uintOverwriteElemBits
out:
- *uintOverwriteElemBits
- go: ShiftRight
signed: true
asm: "VPSRAV[WDQ]"
in:
- *int
- *int
out:
- *int
# Rotate
- go: RotateAllLeft
asm: "VPROL[DQ]"
in:
- *any
- &pureImm
class: immediate
immOffset: 0
name: shift
out:
- *any
- go: RotateAllRight
asm: "VPROR[DQ]"
in:
- *any
- *pureImm
out:
- *any
- go: RotateLeft
asm: "VPROLV[DQ]"
in:
- *any
- *any
out:
- *any
- go: RotateRight
asm: "VPRORV[DQ]"
in:
- *any
- *any
out:
- *any
# Bizzare shifts.
- go: ShiftAllLeftConcat
asm: "VPSHLD[WDQ]"
in:
- *any
- *any
- *pureImm
out:
- *any
- go: ShiftAllRightConcat
asm: "VPSHRD[WDQ]"
in:
- *any
- *any
- *pureImm
out:
- *any
- go: ShiftLeftConcat
asm: "VPSHLDV[WDQ]"
in:
- *any
- *any
- *any
out:
- *any
- go: ShiftRightConcat
asm: "VPSHRDV[WDQ]"
in:
- *any
- *any
- *any
out:
- *any