From f2d2925452b6f002361db4bb3a08b68ebcb8e8a7 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 1 Dec 2003 05:13:56 +0000 Subject: [PATCH] generalize the instruction types permitted a bit git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10274 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/Printer.cpp | 77 +++++++++++++++++--------------- lib/Target/X86/X86AsmPrinter.cpp | 77 +++++++++++++++++--------------- 2 files changed, 84 insertions(+), 70 deletions(-) diff --git a/lib/Target/X86/Printer.cpp b/lib/Target/X86/Printer.cpp index bf90064d2dc..289a68b7f7b 100644 --- a/lib/Target/X86/Printer.cpp +++ b/lib/Target/X86/Printer.cpp @@ -783,8 +783,13 @@ void Printer::printMachineInstruction(const MachineInstr *MI) { // assert(MI->getNumOperands() >= 4 && MI->getNumOperands() <= 5 && isMem(MI, 0) && "Bad MRMSxM format!"); - assert((MI->getNumOperands() != 5 || MI->getOperand(4).isImmediate()) && + assert((MI->getNumOperands() != 5 || + (MI->getOperand(4).isImmediate() || + MI->getOperand(4).isGlobalAddress())) && "Bad MRMSxM format!"); + + const MachineOperand &Op3 = MI->getOperand(3); + // 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 @@ -792,57 +797,59 @@ void Printer::printMachineInstruction(const MachineInstr *MI) { if (MI->getOpCode() == X86::FSTPr80) { 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; + 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 0x" << std::hex << (unsigned) val << std::dec << "\t# "; - } else { // 1 byte disp. - unsigned char val = (unsigned char) DispVal; - O << ".byte 0xdb, 0x7c, 0x24, 0x" << std::hex << (unsigned) val - << std::dec << "\t# "; + O << ".long "; + printOp(Op3); + O << "\t# "; } } } + // 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(); - if ((DispVal < -128) || (DispVal > 127)) { // 4 byte disp. - unsigned int val = (unsigned int) DispVal; - O << ".byte 0xdb, 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 0xdb, 0x6c, 0x24, 0x" << std::hex << (unsigned) val - << std::dec << "\t# "; - } + if (MI->getOpCode() == X86::FLDr80 && + 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 // 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# "; - } + if (MI->getOpCode() == X86::FILDr64 && + 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# "; } } + // 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 diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index bf90064d2dc..289a68b7f7b 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -783,8 +783,13 @@ void Printer::printMachineInstruction(const MachineInstr *MI) { // assert(MI->getNumOperands() >= 4 && MI->getNumOperands() <= 5 && isMem(MI, 0) && "Bad MRMSxM format!"); - assert((MI->getNumOperands() != 5 || MI->getOperand(4).isImmediate()) && + assert((MI->getNumOperands() != 5 || + (MI->getOperand(4).isImmediate() || + MI->getOperand(4).isGlobalAddress())) && "Bad MRMSxM format!"); + + const MachineOperand &Op3 = MI->getOperand(3); + // 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 @@ -792,57 +797,59 @@ void Printer::printMachineInstruction(const MachineInstr *MI) { if (MI->getOpCode() == X86::FSTPr80) { 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; + 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 0x" << std::hex << (unsigned) val << std::dec << "\t# "; - } else { // 1 byte disp. - unsigned char val = (unsigned char) DispVal; - O << ".byte 0xdb, 0x7c, 0x24, 0x" << std::hex << (unsigned) val - << std::dec << "\t# "; + O << ".long "; + printOp(Op3); + O << "\t# "; } } } + // 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(); - if ((DispVal < -128) || (DispVal > 127)) { // 4 byte disp. - unsigned int val = (unsigned int) DispVal; - O << ".byte 0xdb, 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 0xdb, 0x6c, 0x24, 0x" << std::hex << (unsigned) val - << std::dec << "\t# "; - } + if (MI->getOpCode() == X86::FLDr80 && + 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 // 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# "; - } + if (MI->getOpCode() == X86::FILDr64 && + 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# "; } } + // 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