From fd3fe9e45aeadd4cfb41966c7bd5e7c36c687ab0 Mon Sep 17 00:00:00 2001 From: Michael Zuckerman Date: Thu, 12 Nov 2015 16:58:51 +0000 Subject: [PATCH] [x86] translating "fp" (floating point) instructions from {fadd,fdiv,fmul,fsub,fsubr,fdivr} to {faddp,fdivp,fmulp,fsubp,fsubrp,fdivrp} LLVM Missing the following instructions: fadd\fdiv\fmul\fsub\fsubr\fdivr. GAS and MS supporting this instruction and lowering them in to a faddp\fdivp\fmulp\fsubp\fsubrp\fdivrp instructions. Differential Revision: http://reviews.llvm.org/D14217 llvm-svn: 252908 --- llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 14 ++++++++++++++ llvm/lib/Target/X86/X86InstrInfo.td | 2 ++ llvm/test/MC/X86/intel-syntax-2.s | 14 ++++++++++++++ llvm/test/MC/X86/intel-syntax.s | 14 ++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 1760bce4a35d..b7a0e1d7027d 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2218,6 +2218,20 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, (isPrefix && getLexer().is(AsmToken::Slash))) Parser.Lex(); + // This is for gas compatibility and cannot be done in td. + // Adding "p" for some floating point with no argument. + // For example: fsub --> fsubp + bool IsFp = + Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr"; + if (IsFp && Operands.size() == 1) { + const char *Repl = StringSwitch(Name) + .Case("fsub", "fsubp") + .Case("fdiv", "fdivp") + .Case("fsubr", "fsubrp") + .Case("fdivr", "fdivrp"); + static_cast(*Operands[0]).setTokenValue(Repl); + } + // This is a terrible hack to handle "out[bwl]? %al, (%dx)" -> // "outb %al, %dx". Out doesn't take a memory form, but this is a widely // documented form in various unofficial manuals, so a lot of code uses it. diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 9bf0d6d3ffa2..0571b07d2f8b 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -2793,8 +2793,10 @@ def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>; // Various unary fpstack operations default to operating on on ST1. // For example, "fxch" -> "fxch %st(1)" def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>; +def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>; def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>; def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>; +def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>; def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>; def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>; def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>; diff --git a/llvm/test/MC/X86/intel-syntax-2.s b/llvm/test/MC/X86/intel-syntax-2.s index f7bdaf92dbb5..aead5766db4d 100644 --- a/llvm/test/MC/X86/intel-syntax-2.s +++ b/llvm/test/MC/X86/intel-syntax-2.s @@ -15,3 +15,17 @@ _test2: .att_syntax prefix movl $255, -4(%rsp) // CHECK: movl $255, -4(%rsp) + +_test3: +fadd +// CHECK: faddp %st(1) +fmul +// CHECK: fmulp %st(1) +fsub +// CHECK: fsubp %st(1) +fsubr +// CHECK: fsubrp %st(1) +fdiv +// CHECK: fdivp %st(1) +fdivr +// CHECK: fdivrp %st(1) diff --git a/llvm/test/MC/X86/intel-syntax.s b/llvm/test/MC/X86/intel-syntax.s index 002a6f81dcf5..b79b21dc9691 100644 --- a/llvm/test/MC/X86/intel-syntax.s +++ b/llvm/test/MC/X86/intel-syntax.s @@ -533,6 +533,20 @@ fsubrp ST(1) fdivp ST(1) fdivrp ST(1) + +// CHECK: faddp %st(1) +// CHECK: fmulp %st(1) +// CHECK: fsubrp %st(1) +// CHECK: fsubp %st(1) +// CHECK: fdivrp %st(1) +// CHECK: fdivp %st(1) +fadd +fmul +fsub +fsubr +fdiv +fdivr + // CHECK: faddp %st(1) // CHECK: fmulp %st(1) // CHECK: fsubrp %st(1)