X86VectorVTInfo< 2, EltVT64, VR128X>,
X86VectorVTInfo< 4, EltVT64, VR256X>,
null_frag, vinsert128_insert, sched>,
- VEX_W, EVEX_V256;
+ VEX_W1X, EVEX_V256;
// Even with DQI we'd like to only use these instructions for masking.
let Predicates = [HasDQI] in {
X86VectorVTInfo< 4, EltVT64, VR256X>,
X86VectorVTInfo< 2, EltVT64, VR128X>,
null_frag, vextract128_extract, SchedRR, SchedMR>,
- VEX_W, EVEX_V256, EVEX_CD8<64, CD8VT2>;
+ VEX_W1X, EVEX_V256, EVEX_CD8<64, CD8VT2>;
// Even with DQI we'd like to only use these instructions for masking.
let Predicates = [HasDQI] in {
defm VBROADCASTSS : avx512_fp_broadcast_ss<0x18, "vbroadcastss",
avx512vl_f32_info>;
defm VBROADCASTSD : avx512_fp_broadcast_sd<0x19, "vbroadcastsd",
- avx512vl_f64_info>, VEX_W;
+ avx512vl_f64_info>, VEX_W1X;
multiclass avx512_int_broadcast_reg<bits<8> opc, SchedWrite SchedRR,
X86VectorVTInfo _, SDPatternOperator OpNode,
defm VPBROADCASTD : avx512_int_broadcast_rm_vl<0x58, "vpbroadcastd",
avx512vl_i32_info, HasAVX512>;
defm VPBROADCASTQ : avx512_int_broadcast_rm_vl<0x59, "vpbroadcastq",
- avx512vl_i64_info, HasAVX512>, VEX_W;
+ avx512vl_i64_info, HasAVX512>, VEX_W1X;
multiclass avx512_subvec_broadcast_rm<bits<8> opc, string OpcodeStr,
X86VectorVTInfo _Dst, X86VectorVTInfo _Src> {
let Predicates = [HasVLX, HasDQI] in {
defm VBROADCASTI64X2Z128 : avx512_subvec_broadcast_rm_dq<0x5a, "vbroadcasti64x2",
- v4i64x_info, v2i64x_info>, VEX_W,
+ v4i64x_info, v2i64x_info>, VEX_W1X,
EVEX_V256, EVEX_CD8<64, CD8VT2>;
defm VBROADCASTF64X2Z128 : avx512_subvec_broadcast_rm_dq<0x1a, "vbroadcastf64x2",
- v4f64x_info, v2f64x_info>, VEX_W,
+ v4f64x_info, v2f64x_info>, VEX_W1X,
EVEX_V256, EVEX_CD8<64, CD8VT2>;
// Patterns for selects of bitcasted operations.
avx512vl_i32_info>;
let ExeDomain = SSEPackedDouble in
defm VPERMILPD : avx512_permil<"vpermilpd", 0x05, 0x0D, avx512vl_f64_info,
- avx512vl_i64_info>, VEX_W;
+ avx512vl_i64_info>, VEX_W1X;
//===----------------------------------------------------------------------===//
// AVX-512 - VPSHUFD, VPSHUFLW, VPSHUFHW
{"VMOVDQU16Z256rr", "VMOVDQUYrr", false},
{"VMOVDQU16Z256rr_REV", "VMOVDQUYrr_REV", false},
- {"VPERMILPDZ128mi", "VPERMILPDmi", true},
- {"VPERMILPDZ128ri", "VPERMILPDri", true},
- {"VPERMILPDZ128rm", "VPERMILPDrm", true},
- {"VPERMILPDZ128rr", "VPERMILPDrr", true},
- {"VPERMILPDZ256mi", "VPERMILPDYmi", false},
- {"VPERMILPDZ256ri", "VPERMILPDYri", false},
- {"VPERMILPDZ256rm", "VPERMILPDYrm", false},
- {"VPERMILPDZ256rr", "VPERMILPDYrr", false},
-
- {"VPBROADCASTQZ128m", "VPBROADCASTQrm", true},
- {"VPBROADCASTQZ128r", "VPBROADCASTQrr", true},
- {"VPBROADCASTQZ256m", "VPBROADCASTQYrm", false},
- {"VPBROADCASTQZ256r", "VPBROADCASTQYrr", false},
-
- {"VBROADCASTSDZ256m", "VBROADCASTSDYrm", false},
- {"VBROADCASTSDZ256r", "VBROADCASTSDYrr", false},
-
- {"VBROADCASTF64X2Z128rm", "VBROADCASTF128", false},
- {"VBROADCASTI64X2Z128rm", "VBROADCASTI128", false},
-
- {"VEXTRACTF64x2Z256mr", "VEXTRACTF128mr", false},
- {"VEXTRACTF64x2Z256rr", "VEXTRACTF128rr", false},
- {"VEXTRACTI64x2Z256mr", "VEXTRACTI128mr", false},
- {"VEXTRACTI64x2Z256rr", "VEXTRACTI128rr", false},
-
- {"VINSERTF64x2Z256rm", "VINSERTF128rm", false},
- {"VINSERTF64x2Z256rr", "VINSERTF128rr", false},
- {"VINSERTI64x2Z256rm", "VINSERTI128rm", false},
- {"VINSERTI64x2Z256rr", "VINSERTI128rr", false},
-
// These will require some custom adjustment in the conversion pass.
{"VALIGNDZ128rri", "VPALIGNRrri", true},
{"VALIGNQZ128rri", "VPALIGNRrri", true},
{"VSHUFI32X4Z256rri", "VPERM2I128rr", false},
{"VSHUFI64X2Z256rmi", "VPERM2I128rm", false},
{"VSHUFI64X2Z256rri", "VPERM2I128rr", false},
-
- // These can be replaced if we verify the scale part of the immediate is
- // zero.
- {"VRNDSCALEPDZ128rri", "VROUNDPDr", true},
- {"VRNDSCALEPDZ128rmi", "VROUNDPDm", true},
- {"VRNDSCALEPSZ128rri", "VROUNDPSr", true},
- {"VRNDSCALEPSZ128rmi", "VROUNDPSm", true},
- {"VRNDSCALEPDZ256rri", "VROUNDPDYr", false},
- {"VRNDSCALEPDZ256rmi", "VROUNDPDYm", false},
- {"VRNDSCALEPSZ256rri", "VROUNDPSYr", false},
- {"VRNDSCALEPSZ256rmi", "VROUNDPSYm", false},
- {"VRNDSCALESDZr", "VROUNDSDr", true},
- {"VRNDSCALESDZm", "VROUNDSDm", true},
- {"VRNDSCALESSZr", "VROUNDSSr", true},
- {"VRNDSCALESSZm", "VROUNDSSm", true},
- {"VRNDSCALESDZr_Int", "VROUNDSDr_Int", true},
- {"VRNDSCALESDZm_Int", "VROUNDSDm_Int", true},
- {"VRNDSCALESSZr_Int", "VROUNDSSr_Int", true},
- {"VRNDSCALESSZm_Int", "VROUNDSSm_Int", true},
};
// Print the manually added entries
// Function object - Operator() returns true if the given VEX instruction
// matches the EVEX instruction of this object.
class IsMatch {
- const CodeGenInstruction *Inst;
+ const CodeGenInstruction *EVEXInst;
public:
- IsMatch(const CodeGenInstruction *Inst) : Inst(Inst) {}
+ IsMatch(const CodeGenInstruction *EVEXInst) : EVEXInst(EVEXInst) {}
- bool operator()(const CodeGenInstruction *Inst2) {
- Record *Rec1 = Inst->TheDef;
- Record *Rec2 = Inst2->TheDef;
- uint64_t Rec1WVEX =
- getValueFromBitsInit(Rec1->getValueAsBitsInit("VEX_WPrefix"));
- uint64_t Rec2WVEX =
- getValueFromBitsInit(Rec2->getValueAsBitsInit("VEX_WPrefix"));
+ bool operator()(const CodeGenInstruction *VEXInst) {
+ Record *RecE = EVEXInst->TheDef;
+ Record *RecV = VEXInst->TheDef;
+ uint64_t EVEX_W =
+ getValueFromBitsInit(RecE->getValueAsBitsInit("VEX_WPrefix"));
+ uint64_t VEX_W =
+ getValueFromBitsInit(RecV->getValueAsBitsInit("VEX_WPrefix"));
- if (Rec2->getValueAsDef("OpEnc")->getName().str() != "EncVEX" ||
+ if (RecV->getValueAsDef("OpEnc")->getName().str() != "EncVEX" ||
// VEX/EVEX fields
- Rec2->getValueAsDef("OpPrefix") != Rec1->getValueAsDef("OpPrefix") ||
- Rec2->getValueAsDef("OpMap") != Rec1->getValueAsDef("OpMap") ||
- Rec2->getValueAsBit("hasVEX_4V") != Rec1->getValueAsBit("hasVEX_4V") ||
- !equalBitsInits(Rec2->getValueAsBitsInit("EVEX_LL"),
- Rec1->getValueAsBitsInit("EVEX_LL")) ||
- (Rec1WVEX != 2 && Rec2WVEX != 2 && Rec1WVEX != Rec2WVEX) ||
+ RecV->getValueAsDef("OpPrefix") != RecE->getValueAsDef("OpPrefix") ||
+ RecV->getValueAsDef("OpMap") != RecE->getValueAsDef("OpMap") ||
+ RecV->getValueAsBit("hasVEX_4V") != RecE->getValueAsBit("hasVEX_4V") ||
+ !equalBitsInits(RecV->getValueAsBitsInit("EVEX_LL"),
+ RecE->getValueAsBitsInit("EVEX_LL")) ||
+ // Match is allowed if either is VEX_WIG, or they match, or EVEX
+ // is VEX_W1X and VEX is VEX_W0.
+ (!(EVEX_W == 2 || VEX_W == 2 || EVEX_W == VEX_W ||
+ (EVEX_W == 3 && VEX_W == 0))) ||
// Instruction's format
- Rec2->getValueAsDef("Form") != Rec1->getValueAsDef("Form") ||
- Rec2->getValueAsBit("isAsmParserOnly") !=
- Rec1->getValueAsBit("isAsmParserOnly"))
+ RecV->getValueAsDef("Form") != RecE->getValueAsDef("Form") ||
+ RecV->getValueAsBit("isAsmParserOnly") !=
+ RecE->getValueAsBit("isAsmParserOnly"))
return false;
// This is needed for instructions with intrinsic version (_Int).
// Also for instructions that their EVEX version was upgraded to work with
// k-registers. For example VPCMPEQBrm (xmm output register) and
// VPCMPEQBZ128rm (k register output register).
- for (unsigned i = 0, e = Inst->Operands.size(); i < e; i++) {
- Record *OpRec1 = Inst->Operands[i].Rec;
- Record *OpRec2 = Inst2->Operands[i].Rec;
+ for (unsigned i = 0, e = EVEXInst->Operands.size(); i < e; i++) {
+ Record *OpRec1 = EVEXInst->Operands[i].Rec;
+ Record *OpRec2 = VEXInst->Operands[i].Rec;
if (OpRec1 == OpRec2)
continue;
llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled");
}
// VEX_L & VEX_W
- if (!EncodeRC && HasVEX_LPrefix && VEX_WPrefix == X86Local::VEX_W1) {
+ if (!EncodeRC && HasVEX_LPrefix && (VEX_WPrefix == X86Local::VEX_W1 ||
+ VEX_WPrefix == X86Local::VEX_W1X)) {
if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE);
else if (OpPrefix == X86Local::XS)
llvm_unreachable("Invalid prefix");
}
} else if (!EncodeRC && HasEVEX_L2Prefix &&
- VEX_WPrefix == X86Local::VEX_W1) {
+ (VEX_WPrefix == X86Local::VEX_W1 ||
+ VEX_WPrefix == X86Local::VEX_W1X)) {
// EVEX_L2 & VEX_W
if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE);
llvm_unreachable("Invalid prefix");
}
}
- else if (VEX_WPrefix == X86Local::VEX_W1) {
+ else if (VEX_WPrefix == X86Local::VEX_W1 ||
+ VEX_WPrefix == X86Local::VEX_W1X) {
// VEX_W
if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_W_OPSIZE);
}
/// eof EVEX
} else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) {
- if (HasVEX_LPrefix && VEX_WPrefix == X86Local::VEX_W1) {
+ if (HasVEX_LPrefix && (VEX_WPrefix == X86Local::VEX_W1 ||
+ VEX_WPrefix == X86Local::VEX_W1X)) {
if (OpPrefix == X86Local::PD)
insnContext = IC_VEX_L_W_OPSIZE;
else if (OpPrefix == X86Local::XS)
}
} else if (OpPrefix == X86Local::PD && HasVEX_LPrefix)
insnContext = IC_VEX_L_OPSIZE;
- else if (OpPrefix == X86Local::PD && VEX_WPrefix == X86Local::VEX_W1)
+ else if (OpPrefix == X86Local::PD && (VEX_WPrefix == X86Local::VEX_W1 ||
+ VEX_WPrefix == X86Local::VEX_W1X))
insnContext = IC_VEX_W_OPSIZE;
else if (OpPrefix == X86Local::PD)
insnContext = IC_VEX_OPSIZE;
insnContext = IC_VEX_L_XS;
else if (HasVEX_LPrefix && OpPrefix == X86Local::XD)
insnContext = IC_VEX_L_XD;
- else if (VEX_WPrefix == X86Local::VEX_W1 && OpPrefix == X86Local::XS)
+ else if ((VEX_WPrefix == X86Local::VEX_W1 ||
+ VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::XS)
insnContext = IC_VEX_W_XS;
- else if (VEX_WPrefix == X86Local::VEX_W1 && OpPrefix == X86Local::XD)
+ else if ((VEX_WPrefix == X86Local::VEX_W1 ||
+ VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::XD)
insnContext = IC_VEX_W_XD;
- else if (VEX_WPrefix == X86Local::VEX_W1 && OpPrefix == X86Local::PS)
+ else if ((VEX_WPrefix == X86Local::VEX_W1 ||
+ VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::PS)
insnContext = IC_VEX_W;
else if (HasVEX_LPrefix && OpPrefix == X86Local::PS)
insnContext = IC_VEX_L;