Index: lib/Target/X86/Disassembler/X86Disassembler.cpp =================================================================== --- lib/Target/X86/Disassembler/X86Disassembler.cpp +++ lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -989,6 +989,7 @@ case ENCODING_IO: case ENCODING_Iv: case ENCODING_Ia: + case ENCODING_Irc: translateImmediate(mcInst, insn.immediates[insn.numImmediatesTranslated++], operand, Index: lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp =================================================================== --- lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp +++ lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp @@ -1798,6 +1798,13 @@ if (readImmediate(insn, insn->addressSize)) return -1; break; + case ENCODING_Irc: + // AVX512 rc is encoded in L'L bits. + insn->immediates[insn->numImmediatesConsumed] = + (l2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 1) | + lFromEVEX4of4(insn->vectorExtensionPrefix[3]); + ++insn->numImmediatesConsumed; + break; case ENCODING_RB: if (readOpcodeRegister(insn, 1)) return -1; Index: lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h =================================================================== --- lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h +++ lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h @@ -366,6 +366,7 @@ \ ENUM_ENTRY(ENCODING_Iv, "Immediate of operand size") \ ENUM_ENTRY(ENCODING_Ia, "Immediate of address size") \ + ENUM_ENTRY(ENCODING_Irc, "Immediate for static rounding control") \ ENUM_ENTRY(ENCODING_Rv, "Register code of operand size added to the " \ "opcode byte") \ ENUM_ENTRY(ENCODING_DUP, "Duplicate of another operand; ID is encoded " \ Index: lib/Target/X86/X86InstrAVX512.td =================================================================== --- lib/Target/X86/X86InstrAVX512.td +++ lib/Target/X86/X86InstrAVX512.td @@ -1883,7 +1883,7 @@ (X86cmpmRnd (_.VT _.RC:$src1), (_.VT _.RC:$src2), imm:$cc, - (i32 FROUND_NO_EXC))>, EVEX_B; + (i32 FROUND_NO_EXC))>, VEX_LIG, EVEX_B; let isAsmParserOnly = 1, hasSideEffects = 0 in { defm rrib_alt : AVX512_maskable_cmp_alt<0xC2, MRMSrcReg, _, @@ -1891,14 +1891,14 @@ (ins _.RC:$src1, _.RC:$src2, u8imm:$cc), "vcmp"#_.Suffix, "$cc, {sae}, $src2, $src1", - "$src1, $src2, {sae}, $cc">, EVEX_B; + "$src1, $src2, {sae}, $cc">, VEX_LIG, EVEX_B; } } multiclass avx512_vcmp { let Predicates = [HasAVX512] in { - defm Z : avx512_vcmp_common<_.info512>, - avx512_vcmp_sae<_.info512>, EVEX_V512; + defm Z : avx512_vcmp_common<_.info512>, EVEX_V512; + defm Z : avx512_vcmp_sae<_.info512>; } let Predicates = [HasAVX512,HasVLX] in { @@ -4055,7 +4055,7 @@ "$rc, $src2, $src1", "$src1, $src2, $rc", (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2), (i32 imm:$rc)), itins.rr, IsCommutable>, - EVEX_B, EVEX_RC; + VEX_LIG, EVEX_B, EVEX_RC; } multiclass avx512_fp_scalar_sae opc, string OpcodeStr,X86VectorVTInfo _, SDNode VecNode, OpndItins itins, bit IsCommutable> { @@ -4064,7 +4064,7 @@ (ins _.RC:$src1, _.RC:$src2), OpcodeStr, "{sae}, $src2, $src1", "$src1, $src2, {sae}", (VecNode (_.VT _.RC:$src1), (_.VT _.RC:$src2), - (i32 FROUND_NO_EXC))>, EVEX_B; + (i32 FROUND_NO_EXC))>, VEX_LIG, EVEX_B; } multiclass avx512_binop_s_round opc, string OpcodeStr, SDNode OpNode, @@ -4074,12 +4074,12 @@ itins.s, IsCommutable>, avx512_fp_scalar_round, - XS, EVEX_4V, VEX_LIG, EVEX_CD8<32, CD8VT1>; + XS, EVEX_4V, EVEX_CD8<32, CD8VT1>; defm SDZ : avx512_fp_scalar, avx512_fp_scalar_round, - XD, VEX_W, EVEX_4V, VEX_LIG, EVEX_CD8<64, CD8VT1>; + XD, VEX_W, EVEX_4V, EVEX_CD8<64, CD8VT1>; } multiclass avx512_binop_s_sae opc, string OpcodeStr, SDNode OpNode, @@ -4089,12 +4089,12 @@ itins.s, IsCommutable>, avx512_fp_scalar_sae, - XS, EVEX_4V, VEX_LIG, EVEX_CD8<32, CD8VT1>; + XS, EVEX_4V, EVEX_CD8<32, CD8VT1>; defm SDZ : avx512_fp_scalar, avx512_fp_scalar_sae, - XD, VEX_W, EVEX_4V, VEX_LIG, EVEX_CD8<64, CD8VT1>; + XD, VEX_W, EVEX_4V, EVEX_CD8<64, CD8VT1>; } defm VADD : avx512_binop_s_round<0x58, "vadd", fadd, X86faddRnd, SSE_ALU_ITINS_S, 1>; defm VMUL : avx512_binop_s_round<0x59, "vmul", fmul, X86fmulRnd, SSE_MUL_ITINS_S, 1>; @@ -4164,15 +4164,15 @@ multiclass avx512_fp_round_packed opc, string OpcodeStr, SDNode OpNodeRnd, X86VectorVTInfo _> { - let ExeDomain = _.ExeDomain in + let ExeDomain = _.ExeDomain in { defm rb: AVX512_maskable, - EVEX_4V, EVEX_B, EVEX_RC; + VEX_LIG, EVEX_4V, EVEX_B, EVEX_RC; + } } - multiclass avx512_fp_sae_packed opc, string OpcodeStr, SDNode OpNodeRnd, X86VectorVTInfo _> { let ExeDomain = _.ExeDomain in @@ -4214,16 +4214,16 @@ multiclass avx512_fp_binop_p_round opc, string OpcodeStr, SDNode OpNodeRnd> { defm PSZ : avx512_fp_round_packed, - EVEX_V512, PS, EVEX_CD8<32, CD8VF>; + PS, EVEX_CD8<32, CD8VF>; defm PDZ : avx512_fp_round_packed, - EVEX_V512, PD, VEX_W,EVEX_CD8<64, CD8VF>; + PD, VEX_W,EVEX_CD8<64, CD8VF>; } multiclass avx512_fp_binop_p_sae opc, string OpcodeStr, SDNode OpNodeRnd> { defm PSZ : avx512_fp_sae_packed, - EVEX_V512, PS, EVEX_CD8<32, CD8VF>; + VEX_LIG, PS, EVEX_CD8<32, CD8VF>; defm PDZ : avx512_fp_sae_packed, - EVEX_V512, PD, VEX_W,EVEX_CD8<64, CD8VF>; + VEX_LIG, PD, VEX_W,EVEX_CD8<64, CD8VF>; } defm VADD : avx512_fp_binop_p<0x58, "vadd", fadd, HasAVX512, @@ -4359,11 +4359,13 @@ multiclass avx512_fp_scalef_all opc, bits<8> opcScaler, string OpcodeStr, SDNode OpNode, SDNode OpNodeScal> { defm PSZ : avx512_fp_scalef_p, - avx512_fp_round_packed, EVEX_V512, EVEX_CD8<32, CD8VF>; + defm PSZ : avx512_fp_round_packed, + EVEX_CD8<32, CD8VF>; defm PDZ : avx512_fp_scalef_p, - avx512_fp_round_packed, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>; + defm PDZ : avx512_fp_round_packed, + VEX_W, EVEX_CD8<64, CD8VF>; defm SSZ128 : avx512_fp_scalef_scalar, avx512_fp_scalar_round, EVEX_4V,EVEX_CD8<32, CD8VT1>; @@ -5124,7 +5126,7 @@ (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc), OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc", (_.VT ( OpNode _.RC:$src2, _.RC:$src1, _.RC:$src3, (i32 imm:$rc))), 1, 1>, - AVX512FMA3Base, EVEX_B, EVEX_RC; + AVX512FMA3Base, VEX_LIG, EVEX_B, EVEX_RC; } multiclass avx512_fma3p_213_common opc, string OpcodeStr, SDNode OpNode, @@ -5132,8 +5134,9 @@ string Suff> { let Predicates = [HasAVX512] in { defm Z : avx512_fma3p_213_rm, - avx512_fma3_213_round, EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>; + EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>; + defm Z : avx512_fma3_213_round, EVEX_CD8<_.info512.EltSize, CD8VF>; } let Predicates = [HasVLX, HasAVX512] in { defm Z256 : avx512_fma3p_213_rm, @@ -5209,7 +5212,7 @@ (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc), OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc", (_.VT ( OpNode _.RC:$src2, _.RC:$src3, _.RC:$src1, (i32 imm:$rc))), 1, 1>, - AVX512FMA3Base, EVEX_B, EVEX_RC; + AVX512FMA3Base, VEX_LIG, EVEX_B, EVEX_RC; } multiclass avx512_fma3p_231_common opc, string OpcodeStr, SDNode OpNode, @@ -5217,8 +5220,9 @@ string Suff> { let Predicates = [HasAVX512] in { defm Z : avx512_fma3p_231_rm, - avx512_fma3_231_round, EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>; + EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>; + defm Z : avx512_fma3_231_round, EVEX_CD8<_.info512.EltSize, CD8VF>; } let Predicates = [HasVLX, HasAVX512] in { defm Z256 : avx512_fma3p_231_rm, @@ -5283,7 +5287,7 @@ (ins _.RC:$src2, _.RC:$src3, AVX512RC:$rc), OpcodeStr, "$rc, $src3, $src2", "$src2, $src3, $rc", (_.VT ( OpNode _.RC:$src1, _.RC:$src3, _.RC:$src2, (i32 imm:$rc))), 1, 1>, - AVX512FMA3Base, EVEX_B, EVEX_RC; + AVX512FMA3Base, VEX_LIG, EVEX_B, EVEX_RC; } multiclass avx512_fma3p_132_common opc, string OpcodeStr, SDNode OpNode, @@ -5291,8 +5295,9 @@ string Suff> { let Predicates = [HasAVX512] in { defm Z : avx512_fma3p_132_rm, - avx512_fma3_132_round, EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>; + EVEX_V512, EVEX_CD8<_.info512.EltSize, CD8VF>; + defm Z : avx512_fma3_132_round, EVEX_CD8<_.info512.EltSize, CD8VF>; } let Predicates = [HasVLX, HasAVX512] in { defm Z256 : avx512_fma3p_132_rm, @@ -5807,9 +5812,9 @@ X86VectorVTInfo _dst> { let Predicates = [HasAVX512] in { defm Z : avx512_cvt_fp_scalar, - avx512_cvt_fp_rc_scalar, VEX_W, EVEX_CD8<64, CD8VT1>, - EVEX_V512, XD; + VEX_W, EVEX_CD8<64, CD8VT1>, EVEX_V512, XD; + defm Z : avx512_cvt_fp_rc_scalar, VEX_W, EVEX_CD8<64, CD8VT1>, XD; } } @@ -5818,8 +5823,9 @@ X86VectorVTInfo _dst> { let Predicates = [HasAVX512] in { defm Z : avx512_cvt_fp_scalar, - avx512_cvt_fp_sae_scalar, EVEX_CD8<32, CD8VT1>, XS, EVEX_V512; + defm Z : avx512_cvt_fp_sae_scalar, + EVEX_CD8<32, CD8VT1>, XS; } } defm VCVTSD2SS : avx512_cvt_fp_scalar_sd2ss<0x5A, "vcvtsd2ss", @@ -5882,7 +5888,7 @@ "{sae}, $src", "$src, {sae}", (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src), (i32 FROUND_NO_EXC)))>, - EVEX, EVEX_B; + VEX_LIG, EVEX, EVEX_B; } // Conversion with rounding control (RC) @@ -5892,15 +5898,16 @@ (ins _Src.RC:$src, AVX512RC:$rc), OpcodeStr, "$rc, $src", "$src, $rc", (_.VT (OpNodeRnd (_Src.VT _Src.RC:$src), (i32 imm:$rc)))>, - EVEX, EVEX_B, EVEX_RC; + VEX_LIG, EVEX, EVEX_B, EVEX_RC; } // Extend Float to Double multiclass avx512_cvtps2pd opc, string OpcodeStr> { let Predicates = [HasAVX512] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_sae, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_sae; } let Predicates = [HasVLX] in { defm Z128 : avx512_vcvt_fp opc, string OpcodeStr> { let Predicates = [HasAVX512] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_rc, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_rc; } let Predicates = [HasVLX] in { defm Z128 : avx512_vcvt_fp { let Predicates = [HasAVX512] in defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_rc, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_rc; let Predicates = [HasVLX] in { defm Z128 : avx512_vcvt_fp, @@ -5975,8 +5984,9 @@ SDNode OpNode, SDNode OpNodeRnd> { let Predicates = [HasAVX512] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_sae, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_sae; } let Predicates = [HasVLX] in { defm Z128 : avx512_vcvt_fp, @@ -5991,8 +6001,9 @@ SDNode OpNode, SDNode OpNodeRnd> { let Predicates = [HasAVX512] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_rc, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_rc; } let Predicates = [HasVLX] in { defm Z128 : avx512_vcvt_fp, @@ -6007,8 +6018,9 @@ SDNode OpNode, SDNode OpNodeRnd> { let Predicates = [HasAVX512] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_sae, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_sae; } let Predicates = [HasVLX] in { // we need "x"/"y" suffixes in order to distinguish between 128 and 256 @@ -6027,8 +6039,9 @@ SDNode OpNode, SDNode OpNodeRnd> { let Predicates = [HasAVX512] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_rc, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_rc; } let Predicates = [HasVLX] in { // we need "x"/"y" suffixes in order to distinguish between 128 and 256 @@ -6047,8 +6060,9 @@ SDNode OpNode, SDNode OpNodeRnd> { let Predicates = [HasDQI] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_rc, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_rc; } let Predicates = [HasDQI, HasVLX] in { defm Z128 : avx512_vcvt_fp, @@ -6063,8 +6077,9 @@ SDNode OpNode, SDNode OpNodeRnd> { let Predicates = [HasDQI] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_sae, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_sae; } let Predicates = [HasDQI, HasVLX] in { defm Z128 : avx512_vcvt_fp, @@ -6079,8 +6094,9 @@ SDNode OpNode, SDNode OpNodeRnd> { let Predicates = [HasDQI] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_rc, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_rc; } let Predicates = [HasDQI, HasVLX] in { defm Z128 : avx512_vcvt_fp, @@ -6095,8 +6111,9 @@ SDNode OpNode, SDNode OpNodeRnd> { let Predicates = [HasDQI] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_rc, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_rc; } let Predicates = [HasDQI, HasVLX] in { // Explicitly specified broadcast string, since we take only 2 elements @@ -6113,8 +6130,9 @@ SDNode OpNode, SDNode OpNodeRnd> { let Predicates = [HasDQI] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_sae, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_sae; } let Predicates = [HasDQI, HasVLX] in { // Explicitly specified broadcast string, since we take only 2 elements @@ -6131,8 +6149,9 @@ SDNode OpNode, SDNode OpNodeRnd> { let Predicates = [HasDQI] in { defm Z : avx512_vcvt_fp, - avx512_vcvt_fp_rc, EVEX_V512; + EVEX_V512; + defm Z : avx512_vcvt_fp_rc; } let Predicates = [HasDQI, HasVLX] in { // we need "x"/"y" suffixes in order to distinguish between 128 and 256 @@ -6288,14 +6307,15 @@ defm rb : AVX512_maskable<0x13, MRMSrcReg, _dest ,(outs _dest.RC:$dst), (ins _src.RC:$src), "vcvtph2ps", "{sae}, $src", "$src, {sae}", (X86cvtph2ps (_src.VT _src.RC:$src), - (i32 FROUND_NO_EXC))>, T8PD, EVEX_B; + (i32 FROUND_NO_EXC))>, T8PD, VEX_LIG, EVEX_B; } let Predicates = [HasAVX512] in { defm VCVTPH2PSZ : avx512_cvtph2ps, - avx512_cvtph2ps_sae, EVEX, EVEX_V512, EVEX_CD8<32, CD8VH>; + defm VCVTPH2PSZ : avx512_cvtph2ps_sae, + EVEX, EVEX_CD8<32, CD8VH>; let Predicates = [HasVLX] in { defm VCVTPH2PSZ256 : avx512_cvtph2ps,EVEX, EVEX_V256, EVEX_CD8<32, CD8VH>; @@ -6330,12 +6350,13 @@ (outs _dest.RC:$dst), (ins _src.RC:$src1, i32u8imm:$src2), "vcvtps2ph", "$src2, {sae}, $src1", "$src1, {sae}, $src2", - []>, EVEX_B, AVX512AIi8Base; + []>, VEX_LIG, EVEX_B, AVX512AIi8Base; } let Predicates = [HasAVX512] in { defm VCVTPS2PHZ : avx512_cvtps2ph, - avx512_cvtps2ph_sae, EVEX, EVEX_V512, EVEX_CD8<32, CD8VH>; + defm VCVTPS2PHZ : avx512_cvtps2ph_sae, + EVEX, EVEX_CD8<32, CD8VH>; let Predicates = [HasVLX] in { defm VCVTPS2PHZ256 : avx512_cvtps2ph, EVEX, EVEX_V256, EVEX_CD8<32, CD8VH>; @@ -6578,16 +6599,19 @@ defm rb : AVX512_maskable, EVEX_B; + (OpNode (_.VT _.RC:$src), (i32 FROUND_NO_EXC))>, + VEX_LIG, EVEX_B; } multiclass avx512_eri opc, string OpcodeStr, SDNode OpNode> { defm PS : avx512_fp28_p, - avx512_fp28_p_round, T8PD, EVEX_V512, EVEX_CD8<32, CD8VF>; + defm PS : avx512_fp28_p_round, + T8PD, EVEX_CD8<32, CD8VF>; defm PD : avx512_fp28_p, - avx512_fp28_p_round, T8PD, EVEX_V512, VEX_W, EVEX_CD8<64, CD8VF>; + defm PD : avx512_fp28_p_round, + T8PD, VEX_W, EVEX_CD8<64, CD8VF>; } multiclass avx512_fp_unaryop_packed opc, string OpcodeStr, @@ -6618,7 +6642,7 @@ defm rb: AVX512_maskable, - EVEX, EVEX_B, EVEX_RC; + VEX_LIG, EVEX, EVEX_B, EVEX_RC; } multiclass avx512_sqrt_packed opc, string OpcodeStr, @@ -6667,9 +6691,9 @@ multiclass avx512_sqrt_packed_all_round opc, string OpcodeStr, SDNode OpNodeRnd> { defm PSZ : avx512_sqrt_packed_round, EVEX_V512, PS, EVEX_CD8<32, CD8VF>; + v16f32_info>, PS, EVEX_CD8<32, CD8VF>; defm PDZ : avx512_sqrt_packed_round, EVEX_V512, VEX_W, PD, EVEX_CD8<64, CD8VF>; + v8f64_info>, VEX_W, PD, EVEX_CD8<64, CD8VF>; } multiclass avx512_sqrt_scalar opc, string OpcodeStr,X86VectorVTInfo _, @@ -7769,15 +7793,15 @@ "$src1, {sae}, $src2", (OpNode (_.VT _.RC:$src1), (i32 imm:$src2), - (i32 FROUND_NO_EXC))>, EVEX_B; + (i32 FROUND_NO_EXC))>, VEX_LIG, EVEX_B; } multiclass avx512_common_unary_fp_sae_packed_imm opc, SDNode OpNode, Predicate prd>{ let Predicates = [prd] in { defm Z : avx512_unary_fp_packed_imm, - avx512_unary_fp_sae_packed_imm, EVEX_V512; + defm Z : avx512_unary_fp_sae_packed_imm; } let Predicates = [prd, HasVLX] in { defm Z128 : avx512_unary_fp_packed_imm, @@ -7892,7 +7916,7 @@ (OpNode (_.VT _.RC:$src1), (_.VT _.RC:$src2), (i32 imm:$src3), - (i32 FROUND_NO_EXC))>, EVEX_B; + (i32 FROUND_NO_EXC))>, VEX_LIG, EVEX_B; } //handle scalar instruction reg_vec1 = op(reg_vec2,reg_vec3,imm),{sae} multiclass avx512_fp_sae_scalar_imm opc, string OpcodeStr, @@ -7911,9 +7935,8 @@ AVX512VLVectorVTInfo _, bits<8> opc, SDNode OpNode, Predicate prd>{ let Predicates = [prd] in { defm Z : avx512_fp_packed_imm, - avx512_fp_sae_packed_imm, EVEX_V512; - + defm Z : avx512_fp_sae_packed_imm; } let Predicates = [prd, HasVLX] in { defm Z128 : avx512_fp_packed_imm, @@ -8582,7 +8605,7 @@ (_.VT _.RC:$src2), (_.IntVT _.RC:$src3), (i32 imm:$src4), - (i32 FROUND_NO_EXC))>, EVEX_B; + (i32 FROUND_NO_EXC))>, VEX_LIG, EVEX_B; } } @@ -8623,8 +8646,9 @@ multiclass avx512_fixupimm_packed_all{ let Predicates = [HasAVX512] in defm Z : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info512>, - avx512_fixupimm_packed_sae<0x54, "vfixupimm", X86VFixupimm, _Vec.info512>, AVX512AIi8Base, EVEX_4V, EVEX_V512; + defm Z : avx512_fixupimm_packed_sae<0x54, "vfixupimm", X86VFixupimm, _Vec.info512>, + AVX512AIi8Base, EVEX_4V; let Predicates = [HasAVX512, HasVLX] in { defm Z128 : avx512_fixupimm_packed<0x54, "vfixupimm", X86VFixupimm, _Vec.info128>, AVX512AIi8Base, EVEX_4V, EVEX_V128; Index: test/MC/Disassembler/X86/avx-512.txt =================================================================== --- test/MC/Disassembler/X86/avx-512.txt +++ test/MC/Disassembler/X86/avx-512.txt @@ -137,5 +137,104 @@ # CHECK: vpcmpd $8, %zmm10, %zmm25, %k5 0x62 0xd3 0x35 0x40 0x1f 0xea 0x8 +##################################################### +# SAE ATTRIBUTE # +##################################################### + +# CHECK: vcomisd {sae}, %xmm2, %xmm1 +0x62 0xf1 0xfd 0x18 0x2f 0xca + +# Same as above but ignore EVEX L'L bits. +# CHECK: vcomisd {sae}, %xmm2, %xmm1 +0x62 0xf1 0xfd 0x78 0x2f 0xca + +# Ignore L'L bits without {sae} bit set. +# CHECK: vcomisd %xmm2, %xmm1 +0x62 0xf1 0xfd 0x68 0x2f 0xca + +# CHECK: vminpd {sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0xf5 0x10 0x5d 0xda + +# Ignore EVEX L'L bits. +# CHECK: vminpd {sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0xf5 0x30 0x5d 0xda + +# Ignore EVEX L'L bits. +# CHECK: vminpd {sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0xf5 0x50 0x5d 0xda + +# Ignore EVEX L'L bits. +# CHECK: vminpd {sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0xf5 0x70 0x5d 0xda + +# Without {sae} L'L modifies size. +# CHECK: vminpd %ymm2, %ymm17, %ymm19 +0x62 0xe1 0xf5 0x20 0x5d 0xda + +# CHECK: vcmppd $127, {sae}, %zmm27, %zmm11, %k4 +0x62 0x91 0xa5 0x18 0xc2 0xe3 0x7f + # CHECK: vcmppd $127, {sae}, %zmm27, %zmm11, %k4 0x62 0x91 0xa5 0x58 0xc2 0xe3 0x7f + +# CHEC: vrsqrt28pd {sae}, %zmm2, %zmm17 +0x62 0xe2 0xfd 0x18 0xcc 0xca + +##################################################### +# ROUNDING CONTROL # +##################################################### + +# Verify all rounding modes work. + +# CHECK: vaddps {rn-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0x74 0x10 0x58 0xda + +# CHECK: vaddps {rd-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0x74 0x30 0x58 0xda + +# CHECK: vaddps {ru-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0x74 0x50 0x58 0xda + +# CHECK: vaddps {rz-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe1 0x74 0x70 0x58 0xda + +# Without rounding control L'L control vector size. +# CHECK: vaddps %ymm2, %ymm17, %ymm19 +0x62 0xe1 0x74 0x20 0x58 0xda + +# CHECK: vmulss {rn-sae}, %xmm2, %xmm17, %xmm19 +0x62 0xe1 0x76 0x10 0x59 0xda + +# CHECK: vmulss {rd-sae}, %xmm2, %xmm17, %xmm19 +0x62 0xe1 0x76 0x30 0x59 0xda + +# CHECK: vmulss {ru-sae}, %xmm2, %xmm17, %xmm19 +0x62 0xe1 0x76 0x50 0x59 0xda + +# CHECK: vmulss {rz-sae}, %xmm2, %xmm17, %xmm19 +0x62 0xe1 0x76 0x70 0x59 0xda + +# CHECK: vscalefpd {rn-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe2 0xf5 0x10 0x2c 0xda + +# CHECK: vscalefpd {rd-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe2 0xf5 0x30 0x2c 0xda + +# CHECK: vscalefpd {ru-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe2 0xf5 0x50 0x2c 0xda + +# CHECK: vscalefpd {rz-sae}, %zmm2, %zmm17, %zmm19 +0x62 0xe2 0xf5 0x70 0x2c 0xda + +# Without rounding control L'L control vector size. +# CHECK: vscalefpd %ymm2, %ymm17, %ymm19 +0x62 0xe2 0xf5 0x20 0x2c 0xda + +# CHECK: vcvtqq2ps {rd-sae}, %zmm2, %ymm17 +0x62 0xe1 0xfc 0x38 0x5b 0xca + +# CHECK: vsqrtpd {rd-sae}, %zmm2, %zmm17 +0x62 0xe1 0xfd 0x38 0x51 0xca + +# CHECK: vsqrtpd %ymm2, %ymm17 +0x62 0xe1 0xfd 0x28 0x51 0xca Index: utils/TableGen/X86DisassemblerTables.cpp =================================================================== --- utils/TableGen/X86DisassemblerTables.cpp +++ utils/TableGen/X86DisassemblerTables.cpp @@ -67,6 +67,118 @@ } } +/// Return instruction context combined with EVEX_L. +static inline InstructionContext combineEVEX_L(InstructionContext insnContext) { + switch (insnContext) { + default: + return insnContext; + case IC_EVEX: return IC_EVEX_L; + case IC_EVEX_W: return IC_EVEX_L_W; + case IC_EVEX_W_XS: return IC_EVEX_L_W_XS; + case IC_EVEX_W_XD: return IC_EVEX_L_W_XD; + case IC_EVEX_W_OPSIZE: return IC_EVEX_L_W_OPSIZE; + case IC_EVEX_K_B: return IC_EVEX_L_K_B; + case IC_EVEX_KZ_B: return IC_EVEX_L_KZ_B; + case IC_EVEX_B: return IC_EVEX_L_B; + case IC_EVEX_XS: return IC_EVEX_L_XS; + case IC_EVEX_XD: return IC_EVEX_L_XD; + case IC_EVEX_OPSIZE: return IC_EVEX_L_OPSIZE; + case IC_EVEX_W_XS_K: return IC_EVEX_L_W_XS_K; + case IC_EVEX_W_XD_K: return IC_EVEX_L_W_XD_K; + case IC_EVEX_W_XS_KZ: return IC_EVEX_L_W_XS_KZ; + case IC_EVEX_W_XD_KZ: return IC_EVEX_L_W_XD_KZ; + case IC_EVEX_W_OPSIZE_B: return IC_EVEX_L_W_OPSIZE_B; + case IC_EVEX_K: return IC_EVEX_L_K; + case IC_EVEX_XS_K: return IC_EVEX_L_XS_K; + case IC_EVEX_XD_K: return IC_EVEX_L_XD_K; + case IC_EVEX_XD_B: return IC_EVEX_L_XD_B; + case IC_EVEX_XD_K_B: return IC_EVEX_L_XD_K_B; + case IC_EVEX_OPSIZE_K: return IC_EVEX_L_OPSIZE_K; + case IC_EVEX_OPSIZE_B: return IC_EVEX_L_OPSIZE_B; + case IC_EVEX_OPSIZE_K_B: return IC_EVEX_L_OPSIZE_K_B; + case IC_EVEX_KZ: return IC_EVEX_L_KZ; + case IC_EVEX_XS_KZ: return IC_EVEX_L_XS_KZ; + case IC_EVEX_XS_B: return IC_EVEX_L_XS_B; + case IC_EVEX_XS_K_B: return IC_EVEX_L_XS_K_B; + case IC_EVEX_XS_KZ_B: return IC_EVEX_L_XS_KZ_B; + case IC_EVEX_XD_KZ: return IC_EVEX_L_XD_KZ; + case IC_EVEX_XD_KZ_B: return IC_EVEX_L_XD_KZ_B; + case IC_EVEX_OPSIZE_KZ: return IC_EVEX_L_OPSIZE_KZ; + case IC_EVEX_OPSIZE_KZ_B: return IC_EVEX_L_OPSIZE_KZ_B; + case IC_EVEX_W_K: return IC_EVEX_L_W_K; + case IC_EVEX_W_B: return IC_EVEX_L_W_B; + case IC_EVEX_W_K_B: return IC_EVEX_L_W_K_B; + case IC_EVEX_W_XS_B: return IC_EVEX_L_W_XS_B; + case IC_EVEX_W_XS_K_B: return IC_EVEX_L_W_XS_K_B; + case IC_EVEX_W_XS_KZ_B: return IC_EVEX_L_W_XS_KZ_B; + case IC_EVEX_W_OPSIZE_K: return IC_EVEX_L_W_OPSIZE_K; + case IC_EVEX_W_OPSIZE_K_B: return IC_EVEX_L_W_OPSIZE_K_B; + case IC_EVEX_W_KZ: return IC_EVEX_L_W_KZ; + case IC_EVEX_W_KZ_B: return IC_EVEX_L_W_KZ_B; + case IC_EVEX_W_XD_B: return IC_EVEX_L_W_XD_B; + case IC_EVEX_W_XD_K_B: return IC_EVEX_L_W_XD_K_B; + case IC_EVEX_W_XD_KZ_B: return IC_EVEX_L_W_XD_KZ_B; + case IC_EVEX_W_OPSIZE_KZ: return IC_EVEX_L_W_OPSIZE_KZ; + case IC_EVEX_W_OPSIZE_KZ_B: return IC_EVEX_L_W_OPSIZE_KZ_B; + } +} + +/// Return instruction context combined with EVEX_L2. +static inline InstructionContext combineEVEX_L2(InstructionContext insnContext){ + switch (insnContext) { + default: + return insnContext; + case IC_EVEX: return IC_EVEX_L2; + case IC_EVEX_W: return IC_EVEX_L2_W; + case IC_EVEX_W_XS: return IC_EVEX_L2_W_XS; + case IC_EVEX_W_XD: return IC_EVEX_L2_W_XD; + case IC_EVEX_W_OPSIZE: return IC_EVEX_L2_W_OPSIZE; + case IC_EVEX_K_B: return IC_EVEX_L2_K_B; + case IC_EVEX_KZ_B: return IC_EVEX_L2_KZ_B; + case IC_EVEX_B: return IC_EVEX_L2_B; + case IC_EVEX_XS: return IC_EVEX_L2_XS; + case IC_EVEX_XD: return IC_EVEX_L2_XD; + case IC_EVEX_OPSIZE: return IC_EVEX_L2_OPSIZE; + case IC_EVEX_W_XS_K: return IC_EVEX_L2_W_XS_K; + case IC_EVEX_W_XD_K: return IC_EVEX_L2_W_XD_K; + case IC_EVEX_W_XS_KZ: return IC_EVEX_L2_W_XS_KZ; + case IC_EVEX_W_XD_KZ: return IC_EVEX_L2_W_XD_KZ; + case IC_EVEX_W_OPSIZE_B: return IC_EVEX_L2_W_OPSIZE_B; + case IC_EVEX_K: return IC_EVEX_L2_K; + case IC_EVEX_XS_K: return IC_EVEX_L2_XS_K; + case IC_EVEX_XD_K: return IC_EVEX_L2_XD_K; + case IC_EVEX_XD_B: return IC_EVEX_L2_XD_B; + case IC_EVEX_XD_K_B: return IC_EVEX_L2_XD_K_B; + case IC_EVEX_OPSIZE_K: return IC_EVEX_L2_OPSIZE_K; + case IC_EVEX_OPSIZE_B: return IC_EVEX_L2_OPSIZE_B; + case IC_EVEX_OPSIZE_K_B: return IC_EVEX_L2_OPSIZE_K_B; + case IC_EVEX_KZ: return IC_EVEX_L2_KZ; + case IC_EVEX_XS_KZ: return IC_EVEX_L2_XS_KZ; + case IC_EVEX_XS_B: return IC_EVEX_L2_XS_B; + case IC_EVEX_XS_K_B: return IC_EVEX_L2_XS_K_B; + case IC_EVEX_XS_KZ_B: return IC_EVEX_L2_XS_KZ_B; + case IC_EVEX_XD_KZ: return IC_EVEX_L2_XD_KZ; + case IC_EVEX_XD_KZ_B: return IC_EVEX_L2_XD_KZ_B; + case IC_EVEX_OPSIZE_KZ: return IC_EVEX_L2_OPSIZE_KZ; + case IC_EVEX_OPSIZE_KZ_B: return IC_EVEX_L2_OPSIZE_KZ_B; + case IC_EVEX_W_K: return IC_EVEX_L2_W_K; + case IC_EVEX_W_B: return IC_EVEX_L2_W_B; + case IC_EVEX_W_K_B: return IC_EVEX_L2_W_K_B; + case IC_EVEX_W_XS_B: return IC_EVEX_L2_W_XS_B; + case IC_EVEX_W_XS_K_B: return IC_EVEX_L2_W_XS_K_B; + case IC_EVEX_W_XS_KZ_B: return IC_EVEX_L2_W_XS_KZ_B; + case IC_EVEX_W_OPSIZE_K: return IC_EVEX_L2_W_OPSIZE_K; + case IC_EVEX_W_OPSIZE_K_B: return IC_EVEX_L2_W_OPSIZE_K_B; + case IC_EVEX_W_KZ: return IC_EVEX_L2_W_KZ; + case IC_EVEX_W_KZ_B: return IC_EVEX_L2_W_KZ_B; + case IC_EVEX_W_XD_B: return IC_EVEX_L2_W_XD_B; + case IC_EVEX_W_XD_K_B: return IC_EVEX_L2_W_XD_K_B; + case IC_EVEX_W_XD_KZ_B: return IC_EVEX_L2_W_XD_KZ_B; + case IC_EVEX_W_OPSIZE_KZ: return IC_EVEX_L2_W_OPSIZE_KZ; + case IC_EVEX_W_OPSIZE_KZ_B: return IC_EVEX_L2_W_OPSIZE_KZ_B; + } +} + /// inheritsFrom - Indicates whether all instructions in one class also belong /// to another class. /// @@ -171,23 +283,27 @@ return false; case IC_EVEX: return inheritsFrom(child, IC_EVEX_W) || - inheritsFrom(child, IC_EVEX_L_W); + (VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent)))); case IC_EVEX_XS: return inheritsFrom(child, IC_EVEX_W_XS) || - inheritsFrom(child, IC_EVEX_L_W_XS); + (VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent)))); case IC_EVEX_XD: return inheritsFrom(child, IC_EVEX_W_XD) || - inheritsFrom(child, IC_EVEX_L_W_XD); + (VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent)))); case IC_EVEX_OPSIZE: return inheritsFrom(child, IC_EVEX_W_OPSIZE) || - inheritsFrom(child, IC_EVEX_L_W_OPSIZE); + (VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent)))); case IC_EVEX_B: - return false; case IC_EVEX_W: case IC_EVEX_W_XS: case IC_EVEX_W_XD: case IC_EVEX_W_OPSIZE: - return false; + return VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent))); case IC_EVEX_L: case IC_EVEX_L_K_B: case IC_EVEX_L_KZ_B: @@ -213,35 +329,40 @@ return false; case IC_EVEX_K: return inheritsFrom(child, IC_EVEX_W_K) || - inheritsFrom(child, IC_EVEX_L_W_K); + (VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent)))); case IC_EVEX_XS_K: case IC_EVEX_XS_K_B: case IC_EVEX_XS_KZ_B: return inheritsFrom(child, IC_EVEX_W_XS_K) || - inheritsFrom(child, IC_EVEX_L_W_XS_K); + (VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent)))); case IC_EVEX_XD_K: case IC_EVEX_XD_K_B: case IC_EVEX_XD_KZ_B: return inheritsFrom(child, IC_EVEX_W_XD_K) || - inheritsFrom(child, IC_EVEX_L_W_XD_K); - case IC_EVEX_XS_B: - case IC_EVEX_XD_B: - case IC_EVEX_K_B: - case IC_EVEX_KZ: - return false; + (VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent)))); case IC_EVEX_XS_KZ: return inheritsFrom(child, IC_EVEX_W_XS_KZ) || - inheritsFrom(child, IC_EVEX_L_W_XS_KZ); + (VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent)))); case IC_EVEX_XD_KZ: return inheritsFrom(child, IC_EVEX_W_XD_KZ) || - inheritsFrom(child, IC_EVEX_L_W_XD_KZ); + (VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent)))); + case IC_EVEX_XS_B: + case IC_EVEX_XD_B: + case IC_EVEX_K_B: + case IC_EVEX_KZ: case IC_EVEX_KZ_B: + case IC_EVEX_OPSIZE_K: case IC_EVEX_OPSIZE_B: case IC_EVEX_OPSIZE_K_B: case IC_EVEX_OPSIZE_KZ: case IC_EVEX_OPSIZE_KZ_B: - return false; + case IC_EVEX_W_K: case IC_EVEX_W_B: case IC_EVEX_W_K_B: @@ -251,16 +372,7 @@ case IC_EVEX_W_OPSIZE_K: case IC_EVEX_W_OPSIZE_B: case IC_EVEX_W_OPSIZE_K_B: - return false; - case IC_EVEX_L_K: - case IC_EVEX_L_XS_K: - case IC_EVEX_L_XD_K: - case IC_EVEX_L_XD_B: - case IC_EVEX_L_XD_K_B: - case IC_EVEX_L_OPSIZE_K: - case IC_EVEX_L_OPSIZE_B: - case IC_EVEX_L_OPSIZE_K_B: - return false; + case IC_EVEX_W_KZ: case IC_EVEX_W_XS_KZ: case IC_EVEX_W_XD_KZ: @@ -272,6 +384,16 @@ case IC_EVEX_W_XD_KZ_B: case IC_EVEX_W_OPSIZE_KZ: case IC_EVEX_W_OPSIZE_KZ_B: + return VEX_LIG && (inheritsFrom(child, combineEVEX_L(parent)) || + inheritsFrom(child, combineEVEX_L2(parent))); + case IC_EVEX_L_K: + case IC_EVEX_L_XS_K: + case IC_EVEX_L_XD_K: + case IC_EVEX_L_XD_B: + case IC_EVEX_L_XD_K_B: + case IC_EVEX_L_OPSIZE_K: + case IC_EVEX_L_OPSIZE_B: + case IC_EVEX_L_OPSIZE_K_B: return false; case IC_EVEX_L_KZ: case IC_EVEX_L_XS_KZ: Index: utils/TableGen/X86RecognizableInstr.cpp =================================================================== --- utils/TableGen/X86RecognizableInstr.cpp +++ utils/TableGen/X86RecognizableInstr.cpp @@ -993,7 +993,7 @@ TYPE("XOPCC", TYPE_IMM3) TYPE("AVXCC", TYPE_IMM5) TYPE("AVX512ICC", TYPE_AVX512ICC) - TYPE("AVX512RC", TYPE_IMM32) + TYPE("AVX512RC", TYPE_IMM8) TYPE("brtarget32", TYPE_RELv) TYPE("brtarget16", TYPE_RELv) TYPE("brtarget8", TYPE_REL8) @@ -1079,7 +1079,7 @@ ENCODING("XOPCC", ENCODING_IB) ENCODING("AVXCC", ENCODING_IB) ENCODING("AVX512ICC", ENCODING_IB) - ENCODING("AVX512RC", ENCODING_IB) + ENCODING("AVX512RC", ENCODING_Irc) ENCODING("i16imm", ENCODING_Iv) ENCODING("i16i8imm", ENCODING_IB) ENCODING("i32imm", ENCODING_Iv)