X86AsmPrinter.cpp revision 644e1abae4526e3b875d6bcf772089daaa2959b5
1//===-- X86/Printer.cpp - Convert X86 code to human readable rep. ---------===//
2//
3// This file contains a printer that converts from our internal representation
4// of LLVM code to a nice human readable form that is suitable for debuggging.
5//
6//===----------------------------------------------------------------------===//
7
8#include "X86.h"
9#include "X86InstrInfo.h"
10#include "llvm/Pass.h"
11#include "llvm/Function.h"
12#include "llvm/Target/TargetMachine.h"
13#include "llvm/CodeGen/MachineFunction.h"
14#include "llvm/CodeGen/MachineInstr.h"
15
16namespace {
17  struct Printer : public FunctionPass {
18    TargetMachine &TM;
19    std::ostream &O;
20
21    Printer(TargetMachine &tm, std::ostream &o) : TM(tm), O(o) {}
22
23    bool runOnFunction(Function &F);
24  };
25}
26
27/// createX86CodePrinterPass - Print out the specified machine code function to
28/// the specified stream.  This function should work regardless of whether or
29/// not the function is in SSA form or not.
30///
31Pass *createX86CodePrinterPass(TargetMachine &TM, std::ostream &O) {
32  return new Printer(TM, O);
33}
34
35
36/// runOnFunction - This uses the X86InstructionInfo::print method
37/// to print assembly for each instruction.
38bool Printer::runOnFunction (Function & F)
39{
40  static unsigned bbnumber = 0;
41  MachineFunction & MF = MachineFunction::get (&F);
42  const MachineInstrInfo & MII = TM.getInstrInfo ();
43
44  O << "; x86 printing only sorta implemented so far!\n";
45
46  // Print out labels for the function.
47  O << "\t.globl\t" << F.getName () << "\n";
48  O << "\t.type\t" << F.getName () << ", @function\n";
49  O << F.getName () << ":\n";
50
51  // Print out code for the function.
52  for (MachineFunction::const_iterator bb_i = MF.begin (), bb_e = MF.end ();
53       bb_i != bb_e; ++bb_i)
54    {
55      // Print a label for the basic block.
56      O << ".BB" << bbnumber++ << ":\n";
57      for (MachineBasicBlock::const_iterator i_i = bb_i->begin (), i_e =
58	   bb_i->end (); i_i != i_e; ++i_i)
59	{
60	  // Print the assembly for the instruction.
61	  O << "\t";
62          MII.print(*i_i, O, TM);
63	}
64    }
65
66  // We didn't modify anything.
67  return false;
68}
69
70static void printOp(std::ostream &O, const MachineOperand &MO,
71                    const MRegisterInfo &RI) {
72  switch (MO.getType()) {
73  case MachineOperand::MO_VirtualRegister:
74  case MachineOperand::MO_MachineRegister:
75    if (MO.getReg() < MRegisterInfo::FirstVirtualRegister)
76      O << RI.get(MO.getReg()).Name;
77    else
78      O << "%reg" << MO.getReg();
79    return;
80
81  default:
82    O << "<unknown op ty>"; return;
83  }
84}
85
86static inline void toHexDigit(std::ostream &O, unsigned char V) {
87  if (V >= 10)
88    O << (char)('A'+V-10);
89  else
90    O << (char)('0'+V);
91}
92
93static std::ostream &toHex(std::ostream &O, unsigned char V) {
94  toHexDigit(O, V >> 4);
95  toHexDigit(O, V & 0xF);
96  return O;
97}
98
99
100static bool isReg(const MachineOperand &MO) {
101  return MO.getType()==MachineOperand::MO_VirtualRegister ||
102         MO.getType()==MachineOperand::MO_MachineRegister;
103}
104
105
106// print - Print out an x86 instruction in intel syntax
107void X86InstrInfo::print(const MachineInstr *MI, std::ostream &O,
108                         const TargetMachine &TM) const {
109  unsigned Opcode = MI->getOpcode();
110  const MachineInstrDescriptor &Desc = get(Opcode);
111
112  if (Desc.TSFlags & X86II::TB)
113    O << "0F ";
114
115  switch (Desc.TSFlags & X86II::FormMask) {
116  case X86II::OtherFrm:
117    O << "\t";
118    O << "-"; MI->print(O, TM);
119    break;
120  case X86II::RawFrm:
121    toHex(O, getBaseOpcodeFor(Opcode)) << "\t";
122    O << getName(MI->getOpCode()) << " ";
123
124    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
125      if (i) O << ", ";
126      printOp(O, MI->getOperand(i), RI);
127    }
128    O << "\n";
129    return;
130
131
132  case X86II::AddRegFrm:
133    O << "\t-"; MI->print(O, TM); break;
134
135  case X86II::MRMDestReg:
136    // There are two acceptable forms of MRMDestReg instructions, those with 3
137    // and 2 operands:
138    //
139    // 3 Operands: in this form, the first two registers (the destination, and
140    // the first operand) should be the same, post register allocation.  The 3rd
141    // operand is an additional input.  This should be for things like add
142    // instructions.
143    //
144    // 2 Operands: this is for things like mov that do not read a second input
145    //
146    assert(isReg(MI->getOperand(0)) &&
147           (MI->getNumOperands() == 2 ||
148            (MI->getNumOperands() == 3 && isReg(MI->getOperand(1)))) &&
149           isReg(MI->getOperand(MI->getNumOperands()-1))
150           && "Bad format for MRMDestReg!");
151    if (MI->getNumOperands() == 3 &&
152        MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
153      O << "**";
154
155    O << "\t";
156    O << getName(MI->getOpCode()) << " ";
157    printOp(O, MI->getOperand(0), RI);
158    O << ", ";
159    printOp(O, MI->getOperand(MI->getNumOperands()-1), RI);
160    O << "\n";
161    return;
162  case X86II::MRMSrcReg:
163    // There is a two forms that are acceptable for MRMSrcReg instructions,
164    // those with 3 and 2 operands:
165    //
166    // 3 Operands: in this form, the last register (the second input) is the
167    // ModR/M input.  The first two operands should be the same, post register
168    // allocation.  This is for things like: add r32, r/m32
169    //
170    // 2 Operands: this is for things like mov that do not read a second input
171    //
172    assert(isReg(MI->getOperand(0)) &&
173           isReg(MI->getOperand(1)) &&
174           (MI->getNumOperands() == 2 ||
175            (MI->getNumOperands() == 3 && isReg(MI->getOperand(2))))
176           && "Bad format for MRMDestReg!");
177    if (MI->getNumOperands() == 3 &&
178        MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
179      O << "**";
180
181    O << "\t";
182    O << getName(MI->getOpCode()) << " ";
183    printOp(O, MI->getOperand(0), RI);
184    O << ", ";
185    printOp(O, MI->getOperand(MI->getNumOperands()-1), RI);
186    O << "\n";
187    return;
188
189  case X86II::MRMDestMem:
190  case X86II::MRMSrcMem:
191  default:
192    O << "\t-"; MI->print(O, TM); break;
193  }
194}
195