e7821956b33b157816ea1f2875e612407ee8da4a
[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 NO_ASM_WRITER_BOILERPLATE
28 #define X86IntelAsmPrinter X86IntelInstPrinter
29 #include "X86GenAsmWriter1.inc"
30 #undef MachineInstr
31
32 void X86IntelInstPrinter::printInst(const MCInst *MI) { printInstruction(MI); }
33
34 void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op) {
35   switch (MI->getOperand(Op).getImm()) {
36   default: llvm_unreachable("Invalid ssecc argument!");
37   case 0: O << "eq"; break;
38   case 1: O << "lt"; break;
39   case 2: O << "le"; break;
40   case 3: O << "unord"; break;
41   case 4: O << "neq"; break;
42   case 5: O << "nlt"; break;
43   case 6: O << "nle"; break;
44   case 7: O << "ord"; break;
45   }
46 }
47
48 /// print_pcrel_imm - This is used to print an immediate value that ends up
49 /// being encoded as a pc-relative value.  These print slightly differently, for
50 /// example, a $ is not emitted.
51 void X86IntelInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) {
52   const MCOperand &Op = MI->getOperand(OpNo);
53   if (Op.isImm())
54     O << Op.getImm();
55   else {
56     assert(Op.isExpr() && "unknown pcrel immediate operand");
57     Op.getExpr()->print(O, &MAI);
58   }
59 }
60
61 static void PrintRegName(raw_ostream &O, StringRef RegName) {
62   for (unsigned i = 0, e = RegName.size(); i != e; ++i)
63     O << (char)toupper(RegName[i]);
64 }
65
66 void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
67                                      const char *Modifier) {
68   assert(Modifier == 0 && "Modifiers should not be used");
69   
70   const MCOperand &Op = MI->getOperand(OpNo);
71   if (Op.isReg()) {
72     PrintRegName(O, getRegisterName(Op.getReg()));
73   } else if (Op.isImm()) {
74     O << Op.getImm();
75   } else {
76     assert(Op.isExpr() && "unknown operand kind in printOperand");
77     Op.getExpr()->print(O, &MAI);
78   }
79 }
80
81 void X86IntelInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
82   const MCOperand &BaseReg  = MI->getOperand(Op);
83   unsigned ScaleVal         = MI->getOperand(Op+1).getImm();
84   const MCOperand &IndexReg = MI->getOperand(Op+2);
85   const MCOperand &DispSpec = MI->getOperand(Op+3);
86   
87   O << '[';
88   
89   bool NeedPlus = false;
90   if (BaseReg.getReg()) {
91     printOperand(MI, Op);
92     NeedPlus = true;
93   }
94   
95   if (IndexReg.getReg()) {
96     if (NeedPlus) O << " + ";
97     if (ScaleVal != 1)
98       O << ScaleVal << '*';
99     printOperand(MI, Op+2);
100     NeedPlus = true;
101   }
102   
103  
104   if (!DispSpec.isImm()) {
105     if (NeedPlus) O << " + ";
106     assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
107     DispSpec.getExpr()->print(O, &MAI);
108   } else {
109     int64_t DispVal = DispSpec.getImm();
110     if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) {
111       if (NeedPlus) {
112         if (DispVal > 0)
113           O << " + ";
114         else {
115           O << " - ";
116           DispVal = -DispVal;
117         }
118       }
119       O << DispVal;
120     }
121   }
122   
123   O << ']';
124 }
125
126 void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op) {
127   // If this has a segment register, print it.
128   if (MI->getOperand(Op+4).getReg()) {
129     printOperand(MI, Op+4);
130     O << ':';
131   }
132   printLeaMemReference(MI, Op);
133 }