From 2a998bdc7c135f712b04421d573ddb215f4ea7f1 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 11 Aug 2004 07:02:04 +0000 Subject: [PATCH] Finally, the entire instruction asmprinter is now generated from tblgen, woo! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15658 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86AsmPrinter.cpp | 304 +------------------------------ 1 file changed, 8 insertions(+), 296 deletions(-) diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 6f7f642208a..cf7c01f01b1 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -438,8 +438,8 @@ static bool isMem(const MachineInstr *MI, unsigned Op) { if (MI->getOperand(Op).isFrameIndex()) return true; if (MI->getOperand(Op).isConstantPoolIndex()) return true; return Op+4 <= MI->getNumOperands() && - MI->getOperand(Op ).isRegister() &&isScale(MI->getOperand(Op+1)) && - MI->getOperand(Op+2).isRegister() &&MI->getOperand(Op+3).isImmediate(); + MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) && + MI->getOperand(Op+2).isRegister() && MI->getOperand(Op+3).isImmediate(); } @@ -490,17 +490,6 @@ void X86AsmPrinter::printOp(const MachineOperand &MO, } } -static const char* const sizePtr(const TargetInstrDescriptor &Desc) { - switch (Desc.TSFlags & X86II::MemMask) { - default: assert(0 && "Unknown arg size!"); - case X86II::Mem8: return "BYTE PTR"; - case X86II::Mem16: return "WORD PTR"; - case X86II::Mem32: return "DWORD PTR"; - case X86II::Mem64: return "QWORD PTR"; - case X86II::Mem80: return "XWORD PTR"; - } -} - void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) { assert(isMem(MI, Op) && "Invalid memory reference!"); @@ -619,289 +608,12 @@ void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) { O << "\t# "; } - if (printInstruction(MI)) - return; // Printer was automatically generated - - MI->dump(); - abort(); - - unsigned Opcode = MI->getOpcode(); - const TargetInstrInfo &TII = *TM.getInstrInfo(); - const TargetInstrDescriptor &Desc = TII.get(Opcode); - - switch (Desc.TSFlags & X86II::FormMask) { - case X86II::Pseudo: - // Print pseudo-instructions as comments; either they should have been - // turned into real instructions by now, or they don't need to be - // seen by the assembler (e.g., IMPLICIT_USEs.) - O << "# "; - if (Opcode == X86::PHI) { - printOp(MI->getOperand(0)); - O << " = phi "; - for (unsigned i = 1, e = MI->getNumOperands(); i != e; i+=2) { - if (i != 1) O << ", "; - O << "["; - printOp(MI->getOperand(i)); - O << ", "; - printOp(MI->getOperand(i+1)); - O << "]"; - } - } else { - unsigned i = 0; - if (MI->getNumOperands() && MI->getOperand(0).isDef()) { - printOp(MI->getOperand(0)); - O << " = "; - ++i; - } - O << TII.getName(MI->getOpcode()); - - for (unsigned e = MI->getNumOperands(); i != e; ++i) { - O << " "; - if (MI->getOperand(i).isDef()) O << "*"; - printOp(MI->getOperand(i)); - if (MI->getOperand(i).isDef()) O << "*"; - } - } - O << "\n"; - return; - - case X86II::RawFrm: - { - // The accepted forms of Raw instructions are: - // 1. jmp foo - MachineBasicBlock operand - // 2. call bar - GlobalAddress Operand or External Symbol Operand - // 3. in AL, imm - Immediate operand - // - assert(MI->getNumOperands() == 1 && - (MI->getOperand(0).isMachineBasicBlock() || - MI->getOperand(0).isGlobalAddress() || - MI->getOperand(0).isExternalSymbol() || - MI->getOperand(0).isImmediate()) && - "Illegal raw instruction!"); - O << TII.getName(MI->getOpcode()) << " "; - - bool LeadingComma = false; - if (MI->getNumOperands() == 1) { - printOp(MI->getOperand(0), true); // Don't print "OFFSET"... - LeadingComma = true; - } - printImplUsesAfter(Desc, LeadingComma); - O << "\n"; - return; - } - - case X86II::AddRegFrm: { - // There are currently two forms of acceptable AddRegFrm instructions. - // Either the instruction JUST takes a single register (like inc, dec, etc), - // or it takes a register and an immediate of the same size as the register - // (move immediate f.e.). Note that this immediate value might be stored as - // an LLVM value, to represent, for example, loading the address of a global - // into a register. The initial register might be duplicated if this is a - // M_2_ADDR_REG instruction - // - assert(MI->getOperand(0).isRegister() && - (MI->getNumOperands() == 1 || - (MI->getNumOperands() == 2 && - (MI->getOperand(1).getVRegValueOrNull() || - MI->getOperand(1).isImmediate() || - MI->getOperand(1).isRegister() || - MI->getOperand(1).isGlobalAddress() || - MI->getOperand(1).isExternalSymbol()))) && - "Illegal form for AddRegFrm instruction!"); - - unsigned Reg = MI->getOperand(0).getReg(); - - O << TII.getName(MI->getOpcode()) << " "; - - printOp(MI->getOperand(0)); - if (MI->getNumOperands() == 2 && - (!MI->getOperand(1).isRegister() || - MI->getOperand(1).getVRegValueOrNull() || - MI->getOperand(1).isGlobalAddress() || - MI->getOperand(1).isExternalSymbol())) { - O << ", "; - printOp(MI->getOperand(1)); - } - printImplUsesAfter(Desc); - O << "\n"; - return; - } - case X86II::MRMDestReg: { - // There are three forms of MRMDestReg instructions, those with 2 - // or 3 operands: - // - // 2 Operands: this is for things like mov that do not read a - // second input. - // - // 2 Operands: two address instructions which def&use the first - // argument and use the second as input. - // - // 3 Operands: in this form, two address instructions are the same - // as in 2 but have a constant argument as well. - // - bool isTwoAddr = TII.isTwoAddrInstr(Opcode); - assert(MI->getOperand(0).isRegister() && - (MI->getNumOperands() == 2 || - (MI->getNumOperands() == 3 && MI->getOperand(2).isImmediate())) - && "Bad format for MRMDestReg!"); - - O << TII.getName(MI->getOpcode()) << " "; - printOp(MI->getOperand(0)); - O << ", "; - printOp(MI->getOperand(1)); - if (MI->getNumOperands() == 3) { - O << ", "; - printOp(MI->getOperand(2)); - } - printImplUsesAfter(Desc); - O << "\n"; - return; - } - - case X86II::MRMDestMem: { - // These instructions are the same as MRMDestReg, but instead of having a - // register reference for the mod/rm field, it's a memory reference. - // - assert(isMem(MI, 0) && - (MI->getNumOperands() == 4+1 || - (MI->getNumOperands() == 4+2 && MI->getOperand(5).isImmediate())) - && "Bad format for MRMDestMem!"); - - O << TII.getName(MI->getOpcode()) << " " << sizePtr(Desc) << " "; - printMemReference(MI, 0); - O << ", "; - printOp(MI->getOperand(4)); - if (MI->getNumOperands() == 4+2) { - O << ", "; - printOp(MI->getOperand(5)); - } - printImplUsesAfter(Desc); - O << "\n"; - return; - } - - case X86II::MRMSrcReg: { - // There are three forms that are acceptable for MRMSrcReg - // instructions, those with 2 or 3 operands: - // - // 2 Operands: this is for things like mov that do not read a - // second input. - // - // 2 Operands: in this form, the last register is the ModR/M - // input. The first operand is a def&use. This is for things - // like: add r32, r/m32 - // - // 3 Operands: in this form, we can have 'INST R1, R2, imm', which is used - // for instructions like the IMULrri instructions. - // - // - assert(MI->getOperand(0).isRegister() && - MI->getOperand(1).isRegister() && - (MI->getNumOperands() == 2 || - (MI->getNumOperands() == 3 && - (MI->getOperand(2).isImmediate()))) - && "Bad format for MRMSrcReg!"); - - O << TII.getName(MI->getOpcode()) << " "; - printOp(MI->getOperand(0)); - O << ", "; - printOp(MI->getOperand(1)); - if (MI->getNumOperands() == 3) { - O << ", "; - printOp(MI->getOperand(2)); - } - O << "\n"; - return; - } - - case X86II::MRMSrcMem: { - // These instructions are the same as MRMSrcReg, but instead of having a - // register reference for the mod/rm field, it's a memory reference. - // - assert(MI->getOperand(0).isRegister() && - ((MI->getNumOperands() == 1+4 && isMem(MI, 1)) || - (MI->getNumOperands() == 2+4 && MI->getOperand(5).isImmediate() && - isMem(MI, 1))) - && "Bad format for MRMSrcMem!"); - O << TII.getName(MI->getOpcode()) << " "; - printOp(MI->getOperand(0)); - O << ", " << sizePtr(Desc) << " "; - printMemReference(MI, 1); - if (MI->getNumOperands() == 2+4) { - O << ", "; - printOp(MI->getOperand(5)); - } - O << "\n"; - return; - } - - case X86II::MRM0r: case X86II::MRM1r: - case X86II::MRM2r: case X86II::MRM3r: - case X86II::MRM4r: case X86II::MRM5r: - case X86II::MRM6r: case X86II::MRM7r: { - // In this form, the following are valid formats: - // 1. sete r - // 2. cmp reg, immediate - // 2. shl rdest, rinput - // 3. sbb rdest, rinput, immediate [rdest = rinput] - // - assert(MI->getNumOperands() > 0 && MI->getNumOperands() < 4 && - MI->getOperand(0).isRegister() && "Bad MRMSxR format!"); - assert((MI->getNumOperands() != 2 || - MI->getOperand(1).isRegister() || MI->getOperand(1).isImmediate())&& - "Bad MRMSxR format!"); - assert((MI->getNumOperands() < 3 || - (MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate())) && - "Bad MRMSxR format!"); - - if (MI->getNumOperands() > 1 && MI->getOperand(1).isRegister() && - MI->getOperand(0).getReg() != MI->getOperand(1).getReg()) - O << "**"; - - O << TII.getName(MI->getOpcode()) << " "; - printOp(MI->getOperand(0)); - if (MI->getOperand(MI->getNumOperands()-1).isImmediate()) { - O << ", "; - printOp(MI->getOperand(MI->getNumOperands()-1)); - } - printImplUsesAfter(Desc); - O << "\n"; - - return; - } - - case X86II::MRM0m: case X86II::MRM1m: - case X86II::MRM2m: case X86II::MRM3m: - case X86II::MRM4m: case X86II::MRM5m: - case X86II::MRM6m: case X86II::MRM7m: { - // In this form, the following are valid formats: - // 1. sete [m] - // 2. cmp [m], immediate - // 2. shl [m], rinput - // 3. sbb [m], immediate - // - assert(MI->getNumOperands() >= 4 && MI->getNumOperands() <= 5 && - isMem(MI, 0) && "Bad MRMSxM format!"); - assert((MI->getNumOperands() != 5 || - (MI->getOperand(4).isImmediate() || - MI->getOperand(4).isGlobalAddress())) && - "Bad MRMSxM format!"); - - const MachineOperand &Op3 = MI->getOperand(3); - - O << TII.getName(MI->getOpcode()) << " "; - O << sizePtr(Desc) << " "; - printMemReference(MI, 0); - if (MI->getNumOperands() == 5) { - O << ", "; - printOp(MI->getOperand(4)); - } - printImplUsesAfter(Desc); - O << "\n"; - return; - } - default: - O << "\tUNKNOWN FORM:\t\t-"; MI->print(O, &TM); break; + // Call the autogenerated instruction printer routines. + bool Handled = printInstruction(MI); + if (!Handled) { + MI->dump(); + assert(0 && "Do not know how to print this instruction!"); + abort(); } } -- 2.34.1