blob: 0cbd2ecd99fc22d8709ae18676b6a78061a273d0 [file] [log] [blame]
Chad Rosier095e1cd2012-10-03 19:00:20 +00001//===-- X86IntelInstPrinter.cpp - Intel assembly instruction printing -----===//
Chris Lattner44790342009-09-20 07:17:49 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Lattner44790342009-09-20 07:17:49 +00006//
7//===----------------------------------------------------------------------===//
8//
Chad Rosier095e1cd2012-10-03 19:00:20 +00009// This file includes code for rendering MCInst instances as Intel-style
Chris Lattner44790342009-09-20 07:17:49 +000010// assembly.
11//
12//===----------------------------------------------------------------------===//
13
Chandler Carruth6bda14b2017-06-06 11:49:48 +000014#include "X86IntelInstPrinter.h"
Michael Liao425c0db2012-09-26 05:13:44 +000015#include "MCTargetDesc/X86BaseInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "X86InstComments.h"
Chris Lattner44790342009-09-20 07:17:49 +000017#include "llvm/MC/MCExpr.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000018#include "llvm/MC/MCInst.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000019#include "llvm/MC/MCInstrDesc.h"
Craig Topperdab9e352012-04-02 07:01:04 +000020#include "llvm/MC/MCInstrInfo.h"
Craig Toppere33ed7d62018-04-22 00:52:02 +000021#include "llvm/MC/MCSubtargetInfo.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000022#include "llvm/Support/Casting.h"
Chris Lattner44790342009-09-20 07:17:49 +000023#include "llvm/Support/ErrorHandling.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000024#include <cassert>
25#include <cstdint>
26
Chris Lattner44790342009-09-20 07:17:49 +000027using namespace llvm;
28
Chandler Carruth84e68b22014-04-22 02:41:26 +000029#define DEBUG_TYPE "asm-printer"
30
Chris Lattner44790342009-09-20 07:17:49 +000031#include "X86GenAsmWriter1.inc"
Chris Lattner44790342009-09-20 07:17:49 +000032
Rafael Espindolad6860522011-06-02 02:34:55 +000033void X86IntelInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
34 OS << getRegisterName(RegNo);
Rafael Espindola08600bc2011-05-30 20:20:15 +000035}
36
Owen Andersona0c3b972011-09-15 23:38:46 +000037void X86IntelInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
Akira Hatanakab46d0232015-03-27 20:36:02 +000038 StringRef Annot,
39 const MCSubtargetInfo &STI) {
Gabor Buella349ffce2018-06-05 10:41:39 +000040 printInstFlags(MI, OS);
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +000041
Craig Toppere33ed7d62018-04-22 00:52:02 +000042 // In 16-bit mode, print data16 as data32.
43 if (MI->getOpcode() == X86::DATA16_PREFIX &&
44 STI.getFeatureBits()[X86::Mode16Bit]) {
45 OS << "\tdata32";
46 } else
47 printInstruction(MI, OS);
Kevin Enderby6fbcd8d2012-02-23 18:18:17 +000048
49 // Next always print the annotation.
50 printAnnotation(OS, Annot);
51
Chris Lattner7a05e6d2010-08-28 20:42:31 +000052 // If verbose assembly is enabled, we can print some informative comments.
Kevin Enderby6fbcd8d2012-02-23 18:18:17 +000053 if (CommentStream)
Craig Toppera21758f2018-03-29 04:14:04 +000054 EmitAnyX86InstComments(MI, *CommentStream, MII);
Chris Lattner76c564b2010-04-04 04:47:45 +000055}
Chris Lattner44790342009-09-20 07:17:49 +000056
Chris Lattner44790342009-09-20 07:17:49 +000057void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
Chris Lattner76c564b2010-04-04 04:47:45 +000058 raw_ostream &O) {
Chris Lattner44790342009-09-20 07:17:49 +000059 const MCOperand &Op = MI->getOperand(OpNo);
60 if (Op.isReg()) {
Craig Topperefd67d42013-07-31 02:47:52 +000061 printRegName(O, Op.getReg());
Chris Lattner44790342009-09-20 07:17:49 +000062 } else if (Op.isImm()) {
Daniel Maleaa3d42452013-08-01 21:18:16 +000063 O << formatImm((int64_t)Op.getImm());
Chris Lattner44790342009-09-20 07:17:49 +000064 } else {
65 assert(Op.isExpr() && "unknown operand kind in printOperand");
Konstantin Belochapka741099b2017-09-25 19:26:48 +000066 O << "offset ";
Matt Arsenault8b643552015-06-09 00:31:39 +000067 Op.getExpr()->print(O, &MAI);
Chris Lattner44790342009-09-20 07:17:49 +000068 }
69}
70
Chris Lattnerf4693072010-07-08 23:46:44 +000071void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
72 raw_ostream &O) {
Manuel Jacobdcb78db2014-03-18 16:14:11 +000073 const MCOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg);
74 unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm();
75 const MCOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg);
76 const MCOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp);
Michael Liao5bf95782014-12-04 05:20:33 +000077
Chris Lattnerf4693072010-07-08 23:46:44 +000078 // If this has a segment register, print it.
Gabor Buella349ffce2018-06-05 10:41:39 +000079 printOptionalSegReg(MI, Op + X86::AddrSegmentReg, O);
Michael Liao5bf95782014-12-04 05:20:33 +000080
Chris Lattner44790342009-09-20 07:17:49 +000081 O << '[';
Michael Liao5bf95782014-12-04 05:20:33 +000082
Chris Lattner44790342009-09-20 07:17:49 +000083 bool NeedPlus = false;
84 if (BaseReg.getReg()) {
Manuel Jacobdcb78db2014-03-18 16:14:11 +000085 printOperand(MI, Op+X86::AddrBaseReg, O);
Chris Lattner44790342009-09-20 07:17:49 +000086 NeedPlus = true;
87 }
Michael Liao5bf95782014-12-04 05:20:33 +000088
Chris Lattner44790342009-09-20 07:17:49 +000089 if (IndexReg.getReg()) {
90 if (NeedPlus) O << " + ";
91 if (ScaleVal != 1)
92 O << ScaleVal << '*';
Manuel Jacobdcb78db2014-03-18 16:14:11 +000093 printOperand(MI, Op+X86::AddrIndexReg, O);
Chris Lattner44790342009-09-20 07:17:49 +000094 NeedPlus = true;
95 }
Chad Rosier095e1cd2012-10-03 19:00:20 +000096
Chris Lattner44790342009-09-20 07:17:49 +000097 if (!DispSpec.isImm()) {
98 if (NeedPlus) O << " + ";
99 assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
Matt Arsenault8b643552015-06-09 00:31:39 +0000100 DispSpec.getExpr()->print(O, &MAI);
Chris Lattner44790342009-09-20 07:17:49 +0000101 } else {
102 int64_t DispVal = DispSpec.getImm();
103 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) {
104 if (NeedPlus) {
105 if (DispVal > 0)
106 O << " + ";
107 else {
108 O << " - ";
109 DispVal = -DispVal;
110 }
111 }
Daniel Maleaa3d42452013-08-01 21:18:16 +0000112 O << formatImm(DispVal);
Chris Lattner44790342009-09-20 07:17:49 +0000113 }
114 }
Michael Liao5bf95782014-12-04 05:20:33 +0000115
Chris Lattner44790342009-09-20 07:17:49 +0000116 O << ']';
117}
Craig Topper18854172013-08-25 22:23:38 +0000118
David Woodhouse2ef8d9c2014-01-22 15:08:08 +0000119void X86IntelInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op,
120 raw_ostream &O) {
David Woodhouse2ef8d9c2014-01-22 15:08:08 +0000121 // If this has a segment register, print it.
Gabor Buella349ffce2018-06-05 10:41:39 +0000122 printOptionalSegReg(MI, Op + 1, O);
David Woodhouse2ef8d9c2014-01-22 15:08:08 +0000123 O << '[';
124 printOperand(MI, Op, O);
125 O << ']';
126}
127
David Woodhouseb33c2ef2014-01-22 15:08:21 +0000128void X86IntelInstPrinter::printDstIdx(const MCInst *MI, unsigned Op,
129 raw_ostream &O) {
130 // DI accesses are always ES-based.
131 O << "es:[";
132 printOperand(MI, Op, O);
133 O << ']';
134}
135
Craig Topper18854172013-08-25 22:23:38 +0000136void X86IntelInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
137 raw_ostream &O) {
138 const MCOperand &DispSpec = MI->getOperand(Op);
Craig Topper35da3d12014-01-16 07:36:58 +0000139
140 // If this has a segment register, print it.
Gabor Buella349ffce2018-06-05 10:41:39 +0000141 printOptionalSegReg(MI, Op + 1, O);
Craig Topper18854172013-08-25 22:23:38 +0000142
143 O << '[';
144
145 if (DispSpec.isImm()) {
146 O << formatImm(DispSpec.getImm());
147 } else {
148 assert(DispSpec.isExpr() && "non-immediate displacement?");
Matt Arsenault8b643552015-06-09 00:31:39 +0000149 DispSpec.getExpr()->print(O, &MAI);
Craig Topper18854172013-08-25 22:23:38 +0000150 }
151
152 O << ']';
153}
Craig Topper0271d102015-01-23 08:00:59 +0000154
155void X86IntelInstPrinter::printU8Imm(const MCInst *MI, unsigned Op,
156 raw_ostream &O) {
Peter Collingbournec7766772016-10-20 01:58:34 +0000157 if (MI->getOperand(Op).isExpr())
158 return MI->getOperand(Op).getExpr()->print(O, &MAI);
159
Craig Topper0271d102015-01-23 08:00:59 +0000160 O << formatImm(MI->getOperand(Op).getImm() & 0xff);
161}