For now, we lost the encoding information if we using inline assembly.
The encoding for the inline assembly will keep default even if we add
the vex/evex prefix.
Differential Revision: https://reviews.llvm.org/D90009
--- /dev/null
+// RUN:%clang_cc1 %s -ferror-limit 0 -triple=x86_64-pc -target-feature +avx512f -target-feature +avx2 -target-feature +avx512vl -S -o - | FileCheck %s -check-prefix CHECK
+
+// This test is to check if the prefix in inline assembly is correctly
+// preserved.
+
+void check_inline_prefix(void) {
+ __asm__ (
+// CHECK: vcvtps2pd %xmm0, %xmm1
+// CHECK: {vex} vcvtps2pd %xmm0, %xmm1
+// CHECK: {vex2} vcvtps2pd %xmm0, %xmm1
+// CHECK: {vex3} vcvtps2pd %xmm0, %xmm1
+// CHECK: {evex} vcvtps2pd %xmm0, %xmm1
+// CHECK: movl $1, (%rax)
+// CHECK: {disp8} movl $1, (%rax)
+// CHECK: {disp32} movl $1, (%rax)
+ "vcvtps2pd %xmm0, %xmm1\n\t"
+ "{vex} vcvtps2pd %xmm0, %xmm1\n\t"
+ "{vex2} vcvtps2pd %xmm0, %xmm1\n\t"
+ "{vex3} vcvtps2pd %xmm0, %xmm1\n\t"
+ "{evex} vcvtps2pd %xmm0, %xmm1\n\t"
+ "movl $1, (%rax)\n\t"
+ "{disp8} movl $1, (%rax)\n\t"
+ "{disp32} movl $1, (%rax)\n\t"
+ );
+}
enum VEXEncoding {
VEXEncoding_Default,
VEXEncoding_VEX,
+ VEXEncoding_VEX2,
VEXEncoding_VEX3,
VEXEncoding_EVEX,
};
return Error(Parser.getTok().getLoc(), "Expected '}'");
Parser.Lex(); // Eat curly.
- if (Prefix == "vex" || Prefix == "vex2")
+ if (Prefix == "vex")
ForcedVEXEncoding = VEXEncoding_VEX;
+ else if (Prefix == "vex2")
+ ForcedVEXEncoding = VEXEncoding_VEX2;
else if (Prefix == "vex3")
ForcedVEXEncoding = VEXEncoding_VEX3;
else if (Prefix == "evex")
return Match_Unsupported;
if ((ForcedVEXEncoding == VEXEncoding_VEX ||
+ ForcedVEXEncoding == VEXEncoding_VEX2 ||
ForcedVEXEncoding == VEXEncoding_VEX3) &&
(MCID.TSFlags & X86II::EncodingMask) != X86II::VEX)
return Match_Unsupported;
MCInst Inst;
- // If VEX3 encoding is forced, we need to pass the USE_VEX3 flag to the
- // encoder.
- if (ForcedVEXEncoding == VEXEncoding_VEX3)
+ // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
+ // encoder and printer.
+ if (ForcedVEXEncoding == VEXEncoding_VEX)
+ Prefixes |= X86::IP_USE_VEX;
+ else if (ForcedVEXEncoding == VEXEncoding_VEX2)
+ Prefixes |= X86::IP_USE_VEX2;
+ else if (ForcedVEXEncoding == VEXEncoding_VEX3)
Prefixes |= X86::IP_USE_VEX3;
+ else if (ForcedVEXEncoding == VEXEncoding_EVEX)
+ Prefixes |= X86::IP_USE_EVEX;
// Set encoded flags for {disp8} and {disp32}.
if (ForcedDispEncoding == DispEncoding_Disp8)
/// The constants to describe instr prefixes if there are
enum IPREFIXES {
IP_NO_PREFIX = 0,
- IP_HAS_OP_SIZE = 1,
- IP_HAS_AD_SIZE = 2,
- IP_HAS_REPEAT_NE = 4,
- IP_HAS_REPEAT = 8,
- IP_HAS_LOCK = 16,
- IP_HAS_NOTRACK = 32,
- IP_USE_VEX3 = 64,
- IP_USE_DISP8 = 128,
- IP_USE_DISP32 = 256,
+ IP_HAS_OP_SIZE = 1U << 0,
+ IP_HAS_AD_SIZE = 1U << 1,
+ IP_HAS_REPEAT_NE = 1U << 2,
+ IP_HAS_REPEAT = 1U << 3,
+ IP_HAS_LOCK = 1U << 4,
+ IP_HAS_NOTRACK = 1U << 5,
+ IP_USE_VEX = 1U << 6,
+ IP_USE_VEX2 = 1U << 7,
+ IP_USE_VEX3 = 1U << 8,
+ IP_USE_EVEX = 1U << 9,
+ IP_USE_DISP8 = 1U << 10,
+ IP_USE_DISP32 = 1U << 11,
};
enum OperandType : unsigned {
O << "\trepne\t";
else if (Flags & X86::IP_HAS_REPEAT)
O << "\trep\t";
+
+ // These all require a pseudo prefix
+ if (Flags & X86::IP_USE_VEX)
+ O << "\t{vex}";
+ else if (Flags & X86::IP_USE_VEX2)
+ O << "\t{vex2}";
+ else if (Flags & X86::IP_USE_VEX3)
+ O << "\t{vex3}";
+ else if (Flags & X86::IP_USE_EVEX)
+ O << "\t{evex}";
+
+ if (Flags & X86::IP_USE_DISP8)
+ O << "\t{disp8}";
+ else if (Flags & X86::IP_USE_DISP32)
+ O << "\t{disp32}";
}
void X86InstPrinterCommon::printVKPair(const MCInst *MI, unsigned OpNo,