aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/Printer.cpp
diff options
context:
space:
mode:
authorBrian Gaeke <gaeke@uiuc.edu>2003-07-11 18:18:35 +0000
committerBrian Gaeke <gaeke@uiuc.edu>2003-07-11 18:18:35 +0000
commit1aa476edf028fed9b5c8ff537fcab42704037094 (patch)
treec5ce479ddc345f6b30f391ae8a71e95c53f13e99 /lib/Target/X86/Printer.cpp
parent666ff520e6b0a7a3c9f11e7a86d7bf8eebb4e24a (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7165 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/Printer.cpp')
-rw-r--r--lib/Target/X86/Printer.cpp53
1 files changed, 51 insertions, 2 deletions
diff --git a/lib/Target/X86/Printer.cpp b/lib/Target/X86/Printer.cpp
index 74820c8690..164ff0d08b 100644
--- a/lib/Target/X86/Printer.cpp
+++ b/lib/Target/X86/Printer.cpp
@@ -665,6 +665,11 @@ void Printer::printMachineInstruction(const MachineInstr *MI, std::ostream &O,
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 @@ void Printer::printMachineInstruction(const MachineInstr *MI, std::ostream &O,
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 @@ void Printer::printMachineInstruction(const MachineInstr *MI, std::ostream &O,
<< 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 @@ void Printer::printMachineInstruction(const MachineInstr *MI, std::ostream &O,
}
}
}
+ // 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);