move the plethora of fp stack aliases to the .td file.
authorChris Lattner <sabre@nondot.org>
Sat, 6 Nov 2010 20:47:38 +0000 (20:47 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 6 Nov 2010 20:47:38 +0000 (20:47 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118353 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/AsmParser/X86AsmParser.cpp
lib/Target/X86/X86InstrInfo.td

index eaa69f1708dfe3ec1404ab9c838bfdfda05ffe51..37ffeb806a5b508968a580765c7ebd2bca0908d8 100644 (file)
@@ -797,38 +797,6 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
                     X86Operand::CreateImm(One, NameLoc, NameLoc));
   }
 
-  // FIXME: Hack to handle "f{mul*,add*,sub*,div*} $op, st(0)" the same as
-  // "f{mul*,add*,sub*,div*} $op"
-  if ((Name.startswith("fmul") || Name.startswith("fadd") ||
-       Name.startswith("fsub") || Name.startswith("fdiv")) &&
-      Operands.size() == 3 &&
-      static_cast<X86Operand*>(Operands[2])->isReg() &&
-      static_cast<X86Operand*>(Operands[2])->getReg() == X86::ST0) {
-    delete Operands[2];
-    Operands.erase(Operands.begin() + 2);
-  }
-
-  // FIXME: Hack to handle "f{mulp,addp} st(0), $op" the same as
-  // "f{mulp,addp} $op", since they commute.  We also allow fdivrp/fsubrp even
-  // though they don't commute, solely because gas does support this.
-  if ((Name=="fmulp" || Name=="faddp" || Name=="fsubrp" || Name=="fdivrp") &&
-      Operands.size() == 3 &&
-      static_cast<X86Operand*>(Operands[1])->isReg() &&
-      static_cast<X86Operand*>(Operands[1])->getReg() == X86::ST0) {
-    delete Operands[1];
-    Operands.erase(Operands.begin() + 1);
-  }
-
-  // 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 == "faddp" || Name == "fsubp" || Name == "fsubrp" ||
-       Name == "fmulp" || Name == "fdivp" || Name == "fdivrp") &&
-      Operands.size() == 1) {
-    Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"),
-                                             NameLoc, NameLoc));
-  }
-
   return false;
 }
 
index fdb29837fd79502652de35b695e0055ce3d6ff3a..b415b2decb3fa882d05197b1a1abad6a165620ad 100644 (file)
@@ -1377,18 +1377,59 @@ def : InstAlias<"clrw $reg", (XOR16rr GR16:$reg, GR16:$reg)>;
 def : InstAlias<"clrl $reg", (XOR32rr GR32:$reg, GR32:$reg)>;
 def : InstAlias<"clrq $reg", (XOR64rr GR64:$reg, GR64:$reg)>;
 
-// Default arguments for various fp stack instructions.
-def : InstAlias<"fucom",        (UCOM_Fr   ST1)>;
-def : InstAlias<"fucomp",       (UCOM_FPr  ST1)>;
-def : InstAlias<"fcomi",        (COM_FIr   ST1)>;
+// The instruction patterns for these instructions were written with st(0)
+// explicitly in the pattern, match the form with implicit st(0).
+// FIXME: Tweak these to work like fadd etc.
 def : InstAlias<"fcomi   $reg", (COM_FIr   RST:$reg)>;
-def : InstAlias<"fcomip",       (COM_FIPr  ST1)>;
 def : InstAlias<"fcomip  $reg", (COM_FIPr  RST:$reg)>;
-def : InstAlias<"fucomi",       (UCOM_FIr  ST1)>;
 def : InstAlias<"fucomi  $reg", (UCOM_FIr  RST:$reg)>;
-def : InstAlias<"fucomip",      (UCOM_FIPr ST1)>;
 def : InstAlias<"fucomip $reg", (UCOM_FIPr RST:$reg)>;
 
+// Various unary fpstack operations default to operating on on ST1.
+// For example, "fxch" -> "fxch %st(1)"
+def : InstAlias<"faddp",        (ADD_FPrST0  ST1)>;
+def : InstAlias<"fsubp",        (SUBR_FPrST0 ST1)>;
+def : InstAlias<"fsubrp",       (SUB_FPrST0  ST1)>;
+def : InstAlias<"fmulp",        (MUL_FPrST0  ST1)>;
+def : InstAlias<"fdivp",        (DIVR_FPrST0 ST1)>;
+def : InstAlias<"fdivrp",       (DIV_FPrST0  ST1)>;
+def : InstAlias<"fxch",         (XCH_F       ST1)>;
+def : InstAlias<"fcomi",        (COM_FIr     ST1)>;
+def : InstAlias<"fcomip",       (COM_FIPr    ST1)>;
+def : InstAlias<"fucom",        (UCOM_Fr     ST1)>;
+def : InstAlias<"fucomp",       (UCOM_FPr    ST1)>;
+def : InstAlias<"fucomi",       (UCOM_FIr    ST1)>;
+def : InstAlias<"fucomip",      (UCOM_FIPr   ST1)>;
+
+// Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
+// For example, "fadd %st(4), %st(0)" -> "fadd %st(4)".  We also disambiguate
+// instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
+// gas.
+multiclass FpUnaryAlias<string Mnemonic, Instruction Inst> {
+ def : InstAlias<!strconcat(Mnemonic, " $op, %st(0)"),    (Inst RST:$op)>;
+ def : InstAlias<!strconcat(Mnemonic, " %st(0), %st(0)"), (Inst ST0)>;
+}
+
+defm : FpUnaryAlias<"fadd",   ADD_FST0r>;
+defm : FpUnaryAlias<"faddp",  ADD_FPrST0>;
+defm : FpUnaryAlias<"fsub",   SUB_FST0r>;
+defm : FpUnaryAlias<"fsubp",  SUBR_FPrST0>;
+defm : FpUnaryAlias<"fsubr",  SUBR_FST0r>;
+defm : FpUnaryAlias<"fsubrp", SUB_FPrST0>;
+defm : FpUnaryAlias<"fmul",   MUL_FST0r>;
+defm : FpUnaryAlias<"fmulp",  MUL_FPrST0>;
+defm : FpUnaryAlias<"fdiv",   DIV_FST0r>;
+defm : FpUnaryAlias<"fdivp",  DIVR_FPrST0>;
+defm : FpUnaryAlias<"fdivr",  DIVR_FST0r>;
+defm : FpUnaryAlias<"fdivrp", DIV_FPrST0>;
+
+// Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
+// commute.  We also allow fdivrp/fsubrp even though they don't commute, solely
+// because gas supports it.
+def : InstAlias<"faddp %st(0), $op", (ADD_FPrST0 RST:$op)>;
+def : InstAlias<"fmulp %st(0), $op", (MUL_FPrST0 RST:$op)>;
+def : InstAlias<"fsubrp %st(0), $op", (SUB_FPrST0 RST:$op)>;
+def : InstAlias<"fdivrp %st(0), $op", (DIV_FPrST0 RST:$op)>;
 
 // We accepts "fnstsw %eax" even though it only writes %ax.
 def : InstAlias<"fnstsw %eax", (FNSTSW8r)>;