[llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp
Alkis Evlogimenos
alkis at niobe.cs.uiuc.edu
Mon Mar 8 21:36:04 PST 2004
Changes in directory llvm/lib/Target/X86:
Printer.cpp updated: 1.91 -> 1.92
---
Log message:
Use newly added API to emit bytes for instructions that gas misassembles
---
Diffs of the changes: (+53 -66)
Index: llvm/lib/Target/X86/Printer.cpp
diff -u llvm/lib/Target/X86/Printer.cpp:1.91 llvm/lib/Target/X86/Printer.cpp:1.92
--- llvm/lib/Target/X86/Printer.cpp:1.91 Mon Mar 1 17:53:11 2004
+++ llvm/lib/Target/X86/Printer.cpp Mon Mar 8 21:35:34 2004
@@ -16,12 +16,14 @@
#include "X86.h"
#include "X86InstrInfo.h"
+#include "X86TargetMachine.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h"
@@ -38,6 +40,37 @@
cl::opt<bool> EmitCygwin("enable-cygwin-compatible-output", cl::Hidden,
cl::desc("Emit X86 assembly code suitable for consumption by cygwin"));
+ struct GasBugWorkaroundEmitter : public MachineCodeEmitter {
+ GasBugWorkaroundEmitter(std::ostream& o)
+ : O(o), OldFlags(O.flags()), firstByte(true) {
+ O << std::hex;
+ }
+
+ ~GasBugWorkaroundEmitter() {
+ O.flags(OldFlags);
+ O << "\t# ";
+ }
+
+ virtual void emitByte(unsigned char B) {
+ if (!firstByte) O << "\n\t";
+ firstByte = false;
+ O << ".byte 0x" << (unsigned) B;
+ }
+
+ // These should never be called
+ virtual void emitWord(unsigned W) { assert(0); }
+ virtual uint64_t getGlobalValueAddress(GlobalValue *V) { assert(0); }
+ virtual uint64_t getGlobalValueAddress(const std::string &Name) { assert(0); }
+ virtual uint64_t getConstantPoolEntryAddress(unsigned Index) { assert(0); }
+ virtual uint64_t getCurrentPCValue() { assert(0); }
+ virtual uint64_t forceCompilationOf(Function *F) { assert(0); }
+
+ private:
+ std::ostream& O;
+ std::ios::fmtflags OldFlags;
+ bool firstByte;
+ };
+
struct Printer : public MachineFunctionPass {
/// Output stream on which we're printing assembly code.
///
@@ -768,82 +801,37 @@
const MachineOperand &Op3 = MI->getOperand(3);
- // Bug: The 80-bit FP store-pop instruction "fstp XWORD PTR [...]"
+ // gas bugs:
+ //
+ // 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::FSTP80m) {
- if ((MI->getOperand(0).getReg() == X86::ESP)
- && (MI->getOperand(1).getImmedValue() == 1)) {
- if (Op3.isImmediate() &&
- Op3.getImmedValue() >= -128 && Op3.getImmedValue() <= 127) {
- // 1 byte disp.
- O << ".byte 0xdb, 0x7c, 0x24, 0x" << std::hex
- << ((unsigned)Op3.getImmedValue() & 255) << std::dec << "\t# ";
- } else {
- O << ".byte 0xdb, 0xbc, 0x24\n\t";
- O << ".long ";
- printOp(Op3);
- O << "\t# ";
- }
- }
- }
-
- // Bug: The 80-bit FP load instruction "fld XWORD PTR [...]" is
+ //
+ // 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::FLD80m &&
- MI->getOperand(0).getReg() == X86::ESP &&
- MI->getOperand(1).getImmedValue() == 1) {
- if (Op3.isImmediate() && Op3.getImmedValue() >= -128 &&
- Op3.getImmedValue() <= 127) { // 1 byte displacement
- O << ".byte 0xdb, 0x6c, 0x24, 0x" << std::hex
- << ((unsigned)Op3.getImmedValue() & 255) << std::dec << "\t# ";
- } else {
- O << ".byte 0xdb, 0xac, 0x24\n\t";
- O << ".long ";
- printOp(Op3);
- O << "\t# ";
- }
- }
-
- // Bug: gas intel_syntax mode treats "fild QWORD PTR [...]" as an
+ //
+ // 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::FILD64m &&
- MI->getOperand(0).getReg() == X86::ESP &&
- MI->getOperand(1).getImmedValue() == 1) {
- if (Op3.isImmediate() && Op3.getImmedValue() >= -128 &&
- Op3.getImmedValue() <= 127) { // 1 byte displacement
- O << ".byte 0xdf, 0x6c, 0x24, 0x" << std::hex
- << ((unsigned)Op3.getImmedValue() & 255) << std::dec << "\t# ";
- } else {
- O << ".byte 0xdf, 0xac, 0x24\n\t";
- O << ".long ";
- printOp(Op3);
- O << std::dec << "\t# ";
- }
+ //
+ // 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 the raw opcode bytes
+ // instead of the instruction.
+ if (MI->getOpcode() == X86::FSTP80m ||
+ MI->getOpcode() == X86::FLD80m ||
+ MI->getOpcode() == X86::FILD64m ||
+ MI->getOpcode() == X86::FISTP64m) {
+ GasBugWorkaroundEmitter gwe(O);
+ X86::emitInstruction(gwe, (X86InstrInfo&)TM.getInstrInfo(), *MI);
}
- // 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::FISTP64m) {
- O << "fistpll DWORD PTR ";
- printMemReference(MI, 0);
- if (MI->getNumOperands() == 5) {
- O << ", ";
- printOp(MI->getOperand(4));
- }
- O << "\t# ";
- }
-
O << TII.getName(MI->getOpcode()) << " ";
O << sizePtr(Desc) << " ";
printMemReference(MI, 0);
@@ -854,7 +842,6 @@
O << "\n";
return;
}
-
default:
O << "\tUNKNOWN FORM:\t\t-"; MI->print(O, TM); break;
}
More information about the llvm-commits
mailing list