ssa.OpAMD64VPSHRDD512,
ssa.OpAMD64VPSHRDQ128,
ssa.OpAMD64VPSHRDQ256,
- ssa.OpAMD64VPSHRDQ512:
+ ssa.OpAMD64VPSHRDQ512,
+ ssa.OpAMD64VSHUFPS128,
+ ssa.OpAMD64VSHUFPD128,
+ ssa.OpAMD64VSHUFPS256,
+ ssa.OpAMD64VSHUFPS512,
+ ssa.OpAMD64VSHUFPD256,
+ ssa.OpAMD64VSHUFPD512:
p = simdV21Imm8(s, v)
case ssa.OpAMD64VCMPPS512,
ssa.OpAMD64VPSHRDD512load,
ssa.OpAMD64VPSHRDQ128load,
ssa.OpAMD64VPSHRDQ256load,
- ssa.OpAMD64VPSHRDQ512load:
+ ssa.OpAMD64VPSHRDQ512load,
+ ssa.OpAMD64VSHUFPS512load,
+ ssa.OpAMD64VSHUFPD512load:
p = simdV21loadImm8(s, v)
case ssa.OpAMD64VCMPPS512load,
(blendMaskedInt16x32 x y mask) => (VPBLENDMWMasked512 x y (VPMOVVec16x32ToM <types.TypeMask> mask))
(blendMaskedInt32x16 x y mask) => (VPBLENDMDMasked512 x y (VPMOVVec32x16ToM <types.TypeMask> mask))
(blendMaskedInt64x8 x y mask) => (VPBLENDMQMasked512 x y (VPMOVVec64x8ToM <types.TypeMask> mask))
+(concatSelectedConstantFloat32x4 ...) => (VSHUFPS128 ...)
+(concatSelectedConstantFloat64x2 ...) => (VSHUFPD128 ...)
+(concatSelectedConstantInt32x4 ...) => (VSHUFPS128 ...)
+(concatSelectedConstantInt64x2 ...) => (VSHUFPD128 ...)
+(concatSelectedConstantUint32x4 ...) => (VSHUFPS128 ...)
+(concatSelectedConstantUint64x2 ...) => (VSHUFPD128 ...)
+(concatSelectedConstantGroupedFloat32x8 ...) => (VSHUFPS256 ...)
+(concatSelectedConstantGroupedFloat32x16 ...) => (VSHUFPS512 ...)
+(concatSelectedConstantGroupedFloat64x4 ...) => (VSHUFPD256 ...)
+(concatSelectedConstantGroupedFloat64x8 ...) => (VSHUFPD512 ...)
+(concatSelectedConstantGroupedInt32x8 ...) => (VSHUFPS256 ...)
+(concatSelectedConstantGroupedInt32x16 ...) => (VSHUFPS512 ...)
+(concatSelectedConstantGroupedInt64x4 ...) => (VSHUFPD256 ...)
+(concatSelectedConstantGroupedInt64x8 ...) => (VSHUFPD512 ...)
+(concatSelectedConstantGroupedUint32x8 ...) => (VSHUFPS256 ...)
+(concatSelectedConstantGroupedUint32x16 ...) => (VSHUFPS512 ...)
+(concatSelectedConstantGroupedUint64x4 ...) => (VSHUFPD256 ...)
+(concatSelectedConstantGroupedUint64x8 ...) => (VSHUFPD512 ...)
(moveMaskedFloat32x16 x mask) => (VMOVUPSMasked512 x (VPMOVVec32x16ToM <types.TypeMask> mask))
(moveMaskedFloat64x8 x mask) => (VMOVUPDMasked512 x (VPMOVVec64x8ToM <types.TypeMask> mask))
(moveMaskedInt8x64 x mask) => (VMOVDQU8Masked512 x (VPMOVVec8x64ToM <types.TypeMask> mask))
(VPXORQMasked512 x l:(VMOVDQUload512 {sym} [off] ptr mem) mask) && canMergeLoad(v, l) && clobber(l) => (VPXORQMasked512load {sym} [off] x ptr mask mem)
(VPBLENDMDMasked512 x l:(VMOVDQUload512 {sym} [off] ptr mem) mask) && canMergeLoad(v, l) && clobber(l) => (VPBLENDMDMasked512load {sym} [off] x ptr mask mem)
(VPBLENDMQMasked512 x l:(VMOVDQUload512 {sym} [off] ptr mem) mask) && canMergeLoad(v, l) && clobber(l) => (VPBLENDMQMasked512load {sym} [off] x ptr mask mem)
+(VSHUFPS512 [c] x l:(VMOVDQUload512 {sym} [off] ptr mem)) && canMergeLoad(v, l) && clobber(l) => (VSHUFPS512load {sym} [makeValAndOff(int32(int8(c)),off)] x ptr mem)
+(VSHUFPD512 [c] x l:(VMOVDQUload512 {sym} [off] ptr mem)) && canMergeLoad(v, l) && clobber(l) => (VSHUFPD512load {sym} [makeValAndOff(int32(int8(c)),off)] x ptr mem)
(VPSLLD512const [c] l:(VMOVDQUload512 {sym} [off] ptr mem)) && canMergeLoad(v, l) && clobber(l) => (VPSLLD512constload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mem)
(VPSLLQ512const [c] l:(VMOVDQUload512 {sym} [off] ptr mem)) && canMergeLoad(v, l) && clobber(l) => (VPSLLQ512constload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mem)
(VPSLLDMasked128const [c] l:(VMOVDQUload128 {sym} [off] ptr mem) mask) && canMergeLoad(v, l) && clobber(l) => (VPSLLDMasked128constload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mask mem)
{name: "VPSHRDQMasked128", argLength: 3, reg: w2kw, asm: "VPSHRDQ", aux: "UInt8", commutative: false, typ: "Vec128", resultInArg0: false},
{name: "VPSHRDQMasked256", argLength: 3, reg: w2kw, asm: "VPSHRDQ", aux: "UInt8", commutative: false, typ: "Vec256", resultInArg0: false},
{name: "VPSHRDQMasked512", argLength: 3, reg: w2kw, asm: "VPSHRDQ", aux: "UInt8", commutative: false, typ: "Vec512", resultInArg0: false},
+ {name: "VSHUFPS128", argLength: 2, reg: v21, asm: "VSHUFPS", aux: "UInt8", commutative: false, typ: "Vec128", resultInArg0: false},
+ {name: "VSHUFPD128", argLength: 2, reg: v21, asm: "VSHUFPD", aux: "UInt8", commutative: false, typ: "Vec128", resultInArg0: false},
+ {name: "VSHUFPS256", argLength: 2, reg: v21, asm: "VSHUFPS", aux: "UInt8", commutative: false, typ: "Vec256", resultInArg0: false},
+ {name: "VSHUFPS512", argLength: 2, reg: w21, asm: "VSHUFPS", aux: "UInt8", commutative: false, typ: "Vec512", resultInArg0: false},
+ {name: "VSHUFPD256", argLength: 2, reg: v21, asm: "VSHUFPD", aux: "UInt8", commutative: false, typ: "Vec256", resultInArg0: false},
+ {name: "VSHUFPD512", argLength: 2, reg: w21, asm: "VSHUFPD", aux: "UInt8", commutative: false, typ: "Vec512", resultInArg0: false},
{name: "VPSLLW128const", argLength: 1, reg: v11, asm: "VPSLLW", aux: "UInt8", commutative: false, typ: "Vec128", resultInArg0: false},
{name: "VPSLLW256const", argLength: 1, reg: v11, asm: "VPSLLW", aux: "UInt8", commutative: false, typ: "Vec256", resultInArg0: false},
{name: "VPSLLW512const", argLength: 1, reg: w11, asm: "VPSLLW", aux: "UInt8", commutative: false, typ: "Vec512", resultInArg0: false},
{name: "VPSHRDQMasked128load", argLength: 4, reg: w2kwload, asm: "VPSHRDQ", commutative: false, typ: "Vec128", aux: "SymValAndOff", symEffect: "Read", resultInArg0: false},
{name: "VPSHRDQMasked256load", argLength: 4, reg: w2kwload, asm: "VPSHRDQ", commutative: false, typ: "Vec256", aux: "SymValAndOff", symEffect: "Read", resultInArg0: false},
{name: "VPSHRDQMasked512load", argLength: 4, reg: w2kwload, asm: "VPSHRDQ", commutative: false, typ: "Vec512", aux: "SymValAndOff", symEffect: "Read", resultInArg0: false},
+ {name: "VSHUFPS512load", argLength: 3, reg: w21load, asm: "VSHUFPS", commutative: false, typ: "Vec512", aux: "SymValAndOff", symEffect: "Read", resultInArg0: false},
+ {name: "VSHUFPD512load", argLength: 3, reg: w21load, asm: "VSHUFPD", commutative: false, typ: "Vec512", aux: "SymValAndOff", symEffect: "Read", resultInArg0: false},
{name: "VPSLLD512constload", argLength: 2, reg: w11load, asm: "VPSLLD", commutative: false, typ: "Vec512", aux: "SymValAndOff", symEffect: "Read", resultInArg0: false},
{name: "VPSLLQ512constload", argLength: 2, reg: w11load, asm: "VPSLLQ", commutative: false, typ: "Vec512", aux: "SymValAndOff", symEffect: "Read", resultInArg0: false},
{name: "VPSLLDMasked128constload", argLength: 3, reg: wkwload, asm: "VPSLLD", commutative: false, typ: "Vec128", aux: "SymValAndOff", symEffect: "Read", resultInArg0: false},
{name: "TruncScaledResidueFloat64x2", argLength: 1, commutative: false, aux: "UInt8"},
{name: "TruncScaledResidueFloat64x4", argLength: 1, commutative: false, aux: "UInt8"},
{name: "TruncScaledResidueFloat64x8", argLength: 1, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantFloat32x4", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantFloat64x2", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedFloat32x8", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedFloat32x16", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedFloat64x4", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedFloat64x8", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedInt32x8", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedInt32x16", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedInt64x4", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedInt64x8", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedUint32x8", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedUint32x16", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedUint64x4", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantGroupedUint64x8", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantInt32x4", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantInt64x2", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantUint32x4", argLength: 2, commutative: false, aux: "UInt8"},
+ {name: "concatSelectedConstantUint64x2", argLength: 2, commutative: false, aux: "UInt8"},
}
}
OpAMD64VPSHRDQMasked128
OpAMD64VPSHRDQMasked256
OpAMD64VPSHRDQMasked512
+ OpAMD64VSHUFPS128
+ OpAMD64VSHUFPD128
+ OpAMD64VSHUFPS256
+ OpAMD64VSHUFPS512
+ OpAMD64VSHUFPD256
+ OpAMD64VSHUFPD512
OpAMD64VPSLLW128const
OpAMD64VPSLLW256const
OpAMD64VPSLLW512const
OpAMD64VPSHRDQMasked128load
OpAMD64VPSHRDQMasked256load
OpAMD64VPSHRDQMasked512load
+ OpAMD64VSHUFPS512load
+ OpAMD64VSHUFPD512load
OpAMD64VPSLLD512constload
OpAMD64VPSLLQ512constload
OpAMD64VPSLLDMasked128constload
OpTruncScaledResidueFloat64x2
OpTruncScaledResidueFloat64x4
OpTruncScaledResidueFloat64x8
+ OpconcatSelectedConstantFloat32x4
+ OpconcatSelectedConstantFloat64x2
+ OpconcatSelectedConstantGroupedFloat32x8
+ OpconcatSelectedConstantGroupedFloat32x16
+ OpconcatSelectedConstantGroupedFloat64x4
+ OpconcatSelectedConstantGroupedFloat64x8
+ OpconcatSelectedConstantGroupedInt32x8
+ OpconcatSelectedConstantGroupedInt32x16
+ OpconcatSelectedConstantGroupedInt64x4
+ OpconcatSelectedConstantGroupedInt64x8
+ OpconcatSelectedConstantGroupedUint32x8
+ OpconcatSelectedConstantGroupedUint32x16
+ OpconcatSelectedConstantGroupedUint64x4
+ OpconcatSelectedConstantGroupedUint64x8
+ OpconcatSelectedConstantInt32x4
+ OpconcatSelectedConstantInt64x2
+ OpconcatSelectedConstantUint32x4
+ OpconcatSelectedConstantUint64x2
)
var opcodeTable = [...]opInfo{
},
},
},
+ {
+ name: "VSHUFPS128",
+ auxType: auxUInt8,
+ argLen: 2,
+ asm: x86.AVSHUFPS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+ {1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+ },
+ outputs: []outputInfo{
+ {0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+ },
+ },
+ },
+ {
+ name: "VSHUFPD128",
+ auxType: auxUInt8,
+ argLen: 2,
+ asm: x86.AVSHUFPD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+ {1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+ },
+ outputs: []outputInfo{
+ {0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+ },
+ },
+ },
+ {
+ name: "VSHUFPS256",
+ auxType: auxUInt8,
+ argLen: 2,
+ asm: x86.AVSHUFPS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+ {1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+ },
+ outputs: []outputInfo{
+ {0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+ },
+ },
+ },
+ {
+ name: "VSHUFPS512",
+ auxType: auxUInt8,
+ argLen: 2,
+ asm: x86.AVSHUFPS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
+ {1, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
+ },
+ outputs: []outputInfo{
+ {0, 281472829161472}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
+ },
+ },
+ },
+ {
+ name: "VSHUFPD256",
+ auxType: auxUInt8,
+ argLen: 2,
+ asm: x86.AVSHUFPD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+ {1, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
+ },
+ outputs: []outputInfo{
+ {0, 2147418112}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14
+ },
+ },
+ },
+ {
+ name: "VSHUFPD512",
+ auxType: auxUInt8,
+ argLen: 2,
+ asm: x86.AVSHUFPD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
+ {1, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
+ },
+ outputs: []outputInfo{
+ {0, 281472829161472}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
+ },
+ },
+ },
{
name: "VPSLLW128const",
auxType: auxUInt8,
},
},
},
+ {
+ name: "VSHUFPS512load",
+ auxType: auxSymValAndOff,
+ argLen: 3,
+ symEffect: SymRead,
+ asm: x86.AVSHUFPS,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 72057594037977087}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+ {0, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
+ },
+ outputs: []outputInfo{
+ {0, 281472829161472}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
+ },
+ },
+ },
+ {
+ name: "VSHUFPD512load",
+ auxType: auxSymValAndOff,
+ argLen: 3,
+ symEffect: SymRead,
+ asm: x86.AVSHUFPD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {1, 72057594037977087}, // AX CX DX BX SP BP SI DI R8 R9 R10 R11 R12 R13 R15 SB
+ {0, 281474976645120}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
+ },
+ outputs: []outputInfo{
+ {0, 281472829161472}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31
+ },
+ },
+ },
{
name: "VPSLLD512constload",
auxType: auxSymValAndOff,
argLen: 1,
generic: true,
},
+ {
+ name: "concatSelectedConstantFloat32x4",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantFloat64x2",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedFloat32x8",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedFloat32x16",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedFloat64x4",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedFloat64x8",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedInt32x8",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedInt32x16",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedInt64x4",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedInt64x8",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedUint32x8",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedUint32x16",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedUint64x4",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantGroupedUint64x8",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantInt32x4",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantInt64x2",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantUint32x4",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
+ {
+ name: "concatSelectedConstantUint64x2",
+ auxType: auxUInt8,
+ argLen: 2,
+ generic: true,
+ },
}
func (o Op) Asm() obj.As { return opcodeTable[o].asm }
return rewriteValueAMD64_OpAMD64VSCALEFPSMasked256(v)
case OpAMD64VSCALEFPSMasked512:
return rewriteValueAMD64_OpAMD64VSCALEFPSMasked512(v)
+ case OpAMD64VSHUFPD512:
+ return rewriteValueAMD64_OpAMD64VSHUFPD512(v)
+ case OpAMD64VSHUFPS512:
+ return rewriteValueAMD64_OpAMD64VSHUFPS512(v)
case OpAMD64VSQRTPD512:
return rewriteValueAMD64_OpAMD64VSQRTPD512(v)
case OpAMD64VSQRTPDMasked128:
return rewriteValueAMD64_OpblendMaskedInt64x8(v)
case OpblendMaskedInt8x64:
return rewriteValueAMD64_OpblendMaskedInt8x64(v)
+ case OpconcatSelectedConstantFloat32x4:
+ v.Op = OpAMD64VSHUFPS128
+ return true
+ case OpconcatSelectedConstantFloat64x2:
+ v.Op = OpAMD64VSHUFPD128
+ return true
+ case OpconcatSelectedConstantGroupedFloat32x16:
+ v.Op = OpAMD64VSHUFPS512
+ return true
+ case OpconcatSelectedConstantGroupedFloat32x8:
+ v.Op = OpAMD64VSHUFPS256
+ return true
+ case OpconcatSelectedConstantGroupedFloat64x4:
+ v.Op = OpAMD64VSHUFPD256
+ return true
+ case OpconcatSelectedConstantGroupedFloat64x8:
+ v.Op = OpAMD64VSHUFPD512
+ return true
+ case OpconcatSelectedConstantGroupedInt32x16:
+ v.Op = OpAMD64VSHUFPS512
+ return true
+ case OpconcatSelectedConstantGroupedInt32x8:
+ v.Op = OpAMD64VSHUFPS256
+ return true
+ case OpconcatSelectedConstantGroupedInt64x4:
+ v.Op = OpAMD64VSHUFPD256
+ return true
+ case OpconcatSelectedConstantGroupedInt64x8:
+ v.Op = OpAMD64VSHUFPD512
+ return true
+ case OpconcatSelectedConstantGroupedUint32x16:
+ v.Op = OpAMD64VSHUFPS512
+ return true
+ case OpconcatSelectedConstantGroupedUint32x8:
+ v.Op = OpAMD64VSHUFPS256
+ return true
+ case OpconcatSelectedConstantGroupedUint64x4:
+ v.Op = OpAMD64VSHUFPD256
+ return true
+ case OpconcatSelectedConstantGroupedUint64x8:
+ v.Op = OpAMD64VSHUFPD512
+ return true
+ case OpconcatSelectedConstantInt32x4:
+ v.Op = OpAMD64VSHUFPS128
+ return true
+ case OpconcatSelectedConstantInt64x2:
+ v.Op = OpAMD64VSHUFPD128
+ return true
+ case OpconcatSelectedConstantUint32x4:
+ v.Op = OpAMD64VSHUFPS128
+ return true
+ case OpconcatSelectedConstantUint64x2:
+ v.Op = OpAMD64VSHUFPD128
+ return true
case OpmoveMaskedFloat32x16:
return rewriteValueAMD64_OpmoveMaskedFloat32x16(v)
case OpmoveMaskedFloat64x8:
}
return false
}
+func rewriteValueAMD64_OpAMD64VSHUFPD512(v *Value) bool {
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (VSHUFPD512 [c] x l:(VMOVDQUload512 {sym} [off] ptr mem))
+ // cond: canMergeLoad(v, l) && clobber(l)
+ // result: (VSHUFPD512load {sym} [makeValAndOff(int32(int8(c)),off)] x ptr mem)
+ for {
+ c := auxIntToUint8(v.AuxInt)
+ x := v_0
+ l := v_1
+ if l.Op != OpAMD64VMOVDQUload512 {
+ break
+ }
+ off := auxIntToInt32(l.AuxInt)
+ sym := auxToSym(l.Aux)
+ mem := l.Args[1]
+ ptr := l.Args[0]
+ if !(canMergeLoad(v, l) && clobber(l)) {
+ break
+ }
+ v.reset(OpAMD64VSHUFPD512load)
+ v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int8(c)), off))
+ v.Aux = symToAux(sym)
+ v.AddArg3(x, ptr, mem)
+ return true
+ }
+ return false
+}
+func rewriteValueAMD64_OpAMD64VSHUFPS512(v *Value) bool {
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (VSHUFPS512 [c] x l:(VMOVDQUload512 {sym} [off] ptr mem))
+ // cond: canMergeLoad(v, l) && clobber(l)
+ // result: (VSHUFPS512load {sym} [makeValAndOff(int32(int8(c)),off)] x ptr mem)
+ for {
+ c := auxIntToUint8(v.AuxInt)
+ x := v_0
+ l := v_1
+ if l.Op != OpAMD64VMOVDQUload512 {
+ break
+ }
+ off := auxIntToInt32(l.AuxInt)
+ sym := auxToSym(l.Aux)
+ mem := l.Args[1]
+ ptr := l.Args[0]
+ if !(canMergeLoad(v, l) && clobber(l)) {
+ break
+ }
+ v.reset(OpAMD64VSHUFPS512load)
+ v.AuxInt = valAndOffToAuxInt(makeValAndOff(int32(int8(c)), off))
+ v.Aux = symToAux(sym)
+ v.AddArg3(x, ptr, mem)
+ return true
+ }
+ return false
+}
func rewriteValueAMD64_OpAMD64VSQRTPD512(v *Value) bool {
v_0 := v.Args[0]
// match: (VSQRTPD512 l:(VMOVDQUload512 {sym} [off] ptr mem))
addF(simdPackage, "Int16x32.blendMasked", opLen3(ssa.OpblendMaskedInt16x32, types.TypeVec512), sys.AMD64)
addF(simdPackage, "Int32x16.blendMasked", opLen3(ssa.OpblendMaskedInt32x16, types.TypeVec512), sys.AMD64)
addF(simdPackage, "Int64x8.blendMasked", opLen3(ssa.OpblendMaskedInt64x8, types.TypeVec512), sys.AMD64)
+ addF(simdPackage, "Float32x4.concatSelectedConstant", opLen2Imm8(ssa.OpconcatSelectedConstantFloat32x4, types.TypeVec128, 0), sys.AMD64)
+ addF(simdPackage, "Float64x2.concatSelectedConstant", opLen2Imm8(ssa.OpconcatSelectedConstantFloat64x2, types.TypeVec128, 0), sys.AMD64)
+ addF(simdPackage, "Int32x4.concatSelectedConstant", opLen2Imm8(ssa.OpconcatSelectedConstantInt32x4, types.TypeVec128, 0), sys.AMD64)
+ addF(simdPackage, "Int64x2.concatSelectedConstant", opLen2Imm8(ssa.OpconcatSelectedConstantInt64x2, types.TypeVec128, 0), sys.AMD64)
+ addF(simdPackage, "Uint32x4.concatSelectedConstant", opLen2Imm8(ssa.OpconcatSelectedConstantUint32x4, types.TypeVec128, 0), sys.AMD64)
+ addF(simdPackage, "Uint64x2.concatSelectedConstant", opLen2Imm8(ssa.OpconcatSelectedConstantUint64x2, types.TypeVec128, 0), sys.AMD64)
+ addF(simdPackage, "Float32x8.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedFloat32x8, types.TypeVec256, 0), sys.AMD64)
+ addF(simdPackage, "Float32x16.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedFloat32x16, types.TypeVec512, 0), sys.AMD64)
+ addF(simdPackage, "Float64x4.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedFloat64x4, types.TypeVec256, 0), sys.AMD64)
+ addF(simdPackage, "Float64x8.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedFloat64x8, types.TypeVec512, 0), sys.AMD64)
+ addF(simdPackage, "Int32x8.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedInt32x8, types.TypeVec256, 0), sys.AMD64)
+ addF(simdPackage, "Int32x16.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedInt32x16, types.TypeVec512, 0), sys.AMD64)
+ addF(simdPackage, "Int64x4.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedInt64x4, types.TypeVec256, 0), sys.AMD64)
+ addF(simdPackage, "Int64x8.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedInt64x8, types.TypeVec512, 0), sys.AMD64)
+ addF(simdPackage, "Uint32x8.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedUint32x8, types.TypeVec256, 0), sys.AMD64)
+ addF(simdPackage, "Uint32x16.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedUint32x16, types.TypeVec512, 0), sys.AMD64)
+ addF(simdPackage, "Uint64x4.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedUint64x4, types.TypeVec256, 0), sys.AMD64)
+ addF(simdPackage, "Uint64x8.concatSelectedConstantGrouped", opLen2Imm8(ssa.OpconcatSelectedConstantGroupedUint64x8, types.TypeVec512, 0), sys.AMD64)
addF(simdPackage, "Float32x16.moveMasked", opLen2(ssa.OpmoveMaskedFloat32x16, types.TypeVec512), sys.AMD64)
addF(simdPackage, "Float64x8.moveMasked", opLen2(ssa.OpmoveMaskedFloat64x8, types.TypeVec512), sys.AMD64)
addF(simdPackage, "Int8x64.moveMasked", opLen2(ssa.OpmoveMaskedInt8x64, types.TypeVec512), sys.AMD64)
FMT, DEBUG, flag, runtime/trace, internal/sysinfo, math/rand
< testing;
+ testing, math
+ < simd/internal/test_helpers;
+
log/slog, testing
< testing/slogtest;
documentation: !string |-
// NAME interleaves the elements of the low half of each 128-bit subvector of x and y.
+- go: concatSelectedConstant
+ commutative: false
+ out:
+ - elemBits: 32
+ documentation: !string |-
+ // NAME concatenates selected elements from x and y into the lower and upper
+ // halves of the output. The selection is chosen by the constant parameter h1h0l1l0
+ // where each {h,l}{1,0} is two bits specify which element from y or x to select.
+ // For example, {0,1,2,3}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7}) returns
+ // {2, 1, 4, 6} (don't forget that the binary constant is written big-endian).
+
+- go: concatSelectedConstant
+ commutative: false
+ out:
+ - elemBits: 64
+ documentation: !string |-
+ // NAME concatenates selected elements from x and y into the lower and upper
+ // halves of the output. The selection is chosen by the constant parameter hilo
+ // where hi and lo are each one bit specifying which 64-bit element to select
+ // from y and x. For example {4,5}.concatSelectedConstant(0b10, {6,7})
+ // returns {4,7}; bit 0, selecting from x, is zero, and selects 4, and bit 1,
+ // selecting from y, is 1, and selects 7.
+
+- go: concatSelectedConstantGrouped
+ commutative: false
+ out:
+ - elemBits: 32
+ documentation: !string |-
+ // NAME concatenates selected elements from 128-bit subvectors of x and y
+ // into the lower and upper halves of corresponding subvectors of the output.
+ // The selection is chosen by the constant parameter h1h0l1l0
+ // where each {h,l}{1,0} is two bits specify which element from y or x to select.
+ // For example,
+ // {0,1,2,3,8,9,10,11}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7,12,13,14,15})
+ // returns {2,0,5,7,10,8,13,15}
+ // (don't forget that the binary constant is written big-endian).
+
+- go: concatSelectedConstantGrouped
+ commutative: false
+ out:
+ - elemBits: 64
+ documentation: !string |-
+ // NAME concatenates selected elements from 128-bit subvectors of x and y
+ // into the lower and upper halves of corresponding subvectors of the output.
+ // The selections are specified by the constant parameter hilos where each
+ // hi and lo pair select 64-bit elements from the corresponding 128-bit
+ // subvectors of x and y.
+ //
+ // For example {4,5,8,9}.concatSelectedConstant(0b_11_10, {6,7,10,11})
+ // returns {4,7,9,11}; bit 0 is zero, selecting element 0 from x's least
+ // 128-bits (4), then 1, selects the element 1 from y's least 128-bits (7),
+ // then 1, selecting element 1 from x's upper 128 bits (9), then 1,
+ // selecting element 1 from y's upper 128 bits (11).
+ // This differs from the same method applied to a 32x8 vector, where
+ // the 8-bit constant performs the same selection on both subvectors.
\ No newline at end of file
out:
- *256Or512any
+# These are all described separately to carry the name of the constant parameter
+
+- go: concatSelectedConstant
+ asm: VSHUFPS
+ width: 32
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: 128
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: h1h0l1l0
+ inVariant: []
+ out:
+ - *v
+
+- go: concatSelectedConstant
+ asm: VSHUFPS
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: 128
+ OverwriteBase: int
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: h1h0l1l0
+ inVariant: []
+ out:
+ - *v
+
+- go: concatSelectedConstant
+ asm: VSHUFPS
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: 128
+ OverwriteBase: uint
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: h1h0l1l0
+ inVariant: []
+ out:
+ - *v
+
+
+- go: concatSelectedConstantGrouped
+ asm: VSHUFPS
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: "256|512"
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: h1h0l1l0
+ inVariant: []
+ out:
+ - *v
+
+- go: concatSelectedConstantGrouped
+ asm: VSHUFPS
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: "256|512"
+ OverwriteBase: int
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: h1h0l1l0
+ inVariant: []
+ out:
+ - *v
+
+- go: concatSelectedConstantGrouped
+ asm: VSHUFPS
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: "256|512"
+ OverwriteBase: uint
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: h1h0l1l0
+ inVariant: []
+ out:
+ - *v
+
+
+ # 64 bit versions
+
+- go: concatSelectedConstant
+ asm: VSHUFPD
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: 128
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: hilo
+ inVariant: []
+ out:
+ - *v
+
+- go: concatSelectedConstant
+ asm: VSHUFPD
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: 128
+ OverwriteBase: int
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: hilo
+ inVariant: []
+ out:
+ - *v
+
+- go: concatSelectedConstant
+ asm: VSHUFPD
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: 128
+ OverwriteBase: uint
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: hilo
+ inVariant: []
+ out:
+ - *v
+
+
+- go: concatSelectedConstantGrouped
+ asm: VSHUFPD
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: "256|512"
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: hilos
+ inVariant: []
+ out:
+ - *v
+
+- go: concatSelectedConstantGrouped
+ asm: VSHUFPD
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: "256|512"
+ OverwriteBase: int
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: hilos
+ inVariant: []
+ out:
+ - *v
+
+- go: concatSelectedConstantGrouped
+ asm: VSHUFPD
+ in:
+ - &v
+ go: $t
+ class: vreg
+ base: float
+ bits: "256|512"
+ OverwriteBase: uint
+ - *v
+ - class: immediate
+ immOffset: 0
+ name: hilos
+ inVariant: []
+ out:
+ - *v
import (
"math"
+ "simd/internal/test_helpers"
"testing"
)
func checkSlices[T number](t *testing.T, got, want []T) bool {
t.Helper()
- return checkSlicesLogInput[T](t, got, want, 0.0, nil)
+ return test_helpers.CheckSlicesLogInput[T](t, got, want, 0.0, nil)
}
-// checkSlices compares two slices for equality,
-// reporting a test error if there is a problem,
-// and also consumes the two slices so that a
-// test/benchmark won't be dead-code eliminated.
func checkSlicesLogInput[T number](t *testing.T, got, want []T, flakiness float64, logInput func()) bool {
t.Helper()
- var z T
- for i := range want {
- if got[i] != want[i] {
- var ia any = got[i]
- var ib any = want[i]
- switch x := ia.(type) {
- case float32:
- y := ib.(float32)
- if math.IsNaN(float64(x)) && math.IsNaN(float64(y)) {
- continue
- }
- if flakiness > 0 {
- if y == 0 {
- if math.Abs(float64(x)) < flakiness {
- continue
- }
- } else {
- if math.Abs(float64((x-y)/y)) < flakiness {
- continue
- }
- }
- }
- case float64:
- y := ib.(float64)
- if math.IsNaN(x) && math.IsNaN(y) {
- continue
- }
- if flakiness > 0 {
- if y == 0 {
- if math.Abs(x) < flakiness {
- continue
- }
- } else if math.Abs((x-y)/y) < flakiness {
- continue
- }
- }
-
- default:
- }
-
- t.Logf("For %T vector elements:", z)
- t.Logf("got =%v", got)
- t.Logf("want=%v", want)
- if logInput != nil {
- logInput()
- }
- t.Errorf("at index %d, got=%v, want=%v", i, got[i], want[i])
- return false
- } else if got[i] == 0 { // for floating point, 0.0 == -0.0 but a bitwise check can see the difference
- var ia any = got[i]
- var ib any = want[i]
- switch x := ia.(type) {
- case float32:
- y := ib.(float32)
- if math.Float32bits(x) != math.Float32bits(y) {
- t.Logf("For %T vector elements:", z)
- t.Logf("got =%v", got)
- t.Logf("want=%v", want)
- if logInput != nil {
- logInput()
- }
- t.Errorf("at index %d, different signs of zero", i)
- return false
- }
- case float64:
- y := ib.(float64)
- if math.Float64bits(x) != math.Float64bits(y) {
- t.Logf("For %T vector elements:", z)
- t.Logf("got =%v", got)
- t.Logf("want=%v", want)
- if logInput != nil {
- logInput()
- }
- t.Errorf("at index %d, different signs of zero", i)
- return false
- }
- default:
- }
-
- }
- }
- return true
+ return test_helpers.CheckSlicesLogInput[T](t, got, want, flakiness, logInput)
}
// sliceOf returns a slice n T's, with each
--- /dev/null
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.simd && amd64
+
+package test_helpers
+
+import (
+ "math"
+ "testing"
+)
+
+type signed interface {
+ ~int | ~int8 | ~int16 | ~int32 | ~int64
+}
+
+type integer interface {
+ ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
+}
+
+type float interface {
+ ~float32 | ~float64
+}
+
+type number interface {
+ ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64
+}
+
+func CheckSlices[T number](t *testing.T, got, want []T) bool {
+ t.Helper()
+ return CheckSlicesLogInput[T](t, got, want, 0.0, nil)
+}
+
+// CheckSlices compares two slices for equality,
+// reporting a test error if there is a problem,
+// and also consumes the two slices so that a
+// test/benchmark won't be dead-code eliminated.
+func CheckSlicesLogInput[T number](t *testing.T, got, want []T, flakiness float64, logInput func()) bool {
+ t.Helper()
+ var z T
+ for i := range want {
+ if got[i] != want[i] {
+ var ia any = got[i]
+ var ib any = want[i]
+ switch x := ia.(type) {
+ case float32:
+ y := ib.(float32)
+ if math.IsNaN(float64(x)) && math.IsNaN(float64(y)) {
+ continue
+ }
+ if flakiness > 0 {
+ if y == 0 {
+ if math.Abs(float64(x)) < flakiness {
+ continue
+ }
+ } else {
+ if math.Abs(float64((x-y)/y)) < flakiness {
+ continue
+ }
+ }
+ }
+ case float64:
+ y := ib.(float64)
+ if math.IsNaN(x) && math.IsNaN(y) {
+ continue
+ }
+ if flakiness > 0 {
+ if y == 0 {
+ if math.Abs(x) < flakiness {
+ continue
+ }
+ } else if math.Abs((x-y)/y) < flakiness {
+ continue
+ }
+ }
+
+ default:
+ }
+
+ t.Logf("For %T vector elements:", z)
+ t.Logf("got =%v", got)
+ t.Logf("want=%v", want)
+ if logInput != nil {
+ logInput()
+ }
+ t.Errorf("at index %d, got=%v, want=%v", i, got[i], want[i])
+ return false
+ } else if got[i] == 0 { // for floating point, 0.0 == -0.0 but a bitwise check can see the difference
+ var ia any = got[i]
+ var ib any = want[i]
+ switch x := ia.(type) {
+ case float32:
+ y := ib.(float32)
+ if math.Float32bits(x) != math.Float32bits(y) {
+ t.Logf("For %T vector elements:", z)
+ t.Logf("got =%v", got)
+ t.Logf("want=%v", want)
+ if logInput != nil {
+ logInput()
+ }
+ t.Errorf("at index %d, different signs of zero", i)
+ return false
+ }
+ case float64:
+ y := ib.(float64)
+ if math.Float64bits(x) != math.Float64bits(y) {
+ t.Logf("For %T vector elements:", z)
+ t.Logf("got =%v", got)
+ t.Logf("want=%v", want)
+ if logInput != nil {
+ logInput()
+ }
+ t.Errorf("at index %d, different signs of zero", i)
+ return false
+ }
+ default:
+ }
+
+ }
+ }
+ return true
+}
// Asm: VPBLENDMQ, CPU Feature: AVX512
func (x Int64x8) blendMasked(y Int64x8, mask Mask64x8) Int64x8
+/* concatSelectedConstant */
+
+// concatSelectedConstant concatenates selected elements from x and y into the lower and upper
+// halves of the output. The selection is chosen by the constant parameter h1h0l1l0
+// where each {h,l}{1,0} is two bits specify which element from y or x to select.
+// For example, {0,1,2,3}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7}) returns
+// {2, 1, 4, 6} (don't forget that the binary constant is written big-endian).
+//
+// h1h0l1l0 results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPS, CPU Feature: AVX
+func (x Float32x4) concatSelectedConstant(h1h0l1l0 uint8, y Float32x4) Float32x4
+
+// concatSelectedConstant concatenates selected elements from x and y into the lower and upper
+// halves of the output. The selection is chosen by the constant parameter hilo
+// where hi and lo are each one bit specifying which 64-bit element to select
+// from y and x. For example {4,5}.concatSelectedConstant(0b10, {6,7})
+// returns {4,7}; bit 0, selecting from x, is zero, and selects 4, and bit 1,
+// selecting from y, is 1, and selects 7.
+//
+// hilo results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPD, CPU Feature: AVX
+func (x Float64x2) concatSelectedConstant(hilo uint8, y Float64x2) Float64x2
+
+// concatSelectedConstant concatenates selected elements from x and y into the lower and upper
+// halves of the output. The selection is chosen by the constant parameter h1h0l1l0
+// where each {h,l}{1,0} is two bits specify which element from y or x to select.
+// For example, {0,1,2,3}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7}) returns
+// {2, 1, 4, 6} (don't forget that the binary constant is written big-endian).
+//
+// h1h0l1l0 results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPS, CPU Feature: AVX
+func (x Int32x4) concatSelectedConstant(h1h0l1l0 uint8, y Int32x4) Int32x4
+
+// concatSelectedConstant concatenates selected elements from x and y into the lower and upper
+// halves of the output. The selection is chosen by the constant parameter hilo
+// where hi and lo are each one bit specifying which 64-bit element to select
+// from y and x. For example {4,5}.concatSelectedConstant(0b10, {6,7})
+// returns {4,7}; bit 0, selecting from x, is zero, and selects 4, and bit 1,
+// selecting from y, is 1, and selects 7.
+//
+// hilo results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPD, CPU Feature: AVX
+func (x Int64x2) concatSelectedConstant(hilo uint8, y Int64x2) Int64x2
+
+// concatSelectedConstant concatenates selected elements from x and y into the lower and upper
+// halves of the output. The selection is chosen by the constant parameter h1h0l1l0
+// where each {h,l}{1,0} is two bits specify which element from y or x to select.
+// For example, {0,1,2,3}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7}) returns
+// {2, 1, 4, 6} (don't forget that the binary constant is written big-endian).
+//
+// h1h0l1l0 results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPS, CPU Feature: AVX
+func (x Uint32x4) concatSelectedConstant(h1h0l1l0 uint8, y Uint32x4) Uint32x4
+
+// concatSelectedConstant concatenates selected elements from x and y into the lower and upper
+// halves of the output. The selection is chosen by the constant parameter hilo
+// where hi and lo are each one bit specifying which 64-bit element to select
+// from y and x. For example {4,5}.concatSelectedConstant(0b10, {6,7})
+// returns {4,7}; bit 0, selecting from x, is zero, and selects 4, and bit 1,
+// selecting from y, is 1, and selects 7.
+//
+// hilo results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPD, CPU Feature: AVX
+func (x Uint64x2) concatSelectedConstant(hilo uint8, y Uint64x2) Uint64x2
+
+/* concatSelectedConstantGrouped */
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selection is chosen by the constant parameter h1h0l1l0
+// where each {h,l}{1,0} is two bits specify which element from y or x to select.
+// For example,
+// {0,1,2,3,8,9,10,11}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7,12,13,14,15})
+// returns {2,0,5,7,10,8,13,15}
+// (don't forget that the binary constant is written big-endian).
+//
+// h1h0l1l0 results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPS, CPU Feature: AVX
+func (x Float32x8) concatSelectedConstantGrouped(h1h0l1l0 uint8, y Float32x8) Float32x8
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selection is chosen by the constant parameter h1h0l1l0
+// where each {h,l}{1,0} is two bits specify which element from y or x to select.
+// For example,
+// {0,1,2,3,8,9,10,11}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7,12,13,14,15})
+// returns {2,0,5,7,10,8,13,15}
+// (don't forget that the binary constant is written big-endian).
+//
+// h1h0l1l0 results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPS, CPU Feature: AVX512
+func (x Float32x16) concatSelectedConstantGrouped(h1h0l1l0 uint8, y Float32x16) Float32x16
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selections are specified by the constant parameter hilos where each
+// hi and lo pair select 64-bit elements from the corresponding 128-bit
+// subvectors of x and y.
+//
+// For example {4,5,8,9}.concatSelectedConstant(0b_11_10, {6,7,10,11})
+// returns {4,7,9,11}; bit 0 is zero, selecting element 0 from x's least
+// 128-bits (4), then 1, selects the element 1 from y's least 128-bits (7),
+// then 1, selecting element 1 from x's upper 128 bits (9), then 1,
+// selecting element 1 from y's upper 128 bits (11).
+// This differs from the same method applied to a 32x8 vector, where
+// the 8-bit constant performs the same selection on both subvectors.
+//
+// hilos results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPD, CPU Feature: AVX
+func (x Float64x4) concatSelectedConstantGrouped(hilos uint8, y Float64x4) Float64x4
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selections are specified by the constant parameter hilos where each
+// hi and lo pair select 64-bit elements from the corresponding 128-bit
+// subvectors of x and y.
+//
+// For example {4,5,8,9}.concatSelectedConstant(0b_11_10, {6,7,10,11})
+// returns {4,7,9,11}; bit 0 is zero, selecting element 0 from x's least
+// 128-bits (4), then 1, selects the element 1 from y's least 128-bits (7),
+// then 1, selecting element 1 from x's upper 128 bits (9), then 1,
+// selecting element 1 from y's upper 128 bits (11).
+// This differs from the same method applied to a 32x8 vector, where
+// the 8-bit constant performs the same selection on both subvectors.
+//
+// hilos results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPD, CPU Feature: AVX512
+func (x Float64x8) concatSelectedConstantGrouped(hilos uint8, y Float64x8) Float64x8
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selection is chosen by the constant parameter h1h0l1l0
+// where each {h,l}{1,0} is two bits specify which element from y or x to select.
+// For example,
+// {0,1,2,3,8,9,10,11}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7,12,13,14,15})
+// returns {2,0,5,7,10,8,13,15}
+// (don't forget that the binary constant is written big-endian).
+//
+// h1h0l1l0 results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPS, CPU Feature: AVX
+func (x Int32x8) concatSelectedConstantGrouped(h1h0l1l0 uint8, y Int32x8) Int32x8
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selection is chosen by the constant parameter h1h0l1l0
+// where each {h,l}{1,0} is two bits specify which element from y or x to select.
+// For example,
+// {0,1,2,3,8,9,10,11}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7,12,13,14,15})
+// returns {2,0,5,7,10,8,13,15}
+// (don't forget that the binary constant is written big-endian).
+//
+// h1h0l1l0 results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPS, CPU Feature: AVX512
+func (x Int32x16) concatSelectedConstantGrouped(h1h0l1l0 uint8, y Int32x16) Int32x16
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selections are specified by the constant parameter hilos where each
+// hi and lo pair select 64-bit elements from the corresponding 128-bit
+// subvectors of x and y.
+//
+// For example {4,5,8,9}.concatSelectedConstant(0b_11_10, {6,7,10,11})
+// returns {4,7,9,11}; bit 0 is zero, selecting element 0 from x's least
+// 128-bits (4), then 1, selects the element 1 from y's least 128-bits (7),
+// then 1, selecting element 1 from x's upper 128 bits (9), then 1,
+// selecting element 1 from y's upper 128 bits (11).
+// This differs from the same method applied to a 32x8 vector, where
+// the 8-bit constant performs the same selection on both subvectors.
+//
+// hilos results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPD, CPU Feature: AVX
+func (x Int64x4) concatSelectedConstantGrouped(hilos uint8, y Int64x4) Int64x4
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selections are specified by the constant parameter hilos where each
+// hi and lo pair select 64-bit elements from the corresponding 128-bit
+// subvectors of x and y.
+//
+// For example {4,5,8,9}.concatSelectedConstant(0b_11_10, {6,7,10,11})
+// returns {4,7,9,11}; bit 0 is zero, selecting element 0 from x's least
+// 128-bits (4), then 1, selects the element 1 from y's least 128-bits (7),
+// then 1, selecting element 1 from x's upper 128 bits (9), then 1,
+// selecting element 1 from y's upper 128 bits (11).
+// This differs from the same method applied to a 32x8 vector, where
+// the 8-bit constant performs the same selection on both subvectors.
+//
+// hilos results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPD, CPU Feature: AVX512
+func (x Int64x8) concatSelectedConstantGrouped(hilos uint8, y Int64x8) Int64x8
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selection is chosen by the constant parameter h1h0l1l0
+// where each {h,l}{1,0} is two bits specify which element from y or x to select.
+// For example,
+// {0,1,2,3,8,9,10,11}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7,12,13,14,15})
+// returns {2,0,5,7,10,8,13,15}
+// (don't forget that the binary constant is written big-endian).
+//
+// h1h0l1l0 results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPS, CPU Feature: AVX
+func (x Uint32x8) concatSelectedConstantGrouped(h1h0l1l0 uint8, y Uint32x8) Uint32x8
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selection is chosen by the constant parameter h1h0l1l0
+// where each {h,l}{1,0} is two bits specify which element from y or x to select.
+// For example,
+// {0,1,2,3,8,9,10,11}.concatSelectedConstant(0b_11_01_00_10, {4,5,6,7,12,13,14,15})
+// returns {2,0,5,7,10,8,13,15}
+// (don't forget that the binary constant is written big-endian).
+//
+// h1h0l1l0 results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPS, CPU Feature: AVX512
+func (x Uint32x16) concatSelectedConstantGrouped(h1h0l1l0 uint8, y Uint32x16) Uint32x16
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selections are specified by the constant parameter hilos where each
+// hi and lo pair select 64-bit elements from the corresponding 128-bit
+// subvectors of x and y.
+//
+// For example {4,5,8,9}.concatSelectedConstant(0b_11_10, {6,7,10,11})
+// returns {4,7,9,11}; bit 0 is zero, selecting element 0 from x's least
+// 128-bits (4), then 1, selects the element 1 from y's least 128-bits (7),
+// then 1, selecting element 1 from x's upper 128 bits (9), then 1,
+// selecting element 1 from y's upper 128 bits (11).
+// This differs from the same method applied to a 32x8 vector, where
+// the 8-bit constant performs the same selection on both subvectors.
+//
+// hilos results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPD, CPU Feature: AVX
+func (x Uint64x4) concatSelectedConstantGrouped(hilos uint8, y Uint64x4) Uint64x4
+
+// concatSelectedConstantGrouped concatenates selected elements from 128-bit subvectors of x and y
+// into the lower and upper halves of corresponding subvectors of the output.
+// The selections are specified by the constant parameter hilos where each
+// hi and lo pair select 64-bit elements from the corresponding 128-bit
+// subvectors of x and y.
+//
+// For example {4,5,8,9}.concatSelectedConstant(0b_11_10, {6,7,10,11})
+// returns {4,7,9,11}; bit 0 is zero, selecting element 0 from x's least
+// 128-bits (4), then 1, selects the element 1 from y's least 128-bits (7),
+// then 1, selecting element 1 from x's upper 128 bits (9), then 1,
+// selecting element 1 from y's upper 128 bits (11).
+// This differs from the same method applied to a 32x8 vector, where
+// the 8-bit constant performs the same selection on both subvectors.
+//
+// hilos results in better performance when it's a constant, a non-constant value will be translated into a jump table.
+//
+// Asm: VSHUFPD, CPU Feature: AVX512
+func (x Uint64x8) concatSelectedConstantGrouped(hilos uint8, y Uint64x8) Uint64x8
+
/* moveMasked */
// moveMasked blends a vector with zero, with the original value where the mask is true
--- /dev/null
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.simd && amd64
+
+package simd
+
+import (
+ "simd/internal/test_helpers"
+ "testing"
+)
+
+func TestConcatSelectedConstant64(t *testing.T) {
+ a := make([]int64, 2)
+ x := LoadInt64x2Slice([]int64{4, 5})
+ y := LoadInt64x2Slice([]int64{6, 7})
+ z := x.concatSelectedConstant(0b10, y)
+ z.StoreSlice(a)
+ test_helpers.CheckSlices[int64](t, a, []int64{4, 7})
+}
+
+func TestConcatSelectedConstantGrouped64(t *testing.T) {
+ a := make([]float64, 4)
+ x := LoadFloat64x4Slice([]float64{4, 5, 8, 9})
+ y := LoadFloat64x4Slice([]float64{6, 7, 10, 11})
+ z := x.concatSelectedConstantGrouped(0b_11_10, y)
+ z.StoreSlice(a)
+ test_helpers.CheckSlices[float64](t, a, []float64{4, 7, 9, 11})
+}
+
+func TestConcatSelectedConstant32(t *testing.T) {
+ a := make([]float32, 4)
+ x := LoadFloat32x4Slice([]float32{4, 5, 8, 9})
+ y := LoadFloat32x4Slice([]float32{6, 7, 10, 11})
+ z := x.concatSelectedConstant(0b_11_01_10_00, y)
+ z.StoreSlice(a)
+ test_helpers.CheckSlices[float32](t, a, []float32{4, 8, 7, 11})
+}
+
+func TestConcatSelectedConstantGrouped32(t *testing.T) {
+ a := make([]uint32, 8)
+ x := LoadUint32x8Slice([]uint32{0, 1, 2, 3, 8, 9, 10, 11})
+ y := LoadUint32x8Slice([]uint32{4, 5, 6, 7, 12, 13, 14, 15})
+ z := x.concatSelectedConstantGrouped(0b_11_01_00_10, y)
+ z.StoreSlice(a)
+ test_helpers.CheckSlices[uint32](t, a, []uint32{2, 0, 5, 7, 10, 8, 13, 15})
+}