LLVM  4.0.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"
26 #include "llvm/Support/Format.h"
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 
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 
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 immediates as signed values.
169  int64_t Imm = Op.getImm();
170  O << markup("<imm:") << '$' << formatImm(Imm) << markup(">");
171 
172  // TODO: This should be in a helper function in the base class, so it can
173  // be used by other printers.
174 
175  // If there are no instruction-specific comments, add a comment clarifying
176  // the hex value of the immediate operand when it isn't in the range
177  // [-256,255].
178  if (CommentStream && !HasCustomInstComment && (Imm > 255 || Imm < -256)) {
179  // Don't print unnecessary hex sign bits.
180  if (Imm == (int16_t)(Imm))
181  *CommentStream << format("imm = 0x%" PRIX16 "\n", (uint16_t)Imm);
182  else if (Imm == (int32_t)(Imm))
183  *CommentStream << format("imm = 0x%" PRIX32 "\n", (uint32_t)Imm);
184  else
185  *CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Imm);
186  }
187  } else {
188  assert(Op.isExpr() && "unknown operand kind in printOperand");
189  O << markup("<imm:") << '$';
190  Op.getExpr()->print(O, &MAI);
191  O << markup(">");
192  }
193 }
194 
196  raw_ostream &O) {
197  const MCOperand &BaseReg = MI->getOperand(Op + X86::AddrBaseReg);
198  const MCOperand &IndexReg = MI->getOperand(Op + X86::AddrIndexReg);
199  const MCOperand &DispSpec = MI->getOperand(Op + X86::AddrDisp);
200  const MCOperand &SegReg = MI->getOperand(Op + X86::AddrSegmentReg);
201 
202  O << markup("<mem:");
203 
204  // If this has a segment register, print it.
205  if (SegReg.getReg()) {
206  printOperand(MI, Op + X86::AddrSegmentReg, O);
207  O << ':';
208  }
209 
210  if (DispSpec.isImm()) {
211  int64_t DispVal = DispSpec.getImm();
212  if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
213  O << formatImm(DispVal);
214  } else {
215  assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
216  DispSpec.getExpr()->print(O, &MAI);
217  }
218 
219  if (IndexReg.getReg() || BaseReg.getReg()) {
220  O << '(';
221  if (BaseReg.getReg())
222  printOperand(MI, Op + X86::AddrBaseReg, O);
223 
224  if (IndexReg.getReg()) {
225  O << ',';
226  printOperand(MI, Op + X86::AddrIndexReg, O);
227  unsigned ScaleVal = MI->getOperand(Op + X86::AddrScaleAmt).getImm();
228  if (ScaleVal != 1) {
229  O << ',' << markup("<imm:") << ScaleVal // never printed in hex.
230  << markup(">");
231  }
232  }
233  O << ')';
234  }
235 
236  O << markup(">");
237 }
238 
240  raw_ostream &O) {
241  const MCOperand &SegReg = MI->getOperand(Op + 1);
242 
243  O << markup("<mem:");
244 
245  // If this has a segment register, print it.
246  if (SegReg.getReg()) {
247  printOperand(MI, Op + 1, O);
248  O << ':';
249  }
250 
251  O << "(";
252  printOperand(MI, Op, O);
253  O << ")";
254 
255  O << markup(">");
256 }
257 
259  raw_ostream &O) {
260  O << markup("<mem:");
261 
262  O << "%es:(";
263  printOperand(MI, Op, O);
264  O << ")";
265 
266  O << markup(">");
267 }
268 
270  raw_ostream &O) {
271  const MCOperand &DispSpec = MI->getOperand(Op);
272  const MCOperand &SegReg = MI->getOperand(Op + 1);
273 
274  O << markup("<mem:");
275 
276  // If this has a segment register, print it.
277  if (SegReg.getReg()) {
278  printOperand(MI, Op + 1, O);
279  O << ':';
280  }
281 
282  if (DispSpec.isImm()) {
283  O << formatImm(DispSpec.getImm());
284  } else {
285  assert(DispSpec.isExpr() && "non-immediate displacement?");
286  DispSpec.getExpr()->print(O, &MAI);
287  }
288 
289  O << markup(">");
290 }
291 
293  raw_ostream &O) {
294  if (MI->getOperand(Op).isExpr())
295  return printOperand(MI, Op, O);
296 
297  O << markup("<imm:") << '$' << formatImm(MI->getOperand(Op).getImm() & 0xff)
298  << markup(">");
299 }
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)
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:163
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
void printSrcIdx(const MCInst *MI, unsigned OpNo, raw_ostream &OS)
AddrSegmentReg - The operand # of the segment in the memory operand.
Definition: X86BaseInfo.h:39
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &OS)
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:124
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 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:99
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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:46
unsigned getOpcode() const
Definition: MCInst.h:159
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:47
MCSubtargetInfo - Generic base class for all target subtargets.
const MCInstrInfo & MII
Definition: MCInstPrinter.h:48
LLVM_NODISCARD 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:287
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:33
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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:44
bool printAliasInstr(const MCInst *MI, raw_ostream &OS)
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
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...