void genHWIntrinsic(GenTreeHWIntrinsic* node);
#if defined(_TARGET_XARCH_)
void genHWIntrinsic_R_RM(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr);
-void genHWIntrinsic_R_RM_I(GenTreeHWIntrinsic* node, instruction ins);
+void genHWIntrinsic_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, int8_t ival);
void genHWIntrinsic_R_R_RM(GenTreeHWIntrinsic* node, instruction ins);
-void genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins);
+void genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, int8_t ival);
+void genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins);
void genHWIntrinsic_R_R_R_RM(
instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTree* op3);
void genSSEIntrinsic(GenTreeHWIntrinsic* node);
IF_DEF(RWR_RRD_MRD, IS_GM_RD|IS_R1_WR|IS_R2_RD, DSP) // write reg , read reg2 , read [mem]
IF_DEF(RWR_MRD_CNS, IS_GM_RD|IS_R1_WR, DSP_CNS) // write reg , read [mem], const
IF_DEF(RWR_RRD_MRD_CNS, IS_GM_RD|IS_R1_WR|IS_R2_RD, DSP_CNS) // write reg , read reg2 , read [mem], const
+IF_DEF(RWR_RRD_MRD_RRD, IS_GM_RD|IS_R1_WR|IS_R2_RD|IS_R3_RD, DSP_CNS) // write reg , read reg2 , read [mem], read reg3
IF_DEF(RWR_MRD_OFF, IS_GM_RD|IS_R1_WR, DSP) // write reg , offset mem
IF_DEF(MRD_RRD, IS_GM_RD|IS_R1_RD, DSP) // read [mem], read reg
IF_DEF(RWR_RRD_SRD, IS_SF_RD|IS_R1_WR|IS_R2_RD, NONE) // write reg , read reg2, read [stk]
IF_DEF(RWR_SRD_CNS, IS_SF_RD|IS_R1_WR, CNS ) // write reg , read [stk], const
IF_DEF(RWR_RRD_SRD_CNS, IS_SF_RD|IS_R1_WR|IS_R2_RD, CNS ) // write reg , read reg2, read [stk], const
+IF_DEF(RWR_RRD_SRD_RRD, IS_SF_RD|IS_R1_WR|IS_R2_RD|IS_R3_RD, CNS ) // write reg , read reg2, read [stk], read reg3
IF_DEF(SRD_RRD, IS_SF_RD|IS_R1_RD, NONE) // read [stk], read reg
IF_DEF(SWR_RRD, IS_SF_WR|IS_R1_RD, NONE) // write [stk], read reg
IF_DEF(RWR_RRD_ARD, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD ) // write reg , read reg2, read [adr]
IF_DEF(RWR_ARD_CNS, IS_AM_RD|IS_R1_WR, AMD_CNS) // write reg , read [adr], const
IF_DEF(RWR_RRD_ARD_CNS, IS_AM_RD|IS_R1_WR|IS_R2_RD, AMD_CNS) // write reg , read reg2, read [adr], const
+IF_DEF(RWR_RRD_ARD_RRD, IS_AM_RD|IS_R1_WR|IS_R2_RD|IS_R3_RD, AMD_CNS) // write reg , read reg2, read [adr], read reg3
IF_DEF(ARD_RRD, IS_AM_RD|IS_R1_RD, AMD ) // read [adr], read reg
IF_DEF(AWR_RRD, IS_AM_WR|IS_R1_RD, AMD ) // write [adr], read reg
case INS_pshufd:
case INS_pshufhw:
case INS_pshuflw:
+ case INS_roundpd:
+ case INS_roundps:
return true;
default:
return false;
}
}
-inline UNATIVE_OFFSET emitter::emitInsSizeSV(instrDesc* id, int var, int dsp, int val)
+inline UNATIVE_OFFSET emitter::emitInsSizeSV(instrDesc* id, code_t code, int var, int dsp)
+{
+ instruction ins = id->idIns();
+ emitAttr attrSize = id->idOpSize();
+ UNATIVE_OFFSET prefix = emitGetVexPrefixAdjustedSize(ins, attrSize, code);
+ return prefix + emitInsSizeSV(code, var, dsp);
+}
+
+inline UNATIVE_OFFSET emitter::emitInsSizeSV(instrDesc* id, code_t code, int var, int dsp, int val)
{
instruction ins = id->idIns();
- UNATIVE_OFFSET valSize = EA_SIZE_IN_BYTES(id->idOpSize());
- UNATIVE_OFFSET prefix = 0;
+ emitAttr attrSize = id->idOpSize();
+ UNATIVE_OFFSET valSize = EA_SIZE_IN_BYTES(attrSize);
+ UNATIVE_OFFSET prefix = emitGetVexPrefixAdjustedSize(ins, attrSize, code);
bool valInByte = ((signed char)val == val) && (ins != INS_mov) && (ins != INS_test);
#ifdef _TARGET_AMD64_
// This referes to 66h size prefix override
if (id->idOpSize() == EA_2BYTE)
{
- prefix = 1;
+ prefix += 1;
}
- return prefix + valSize + emitInsSizeSV(insCodeMI(ins), var, dsp);
+ return prefix + valSize + emitInsSizeSV(code, var, dsp);
}
/*****************************************************************************/
// so we should only hit this path for statics that are RIP-relative
UNATIVE_OFFSET size = sizeof(INT32);
+ size += emitGetVexPrefixAdjustedSize(ins, id->idOpSize(), code);
+
// Most 16-bit operand instructions will need a prefix.
// This refers to 66h size prefix override.
return IF_RWR_RRD_MRD;
case IF_RWR_RRD_ARD_CNS:
return IF_RWR_RRD_MRD_CNS;
+ case IF_RWR_RRD_ARD_RRD:
+ return IF_RWR_RRD_MRD_RRD;
case IF_ARD_RRD:
return IF_MRD_RRD;
emitHandleMemOp(indir, id, IF_RRW_ARD_CNS, ins);
- // Plus one for the 1-byte immediate (ival)
- UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins)) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins)) + 1;
+ UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival);
if (Is4ByteSSE4Instruction(ins))
{
id->idAddr()->iiaAddrMode.amBaseReg = base;
id->idAddr()->iiaAddrMode.amIndxReg = REG_NA;
- // Plus one for the 1-byte immediate (ival)
- UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins)) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins)) + 1;
+ UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival);
if (Is4ByteSSE4Instruction(ins))
{
noway_assert(emitVerifyEncodable(ins, EA_SIZE(attr), reg1));
assert(IsSSEOrAVXInstruction(ins));
- instrDesc* id = emitNewInstrCnsDsp(attr, ival, offs);
- UNATIVE_OFFSET sz = emitInsSizeCV(id, insCodeRM(ins)) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins)) + 1;
+ instrDesc* id = emitNewInstrCnsDsp(attr, ival, offs);
+
+ id->idIns(ins);
+ id->idInsFmt(IF_RRW_MRD_CNS);
+ id->idReg1(reg1);
+ id->idAddr()->iiaFieldHnd = fldHnd;
+
+ UNATIVE_OFFSET sz = emitInsSizeCV(id, insCodeRM(ins), ival);
if (Is4ByteSSE4Instruction(ins))
{
sz += 2;
}
- id->idIns(ins);
- id->idInsFmt(IF_RRW_MRD_CNS);
- id->idReg1(reg1);
- id->idAddr()->iiaFieldHnd = fldHnd;
-
id->idCodeSize(sz);
+
dispIns(id);
emitCurIGsize += sz;
}
noway_assert(emitVerifyEncodable(ins, EA_SIZE(attr), reg1));
assert(IsSSEOrAVXInstruction(ins));
- instrDesc* id = emitNewInstrCns(attr, ival);
- UNATIVE_OFFSET sz =
- emitInsSizeSV(insCodeRM(ins), varx, offs) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins)) + 1;
-
- if (Is4ByteSSE4Instruction(ins))
- {
- // The 4-Byte SSE4 instructions require two additional bytes
- sz += 2;
- }
+ instrDesc* id = emitNewInstrCns(attr, ival);
id->idIns(ins);
id->idInsFmt(IF_RRW_SRD_CNS);
id->idDebugOnlyInfo()->idVarRefOffs = emitVarRefOffs;
#endif
+ UNATIVE_OFFSET sz = emitInsSizeSV(id, insCodeRM(ins), varx, offs, ival);
+
+ if (Is4ByteSSE4Instruction(ins))
+ {
+ // The 4-Byte SSE4 instructions require two additional bytes
+ sz += 2;
+ }
+
id->idCodeSize(sz);
dispIns(id);
emitHandleMemOp(indir, id, IF_RWR_RRD_ARD, ins);
- UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins)) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins));
+ UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins));
id->idCodeSize(sz);
dispIns(id);
id->idAddr()->iiaAddrMode.amBaseReg = base;
id->idAddr()->iiaAddrMode.amIndxReg = REG_NA;
- UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins)) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins));
+ UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins));
id->idCodeSize(sz);
dispIns(id);
}
instrDesc* id = emitNewInstrDsp(attr, offs);
- UNATIVE_OFFSET sz = emitInsSizeCV(id, insCodeRM(ins)) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins));
+ UNATIVE_OFFSET sz = emitInsSizeCV(id, insCodeRM(ins));
id->idIns(ins);
id->idInsFmt(IF_RWR_RRD_MRD);
assert(IsSSEOrAVXInstruction(ins));
assert(IsThreeOperandAVXInstruction(ins));
- instrDesc* id = emitNewInstr(attr);
- UNATIVE_OFFSET sz =
- emitInsSizeSV(insCodeRM(ins), varx, offs) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins));
+ instrDesc* id = emitNewInstr(attr);
id->idIns(ins);
id->idInsFmt(IF_RWR_RRD_SRD);
id->idDebugOnlyInfo()->idVarRefOffs = emitVarRefOffs;
#endif
+ UNATIVE_OFFSET sz = emitInsSizeSV(id, insCodeRM(ins), varx, offs);
id->idCodeSize(sz);
+
dispIns(id);
emitCurIGsize += sz;
}
emitHandleMemOp(indir, id, fmt, ins);
- UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins)) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins)) + 1;
+ UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival);
id->idCodeSize(sz);
dispIns(id);
id->idAddr()->iiaAddrMode.amBaseReg = base;
id->idAddr()->iiaAddrMode.amIndxReg = REG_NA;
- // Plus one for the 1-byte immediate (ival)
- UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins)) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins)) + 1;
+ UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival);
id->idCodeSize(sz);
dispIns(id);
attr = EA_SET_FLG(attr, EA_DSP_RELOC_FLG);
}
- instrDesc* id = emitNewInstrCnsDsp(attr, ival, offs);
- UNATIVE_OFFSET sz = emitInsSizeCV(id, insCodeRM(ins)) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins)) + 1;
+ instrDesc* id = emitNewInstrCnsDsp(attr, ival, offs);
id->idIns(ins);
id->idInsFmt(IF_RWR_RRD_MRD_CNS);
id->idReg2(reg2);
id->idAddr()->iiaFieldHnd = fldHnd;
+ UNATIVE_OFFSET sz = emitInsSizeCV(id, insCodeRM(ins), ival);
id->idCodeSize(sz);
+
dispIns(id);
emitCurIGsize += sz;
}
assert(IsSSEOrAVXInstruction(ins));
assert(IsThreeOperandAVXInstruction(ins));
- instrDesc* id = emitNewInstrCns(attr, ival);
- UNATIVE_OFFSET sz =
- emitInsSizeSV(insCodeRM(ins), varx, offs) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeRM(ins)) + 1;
+ instrDesc* id = emitNewInstrCns(attr, ival);
id->idIns(ins);
id->idInsFmt(IF_RWR_RRD_SRD_CNS);
id->idDebugOnlyInfo()->idVarRefOffs = emitVarRefOffs;
#endif
+ UNATIVE_OFFSET sz = emitInsSizeSV(id, insCodeRM(ins), varx, offs, ival);
id->idCodeSize(sz);
+
+ dispIns(id);
+ emitCurIGsize += sz;
+}
+
+//------------------------------------------------------------------------
+// encodeXmmRegAsIval: Encodes a XMM register into imm[7:4] for use by a SIMD instruction
+//
+// Arguments
+// opReg -- The register being encoded
+//
+// Returns:
+// opReg encoded in imm[7:4]
+static int encodeXmmRegAsIval(regNumber opReg)
+{
+ assert(opReg >= XMMBASE);
+ // AVX/AVX2 supports 4-reg format for vblendvps/vblendvpd/vpblendvb,
+ // which encodes the fourth register into imm8[7:4]
+ return (opReg - XMMBASE) << 4;
+}
+
+//------------------------------------------------------------------------
+// emitIns_R_R_A_R: emits the code for an instruction that takes a register operand, a GenTreeIndir address,
+// another register operand, and that returns a value in register
+//
+// Arguments:
+// ins -- The instruction being emitted
+// attr -- The emit attribute
+// targetReg -- The target register
+// op1Reg -- The register of the first operand
+// op3Reg -- The register of the third operand
+// indir -- The GenTreeIndir used for the memory address
+//
+// Remarks:
+// op2 is built from indir
+//
+void emitter::emitIns_R_R_A_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, GenTreeIndir* indir)
+{
+ assert(isAvxBlendv(ins));
+ assert(UseVEXEncoding());
+
+ int ival = encodeXmmRegAsIval(op3Reg);
+ ssize_t offs = indir->Offset();
+ instrDesc* id = emitNewInstrAmdCns(attr, offs, ival);
+
+ id->idIns(ins);
+ id->idReg1(targetReg);
+ id->idReg2(op1Reg);
+
+ emitHandleMemOp(indir, id, IF_RWR_RRD_ARD_RRD, ins);
+
+ UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival);
+ id->idCodeSize(sz);
+
+ dispIns(id);
+ emitCurIGsize += sz;
+}
+
+//------------------------------------------------------------------------
+// emitIns_R_R_AR_R: emits the code for an instruction that takes a register operand, a base memory
+// register, another register operand, and that returns a value in register
+//
+// Arguments:
+// ins -- The instruction being emitted
+// attr -- The emit attribute
+// targetReg -- The target register
+// op1Reg -- The register of the first operands
+// op3Reg -- The register of the third operand
+// base -- The base register used for the memory address
+// offs -- The offset added to the memory address from base
+//
+// Remarks:
+// op2 is built from base + offs
+//
+void emitter::emitIns_R_R_AR_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, regNumber base, int offs)
+{
+ assert(isAvxBlendv(ins));
+ assert(UseVEXEncoding());
+
+ int ival = encodeXmmRegAsIval(op3Reg);
+ instrDesc* id = emitNewInstrAmdCns(attr, offs, ival);
+
+ id->idIns(ins);
+ id->idReg1(targetReg);
+ id->idReg2(op1Reg);
+
+ id->idInsFmt(IF_RWR_RRD_ARD_RRD);
+ id->idAddr()->iiaAddrMode.amBaseReg = base;
+ id->idAddr()->iiaAddrMode.amIndxReg = REG_NA;
+
+ UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival);
+ id->idCodeSize(sz);
+
+ dispIns(id);
+ emitCurIGsize += sz;
+}
+
+//------------------------------------------------------------------------
+// emitIns_R_R_C_R: emits the code for an instruction that takes a register operand, a field handle +
+// offset, another register operand, and that returns a value in register
+//
+// Arguments:
+// ins -- The instruction being emitted
+// attr -- The emit attribute
+// targetReg -- The target register
+// op1Reg -- The register of the first operand
+// op3Reg -- The register of the third operand
+// fldHnd -- The CORINFO_FIELD_HANDLE used for the memory address
+// offs -- The offset added to the memory address from fldHnd
+//
+// Remarks:
+// op2 is built from fldHnd + offs
+//
+void emitter::emitIns_R_R_C_R(instruction ins,
+ emitAttr attr,
+ regNumber targetReg,
+ regNumber op1Reg,
+ regNumber op3Reg,
+ CORINFO_FIELD_HANDLE fldHnd,
+ int offs)
+{
+ assert(isAvxBlendv(ins));
+ assert(UseVEXEncoding());
+
+ // Static always need relocs
+ if (!jitStaticFldIsGlobAddr(fldHnd))
+ {
+ attr = EA_SET_FLG(attr, EA_DSP_RELOC_FLG);
+ }
+
+ int ival = encodeXmmRegAsIval(op3Reg);
+ instrDesc* id = emitNewInstrCnsDsp(attr, ival, offs);
+
+ id->idIns(ins);
+ id->idReg1(targetReg);
+ id->idReg2(op1Reg);
+
+ id->idInsFmt(IF_RWR_RRD_MRD_RRD);
+ id->idAddr()->iiaFieldHnd = fldHnd;
+
+ UNATIVE_OFFSET sz = emitInsSizeCV(id, insCodeRM(ins), ival);
+ id->idCodeSize(sz);
+
+ dispIns(id);
+ emitCurIGsize += sz;
+}
+
+//------------------------------------------------------------------------
+// emitIns_R_R_R_S: emits the code for a instruction that takes a register operand, a variable index +
+// offset, another register operand, and that returns a value in register
+//
+// Arguments:
+// ins -- The instruction being emitted
+// attr -- The emit attribute
+// targetReg -- The target register
+// op1Reg -- The register of the first operand
+// op3Reg -- The register of the third operand
+// varx -- The variable index used for the memory address
+// offs -- The offset added to the memory address from varx
+//
+// Remarks:
+// op2 is built from varx + offs
+//
+void emitter::emitIns_R_R_S_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, int varx, int offs)
+{
+ assert(isAvxBlendv(ins));
+ assert(UseVEXEncoding());
+
+ int ival = encodeXmmRegAsIval(op3Reg);
+ instrDesc* id = emitNewInstrCns(attr, ival);
+
+ id->idIns(ins);
+ id->idReg1(targetReg);
+ id->idReg2(op1Reg);
+
+ id->idInsFmt(IF_RWR_RRD_SRD_RRD);
+ id->idAddr()->iiaLclVar.initLclVarAddr(varx, offs);
+
+ UNATIVE_OFFSET sz = emitInsSizeSV(id, insCodeRM(ins), varx, offs, ival);
+ id->idCodeSize(sz);
+
dispIns(id);
emitCurIGsize += sz;
}
// TODO-XArch-CQ: We should create function which can calculate all kinds of AVX instructions size in future
UNATIVE_OFFSET sz = 6;
- // AVX/AVX2 supports 4-reg format for vblendvps/vblendvpd/vpblendvb,
- // which encodes the fourth register into imm8[7:4]
- int ival = (reg3 - XMMBASE) << 4; // convert reg3 to ival
+ int ival = encodeXmmRegAsIval(reg3);
+ instrDesc* id = emitNewInstrCns(attr, ival);
- instrDesc* id = emitNewInstrCns(attr, ival);
id->idIns(ins);
id->idInsFmt(IF_RWR_RRD_RRD_RRD);
id->idReg1(targetReg);
id->idjNext = emitCurIGjmpList;
emitCurIGjmpList = id;
- UNATIVE_OFFSET sz = sizeof(INT32) + emitInsSizeSV(insCodeMI(ins), varx, offs);
+ UNATIVE_OFFSET sz = sizeof(INT32) + emitInsSizeSV(id, insCodeMI(ins), varx, offs);
id->dstLclVar.initLclVarAddr(varx, offs);
#ifdef DEBUG
id->idDebugOnlyInfo()->idVarRefOffs = emitVarRefOffs;
assert(emitGetInsAmdAny(id) == disp); // make sure "disp" is stored properly
- // Plus one for the 1-byte immediate (ival)
- UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeMR(ins)) + emitGetVexPrefixAdjustedSize(ins, attr, insCodeMR(ins)) + 1;
+ UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeMR(ins), ival);
id->idCodeSize(sz);
dispIns(id);
}
if (op1Reg != targetReg)
{
- // Ensure we aren't overwriting op2 or op3
+ // Ensure we aren't overwriting op2 or oop3 (which should be REG_XMM0)
assert(op2Reg != targetReg);
- assert(op3Reg != targetReg);
+ assert(targetReg != REG_XMM0);
emitIns_R_R(INS_movaps, attr, targetReg, op1Reg);
}
emitIns_R_R_S(ins, attr, targetReg, op2Reg, varx, offs);
}
+
+//------------------------------------------------------------------------
+// emitIns_SIMD_R_R_A_R: emits the code for a SIMD instruction that takes a register operand, a GenTreeIndir address,
+// another register operand, and that returns a value in register
+//
+// Arguments:
+// ins -- The instruction being emitted
+// attr -- The emit attribute
+// targetReg -- The target register
+// op1Reg -- The register of the first operand
+// op3Reg -- The register of the third operand
+// indir -- The GenTreeIndir used for the memory address
+//
+void emitter::emitIns_SIMD_R_R_A_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, GenTreeIndir* indir)
+{
+ if (UseVEXEncoding())
+ {
+ assert(isAvxBlendv(ins) || isSse41Blendv(ins));
+
+ // convert SSE encoding of SSE4.1 instructions to VEX encoding
+ switch (ins)
+ {
+ case INS_blendvps:
+ {
+ ins = INS_vblendvps;
+ break;
+ }
+
+ case INS_blendvpd:
+ {
+ ins = INS_vblendvpd;
+ break;
+ }
+
+ case INS_pblendvb:
+ {
+ ins = INS_vpblendvb;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ emitIns_R_R_A_R(ins, attr, targetReg, op1Reg, op3Reg, indir);
+ }
+ else
+ {
+ assert(isSse41Blendv(ins));
+
+ // SSE4.1 blendv* hardcode the mask vector (op3) in XMM0
+ if (op3Reg != REG_XMM0)
+ {
+ // Ensure we aren't overwriting op1
+ assert(op1Reg != REG_XMM0);
+
+ emitIns_R_R(INS_movaps, attr, REG_XMM0, op3Reg);
+ }
+ if (op1Reg != targetReg)
+ {
+ // Ensure we aren't overwriting op3 (which should be REG_XMM0)
+ assert(targetReg != REG_XMM0);
+
+ emitIns_R_R(INS_movaps, attr, targetReg, op1Reg);
+ }
+
+ emitIns_R_A(ins, attr, targetReg, indir);
+ }
+}
+
+//------------------------------------------------------------------------
+// emitIns_SIMD_R_R_AR_R: emits the code for a SIMD instruction that takes a register operand, a base memory
+// register, another register operand, and that returns a value in register
+//
+// Arguments:
+// ins -- The instruction being emitted
+// attr -- The emit attribute
+// targetReg -- The target register
+// op1Reg -- The register of the first operands
+// op3Reg -- The register of the third operand
+// base -- The base register used for the memory address
+//
+void emitter::emitIns_SIMD_R_R_AR_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, regNumber base)
+{
+ if (UseVEXEncoding())
+ {
+ assert(isAvxBlendv(ins) || isSse41Blendv(ins));
+
+ // convert SSE encoding of SSE4.1 instructions to VEX encoding
+ switch (ins)
+ {
+ case INS_blendvps:
+ {
+ ins = INS_vblendvps;
+ break;
+ }
+
+ case INS_blendvpd:
+ {
+ ins = INS_vblendvpd;
+ break;
+ }
+
+ case INS_pblendvb:
+ {
+ ins = INS_vpblendvb;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ emitIns_R_R_AR_R(ins, attr, targetReg, op1Reg, op3Reg, base, 0);
+ }
+ else
+ {
+ assert(isSse41Blendv(ins));
+
+ // SSE4.1 blendv* hardcode the mask vector (op3) in XMM0
+ if (op3Reg != REG_XMM0)
+ {
+ // Ensure we aren't overwriting op1
+ assert(op1Reg != REG_XMM0);
+
+ emitIns_R_R(INS_movaps, attr, REG_XMM0, op3Reg);
+ }
+ if (op1Reg != targetReg)
+ {
+ // Ensure we aren't overwriting op3 (which should be REG_XMM0)
+ assert(targetReg != REG_XMM0);
+
+ emitIns_R_R(INS_movaps, attr, targetReg, op1Reg);
+ }
+
+ emitIns_R_AR(ins, attr, targetReg, base, 0);
+ }
+}
+
+//------------------------------------------------------------------------
+// emitIns_SIMD_R_R_C_R: emits the code for a SIMD instruction that takes a register operand, a field handle +
+// offset, another register operand, and that returns a value in register
+//
+// Arguments:
+// ins -- The instruction being emitted
+// attr -- The emit attribute
+// targetReg -- The target register
+// op1Reg -- The register of the first operand
+// op3Reg -- The register of the third operand
+// fldHnd -- The CORINFO_FIELD_HANDLE used for the memory address
+// offs -- The offset added to the memory address from fldHnd
+//
+void emitter::emitIns_SIMD_R_R_C_R(instruction ins,
+ emitAttr attr,
+ regNumber targetReg,
+ regNumber op1Reg,
+ regNumber op3Reg,
+ CORINFO_FIELD_HANDLE fldHnd,
+ int offs)
+{
+ if (UseVEXEncoding())
+ {
+ assert(isAvxBlendv(ins) || isSse41Blendv(ins));
+
+ // convert SSE encoding of SSE4.1 instructions to VEX encoding
+ switch (ins)
+ {
+ case INS_blendvps:
+ {
+ ins = INS_vblendvps;
+ break;
+ }
+
+ case INS_blendvpd:
+ {
+ ins = INS_vblendvpd;
+ break;
+ }
+
+ case INS_pblendvb:
+ {
+ ins = INS_vpblendvb;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ emitIns_R_R_C_R(ins, attr, targetReg, op1Reg, op3Reg, fldHnd, offs);
+ }
+ else
+ {
+ assert(isSse41Blendv(ins));
+
+ // SSE4.1 blendv* hardcode the mask vector (op3) in XMM0
+ if (op3Reg != REG_XMM0)
+ {
+ // Ensure we aren't overwriting op1
+ assert(op1Reg != REG_XMM0);
+
+ emitIns_R_R(INS_movaps, attr, REG_XMM0, op3Reg);
+ }
+ if (op1Reg != targetReg)
+ {
+ // Ensure we aren't overwriting op3 (which should be REG_XMM0)
+ assert(targetReg != REG_XMM0);
+
+ emitIns_R_R(INS_movaps, attr, targetReg, op1Reg);
+ }
+
+ emitIns_R_C(ins, attr, targetReg, fldHnd, offs);
+ }
+}
+
+//------------------------------------------------------------------------
+// emitIns_SIMD_R_R_S_R: emits the code for a SIMD instruction that takes a register operand, a variable index +
+// offset, another register operand, and that returns a value in register
+//
+// Arguments:
+// ins -- The instruction being emitted
+// attr -- The emit attribute
+// targetReg -- The target register
+// op1Reg -- The register of the first operand
+// op3Reg -- The register of the third operand
+// varx -- The variable index used for the memory address
+// offs -- The offset added to the memory address from varx
+//
+void emitter::emitIns_SIMD_R_R_S_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, int varx, int offs)
+{
+ if (UseVEXEncoding())
+ {
+ assert(isAvxBlendv(ins) || isSse41Blendv(ins));
+
+ // convert SSE encoding of SSE4.1 instructions to VEX encoding
+ switch (ins)
+ {
+ case INS_blendvps:
+ {
+ ins = INS_vblendvps;
+ break;
+ }
+
+ case INS_blendvpd:
+ {
+ ins = INS_vblendvpd;
+ break;
+ }
+
+ case INS_pblendvb:
+ {
+ ins = INS_vpblendvb;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ emitIns_R_R_S_R(ins, attr, targetReg, op1Reg, op3Reg, varx, offs);
+ }
+ else
+ {
+ assert(isSse41Blendv(ins));
+
+ // SSE4.1 blendv* hardcode the mask vector (op3) in XMM0
+ if (op3Reg != REG_XMM0)
+ {
+ // Ensure we aren't overwriting op1
+ assert(op1Reg != REG_XMM0);
+
+ emitIns_R_R(INS_movaps, attr, REG_XMM0, op3Reg);
+ }
+ if (op1Reg != targetReg)
+ {
+ // Ensure we aren't overwriting op3 (which should be REG_XMM0)
+ assert(targetReg != REG_XMM0);
+
+ emitIns_R_R(INS_movaps, attr, targetReg, op1Reg);
+ }
+
+ emitIns_R_S(ins, attr, targetReg, varx, offs);
+ }
+}
#endif // FEATURE_HW_INTRINSICS
/*****************************************************************************
void emitter::emitIns_S(instruction ins, emitAttr attr, int varx, int offs)
{
instrDesc* id = emitNewInstr(attr);
- UNATIVE_OFFSET sz = emitInsSizeSV(insCodeMR(ins), varx, offs);
+ UNATIVE_OFFSET sz = emitInsSizeSV(id, insCodeMR(ins), varx, offs);
insFormat fmt = emitInsModeFormat(ins, IF_SRD);
// 16-bit operand instructions will need a prefix
void emitter::emitIns_S_R(instruction ins, emitAttr attr, regNumber ireg, int varx, int offs)
{
instrDesc* id = emitNewInstr(attr);
- UNATIVE_OFFSET sz = emitInsSizeSV(insCodeMR(ins), varx, offs);
+ UNATIVE_OFFSET sz = emitInsSizeSV(id, insCodeMR(ins), varx, offs);
insFormat fmt = emitInsModeFormat(ins, IF_SRD_RRD);
#ifdef _TARGET_X86_
noway_assert(emitVerifyEncodable(ins, size, ireg));
instrDesc* id = emitNewInstr(attr);
- UNATIVE_OFFSET sz = emitInsSizeSV(insCodeRM(ins), varx, offs);
+ UNATIVE_OFFSET sz = emitInsSizeSV(id, insCodeRM(ins), varx, offs);
insFormat fmt = emitInsModeFormat(ins, IF_RRD_SRD);
// Most 16-bit operand instructions need a prefix
instrDesc* id = emitNewInstrCns(attr, val);
id->idIns(ins);
id->idInsFmt(fmt);
- UNATIVE_OFFSET sz = emitInsSizeSV(id, varx, offs, val);
+ UNATIVE_OFFSET sz = emitInsSizeSV(id, insCodeMI(ins), varx, offs, val);
// VEX prefix
sz += emitGetVexPrefixAdjustedSize(ins, attr, insCodeMI(ins));
// disp is really a lclVarNum
noway_assert((unsigned)disp == (size_t)disp);
id->idAddr()->iiaLclVar.initLclVarAddr((unsigned)disp, 0);
- sz = emitInsSizeSV(insCodeMR(INS_call), (unsigned)disp, 0);
+ sz = emitInsSizeSV(id, insCodeMR(INS_call), (unsigned)disp, 0);
break;
break;
}
+ case IF_RWR_RRD_ARD_RRD:
+ {
+ printf("%s, ", emitRegName(id->idReg1(), attr));
+ printf("%s, ", emitRegName(id->idReg2(), attr));
+ emitDispAddrMode(id);
+
+ emitGetInsAmdCns(id, &cnsVal);
+ val = (cnsVal.cnsVal >> 4) + XMMBASE;
+ printf(", %s", emitRegName((regNumber)val, attr));
+ break;
+ }
+
case IF_ARD_RRD:
case IF_AWR_RRD:
case IF_ARW_RRD:
break;
}
+ case IF_RWR_RRD_SRD_RRD:
+ {
+ printf("%s, ", emitRegName(id->idReg1(), attr));
+ printf("%s, ", emitRegName(id->idReg2(), attr));
+ emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(),
+ id->idDebugOnlyInfo()->idVarRefOffs, asmfm);
+
+ emitGetInsCns(id, &cnsVal);
+ val = (cnsVal.cnsVal >> 4) + XMMBASE;
+ printf(", %s", emitRegName((regNumber)val, attr));
+ break;
+ }
+
case IF_RRD_RRD:
case IF_RWR_RRD:
case IF_RRW_RRD:
break;
}
+ case IF_RWR_RRD_MRD_RRD:
+ {
+ printf("%s, ", emitRegName(id->idReg1(), attr));
+ printf("%s, ", emitRegName(id->idReg2(), attr));
+
+ offs = emitGetInsDsp(id);
+ emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC);
+
+ emitGetInsDcmCns(id, &cnsVal);
+ val = (cnsVal.cnsVal >> 4) + XMMBASE;
+ printf(", %s", emitRegName((regNumber)val, attr));
+ break;
+ }
+
case IF_RWR_MRD_OFF:
printf("%s, %s", emitRegName(id->idReg1(), attr), "offset");
// Does the constant fit in a byte?
if ((signed char)cval == cval && addc->cnsReloc == false && ins != INS_mov && ins != INS_test)
{
- if (id->idInsFmt() != IF_SRW_SHF)
+ if ((id->idInsFmt() != IF_SRW_SHF) && (id->idInsFmt() != IF_RRW_SRD_CNS) &&
+ (id->idInsFmt() != IF_RWR_RRD_SRD_CNS))
{
code |= 2;
}
break;
case IF_RWR_RRD_ARD_CNS:
+ case IF_RWR_RRD_ARD_RRD:
{
emitGetInsAmdCns(id, &cnsVal);
code = insCodeRM(ins);
}
case IF_RWR_RRD_SRD_CNS:
+ case IF_RWR_RRD_SRD_RRD:
{
// This should only be called on AVX instructions
assert(IsAVXInstruction(ins));
regcode = (insEncodeReg345(ins, id->idReg1(), size, &code) << 8);
dst = emitOutputSV(dst, id, code | regcode, &cnsVal);
}
+
+ sz = emitSizeOfInsDsc(id);
break;
}
}
case IF_RWR_RRD_MRD_CNS:
+ case IF_RWR_RRD_MRD_RRD:
{
// This should only be called on AVX instructions
assert(IsAVXInstruction(ins));
UNATIVE_OFFSET emitInsSize(code_t code);
UNATIVE_OFFSET emitInsSizeRM(instruction ins);
UNATIVE_OFFSET emitInsSizeSV(code_t code, int var, int dsp);
-UNATIVE_OFFSET emitInsSizeSV(instrDesc* id, int var, int dsp, int val);
+UNATIVE_OFFSET emitInsSizeSV(instrDesc* id, code_t code, int var, int dsp);
+UNATIVE_OFFSET emitInsSizeSV(instrDesc* id, code_t code, int var, int dsp, int val);
UNATIVE_OFFSET emitInsSizeRR(instruction ins, regNumber reg1, regNumber reg2, emitAttr attr);
UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, code_t code);
UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, code_t code, int val);
void emitIns_R_R_S_I(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, int varx, int offs, int ival);
+void emitIns_R_R_A_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, GenTreeIndir* indir);
+
+void emitIns_R_R_AR_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, regNumber base, int offs);
+
+void emitIns_R_R_C_R(instruction ins,
+ emitAttr attr,
+ regNumber targetReg,
+ regNumber op1Reg,
+ regNumber op3Reg,
+ CORINFO_FIELD_HANDLE fldHnd,
+ int offs);
+
+void emitIns_R_R_S_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, int varx, int offs);
+
void emitIns_R_R_R_R(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber reg3, regNumber reg4);
void emitIns_S(instruction ins, emitAttr attr, int varx, int offs);
instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, regNumber op3Reg);
void emitIns_SIMD_R_R_R_S(
instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, int varx, int offs);
+
+void emitIns_SIMD_R_R_A_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTreeIndir* indir);
+void emitIns_SIMD_R_R_AR_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, regNumber base);
+void emitIns_SIMD_R_R_C_R(instruction ins,
+ emitAttr attr,
+ regNumber targetReg,
+ regNumber op1Reg,
+ regNumber op2Reg,
+ CORINFO_FIELD_HANDLE fldHnd,
+ int offs);
+void emitIns_SIMD_R_R_S_R(
+ instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, int varx, int offs);
#endif // FEATURE_HW_INTRINSICS
enum EmitCallType
else if ((ival != -1) && varTypeIsFloating(baseType))
{
assert((ival >= 0) && (ival <= 127));
- genHWIntrinsic_R_RM_I(node, ins);
+ genHWIntrinsic_R_RM_I(node, ins, (int8_t)ival);
}
else
{
else if ((ival != -1) && varTypeIsFloating(baseType))
{
assert((ival >= 0) && (ival <= 127));
- genHWIntrinsic_R_R_RM_I(node, ins);
+ genHWIntrinsic_R_R_RM_I(node, ins, ival);
}
else if (category == HW_Category_MemoryLoad)
{
simdSize = emitTypeSize(TYP_INT);
}
- auto emitSwCase = [&](int8_t i) { emit->emitIns_SIMD_R_R_I(ins, simdSize, targetReg, op1Reg, i); };
+ auto emitSwCase = [&](int8_t i) { genHWIntrinsic_R_RM_I(node, ins, i); };
if (op2->IsCnsIntOrI())
{
{
assert(ival == -1);
- auto emitSwCase = [&](int8_t i) {
- emit->emitIns_SIMD_R_R_R_I(ins, simdSize, targetReg, op1Reg, op2Reg, i);
- };
+ auto emitSwCase = [&](int8_t i) { genHWIntrinsic_R_R_RM_I(node, ins, i); };
if (op3->IsCnsIntOrI())
{
ssize_t ival = op3->AsIntCon()->IconValue();
assert((ival >= 0) && (ival <= 255));
+
+ if ((intrinsicId == NI_SSE41_Insert) && (baseType == TYP_FLOAT))
+ {
+ // Bits 6 and 7 impact the index that is selected from op2
+ // when op2 is already in register. However, our API exposes
+ // op2 as a scalar and so bits 6 and 7 must be set to 0.
+ ival &= 0x3F;
+ }
+
emitSwCase((int8_t)ival);
}
else
{
+ if ((intrinsicId == NI_SSE41_Insert) && (baseType == TYP_FLOAT))
+ {
+ // Bits 6 and 7 impact the index that is selected from op2
+ // when op2 is already in register. However, our API exposes
+ // op2 as a scalar and so bits 6 and 7 must be set to 0.
+ emit->emitIns_R_I(INS_and, EA_1BYTE, op3Reg, 0x3F);
+ }
+
// We emit a fallback case for the scenario when the imm-op is not a constant. This should
// normally happen when the intrinsic is called indirectly, such as via Reflection. However, it
// can also occur if the consumer calls it directly and just doesn't pass a constant value.
}
else
{
- emit->emitIns_SIMD_R_R_R_R(ins, simdSize, targetReg, op1Reg, op2Reg, op3Reg);
+ switch (intrinsicId)
+ {
+ case NI_SSE41_BlendVariable:
+ case NI_AVX_BlendVariable:
+ case NI_AVX2_BlendVariable:
+ {
+ genHWIntrinsic_R_R_RM_R(node, ins);
+ break;
+ }
+
+ default:
+ {
+ unreached();
+ break;
+ };
+ }
}
break;
}
// Arguments:
// node - The hardware intrinsic node
// ins - The instruction being generated
+// ival - The immediate value
//
-void CodeGen::genHWIntrinsic_R_RM_I(GenTreeHWIntrinsic* node, instruction ins)
+void CodeGen::genHWIntrinsic_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, int8_t ival)
{
var_types targetType = node->TypeGet();
regNumber targetReg = node->gtRegNum;
emitAttr simdSize = EA_ATTR(node->gtSIMDSize);
emitter* emit = getEmitter();
- int ival = HWIntrinsicInfo::lookupIval(node->gtHWIntrinsicId);
- assert((ival >= 0) && (ival <= 127));
-
// TODO-XArch-CQ: Commutative operations can have op1 be contained
// TODO-XArch-CQ: Non-VEX encoded instructions can have both ops contained
assert(targetReg != REG_NA);
- assert(node->gtGetOp2() == nullptr); // The second operand is implicit and comes from lookupIval
- assert(!node->OperIsCommutative()); // One operand intrinsics cannot be commutative
+ assert(!node->OperIsCommutative()); // One operand intrinsics cannot be commutative
if (op1->isContained() || op1->isUsedFromSpillTemp())
{
else
{
regNumber op1Reg = op1->gtRegNum;
- emit->emitIns_R_R_I(ins, simdSize, targetReg, op1Reg, ival);
+ emit->emitIns_SIMD_R_R_I(ins, simdSize, targetReg, op1Reg, ival);
}
}
// Arguments:
// node - The hardware intrinsic node
// ins - The instruction being generated
+// ival - The immediate value
//
-void CodeGen::genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins)
+void CodeGen::genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, int8_t ival)
{
var_types targetType = node->TypeGet();
regNumber targetReg = node->gtRegNum;
emitAttr simdSize = EA_ATTR(node->gtSIMDSize);
emitter* emit = getEmitter();
- int ival = HWIntrinsicInfo::lookupIval(node->gtHWIntrinsicId);
- assert((ival >= 0) && (ival <= 127));
-
// TODO-XArch-CQ: Commutative operations can have op1 be contained
// TODO-XArch-CQ: Non-VEX encoded instructions can have both ops contained
+ if (op1->OperIsList())
+ {
+ assert(op2 == nullptr);
+
+ GenTreeArgList* argList = op1->AsArgList();
+
+ op1 = argList->Current();
+ argList = argList->Rest();
+
+ op2 = argList->Current();
+ argList = argList->Rest();
+
+ assert(argList->Current() != nullptr);
+ assert(argList->Rest() == nullptr);
+ }
+
regNumber op1Reg = op1->gtRegNum;
assert(targetReg != REG_NA);
}
}
+//------------------------------------------------------------------------
+// genHWIntrinsic_R_R_RM_R: Generates the code for a hardware intrinsic node that takes a register operand, a
+// register/memory operand, another register operand, and that returns a value in register
+//
+// Arguments:
+// node - The hardware intrinsic node
+// ins - The instruction being generated
+//
+void CodeGen::genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins)
+{
+ var_types targetType = node->TypeGet();
+ regNumber targetReg = node->gtRegNum;
+ GenTree* op1 = node->gtGetOp1();
+ GenTree* op2 = node->gtGetOp2();
+ GenTree* op3 = nullptr;
+ emitAttr simdSize = EA_ATTR(node->gtSIMDSize);
+ emitter* emit = getEmitter();
+
+ assert(op1->OperIsList());
+ assert(op2 == nullptr);
+
+ GenTreeArgList* argList = op1->AsArgList();
+
+ op1 = argList->Current();
+ argList = argList->Rest();
+
+ op2 = argList->Current();
+ argList = argList->Rest();
+
+ op3 = argList->Current();
+ assert(argList->Rest() == nullptr);
+
+ regNumber op1Reg = op1->gtRegNum;
+ regNumber op3Reg = op3->gtRegNum;
+
+ assert(targetReg != REG_NA);
+ assert(op1Reg != REG_NA);
+ assert(op3Reg != REG_NA);
+
+ if (op2->isContained() || op2->isUsedFromSpillTemp())
+ {
+ TempDsc* tmpDsc = nullptr;
+ unsigned varNum = BAD_VAR_NUM;
+ unsigned offset = (unsigned)-1;
+
+ if (op2->isUsedFromSpillTemp())
+ {
+ assert(op2->IsRegOptional());
+
+ // TODO-XArch-Cleanup: The getSpillTempDsc...tempRlsTemp code is a fairly common
+ // pattern. It could probably be extracted to its own method.
+ tmpDsc = getSpillTempDsc(op2);
+ varNum = tmpDsc->tdTempNum();
+ offset = 0;
+
+ compiler->tmpRlsTemp(tmpDsc);
+ }
+ else if (op2->OperIsHWIntrinsic())
+ {
+ emit->emitIns_SIMD_R_R_AR_R(ins, simdSize, targetReg, op1Reg, op2->gtGetOp1()->gtRegNum, op3Reg);
+ return;
+ }
+ else if (op2->isIndir())
+ {
+ GenTreeIndir* memIndir = op2->AsIndir();
+ GenTree* memBase = memIndir->gtOp1;
+
+ switch (memBase->OperGet())
+ {
+ case GT_LCL_VAR_ADDR:
+ {
+ varNum = memBase->AsLclVarCommon()->GetLclNum();
+ offset = 0;
+
+ // Ensure that all the GenTreeIndir values are set to their defaults.
+ assert(!memIndir->HasIndex());
+ assert(memIndir->Scale() == 1);
+ assert(memIndir->Offset() == 0);
+
+ break;
+ }
+
+ case GT_CLS_VAR_ADDR:
+ {
+ emit->emitIns_SIMD_R_R_C_R(ins, simdSize, targetReg, op1Reg, op3Reg, memBase->gtClsVar.gtClsVarHnd,
+ 0);
+ return;
+ }
+
+ default:
+ {
+ emit->emitIns_SIMD_R_R_A_R(ins, simdSize, targetReg, op1Reg, op3Reg, memIndir);
+ return;
+ }
+ }
+ }
+ else
+ {
+ switch (op2->OperGet())
+ {
+ case GT_LCL_FLD:
+ {
+ GenTreeLclFld* lclField = op2->AsLclFld();
+
+ varNum = lclField->GetLclNum();
+ offset = lclField->gtLclFld.gtLclOffs;
+ break;
+ }
+
+ case GT_LCL_VAR:
+ {
+ assert(op2->IsRegOptional() || !compiler->lvaTable[op2->gtLclVar.gtLclNum].lvIsRegCandidate());
+ varNum = op2->AsLclVar()->GetLclNum();
+ offset = 0;
+ break;
+ }
+
+ default:
+ unreached();
+ break;
+ }
+ }
+
+ // Ensure we got a good varNum and offset.
+ // We also need to check for `tmpDsc != nullptr` since spill temp numbers
+ // are negative and start with -1, which also happens to be BAD_VAR_NUM.
+ assert((varNum != BAD_VAR_NUM) || (tmpDsc != nullptr));
+ assert(offset != (unsigned)-1);
+
+ emit->emitIns_SIMD_R_R_S_R(ins, simdSize, targetReg, op1Reg, op3Reg, varNum, offset);
+ }
+ else
+ {
+ emit->emitIns_SIMD_R_R_R_R(ins, simdSize, targetReg, op1Reg, op2->gtRegNum, op3Reg);
+ }
+}
+
//------------------------------------------------------------------------
// genHWIntrinsic_R_R_R_RM: Generates the code for a hardware intrinsic node that takes two register operands,
// a register/memory operand, and that returns a value in register
//
void CodeGen::genLZCNTIntrinsic(GenTreeHWIntrinsic* node)
{
- NamedIntrinsic intrinsicId = node->gtHWIntrinsicId;
- GenTree* op1 = node->gtGetOp1();
- regNumber targetReg = node->gtRegNum;
- assert(targetReg != REG_NA);
- var_types targetType = node->TypeGet();
- regNumber op1Reg = op1->gtRegNum;
- genConsumeOperands(node);
-
- assert(intrinsicId == NI_LZCNT_LeadingZeroCount);
-
- inst_RV_RV(INS_lzcnt, targetReg, op1Reg, targetType, emitTypeSize(targetType));
+ assert(node->gtHWIntrinsicId == NI_LZCNT_LeadingZeroCount);
+ genConsumeOperands(node);
+ genHWIntrinsic_R_RM(node, INS_lzcnt, emitTypeSize(node->TypeGet()));
genProduceReg(node);
}
//
void CodeGen::genPOPCNTIntrinsic(GenTreeHWIntrinsic* node)
{
- NamedIntrinsic intrinsicId = node->gtHWIntrinsicId;
- GenTree* op1 = node->gtGetOp1();
- regNumber targetReg = node->gtRegNum;
- assert(targetReg != REG_NA);
- var_types targetType = node->TypeGet();
- regNumber op1Reg = op1->gtRegNum;
- genConsumeOperands(node);
-
- assert(intrinsicId == NI_POPCNT_PopCount);
-
- inst_RV_RV(INS_popcnt, targetReg, op1Reg, targetType, emitTypeSize(targetType));
+ assert(node->gtHWIntrinsicId == NI_POPCNT_PopCount);
+ genConsumeOperands(node);
+ genHWIntrinsic_R_RM(node, INS_popcnt, emitTypeSize(node->TypeGet()));
genProduceReg(node);
}
break;
}
}
+ break;
}
case HW_Category_SIMDScalar:
{
case HW_Category_SimpleSIMD:
case HW_Category_SIMDScalar:
+ case HW_Category_Scalar:
{
switch (intrinsicId)
{
default:
{
- // TODO-XArch-CQ: Assert that this is unreached after we have ensured the relevant node types are
- // handled.
- // https://github.com/dotnet/coreclr/issues/16497
+ unreached();
break;
}
}
break;
}
+ case HW_Category_IMM:
+ {
+ // We don't currently have any IMM intrinsics which are also commutative
+ assert(!isCommutative);
+ bool supportsRegOptional = false;
+
+ switch (intrinsicId)
+ {
+ case NI_SSE2_ShiftLeftLogical:
+ case NI_SSE2_ShiftRightArithmetic:
+ case NI_SSE2_ShiftRightLogical:
+ case NI_AVX2_ShiftLeftLogical:
+ case NI_AVX2_ShiftRightArithmetic:
+ case NI_AVX2_ShiftRightLogical:
+ {
+ // These intrinsics can have op2 be imm or reg/mem
+
+ if (!HWIntrinsicInfo::isImmOp(intrinsicId, op2))
+ {
+ if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
+ {
+ MakeSrcContained(node, op2);
+ }
+ else if (supportsRegOptional)
+ {
+ op2->SetRegOptional();
+ }
+ }
+ break;
+ }
+
+ case NI_SSE2_Shuffle:
+ case NI_SSE2_ShuffleHigh:
+ case NI_SSE2_ShuffleLow:
+ {
+ // These intrinsics have op2 as an imm and op1 as a reg/mem
+
+ if (IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional))
+ {
+ MakeSrcContained(node, op1);
+ }
+ else if (supportsRegOptional)
+ {
+ op1->SetRegOptional();
+ }
+ break;
+ }
+
+ case NI_AVX_Permute:
+ {
+ // These intrinsics can have op2 be imm or reg/mem
+ // They also can have op1 be reg/mem and op2 be imm
+
+ if (HWIntrinsicInfo::isImmOp(intrinsicId, op2))
+ {
+ if (IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional))
+ {
+ MakeSrcContained(node, op1);
+ }
+ else if (supportsRegOptional)
+ {
+ op1->SetRegOptional();
+ }
+ }
+ else if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
+ {
+ MakeSrcContained(node, op2);
+ }
+ else if (supportsRegOptional)
+ {
+ op2->SetRegOptional();
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case HW_Category_Special:
+ {
+ if (intrinsicId == NI_SSE2_CompareLessThan)
+ {
+ bool supportsRegOptional = false;
+
+ if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
+ {
+ MakeSrcContained(node, op2);
+ }
+ else if (supportsRegOptional)
+ {
+ op2->SetRegOptional();
+ }
+ }
+ else
+ {
+ unreached();
+ }
+ break;
+ }
+
default:
{
// TODO-XArch-CQ: Assert that this is unreached after we have ensured the relevant node types are
op3->SetRegOptional();
}
}
+ else
+ {
+ bool supportsRegOptional = false;
+
+ switch (intrinsicId)
+ {
+ case NI_SSE41_BlendVariable:
+ case NI_AVX_BlendVariable:
+ case NI_AVX2_BlendVariable:
+ {
+ if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
+ {
+ MakeSrcContained(node, op2);
+ }
+ else if (supportsRegOptional)
+ {
+ op2->SetRegOptional();
+ }
+ break;
+ }
+
+ default:
+ {
+ unreached();
+ break;
+ }
+ }
+ }
+ }
+
+ case HW_Category_IMM:
+ {
+ bool supportsRegOptional = false;
+
+ switch (intrinsicId)
+ {
+ case NI_SSE_Shuffle:
+ case NI_SSE2_Insert:
+ case NI_SSE2_Shuffle:
+ case NI_SSSE3_AlignRight:
+ case NI_SSE41_Blend:
+ case NI_SSE41_DotProduct:
+ case NI_SSE41_Insert:
+ case NI_SSE41_MultipleSumAbsoluteDifferences:
+ case NI_AVX_Blend:
+ case NI_AVX_Compare:
+ case NI_AVX_CompareScalar:
+ case NI_AVX_DotProduct:
+ case NI_AVX_Insert:
+ case NI_AVX_Permute2x128:
+ case NI_AVX_Shuffle:
+ case NI_AVX2_Permute2x128:
+ {
+ if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
+ {
+ MakeSrcContained(node, op2);
+ }
+ else if (supportsRegOptional)
+ {
+ op2->SetRegOptional();
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ break;
}
default:
{
- // TODO-XArch-CQ: Assert that this is unreached after we have ensured the relevant node types are
- // handled.
- // https://github.com/dotnet/coreclr/issues/16497
+ unreached();
break;
}
}
("SimpleUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Floor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(MathF.Floor(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(MathF.Floor(firstOp[i]))"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "FloorScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Floor(right[0]))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(left[i])"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "FloorScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["NextValueOp2"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(MathF.Floor(right[0]))", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(left[i])"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Byte", ["Data"] = "(byte)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(byte)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "SByte", ["Data"] = "(sbyte)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(int)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(uint)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Int64", ["Data"] = "(long)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(long)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "UInt64", ["Data"] = "(ulong)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(ulong)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "0", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)0", ["ValidateFirstResult"] = "(i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits((float)2) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits((float)0))"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Byte", ["Data"] = "(byte)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(byte)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "SByte", ["Data"] = "(sbyte)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(int)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(uint)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Int64", ["Data"] = "(long)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(long)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "UInt64", ["Data"] = "(ulong)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(ulong)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "217", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 2 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits((float)0))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "0", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Byte", ["Data"] = "(byte)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "SByte", ["Data"] = "(sbyte)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Int64", ["Data"] = "(long)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "UInt64", ["Data"] = "(ulong)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(0.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "2", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : i == 1 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(0.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "4", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : i == 2 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(0.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "8", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : i == 3 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(0.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 1 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 2 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "48", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 3 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "128", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Byte", ["Data"] = "(byte)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "SByte", ["Data"] = "(sbyte)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Int64", ["Data"] = "(long)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "UInt64", ["Data"] = "(ulong)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != firstOp[i])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(0.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Single", ["Data"] = "(float)2", ["Imm"] = "192", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i]))"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Max(left[i], right[i])"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Max(left[i], right[i])"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse41", ["LoadIsa"] = "Sse2", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != Math.Max(left[0], right[0])", ["ValidateRemainingResults"] = "result[i] != Math.Max(left[i], right[i])"}),
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
_dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits((float)2) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits((float)0)))
+ if ((i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
{
Succeeded = false;
break;
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle1()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle1();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle1
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle1();
+ var result = Sse41.Insert(test._fld, (float)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(0.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle128()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle128();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle128
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle128()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle128()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 128
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 128
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 128
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)128
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)128
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)128
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 128
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 128);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 128);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 128);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle128();
+ var result = Sse41.Insert(test._fld, (float)2, 128);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 128);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle129()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle129();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle129
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle129()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle129()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 129
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 129
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 129
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)129
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)129
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)129
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 129
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 129);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 129);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 129);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle129();
+ var result = Sse41.Insert(test._fld, (float)2, 129);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 129);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(0.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle16()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle16();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle16
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 16
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 16
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 16
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)16
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)16
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)16
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 16
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 16);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 16);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 16);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle16();
+ var result = Sse41.Insert(test._fld, (float)2, 16);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 16);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 1 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle192()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle192();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle192
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle192()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle192()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 192
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 192
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 192
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)192
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)192
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)192
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 192
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 192);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 192);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 192);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle192();
+ var result = Sse41.Insert(test._fld, (float)2, 192);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 192);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle2()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle2();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle2
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle2()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle2()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)2
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)2
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)2
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle2();
+ var result = Sse41.Insert(test._fld, (float)2, 2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : i == 1 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(0.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle32()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle32();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle32
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 32
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 32
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 32
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)32
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)32
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)32
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 32
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 32);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 32);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 32);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle32();
+ var result = Sse41.Insert(test._fld, (float)2, 32);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 32);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 2 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle4()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle4();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle4
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle4()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle4()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 4
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 4
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 4
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)4
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)4
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)4
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 4
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 4);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 4);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 4);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle4();
+ var result = Sse41.Insert(test._fld, (float)2, 4);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 4);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : i == 2 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(0.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle48()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle48();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle48
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle48()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle48()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 48
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 48
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 48
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)48
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)48
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)48
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 48
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 48);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 48);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 48);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle48();
+ var result = Sse41.Insert(test._fld, (float)2, 48);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 48);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 3 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle64()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle64();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle64
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 64
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 64
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 64
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)64
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)64
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)64
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 64
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 64);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 64);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 64);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle64();
+ var result = Sse41.Insert(test._fld, (float)2, 64);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 64);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertSingle8()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle8();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+ }
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+ }
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSingle8
+ {
+ private static readonly int LargestVectorSize = 16;
+
+ private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+ private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector128<Single> _clsVar;
+
+ private Vector128<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSingle8()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ }
+
+ public SimpleUnaryOpTest__InsertSingle8()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ }
+
+ public bool IsSupported => Sse41.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse41.Insert(
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ 8
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 8
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse41.Insert(
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ 8
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr),
+ (float)2,
+ (byte)8
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)8
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Single), typeof(byte) })
+ .Invoke(null, new object[] {
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr)),
+ (float)2,
+ (byte)8
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse41.Insert(
+ _clsVar,
+ (float)2,
+ 8
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
+ var result = Sse41.Insert(firstOp, (float)2, 8);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 8);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
+ var result = Sse41.Insert(firstOp, (float)2, 8);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSingle8();
+ var result = Sse41.Insert(test._fld, (float)2, 8);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse41.Insert(_fld, (float)2, 8);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 0 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(2.0f) : i == 3 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(0.0f) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
{
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
}
var random = new Random();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
_dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], LargestVectorSize);
}
for (var i = 0; i < RetElementCount; i++)
{
- if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
{
Succeeded = false;
break;
["Floor.Single"] = FloorSingle,
["FloorScalar.Double"] = FloorScalarDouble,
["FloorScalar.Single"] = FloorScalarSingle,
+ ["Insert.Single.0"] = InsertSingle0,
["Insert.Byte.1"] = InsertByte1,
["Insert.SByte.1"] = InsertSByte1,
["Insert.Int32.1"] = InsertInt321,
["Insert.UInt32.1"] = InsertUInt321,
["Insert.Int64.1"] = InsertInt641,
["Insert.UInt64.1"] = InsertUInt641,
- ["Insert.Single.0"] = InsertSingle0,
+ ["Insert.Single.1"] = InsertSingle1,
+ ["Insert.Single.2"] = InsertSingle2,
+ ["Insert.Single.4"] = InsertSingle4,
+ ["Insert.Single.8"] = InsertSingle8,
+ ["Insert.Single.16"] = InsertSingle16,
+ ["Insert.Single.32"] = InsertSingle32,
+ ["Insert.Single.48"] = InsertSingle48,
+ ["Insert.Single.64"] = InsertSingle64,
+ ["Insert.Single.128"] = InsertSingle128,
["Insert.Byte.129"] = InsertByte129,
["Insert.SByte.129"] = InsertSByte129,
["Insert.Int32.129"] = InsertInt32129,
["Insert.UInt32.129"] = InsertUInt32129,
["Insert.Int64.129"] = InsertInt64129,
["Insert.UInt64.129"] = InsertUInt64129,
- ["Insert.Single.217"] = InsertSingle217,
+ ["Insert.Single.129"] = InsertSingle129,
+ ["Insert.Single.192"] = InsertSingle192,
["Max.Int32"] = MaxInt32,
["Max.SByte"] = MaxSByte,
["Max.UInt16"] = MaxUInt16,
<Compile Include="Extract.Int64.129.cs" />
<Compile Include="Extract.UInt64.129.cs" />
<Compile Include="Extract.Single.129.cs" />
+ <Compile Include="Insert.Single.0.cs" />
<Compile Include="Insert.Byte.1.cs" />
<Compile Include="Insert.SByte.1.cs" />
<Compile Include="Insert.Int32.1.cs" />
<Compile Include="Insert.UInt32.1.cs" />
<Compile Include="Insert.Int64.1.cs" />
<Compile Include="Insert.UInt64.1.cs" />
- <Compile Include="Insert.Single.0.cs" />
+ <Compile Include="Insert.Single.1.cs" />
+ <Compile Include="Insert.Single.2.cs" />
+ <Compile Include="Insert.Single.4.cs" />
+ <Compile Include="Insert.Single.8.cs" />
+ <Compile Include="Insert.Single.16.cs" />
+ <Compile Include="Insert.Single.32.cs" />
+ <Compile Include="Insert.Single.48.cs" />
+ <Compile Include="Insert.Single.64.cs" />
+ <Compile Include="Insert.Single.128.cs" />
<Compile Include="Insert.Byte.129.cs" />
<Compile Include="Insert.SByte.129.cs" />
<Compile Include="Insert.Int32.129.cs" />
<Compile Include="Insert.UInt32.129.cs" />
<Compile Include="Insert.Int64.129.cs" />
<Compile Include="Insert.UInt64.129.cs" />
- <Compile Include="Insert.Single.217.cs" />
+ <Compile Include="Insert.Single.129.cs" />
+ <Compile Include="Insert.Single.192.cs" />
<Compile Include="Program.Sse41.cs" />
<Compile Include="..\Shared\BooleanUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\BooleanBinOpTest_DataTable.cs" />
<Compile Include="Extract.Int64.129.cs" />
<Compile Include="Extract.UInt64.129.cs" />
<Compile Include="Extract.Single.129.cs" />
+ <Compile Include="Insert.Single.0.cs" />
<Compile Include="Insert.Byte.1.cs" />
<Compile Include="Insert.SByte.1.cs" />
<Compile Include="Insert.Int32.1.cs" />
<Compile Include="Insert.UInt32.1.cs" />
<Compile Include="Insert.Int64.1.cs" />
<Compile Include="Insert.UInt64.1.cs" />
- <Compile Include="Insert.Single.0.cs" />
+ <Compile Include="Insert.Single.1.cs" />
+ <Compile Include="Insert.Single.2.cs" />
+ <Compile Include="Insert.Single.4.cs" />
+ <Compile Include="Insert.Single.8.cs" />
+ <Compile Include="Insert.Single.16.cs" />
+ <Compile Include="Insert.Single.32.cs" />
+ <Compile Include="Insert.Single.48.cs" />
+ <Compile Include="Insert.Single.64.cs" />
+ <Compile Include="Insert.Single.128.cs" />
<Compile Include="Insert.Byte.129.cs" />
<Compile Include="Insert.SByte.129.cs" />
<Compile Include="Insert.Int32.129.cs" />
<Compile Include="Insert.UInt32.129.cs" />
<Compile Include="Insert.Int64.129.cs" />
<Compile Include="Insert.UInt64.129.cs" />
- <Compile Include="Insert.Single.217.cs" />
+ <Compile Include="Insert.Single.129.cs" />
+ <Compile Include="Insert.Single.192.cs" />
<Compile Include="Program.Sse41.cs" />
<Compile Include="..\Shared\BooleanUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\BooleanBinOpTest_DataTable.cs" />