fix an ugly wart in the MCInstPrinter api where the
[oota-llvm.git] / lib / Target / X86 / AsmPrinter / X86IntelInstPrinter.cpp
1 //===-- X86IntelInstPrinter.cpp - AT&T assembly instruction printing ------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file includes code for rendering MCInst instances as AT&T-style
11 // assembly.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "asm-printer"
16 #include "X86IntelInstPrinter.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/FormattedStream.h"
22 #include "X86GenInstrNames.inc"
23 using namespace llvm;
24
25 // Include the auto-generated portion of the assembly writer.
26 #define MachineInstr MCInst
27 #define GET_INSTRUCTION_NAME
28 #include "X86GenAsmWriter1.inc"
29 #undef MachineInstr
30
31 void X86IntelInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) {
32   printInstruction(MI, OS);
33 }
34 StringRef X86IntelInstPrinter::getOpcodeName(unsigned Opcode) const {
35   return getInstructionName(Opcode);
36 }
37
38 void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
39                                      raw_ostream &O) {
40   switch (MI->getOperand(Op).getImm()) {
41   default: assert(0 && "Invalid ssecc argument!");
42   case 0: O << "eq"; break;
43   case 1: O << "lt"; break;
44   case 2: O << "le"; break;
45   case 3: O << "unord"; break;
46   case 4: O << "neq"; break;
47   case 5: O << "nlt"; break;
48   case 6: O << "nle"; break;
49   case 7: O << "ord"; break;
50   }
51 }
52
53 /// print_pcrel_imm - This is used to print an immediate value that ends up
54 /// being encoded as a pc-relative value.
55 void X86IntelInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo,
56                                           raw_ostream &O) {
57   const MCOperand &Op = MI->getOperand(OpNo);
58   if (Op.isImm())
59     O << Op.getImm();
60   else {
61     assert(Op.isExpr() && "unknown pcrel immediate operand");
62     O << *Op.getExpr();
63   }
64 }
65
66 static void PrintRegName(raw_ostream &O, StringRef RegName) {
67   for (unsigned i = 0, e = RegName.size(); i != e; ++i)
68     O << (char)toupper(RegName[i]);
69 }
70
71 void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
72                                        raw_ostream &O) {
73   const MCOperand &Op = MI->getOperand(OpNo);
74   if (Op.isReg()) {
75     PrintRegName(O, getRegisterName(Op.getReg()));
76   } else if (Op.isImm()) {
77     O << Op.getImm();
78   } else {
79     assert(Op.isExpr() && "unknown operand kind in printOperand");
80     O << *Op.getExpr();
81   }
82 }
83
84 void X86IntelInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op,
85                                                raw_ostream &O) {
86   const MCOperand &BaseReg  = MI->getOperand(Op);
87   unsigned ScaleVal         = MI->getOperand(Op+1).getImm();
88   const MCOperand &IndexReg = MI->getOperand(Op+2);
89   const MCOperand &DispSpec = MI->getOperand(Op+3);
90   
91   O << '[';
92   
93   bool NeedPlus = false;
94   if (BaseReg.getReg()) {
95     printOperand(MI, Op, O);
96     NeedPlus = true;
97   }
98   
99   if (IndexReg.getReg()) {
100     if (NeedPlus) O << " + ";
101     if (ScaleVal != 1)
102       O << ScaleVal << '*';
103     printOperand(MI, Op+2, O);
104     NeedPlus = true;
105   }
106   
107  
108   if (!DispSpec.isImm()) {
109     if (NeedPlus) O << " + ";
110     assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
111     O << *DispSpec.getExpr();
112   } else {
113     int64_t DispVal = DispSpec.getImm();
114     if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) {
115       if (NeedPlus) {
116         if (DispVal > 0)
117           O << " + ";
118         else {
119           O << " - ";
120           DispVal = -DispVal;
121         }
122       }
123       O << DispVal;
124     }
125   }
126   
127   O << ']';
128 }
129
130 void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
131                                             raw_ostream &O) {
132   // If this has a segment register, print it.
133   if (MI->getOperand(Op+4).getReg()) {
134     printOperand(MI, Op+4, O);
135     O << ':';
136   }
137   printLeaMemReference(MI, Op, O);
138 }