LLVM  3.7.0
X86ATTInstPrinter.cpp
Go to the documentation of this file.
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"
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"
25 #include "llvm/Support/Format.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, unsigned RegNo) const {
37  OS << markup("<reg:") << '%' << getRegisterName(RegNo) << markup(">");
38 }
39 
41  StringRef Annot, const MCSubtargetInfo &STI) {
42  const MCInstrDesc &Desc = MII.get(MI->getOpcode());
43  uint64_t TSFlags = Desc.TSFlags;
44 
45  // If verbose assembly is enabled, we can print some informative comments.
46  if (CommentStream)
47  HasCustomInstComment =
49 
50  if (TSFlags & X86II::LOCK)
51  OS << "\tlock\t";
52 
53  // Output CALLpcrel32 as "callq" in 64-bit mode.
54  // In Intel annotation it's always emitted as "call".
55  //
56  // TODO: Probably this hack should be redesigned via InstAlias in
57  // InstrInfo.td as soon as Requires clause is supported properly
58  // for InstAlias.
59  if (MI->getOpcode() == X86::CALLpcrel32 &&
60  (STI.getFeatureBits()[X86::Mode64Bit])) {
61  OS << "\tcallq\t";
62  printPCRelImm(MI, 0, OS);
63  }
64  // Try to print any aliases first.
65  else if (!printAliasInstr(MI, OS))
66  printInstruction(MI, OS);
67 
68  // Next always print the annotation.
69  printAnnotation(OS, Annot);
70 }
71 
72 void X86ATTInstPrinter::printSSEAVXCC(const MCInst *MI, unsigned Op,
73  raw_ostream &O) {
74  int64_t Imm = MI->getOperand(Op).getImm();
75  switch (Imm) {
76  default: llvm_unreachable("Invalid ssecc/avxcc argument!");
77  case 0: O << "eq"; break;
78  case 1: O << "lt"; break;
79  case 2: O << "le"; break;
80  case 3: O << "unord"; break;
81  case 4: O << "neq"; break;
82  case 5: O << "nlt"; break;
83  case 6: O << "nle"; break;
84  case 7: O << "ord"; break;
85  case 8: O << "eq_uq"; break;
86  case 9: O << "nge"; break;
87  case 0xa: O << "ngt"; break;
88  case 0xb: O << "false"; break;
89  case 0xc: O << "neq_oq"; break;
90  case 0xd: O << "ge"; break;
91  case 0xe: O << "gt"; break;
92  case 0xf: O << "true"; break;
93  case 0x10: O << "eq_os"; break;
94  case 0x11: O << "lt_oq"; break;
95  case 0x12: O << "le_oq"; break;
96  case 0x13: O << "unord_s"; break;
97  case 0x14: O << "neq_us"; break;
98  case 0x15: O << "nlt_uq"; break;
99  case 0x16: O << "nle_uq"; break;
100  case 0x17: O << "ord_s"; break;
101  case 0x18: O << "eq_us"; break;
102  case 0x19: O << "nge_uq"; break;
103  case 0x1a: O << "ngt_uq"; break;
104  case 0x1b: O << "false_os"; break;
105  case 0x1c: O << "neq_os"; break;
106  case 0x1d: O << "ge_oq"; break;
107  case 0x1e: O << "gt_oq"; break;
108  case 0x1f: O << "true_us"; break;
109  }
110 }
111 
112 void X86ATTInstPrinter::printXOPCC(const MCInst *MI, unsigned Op,
113  raw_ostream &O) {
114  int64_t Imm = MI->getOperand(Op).getImm();
115  switch (Imm) {
116  default: llvm_unreachable("Invalid xopcc argument!");
117  case 0: O << "lt"; break;
118  case 1: O << "le"; break;
119  case 2: O << "gt"; break;
120  case 3: O << "ge"; break;
121  case 4: O << "eq"; break;
122  case 5: O << "neq"; break;
123  case 6: O << "false"; break;
124  case 7: O << "true"; break;
125  }
126 }
127 
129  raw_ostream &O) {
130  int64_t Imm = MI->getOperand(Op).getImm() & 0x3;
131  switch (Imm) {
132  case 0: O << "{rn-sae}"; break;
133  case 1: O << "{rd-sae}"; break;
134  case 2: O << "{ru-sae}"; break;
135  case 3: O << "{rz-sae}"; break;
136  }
137 }
138 /// printPCRelImm - This is used to print an immediate value that ends up
139 /// being encoded as a pc-relative value (e.g. for jumps and calls). These
140 /// print slightly differently than normal immediates. For example, a $ is not
141 /// emitted.
142 void X86ATTInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
143  raw_ostream &O) {
144  const MCOperand &Op = MI->getOperand(OpNo);
145  if (Op.isImm())
146  O << formatImm(Op.getImm());
147  else {
148  assert(Op.isExpr() && "unknown pcrel immediate operand");
149  // If a symbolic branch target was added as a constant expression then print
150  // that address in hex.
151  const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
152  int64_t Address;
153  if (BranchTarget && BranchTarget->evaluateAsAbsolute(Address)) {
154  O << formatHex((uint64_t)Address);
155  } else {
156  // Otherwise, just print the expression.
157  Op.getExpr()->print(O, &MAI);
158  }
159  }
160 }
161 
162 void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
163  raw_ostream &O) {
164  const MCOperand &Op = MI->getOperand(OpNo);
165  if (Op.isReg()) {
166  printRegName(O, Op.getReg());
167  } else if (Op.isImm()) {
168  // Print X86 immediates as signed values.
169  O << markup("<imm:") << '$' << formatImm((int64_t)Op.getImm())
170  << markup(">");
171 
172  // If there are no instruction-specific comments, add a comment clarifying
173  // the hex value of the immediate operand when it isn't in the range
174  // [-256,255].
175  if (CommentStream && !HasCustomInstComment &&
176  (Op.getImm() > 255 || Op.getImm() < -256))
177  *CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Op.getImm());
178 
179  } else {
180  assert(Op.isExpr() && "unknown operand kind in printOperand");
181  O << markup("<imm:") << '$';
182  Op.getExpr()->print(O, &MAI);
183  O << markup(">");
184  }
185 }
186 
188  raw_ostream &O) {
189  const MCOperand &BaseReg = MI->getOperand(Op + X86::AddrBaseReg);
190  const MCOperand &IndexReg = MI->getOperand(Op + X86::AddrIndexReg);
191  const MCOperand &DispSpec = MI->getOperand(Op + X86::AddrDisp);
192  const MCOperand &SegReg = MI->getOperand(Op + X86::AddrSegmentReg);
193 
194  O << markup("<mem:");
195 
196  // If this has a segment register, print it.
197  if (SegReg.getReg()) {
198  printOperand(MI, Op + X86::AddrSegmentReg, O);
199  O << ':';
200  }
201 
202  if (DispSpec.isImm()) {
203  int64_t DispVal = DispSpec.getImm();
204  if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
205  O << formatImm(DispVal);
206  } else {
207  assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
208  DispSpec.getExpr()->print(O, &MAI);
209  }
210 
211  if (IndexReg.getReg() || BaseReg.getReg()) {
212  O << '(';
213  if (BaseReg.getReg())
214  printOperand(MI, Op + X86::AddrBaseReg, O);
215 
216  if (IndexReg.getReg()) {
217  O << ',';
218  printOperand(MI, Op + X86::AddrIndexReg, O);
219  unsigned ScaleVal = MI->getOperand(Op + X86::AddrScaleAmt).getImm();
220  if (ScaleVal != 1) {
221  O << ',' << markup("<imm:") << ScaleVal // never printed in hex.
222  << markup(">");
223  }
224  }
225  O << ')';
226  }
227 
228  O << markup(">");
229 }
230 
231 void X86ATTInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op,
232  raw_ostream &O) {
233  const MCOperand &SegReg = MI->getOperand(Op + 1);
234 
235  O << markup("<mem:");
236 
237  // If this has a segment register, print it.
238  if (SegReg.getReg()) {
239  printOperand(MI, Op + 1, O);
240  O << ':';
241  }
242 
243  O << "(";
244  printOperand(MI, Op, O);
245  O << ")";
246 
247  O << markup(">");
248 }
249 
250 void X86ATTInstPrinter::printDstIdx(const MCInst *MI, unsigned Op,
251  raw_ostream &O) {
252  O << markup("<mem:");
253 
254  O << "%es:(";
255  printOperand(MI, Op, O);
256  O << ")";
257 
258  O << markup(">");
259 }
260 
261 void X86ATTInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
262  raw_ostream &O) {
263  const MCOperand &DispSpec = MI->getOperand(Op);
264  const MCOperand &SegReg = MI->getOperand(Op + 1);
265 
266  O << markup("<mem:");
267 
268  // If this has a segment register, print it.
269  if (SegReg.getReg()) {
270  printOperand(MI, Op + 1, O);
271  O << ':';
272  }
273 
274  if (DispSpec.isImm()) {
275  O << formatImm(DispSpec.getImm());
276  } else {
277  assert(DispSpec.isExpr() && "non-immediate displacement?");
278  DispSpec.getExpr()->print(O, &MAI);
279  }
280 
281  O << markup(">");
282 }
283 
284 void X86ATTInstPrinter::printU8Imm(const MCInst *MI, unsigned Op,
285  raw_ostream &O) {
286  O << markup("<imm:") << '$' << formatImm(MI->getOperand(Op).getImm() & 0xff)
287  << markup(">");
288 }
void printDstIdx(const MCInst *MI, unsigned OpNo, raw_ostream &OS)
void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, const MCSubtargetInfo &STI) override
Print the specified MCInst to the specified raw_ostream.
static const char * getRegisterName(unsigned RegNo)
AddrSegmentReg - The operand # of the segment in the memory operand.
Definition: X86BaseInfo.h:39
bool isReg() const
Definition: MCInst.h:56
format_object< int64_t > formatHex(int64_t Value) const
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:138
void printSrcIdx(const MCInst *MI, unsigned OpNo, raw_ostream &OS)
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &OS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
void printInstruction(const MCInst *MI, raw_ostream &OS)
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:63
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:111
bool isImm() const
Definition: MCInst.h:57
void printRegName(raw_ostream &OS, unsigned RegNo) const override
Print the assembler register name.
void printMemOffset(const MCInst *MI, unsigned OpNo, raw_ostream &OS)
const MCExpr * getExpr() const
Definition: MCInst.h:93
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
Definition: MCExpr.cpp:33
void printSSEAVXCC(const MCInst *MI, unsigned Op, raw_ostream &OS)
StringRef markup(StringRef s) const
Utility functions to make adding mark ups simpler.
bool isExpr() const
Definition: MCInst.h:59
void printXOPCC(const MCInst *MI, unsigned Op, raw_ostream &OS)
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
Definition: MCInstPrinter.h:96
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
void printMemReference(const MCInst *MI, unsigned Op, raw_ostream &OS)
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
void printU8Imm(const MCInst *MI, unsigned Op, raw_ostream &OS)
raw_ostream * CommentStream
A stream that comments can be emitted to if desired.
Definition: MCInstPrinter.h:43
unsigned getOpcode() const
Definition: MCInst.h:159
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:285
int64_t getImm() const
Definition: MCInst.h:74
void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &OS)
printPCRelImm - This is used to print an immediate value that ends up being encoded as a pc-relative ...
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:44
MCSubtargetInfo - Generic base class for all target subtargets.
const MCInstrInfo & MII
Definition: MCInstPrinter.h:45
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
bool printAliasInstr(const MCInst *MI, raw_ostream &OS)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164
void printRoundingControl(const MCInst *MI, unsigned Op, raw_ostream &OS)
bool EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, const char *(*getRegName)(unsigned))
EmitAnyX86InstComments - This function decodes x86 instructions and prints newline terminated strings...