[PowerPC] Support the (old) cntlz instruction alias
[oota-llvm.git] / lib / Target / X86 / InstPrinter / X86ATTInstPrinter.cpp
1 //===-- X86ATTInstPrinter.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 #include "X86ATTInstPrinter.h"
16 #include "MCTargetDesc/X86BaseInfo.h"
17 #include "MCTargetDesc/X86MCTargetDesc.h"
18 #include "X86InstComments.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCRegisterInfo.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/Format.h"
26 #include "llvm/Support/FormattedStream.h"
27 #include <map>
28 using namespace llvm;
29
30 #define DEBUG_TYPE "asm-printer"
31
32 // Include the auto-generated portion of the assembly writer.
33 #define PRINT_ALIAS_INSTR
34 #include "X86GenAsmWriter.inc"
35
36 void X86ATTInstPrinter::printRegName(raw_ostream &OS,
37                                      unsigned RegNo) const {
38   OS << markup("<reg:")
39      << '%' << getRegisterName(RegNo)
40      << markup(">");
41 }
42
43 void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
44                                   StringRef Annot) {
45   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
46   uint64_t TSFlags = Desc.TSFlags;
47
48   // If verbose assembly is enabled, we can print some informative comments.
49   if (CommentStream)
50     HasCustomInstComment =
51         EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
52
53   if (TSFlags & X86II::LOCK)
54     OS << "\tlock\n";
55
56   // Output CALLpcrel32 as "callq" in 64-bit mode.
57   // In Intel annotation it's always emitted as "call".
58   //
59   // TODO: Probably this hack should be redesigned via InstAlias in
60   // InstrInfo.td as soon as Requires clause is supported properly
61   // for InstAlias.
62   if (MI->getOpcode() == X86::CALLpcrel32 &&
63       (getAvailableFeatures() & X86::Mode64Bit) != 0) {
64     OS << "\tcallq\t";
65     printPCRelImm(MI, 0, OS);
66   }
67   // Try to print any aliases first.
68   else if (!printAliasInstr(MI, OS))
69     printInstruction(MI, OS);
70
71   // Next always print the annotation.
72   printAnnotation(OS, Annot);
73 }
74
75 void X86ATTInstPrinter::printSSEAVXCC(const MCInst *MI, unsigned Op,
76                                       raw_ostream &O) {
77   int64_t Imm = MI->getOperand(Op).getImm();
78   switch (Imm) {
79   default: llvm_unreachable("Invalid ssecc/avxcc argument!");
80   case    0: O << "eq"; break;
81   case    1: O << "lt"; break;
82   case    2: O << "le"; break;
83   case    3: O << "unord"; break;
84   case    4: O << "neq"; break;
85   case    5: O << "nlt"; break;
86   case    6: O << "nle"; break;
87   case    7: O << "ord"; break;
88   case    8: O << "eq_uq"; break;
89   case    9: O << "nge"; break;
90   case  0xa: O << "ngt"; break;
91   case  0xb: O << "false"; break;
92   case  0xc: O << "neq_oq"; break;
93   case  0xd: O << "ge"; break;
94   case  0xe: O << "gt"; break;
95   case  0xf: O << "true"; break;
96   case 0x10: O << "eq_os"; break;
97   case 0x11: O << "lt_oq"; break;
98   case 0x12: O << "le_oq"; break;
99   case 0x13: O << "unord_s"; break;
100   case 0x14: O << "neq_us"; break;
101   case 0x15: O << "nlt_uq"; break;
102   case 0x16: O << "nle_uq"; break;
103   case 0x17: O << "ord_s"; break;
104   case 0x18: O << "eq_us"; break;
105   case 0x19: O << "nge_uq"; break;
106   case 0x1a: O << "ngt_uq"; break;
107   case 0x1b: O << "false_os"; break;
108   case 0x1c: O << "neq_os"; break;
109   case 0x1d: O << "ge_oq"; break;
110   case 0x1e: O << "gt_oq"; break;
111   case 0x1f: O << "true_us"; break;
112   }
113 }
114
115 void X86ATTInstPrinter::printRoundingControl(const MCInst *MI, unsigned Op,
116                                    raw_ostream &O) {
117   int64_t Imm = MI->getOperand(Op).getImm() & 0x3;
118   switch (Imm) {
119   case 0: O << "{rn-sae}"; break;
120   case 1: O << "{rd-sae}"; break;
121   case 2: O << "{ru-sae}"; break;
122   case 3: O << "{rz-sae}"; break;
123   }
124 }
125 /// printPCRelImm - This is used to print an immediate value that ends up
126 /// being encoded as a pc-relative value (e.g. for jumps and calls).  These
127 /// print slightly differently than normal immediates.  For example, a $ is not
128 /// emitted.
129 void X86ATTInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
130                                       raw_ostream &O) {
131   const MCOperand &Op = MI->getOperand(OpNo);
132   if (Op.isImm())
133     O << formatImm(Op.getImm());
134   else {
135     assert(Op.isExpr() && "unknown pcrel immediate operand");
136     // If a symbolic branch target was added as a constant expression then print
137     // that address in hex.
138     const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
139     int64_t Address;
140     if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
141       O << formatHex((uint64_t)Address);
142     } else {
143       // Otherwise, just print the expression.
144       O << *Op.getExpr();
145     }
146   }
147 }
148
149 void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
150                                      raw_ostream &O) {
151   const MCOperand &Op = MI->getOperand(OpNo);
152   if (Op.isReg()) {
153     printRegName(O, Op.getReg());
154   } else if (Op.isImm()) {
155     // Print X86 immediates as signed values.
156     O << markup("<imm:")
157       << '$' << formatImm((int64_t)Op.getImm())
158       << markup(">");
159
160     // If there are no instruction-specific comments, add a comment clarifying
161     // the hex value of the immediate operand when it isn't in the range
162     // [-256,255].
163     if (CommentStream && !HasCustomInstComment &&
164         (Op.getImm() > 255 || Op.getImm() < -256))
165       *CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Op.getImm());
166
167   } else {
168     assert(Op.isExpr() && "unknown operand kind in printOperand");
169     O << markup("<imm:")
170       << '$' << *Op.getExpr()
171       << markup(">");
172   }
173 }
174
175 void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
176                                           raw_ostream &O) {
177   const MCOperand &BaseReg  = MI->getOperand(Op+X86::AddrBaseReg);
178   const MCOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg);
179   const MCOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp);
180   const MCOperand &SegReg = MI->getOperand(Op+X86::AddrSegmentReg);
181
182   O << markup("<mem:");
183
184   // If this has a segment register, print it.
185   if (SegReg.getReg()) {
186     printOperand(MI, Op+X86::AddrSegmentReg, O);
187     O << ':';
188   }
189
190   if (DispSpec.isImm()) {
191     int64_t DispVal = DispSpec.getImm();
192     if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
193       O << formatImm(DispVal);
194   } else {
195     assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
196     O << *DispSpec.getExpr();
197   }
198
199   if (IndexReg.getReg() || BaseReg.getReg()) {
200     O << '(';
201     if (BaseReg.getReg())
202       printOperand(MI, Op+X86::AddrBaseReg, O);
203
204     if (IndexReg.getReg()) {
205       O << ',';
206       printOperand(MI, Op+X86::AddrIndexReg, O);
207       unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm();
208       if (ScaleVal != 1) {
209         O << ','
210           << markup("<imm:")
211           << ScaleVal // never printed in hex.
212           << markup(">");
213       }
214     }
215     O << ')';
216   }
217
218   O << markup(">");
219 }
220
221 void X86ATTInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op,
222                                     raw_ostream &O) {
223   const MCOperand &SegReg = MI->getOperand(Op+1);
224
225   O << markup("<mem:");
226
227   // If this has a segment register, print it.
228   if (SegReg.getReg()) {
229     printOperand(MI, Op+1, O);
230     O << ':';
231   }
232
233   O << "(";
234   printOperand(MI, Op, O);
235   O << ")";
236
237   O << markup(">");
238 }
239
240 void X86ATTInstPrinter::printDstIdx(const MCInst *MI, unsigned Op,
241                                     raw_ostream &O) {
242   O << markup("<mem:");
243
244   O << "%es:(";
245   printOperand(MI, Op, O);
246   O << ")";
247
248   O << markup(">");
249 }
250
251 void X86ATTInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
252                                        raw_ostream &O) {
253   const MCOperand &DispSpec = MI->getOperand(Op);
254   const MCOperand &SegReg = MI->getOperand(Op+1);
255
256   O << markup("<mem:");
257
258   // If this has a segment register, print it.
259   if (SegReg.getReg()) {
260     printOperand(MI, Op+1, O);
261     O << ':';
262   }
263
264   if (DispSpec.isImm()) {
265     O << formatImm(DispSpec.getImm());
266   } else {
267     assert(DispSpec.isExpr() && "non-immediate displacement?");
268     O << *DispSpec.getExpr();
269   }
270
271   O << markup(">");
272 }
273
274 void X86ATTInstPrinter::printU8Imm(const MCInst *MI, unsigned Op,
275                                    raw_ostream &O) {
276   O << markup("<imm:")
277     << '$' << formatImm(MI->getOperand(Op).getImm() & 0xff)
278     << markup(">");
279 }