diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h index 7dcac932a2f..6b38b8c7e17 100644 --- a/include/llvm/Target/TargetAsmParser.h +++ b/include/llvm/Target/TargetAsmParser.h @@ -78,7 +78,7 @@ public: /// explaining the match failure. virtual bool MatchAndEmitInstruction(SMLoc IDLoc, - const SmallVectorImpl &Operands, + SmallVectorImpl &Operands, MCStreamer &Out) = 0; }; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 6eb564bc562..95b57f34716 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -81,8 +81,8 @@ private: bool ParseDirectiveSyntax(SMLoc L); bool MatchAndEmitInstruction(SMLoc IDLoc, - const SmallVectorImpl &Operands, - MCStreamer &Out) { + SmallVectorImpl &Operands, + MCStreamer &Out) { MCInst Inst; unsigned ErrorInfo; if (MatchInstructionImpl(Operands, Inst, ErrorInfo) == Match_Success) { diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 012288a1446..c8b25cea30b 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -52,7 +52,7 @@ private: bool ParseDirectiveWord(unsigned Size, SMLoc L); bool MatchAndEmitInstruction(SMLoc IDLoc, - const SmallVectorImpl &Operands, + SmallVectorImpl &Operands, MCStreamer &Out); /// @name Auto-generated Matcher Functions @@ -1109,10 +1109,24 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { bool X86ATTAsmParser:: MatchAndEmitInstruction(SMLoc IDLoc, - const SmallVectorImpl &Operands, + SmallVectorImpl &Operands, MCStreamer &Out) { assert(!Operands.empty() && "Unexpect empty operand list!"); + X86Operand *Op = static_cast(Operands[0]); + assert(Op->isToken() && "Leading operand should always be a mnemonic!"); + // First, handle aliases that expand to multiple instructions. + // FIXME: This should be replaced with a real .td file alias mechanism. + if (Op->getToken() == "fstsw") { + MCInst Inst; + Inst.setOpcode(X86::WAIT); + Out.EmitInstruction(Inst); + + delete Operands[0]; + Operands[0] = X86Operand::CreateToken("fnstsw", IDLoc); + } + + bool WasOriginallyInvalidOperand = false; unsigned OrigErrorInfo; MCInst Inst; @@ -1136,9 +1150,6 @@ MatchAndEmitInstruction(SMLoc IDLoc, // valid prefixes, and we could just infer the right unambiguous // type. However, that requires substantially more matcher support than the // following hack. - - X86Operand *Op = static_cast(Operands[0]); - assert(Op->isToken() && "Leading operand should always be a mnemonic!"); // Change the operand to point to a temporary token. StringRef Base = Op->getToken(); diff --git a/test/MC/AsmParser/X86/x86_instructions.s b/test/MC/AsmParser/X86/x86_instructions.s index 65c27a35324..bf33ea37422 100644 --- a/test/MC/AsmParser/X86/x86_instructions.s +++ b/test/MC/AsmParser/X86/x86_instructions.s @@ -407,3 +407,11 @@ cwtl // CHECK: cwtl cbw // CHECK: cbtw cwd // CHECK: cwtd cdq // CHECK: cltd + +// rdar://8456378 and PR7557 - fstsw +fstsw %ax +// CHECK: wait +// CHECK: fnstsw %ax +fstsw (%rax) +// CHECK: wait +// CHECK: fnstsw (%rax)