blob: 4d91300c7edecf6edbe4641c6bb9ed9a4e9b5462 [file] [log] [blame]
Chris Lattnera08186a2009-06-19 00:47:59 +00001//===-- 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
Eugene Zelenko90562df2017-02-06 21:55:43 +000015#include "X86ATTInstPrinter.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000016#include "MCTargetDesc/X86BaseInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000017#include "X86InstComments.h"
Daniel Dunbar73da11e2009-08-31 08:08:38 +000018#include "llvm/MC/MCExpr.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000019#include "llvm/MC/MCInst.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000020#include "llvm/MC/MCInstrDesc.h"
Craig Topperdab9e352012-04-02 07:01:04 +000021#include "llvm/MC/MCInstrInfo.h"
Craig Topperdaf2e3f2015-12-25 22:10:01 +000022#include "llvm/MC/MCSubtargetInfo.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000023#include "llvm/Support/Casting.h"
Torok Edwin6dd27302009-07-08 18:01:40 +000024#include "llvm/Support/ErrorHandling.h"
Chris Lattner482bf692010-02-10 00:10:18 +000025#include "llvm/Support/Format.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000026#include "llvm/Support/raw_ostream.h"
27#include <cassert>
28#include <cinttypes>
29#include <cstdint>
30
Chris Lattnera08186a2009-06-19 00:47:59 +000031using namespace llvm;
32
Chandler Carruth84e68b22014-04-22 02:41:26 +000033#define DEBUG_TYPE "asm-printer"
34
Chris Lattner8d284c72009-06-19 23:59:57 +000035// Include the auto-generated portion of the assembly writer.
Bill Wendlingbc3f7902011-04-07 21:20:06 +000036#define PRINT_ALIAS_INSTR
Chris Lattner8d284c72009-06-19 23:59:57 +000037#include "X86GenAsmWriter.inc"
Bill Wendlingbc3f7902011-04-07 21:20:06 +000038
Akira Hatanakaba511fd2015-03-28 04:25:41 +000039void X86ATTInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
40 OS << markup("<reg:") << '%' << getRegisterName(RegNo) << markup(">");
Rafael Espindola08600bc2011-05-30 20:20:15 +000041}
42
Owen Andersona0c3b972011-09-15 23:38:46 +000043void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
Akira Hatanakab46d0232015-03-27 20:36:02 +000044 StringRef Annot, const MCSubtargetInfo &STI) {
Michael Liao425c0db2012-09-26 05:13:44 +000045 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
46 uint64_t TSFlags = Desc.TSFlags;
47
Chandler Carruth23173112014-09-03 22:46:44 +000048 // If verbose assembly is enabled, we can print some informative comments.
49 if (CommentStream)
50 HasCustomInstComment =
51 EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
52
Michael Liao425c0db2012-09-26 05:13:44 +000053 if (TSFlags & X86II::LOCK)
Rafael Espindola2fb84012015-05-26 18:35:10 +000054 OS << "\tlock\t";
Michael Liao425c0db2012-09-26 05:13:44 +000055
Pavel Chupine6617fc2014-09-09 11:54:12 +000056 // 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 &&
Michael Kupersteindb0712f2015-05-26 10:47:10 +000063 (STI.getFeatureBits()[X86::Mode64Bit])) {
Pavel Chupine6617fc2014-09-09 11:54:12 +000064 OS << "\tcallq\t";
65 printPCRelImm(MI, 0, OS);
66 }
Marina Yatsina197db002017-01-18 08:07:51 +000067 // data16 and data32 both have the same encoding of 0x66. While data32 is
68 // valid only in 16 bit systems, data16 is valid in the rest.
69 // There seems to be some lack of support of the Requires clause that causes
70 // 0x66 to be interpreted as "data16" by the asm printer.
71 // Thus we add an adjustment here in order to print the "right" instruction.
72 else if (MI->getOpcode() == X86::DATA16_PREFIX &&
73 (STI.getFeatureBits()[X86::Mode16Bit])) {
74 MCInst Data32MI(*MI);
75 Data32MI.setOpcode(X86::DATA32_PREFIX);
76 printInstruction(&Data32MI, OS);
77 }
Eric Christopher2e3fbaa2011-04-18 21:28:11 +000078 // Try to print any aliases first.
Pavel Chupine6617fc2014-09-09 11:54:12 +000079 else if (!printAliasInstr(MI, OS))
Bill Wendling7e07d6f2011-04-14 01:11:51 +000080 printInstruction(MI, OS);
Craig Topper75a5ba72013-07-31 02:00:15 +000081
Kevin Enderby6fbcd8d2012-02-23 18:18:17 +000082 // Next always print the annotation.
83 printAnnotation(OS, Annot);
Chris Lattner76c564b2010-04-04 04:47:45 +000084}
Bill Wendlingbc3f7902011-04-07 21:20:06 +000085
Craig Topper6772eac2015-01-28 10:09:52 +000086void X86ATTInstPrinter::printSSEAVXCC(const MCInst *MI, unsigned Op,
87 raw_ostream &O) {
88 int64_t Imm = MI->getOperand(Op).getImm();
Craig Topperf1c20162012-10-09 05:26:13 +000089 switch (Imm) {
Akira Hatanaka5f117812015-03-28 04:40:43 +000090 default: llvm_unreachable("Invalid ssecc/avxcc argument!");
91 case 0: O << "eq"; break;
92 case 1: O << "lt"; break;
93 case 2: O << "le"; break;
94 case 3: O << "unord"; break;
95 case 4: O << "neq"; break;
96 case 5: O << "nlt"; break;
97 case 6: O << "nle"; break;
98 case 7: O << "ord"; break;
99 case 8: O << "eq_uq"; break;
100 case 9: O << "nge"; break;
101 case 0xa: O << "ngt"; break;
102 case 0xb: O << "false"; break;
103 case 0xc: O << "neq_oq"; break;
104 case 0xd: O << "ge"; break;
105 case 0xe: O << "gt"; break;
106 case 0xf: O << "true"; break;
107 case 0x10: O << "eq_os"; break;
108 case 0x11: O << "lt_oq"; break;
109 case 0x12: O << "le_oq"; break;
110 case 0x13: O << "unord_s"; break;
111 case 0x14: O << "neq_us"; break;
112 case 0x15: O << "nlt_uq"; break;
113 case 0x16: O << "nle_uq"; break;
114 case 0x17: O << "ord_s"; break;
115 case 0x18: O << "eq_us"; break;
116 case 0x19: O << "nge_uq"; break;
117 case 0x1a: O << "ngt_uq"; break;
118 case 0x1b: O << "false_os"; break;
119 case 0x1c: O << "neq_os"; break;
120 case 0x1d: O << "ge_oq"; break;
121 case 0x1e: O << "gt_oq"; break;
122 case 0x1f: O << "true_us"; break;
Chris Lattner8d284c72009-06-19 23:59:57 +0000123 }
124}
125
Craig Topper916708f2015-02-13 07:42:25 +0000126void X86ATTInstPrinter::printXOPCC(const MCInst *MI, unsigned Op,
Elena Demikhovskyde3f7512014-01-01 15:12:34 +0000127 raw_ostream &O) {
Craig Topper916708f2015-02-13 07:42:25 +0000128 int64_t Imm = MI->getOperand(Op).getImm();
129 switch (Imm) {
Akira Hatanaka5f117812015-03-28 04:40:43 +0000130 default: llvm_unreachable("Invalid xopcc argument!");
131 case 0: O << "lt"; break;
132 case 1: O << "le"; break;
133 case 2: O << "gt"; break;
134 case 3: O << "ge"; break;
135 case 4: O << "eq"; break;
136 case 5: O << "neq"; break;
137 case 6: O << "false"; break;
138 case 7: O << "true"; break;
Craig Topper916708f2015-02-13 07:42:25 +0000139 }
140}
141
142void X86ATTInstPrinter::printRoundingControl(const MCInst *MI, unsigned Op,
Akira Hatanaka5f117812015-03-28 04:40:43 +0000143 raw_ostream &O) {
Elena Demikhovskyb19c9dc2014-01-13 12:55:03 +0000144 int64_t Imm = MI->getOperand(Op).getImm() & 0x3;
Elena Demikhovskyde3f7512014-01-01 15:12:34 +0000145 switch (Imm) {
Akira Hatanaka5f117812015-03-28 04:40:43 +0000146 case 0: O << "{rn-sae}"; break;
147 case 1: O << "{rd-sae}"; break;
148 case 2: O << "{ru-sae}"; break;
149 case 3: O << "{rz-sae}"; break;
Elena Demikhovskyde3f7512014-01-01 15:12:34 +0000150 }
151}
Eugene Zelenko90562df2017-02-06 21:55:43 +0000152
Chad Rosier38e05a92012-09-10 22:50:57 +0000153/// printPCRelImm - This is used to print an immediate value that ends up
Chris Lattner6211d7b2009-12-22 00:44:05 +0000154/// being encoded as a pc-relative value (e.g. for jumps and calls). These
155/// print slightly differently than normal immediates. For example, a $ is not
156/// emitted.
Chad Rosier38e05a92012-09-10 22:50:57 +0000157void X86ATTInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
158 raw_ostream &O) {
Chris Lattner9c211962009-06-20 19:34:09 +0000159 const MCOperand &Op = MI->getOperand(OpNo);
Chris Lattner9c211962009-06-20 19:34:09 +0000160 if (Op.isImm())
Kevin Enderby168ffb32012-12-05 18:13:19 +0000161 O << formatImm(Op.getImm());
Chris Lattneraa398f52009-09-14 01:34:40 +0000162 else {
163 assert(Op.isExpr() && "unknown pcrel immediate operand");
Kevin Enderby6fbcd8d2012-02-23 18:18:17 +0000164 // If a symbolic branch target was added as a constant expression then print
165 // that address in hex.
166 const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
167 int64_t Address;
Jim Grosbach13760bd2015-05-30 01:25:56 +0000168 if (BranchTarget && BranchTarget->evaluateAsAbsolute(Address)) {
Daniel Maleaa3d42452013-08-01 21:18:16 +0000169 O << formatHex((uint64_t)Address);
Michael Liao5bf95782014-12-04 05:20:33 +0000170 } else {
Kevin Enderby6fbcd8d2012-02-23 18:18:17 +0000171 // Otherwise, just print the expression.
Matt Arsenault8b643552015-06-09 00:31:39 +0000172 Op.getExpr()->print(O, &MAI);
Kevin Enderby6fbcd8d2012-02-23 18:18:17 +0000173 }
Chris Lattneraa398f52009-09-14 01:34:40 +0000174 }
Chris Lattner9c211962009-06-20 19:34:09 +0000175}
176
Chris Lattner76c564b2010-04-04 04:47:45 +0000177void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
178 raw_ostream &O) {
Chris Lattner46820152009-06-20 00:49:26 +0000179 const MCOperand &Op = MI->getOperand(OpNo);
180 if (Op.isReg()) {
Kevin Enderbydccdac62012-10-23 22:52:52 +0000181 printRegName(O, Op.getReg());
Chris Lattner46820152009-06-20 00:49:26 +0000182 } else if (Op.isImm()) {
Sanjay Patel97c2c102016-05-28 14:58:37 +0000183 // Print immediates as signed values.
Sanjay Patele99014d2016-05-18 17:23:38 +0000184 int64_t Imm = Op.getImm();
185 O << markup("<imm:") << '$' << formatImm(Imm) << markup(">");
Craig Topper75a5ba72013-07-31 02:00:15 +0000186
Sanjay Patel97c2c102016-05-28 14:58:37 +0000187 // TODO: This should be in a helper function in the base class, so it can
188 // be used by other printers.
189
Chandler Carruth23173112014-09-03 22:46:44 +0000190 // If there are no instruction-specific comments, add a comment clarifying
191 // the hex value of the immediate operand when it isn't in the range
192 // [-256,255].
Sanjay Patel97c2c102016-05-28 14:58:37 +0000193 if (CommentStream && !HasCustomInstComment && (Imm > 255 || Imm < -256)) {
194 // Don't print unnecessary hex sign bits.
195 if (Imm == (int16_t)(Imm))
196 *CommentStream << format("imm = 0x%" PRIX16 "\n", (uint16_t)Imm);
197 else if (Imm == (int32_t)(Imm))
198 *CommentStream << format("imm = 0x%" PRIX32 "\n", (uint32_t)Imm);
199 else
200 *CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Imm);
201 }
Chris Lattneraa398f52009-09-14 01:34:40 +0000202 } else {
203 assert(Op.isExpr() && "unknown operand kind in printOperand");
Matt Arsenault8b643552015-06-09 00:31:39 +0000204 O << markup("<imm:") << '$';
205 Op.getExpr()->print(O, &MAI);
206 O << markup(">");
Chris Lattner46820152009-06-20 00:49:26 +0000207 }
Chris Lattner8d284c72009-06-19 23:59:57 +0000208}
209
Chris Lattnerf4693072010-07-08 23:46:44 +0000210void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
211 raw_ostream &O) {
Akira Hatanakaba511fd2015-03-28 04:25:41 +0000212 const MCOperand &BaseReg = MI->getOperand(Op + X86::AddrBaseReg);
213 const MCOperand &IndexReg = MI->getOperand(Op + X86::AddrIndexReg);
214 const MCOperand &DispSpec = MI->getOperand(Op + X86::AddrDisp);
215 const MCOperand &SegReg = MI->getOperand(Op + X86::AddrSegmentReg);
Craig Topper75a5ba72013-07-31 02:00:15 +0000216
Kevin Enderbydccdac62012-10-23 22:52:52 +0000217 O << markup("<mem:");
Kevin Enderby62183c42012-10-22 22:31:46 +0000218
Chris Lattnerf4693072010-07-08 23:46:44 +0000219 // If this has a segment register, print it.
220 if (SegReg.getReg()) {
Akira Hatanakaba511fd2015-03-28 04:25:41 +0000221 printOperand(MI, Op + X86::AddrSegmentReg, O);
Chris Lattnerf4693072010-07-08 23:46:44 +0000222 O << ':';
223 }
Craig Topper75a5ba72013-07-31 02:00:15 +0000224
Chris Lattner46820152009-06-20 00:49:26 +0000225 if (DispSpec.isImm()) {
226 int64_t DispVal = DispSpec.getImm();
227 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
Kevin Enderby168ffb32012-12-05 18:13:19 +0000228 O << formatImm(DispVal);
Chris Lattner46820152009-06-20 00:49:26 +0000229 } else {
Chris Lattner24083062009-09-09 00:40:31 +0000230 assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
Matt Arsenault8b643552015-06-09 00:31:39 +0000231 DispSpec.getExpr()->print(O, &MAI);
Chris Lattner46820152009-06-20 00:49:26 +0000232 }
Craig Topper75a5ba72013-07-31 02:00:15 +0000233
Chris Lattner46820152009-06-20 00:49:26 +0000234 if (IndexReg.getReg() || BaseReg.getReg()) {
Chris Lattner46820152009-06-20 00:49:26 +0000235 O << '(';
236 if (BaseReg.getReg())
Akira Hatanakaba511fd2015-03-28 04:25:41 +0000237 printOperand(MI, Op + X86::AddrBaseReg, O);
Craig Topper75a5ba72013-07-31 02:00:15 +0000238
Chris Lattner46820152009-06-20 00:49:26 +0000239 if (IndexReg.getReg()) {
240 O << ',';
Akira Hatanakaba511fd2015-03-28 04:25:41 +0000241 printOperand(MI, Op + X86::AddrIndexReg, O);
242 unsigned ScaleVal = MI->getOperand(Op + X86::AddrScaleAmt).getImm();
Kevin Enderby62183c42012-10-22 22:31:46 +0000243 if (ScaleVal != 1) {
Akira Hatanakaba511fd2015-03-28 04:25:41 +0000244 O << ',' << markup("<imm:") << ScaleVal // never printed in hex.
Craig Topper75a5ba72013-07-31 02:00:15 +0000245 << markup(">");
Kevin Enderby62183c42012-10-22 22:31:46 +0000246 }
Chris Lattner46820152009-06-20 00:49:26 +0000247 }
248 O << ')';
249 }
Kevin Enderby62183c42012-10-22 22:31:46 +0000250
Kevin Enderbydccdac62012-10-23 22:52:52 +0000251 O << markup(">");
Chris Lattner8d284c72009-06-19 23:59:57 +0000252}
Craig Topper18854172013-08-25 22:23:38 +0000253
David Woodhouse2ef8d9c2014-01-22 15:08:08 +0000254void X86ATTInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op,
255 raw_ostream &O) {
Akira Hatanakaba511fd2015-03-28 04:25:41 +0000256 const MCOperand &SegReg = MI->getOperand(Op + 1);
David Woodhouse2ef8d9c2014-01-22 15:08:08 +0000257
258 O << markup("<mem:");
259
260 // If this has a segment register, print it.
261 if (SegReg.getReg()) {
Akira Hatanakaba511fd2015-03-28 04:25:41 +0000262 printOperand(MI, Op + 1, O);
David Woodhouse2ef8d9c2014-01-22 15:08:08 +0000263 O << ':';
264 }
265
266 O << "(";
267 printOperand(MI, Op, O);
268 O << ")";
269
270 O << markup(">");
271}
272
David Woodhouseb33c2ef2014-01-22 15:08:21 +0000273void X86ATTInstPrinter::printDstIdx(const MCInst *MI, unsigned Op,
274 raw_ostream &O) {
275 O << markup("<mem:");
276
277 O << "%es:(";
278 printOperand(MI, Op, O);
279 O << ")";
280
281 O << markup(">");
282}
283
Craig Topper18854172013-08-25 22:23:38 +0000284void X86ATTInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
285 raw_ostream &O) {
286 const MCOperand &DispSpec = MI->getOperand(Op);
Akira Hatanakaba511fd2015-03-28 04:25:41 +0000287 const MCOperand &SegReg = MI->getOperand(Op + 1);
Craig Topper18854172013-08-25 22:23:38 +0000288
289 O << markup("<mem:");
290
Craig Topper35da3d12014-01-16 07:36:58 +0000291 // If this has a segment register, print it.
292 if (SegReg.getReg()) {
Akira Hatanakaba511fd2015-03-28 04:25:41 +0000293 printOperand(MI, Op + 1, O);
Craig Topper35da3d12014-01-16 07:36:58 +0000294 O << ':';
295 }
296
Craig Topper18854172013-08-25 22:23:38 +0000297 if (DispSpec.isImm()) {
298 O << formatImm(DispSpec.getImm());
299 } else {
300 assert(DispSpec.isExpr() && "non-immediate displacement?");
Matt Arsenault8b643552015-06-09 00:31:39 +0000301 DispSpec.getExpr()->print(O, &MAI);
Craig Topper18854172013-08-25 22:23:38 +0000302 }
303
304 O << markup(">");
305}
Craig Topper0271d102015-01-23 08:00:59 +0000306
307void X86ATTInstPrinter::printU8Imm(const MCInst *MI, unsigned Op,
308 raw_ostream &O) {
Peter Collingbournec7766772016-10-20 01:58:34 +0000309 if (MI->getOperand(Op).isExpr())
310 return printOperand(MI, Op, O);
311
Akira Hatanakaba511fd2015-03-28 04:25:41 +0000312 O << markup("<imm:") << '$' << formatImm(MI->getOperand(Op).getImm() & 0xff)
Craig Topper0271d102015-01-23 08:00:59 +0000313 << markup(">");
314}