[llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp X86InstrInfo.def

Brian Gaeke gaeke at cs.uiuc.edu
Fri Jul 11 13:19:01 PDT 2003


Changes in directory llvm/lib/Target/X86:

Printer.cpp updated: 1.42 -> 1.43
X86InstrInfo.def updated: 1.61 -> 1.62

---
Log message:

Fix some serious floating-point bugs (fixes test cases such as Oscar,
Fhourstones, McCat-vor, and many others...)

Printer.cpp: Print implicit uses for AddRegFrm instructions.  Break gas
bug workarounds up into separate stanzas of code for each bug.  Add new
workarounds for fild and fistp.

X86InstrInfo.def: Add O_ST0 implicit uses for more FP instrs where they
obviously apply. Also add PrintImplUses flags for FP instrs where they
are necessary for gas to understand the output.


---
Diffs of the changes:

Index: llvm/lib/Target/X86/Printer.cpp
diff -u llvm/lib/Target/X86/Printer.cpp:1.42 llvm/lib/Target/X86/Printer.cpp:1.43
--- llvm/lib/Target/X86/Printer.cpp:1.42	Mon Jul  7 13:34:20 2003
+++ llvm/lib/Target/X86/Printer.cpp	Fri Jul 11 13:18:35 2003
@@ -665,6 +665,11 @@
       O << ", ";
       printOp(O, MI->getOperand(1), RI);
     }
+    if (Desc.TSFlags & X86II::PrintImplUses) {
+      for (const unsigned *p = Desc.ImplicitUses; *p; ++p) {
+	O << ", " << RI.get(*p).Name;
+      }
+    }
     O << "\n";
     return;
   }
@@ -819,7 +824,10 @@
            isMem(MI, 0) && "Bad MRMSxM format!");
     assert((MI->getNumOperands() != 5 || MI->getOperand(4).isImmediate()) &&
            "Bad MRMSxM format!");
-    // Work around GNU assembler bugs in FSTP and FLD.
+    // Bug: The 80-bit FP store-pop instruction "fstp XWORD PTR [...]"
+    // is misassembled by gas in intel_syntax mode as its 32-bit
+    // equivalent "fstp DWORD PTR [...]". Workaround: Output the raw
+    // opcode bytes instead of the instruction.
     if (MI->getOpCode() == X86::FSTPr80) {
       if ((MI->getOperand(0).getReg() == X86::ESP)
 	  && (MI->getOperand(1).getImmedValue() == 1)) {
@@ -834,7 +842,12 @@
             << std::dec << "\t# ";
 	}
       }
-    } else if (MI->getOpCode() == X86::FLDr80) {
+    }
+    // Bug: The 80-bit FP load instruction "fld XWORD PTR [...]" is
+    // misassembled by gas in intel_syntax mode as its 32-bit
+    // equivalent "fld DWORD PTR [...]". Workaround: Output the raw
+    // opcode bytes instead of the instruction.
+    if (MI->getOpCode() == X86::FLDr80) {
       if ((MI->getOperand(0).getReg() == X86::ESP)
           && (MI->getOperand(1).getImmedValue() == 1)) {
 	int DispVal = MI->getOperand(3).getImmedValue();
@@ -849,6 +862,42 @@
 	}
       }
     }
+    // Bug: gas intel_syntax mode treats "fild QWORD PTR [...]" as an
+    // invalid opcode, saying "64 bit operations are only supported in
+    // 64 bit modes." libopcodes disassembles it as "fild DWORD PTR
+    // [...]", which is wrong. Workaround: Output the raw opcode bytes
+    // instead of the instruction.
+    if (MI->getOpCode() == X86::FILDr64) {
+      if ((MI->getOperand(0).getReg() == X86::ESP)
+          && (MI->getOperand(1).getImmedValue() == 1)) {
+	int DispVal = MI->getOperand(3).getImmedValue();
+	if ((DispVal < -128) || (DispVal > 127)) { // 4 byte disp.
+          unsigned int val = (unsigned int) DispVal;
+          O << ".byte 0xdf, 0xac, 0x24\n\t";
+          O << ".long 0x" << std::hex << (unsigned) val << std::dec << "\t# ";
+	} else { // 1 byte disp.
+          unsigned char val = (unsigned char) DispVal;
+          O << ".byte 0xdf, 0x6c, 0x24, 0x" << std::hex << (unsigned) val
+            << std::dec << "\t# ";
+	}
+      }
+    }
+    // Bug: gas intel_syntax mode treats "fistp QWORD PTR [...]" as
+    // an invalid opcode, saying "64 bit operations are only
+    // supported in 64 bit modes." libopcodes disassembles it as
+    // "fistpll DWORD PTR [...]", which is wrong. Workaround: Output
+    // "fistpll DWORD PTR " instead, which is what libopcodes is
+    // expecting to see.
+    if (MI->getOpCode() == X86::FISTPr64) {
+      O << "fistpll DWORD PTR ";
+      printMemReference(O, MI, 0, RI);
+      if (MI->getNumOperands() == 5) {
+	O << ", ";
+	printOp(O, MI->getOperand(4), RI);
+      }
+      O << "\t# ";
+    }
+    
     O << TII.getName(MI->getOpCode()) << " ";
     O << sizePtr(Desc) << " ";
     printMemReference(O, MI, 0, RI);


Index: llvm/lib/Target/X86/X86InstrInfo.def
diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.61 llvm/lib/Target/X86/X86InstrInfo.def:1.62
--- llvm/lib/Target/X86/X86InstrInfo.def:1.61	Thu Jun 26 19:00:46 2003
+++ llvm/lib/Target/X86/X86InstrInfo.def	Fri Jul 11 13:18:35 2003
@@ -318,14 +318,14 @@
 I(FSTPr32     , "fstp",  0xD9,            0,             X86II::Void | X86II::ArgF32 | X86II::MRMS3m                   , NoIR, NoIR)   // store float, pop
 I(FSTPr64     , "fstp",  0xDD,            0,             X86II::Void | X86II::ArgF64 | X86II::MRMS3m                   , NoIR, NoIR)   // store double, pop
 I(FSTPr80     , "fstp",  0xDB,            0,             X86II::Void | X86II::ArgF80 | X86II::MRMS7m | X86II::OneArgFP , NoIR, NoIR)   // store extended, pop
-I(FSTrr       , "fst"  ,   0xD0,            0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm                , NoIR, NoIR)   // ST(i) = ST(0)
-I(FSTPrr      , "fstp" ,   0xD8,            0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm                , NoIR, NoIR)   // ST(i) = ST(0), pop
+I(FSTrr       , "fst"  ,   0xD0,            0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm                , O_ST0, NoIR)   // ST(i) = ST(0)
+I(FSTPrr      , "fstp" ,   0xD8,            0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm                , O_ST0, NoIR)   // ST(i) = ST(0), pop
 
 I(FISTr16     , "fist",  0xDF,            0,             X86II::Void | X86II::Arg16  | X86II::MRMS2m | X86II::OneArgFP , NoIR, NoIR)   // store signed short
 I(FISTr32     , "fist",  0xDB,            0,             X86II::Void | X86II::Arg32  | X86II::MRMS2m | X86II::OneArgFP , NoIR, NoIR)   // store signed int
 I(FISTPr16    , "fistp", 0xDF,            0,             X86II::Void | X86II::Arg16  | X86II::MRMS3m                   , NoIR, NoIR)   // store short, pop
 I(FISTPr32    , "fistp", 0xDB,            0,             X86II::Void | X86II::Arg32  | X86II::MRMS3m                   , NoIR, NoIR)   // store int, pop
-I(FISTPr64    , "fistp", 0xDF,            0,             X86II::Void | X86II::Arg64  | X86II::MRMS7m | X86II::OneArgFP , NoIR, NoIR)   // store long, pop
+I(FISTPr64    , "fistpll", 0xDF,          0,             X86II::Void | X86II::Arg64  | X86II::MRMS7m | X86II::OneArgFP , NoIR, NoIR)   // store long, pop
 
 
 I(FXCH        , "fxch" , 0xC8,              0, X86II::D9 | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm                , O_ST0, O_ST0) // fxch ST(i), ST(0)
@@ -335,34 +335,34 @@
 I(FLD1        , "fld1" , 0xE8,              0, X86II::D9 |               X86II::ArgF80 | X86II::RawFrm | X86II::ZeroArgFP, NoIR, NoIR)   // load +1.0
 
 // Binary arithmetic operations...
-I(FADDST0r    , "fadd",   0xC0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) + ST(i)
-I(FADDrST0    , "fadd",   0xC0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) + ST(0)
-I(FADDPrST0   , "faddp",  0xC0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) + ST(0), pop
-
-I(FSUBRST0r   , "fsubr" , 0xE8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(i) - ST(0)
-I(FSUBrST0    , "fsub"  , 0xE8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) - ST(0)
-I(FSUBPrST0   , "fsubp" , 0xE8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) - ST(0), pop
-
-I(FSUBST0r    , "fsub"  , 0xE0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) - ST(i)
-I(FSUBRrST0   , "fsubr" , 0xE0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) - ST(i)
-I(FSUBRPrST0  , "fsubrp", 0xE0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) - ST(i), pop
-
-I(FMULST0r    , "fmul",   0xC8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) * ST(i)
-I(FMULrST0    , "fmul",   0xC8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) * ST(0)
-I(FMULPrST0   , "fmulp",  0xC8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) * ST(0), pop
-
-I(FDIVRST0r   , "fdivr" , 0xF8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(i) / ST(0)
-I(FDIVrST0    , "fdiv"  , 0xF8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) / ST(0)
-I(FDIVPrST0   , "fdivp" , 0xF8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) / ST(0), pop
-
-I(FDIVST0r    , "fdiv"  , 0xF0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) / ST(i)
-I(FDIVRrST0   , "fdivr" , 0xF0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) / ST(i)
-I(FDIVRPrST0  , "fdivrp", 0xF0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) / ST(i), pop
+I(FADDST0r    , "fadd",   0xC0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, O_ST0)   // ST(0) = ST(0) + ST(i)
+I(FADDrST0    , "fadd",   0xC0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm | X86II::PrintImplUses, O_ST0, NoIR)   // ST(i) = ST(i) + ST(0)
+I(FADDPrST0   , "faddp",  0xC0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, NoIR)    // ST(i) = ST(i) + ST(0), pop
+
+I(FSUBRST0r   , "fsubr" , 0xE8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, O_ST0)   // ST(0) = ST(i) - ST(0)
+I(FSUBrST0    , "fsub"  , 0xE8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm | X86II::PrintImplUses, O_ST0, NoIR)   // ST(i) = ST(i) - ST(0)
+I(FSUBPrST0   , "fsubp" , 0xE8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, NoIR)    // ST(i) = ST(i) - ST(0), pop
+
+I(FSUBST0r    , "fsub"  , 0xE0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, O_ST0)   // ST(0) = ST(0) - ST(i)
+I(FSUBRrST0   , "fsubr" , 0xE0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm | X86II::PrintImplUses, O_ST0, NoIR)   // ST(i) = ST(0) - ST(i)
+I(FSUBRPrST0  , "fsubrp", 0xE0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, NoIR)    // ST(i) = ST(0) - ST(i), pop
+
+I(FMULST0r    , "fmul",   0xC8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, O_ST0)   // ST(0) = ST(0) * ST(i)
+I(FMULrST0    , "fmul",   0xC8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm | X86II::PrintImplUses, O_ST0, NoIR)   // ST(i) = ST(i) * ST(0)
+I(FMULPrST0   , "fmulp",  0xC8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, NoIR)    // ST(i) = ST(i) * ST(0), pop
+
+I(FDIVRST0r   , "fdivr" , 0xF8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, O_ST0)   // ST(0) = ST(i) / ST(0)
+I(FDIVrST0    , "fdiv"  , 0xF8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm | X86II::PrintImplUses, O_ST0, NoIR)   // ST(i) = ST(i) / ST(0)
+I(FDIVPrST0   , "fdivp" , 0xF8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, NoIR)    // ST(i) = ST(i) / ST(0), pop
+
+I(FDIVST0r    , "fdiv"  , 0xF0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, O_ST0)   // ST(0) = ST(0) / ST(i)
+I(FDIVRrST0   , "fdivr" , 0xF0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm | X86II::PrintImplUses, O_ST0, NoIR)   // ST(i) = ST(0) / ST(i)
+I(FDIVRPrST0  , "fdivrp", 0xF0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, NoIR)    // ST(i) = ST(0) / ST(i), pop
 
 // Floating point compares
-I(FUCOMr      , "fucom"   , 0xE0,           0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // FPSW = compare ST(0) with ST(i)
-I(FUCOMPr     , "fucomp"  , 0xE8,           0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // compare, pop
-I(FUCOMPPr    , "fucompp" , 0xE9,           0, X86II::DA | X86II::Void                 | X86II::RawFrm                  , NoIR, NoIR)   // compare ST(0) with ST(1), pop, pop
+I(FUCOMr      , "fucom"   , 0xE0,           0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, NoIR)   // FPSW = compare ST(0) with ST(i)
+I(FUCOMPr     , "fucomp"  , 0xE8,           0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm               , O_ST0, NoIR)   // compare, pop
+I(FUCOMPPr    , "fucompp" , 0xE9,           0, X86II::DA | X86II::Void                 | X86II::RawFrm                  , O_ST0, NoIR)   // compare ST(0) with ST(1), pop, pop
 
 // Floating point flag ops
 I(FNSTSWr8    , "fnstsw"  , 0xE0,           0, X86II::DF | X86II::Void                 | X86II::RawFrm                  , NoIR, O_AX)   // AX = fp flags





More information about the llvm-commits mailing list