class X86AsmParser : public MCTargetAsmParser {
ParseInstructionInfo *InstInfo;
bool Code16GCC;
+ unsigned ForcedDataPrefix = 0;
enum VEXEncoding {
VEXEncoding_Default,
if (getLexer().isNot(AsmToken::EndOfStatement)) {
StringRef Next = Parser.getTok().getString();
- // Parse data32 call as calll.
- if (Next == "call" || Next == "callw") {
- getLexer().Lex();
- Name = "calll";
- PatchedName = Name;
- isPrefix = false;
- }
+ getLexer().Lex();
+ // data32 effectively changes the instruction suffix.
+ // TODO Generalize.
+ if (Next == "callw")
+ Next = "calll";
+ if (Next == "ljmpw")
+ Next = "ljmpl";
+
+ Name = Next;
+ PatchedName = Name;
+ ForcedDataPrefix = X86::Mode32Bit;
+ isPrefix = false;
}
}
if (Prefixes)
Inst.setFlags(Prefixes);
+ // In 16-bit mode, if data32 is specified, temporarily switch to 32-bit mode
+ // when matching the instruction.
+ if (ForcedDataPrefix == X86::Mode32Bit)
+ SwitchMode(X86::Mode32Bit);
// First, try a direct match.
FeatureBitset MissingFeatures;
unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
MissingFeatures, MatchingInlineAsm,
isParsingIntelSyntax());
+ if (ForcedDataPrefix == X86::Mode32Bit) {
+ SwitchMode(X86::Mode16Bit);
+ ForcedDataPrefix = 0;
+ }
switch (OriginalError) {
default: llvm_unreachable("Unexpected match result!");
case Match_Success:
// ERR64: error: 'data32' is not supported in 64-bit mode
// ERR32: error: redundant data32 prefix
-// 16: data32
-// 16: encoding: [0x66]
-// 16: lgdtw 0
-// 16: encoding: [0x0f,0x01,0x16,0x00,0x00]
+// 16: lgdtl 0
+// 16-SAME: encoding: [0x66,0x0f,0x01,0x16,0x00,0x00]
data32 lgdt 0
// 64: data16
data32 call a
data32 callw a
+// CHECK: ljmpl $1, $2
+// CHECK-NEXT: ljmpl $1, $2
+data32 ljmp $1, $2
+data32 ljmpw $1, $2
+
// CHECK: incb %al # encoding: [0xfe,0xc0]
incb %al
// CHECK: encoding: [0x66]
data32
-// CHECK: data32
-// CHECK: encoding: [0x66]
-// CHECK: lgdtw 4(%eax)
-// CHECK: encoding: [0x67,0x0f,0x01,0x50,0x04]
+// CHECK: lgdtl 4(%eax)
+// CHECK-SAME: encoding: [0x67,0x66,0x0f,0x01,0x50,0x04]
data32 lgdt 4(%eax)
// CHECK: wbnoinvd