diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 505293134033..dde34631ef41 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -923,6 +923,24 @@ ParseInstruction(StringRef Name, SMLoc NameLoc, std::swap(Operands[1], Operands[2]); } + // The assembler accepts these instructions with no operand as a synonym for + // an instruction acting on st(1). e.g. "fxch" -> "fxch %st(1)". + if ((Name == "fxch" || Name == "fucom" || Name == "fucomp" || + Name == "faddp" || Name == "fsubp" || Name == "fsubrp" || + Name == "fmulp" || Name == "fdivp" || Name == "fdivrp") && + Operands.size() == 1) { + Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"), + NameLoc, NameLoc)); + } + + // The assembler accepts these instructions with no operand as a synonym for + // an instruction acting on st,st(1). e.g. "faddp" -> "faddp %st(0),%st(1)". + //if (() && + // Operands.size() == 1) { + // Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"), + // NameLoc, NameLoc)); + //} + return false; } @@ -959,11 +977,10 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { } -bool -X86ATTAsmParser::MatchInstruction(SMLoc IDLoc, - const SmallVectorImpl - &Operands, - MCInst &Inst) { +bool X86ATTAsmParser:: +MatchInstruction(SMLoc IDLoc, + const SmallVectorImpl &Operands, + MCInst &Inst) { assert(!Operands.empty() && "Unexpect empty operand list!"); bool WasOriginallyInvalidOperand = false; diff --git a/llvm/test/MC/AsmParser/X86/x86_instructions.s b/llvm/test/MC/AsmParser/X86/x86_instructions.s index d4444f895237..4bdd171445de 100644 --- a/llvm/test/MC/AsmParser/X86/x86_instructions.s +++ b/llvm/test/MC/AsmParser/X86/x86_instructions.s @@ -210,3 +210,28 @@ inl %dx out %al, (%dx) out %ax, (%dx) outl %eax, (%dx) + + +// rdar://8431422 + +// CHECK: fxch %st(1) +// CHECK: fucom %st(1) +// CHECK: fucomp %st(1) +// CHECK: faddp %st(1) +// CHECK: faddp %st(0) +// CHECK: fsubp %st(1) +// CHECK: fsubrp %st(1) +// CHECK: fmulp %st(1) +// CHECK: fdivp %st(1) +// CHECK: fdivrp %st(1) + +fxch +fucom +fucomp +faddp +faddp %st +fsubp +fsubrp +fmulp +fdivp +fdivrp