blob: 4fc67a4f6eb5e099d77fd470be55a3ba06a731cb [file] [log] [blame]
Chris Lattnera2907782009-10-19 19:56:26 +00001//===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
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 class prints an ARM MCInst to a .s file.
11//
12//===----------------------------------------------------------------------===//
13
Chris Lattnera2907782009-10-19 19:56:26 +000014#include "ARMInstPrinter.h"
Javed Absar2cb0c952017-07-19 12:57:16 +000015#include "Utils/ARMBaseInfo.h"
16#include "ARMBaseRegisterInfo.h"
17#include "ARMBaseRegisterInfo.h"
Evan Chenga20cde32011-07-20 23:34:39 +000018#include "MCTargetDesc/ARMAddressingModes.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000019#include "MCTargetDesc/ARMBaseInfo.h"
Chris Lattner89d47202009-10-19 21:21:39 +000020#include "llvm/MC/MCAsmInfo.h"
Chris Lattner889a6212009-10-19 21:53:00 +000021#include "llvm/MC/MCExpr.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000022#include "llvm/MC/MCInst.h"
Craig Topperdab9e352012-04-02 07:01:04 +000023#include "llvm/MC/MCInstrInfo.h"
Jim Grosbachc988e0c2012-03-05 19:33:30 +000024#include "llvm/MC/MCRegisterInfo.h"
Craig Topperdaf2e3f2015-12-25 22:10:01 +000025#include "llvm/MC/MCSubtargetInfo.h"
Eugene Zelenko07dc38f2017-02-03 21:48:12 +000026#include "llvm/MC/SubtargetFeature.h"
27#include "llvm/Support/Casting.h"
28#include "llvm/Support/ErrorHandling.h"
29#include "llvm/Support/MathExtras.h"
Chris Lattner889a6212009-10-19 21:53:00 +000030#include "llvm/Support/raw_ostream.h"
Eugene Zelenko07dc38f2017-02-03 21:48:12 +000031#include <algorithm>
32#include <cassert>
33#include <cstdint>
34
Chris Lattnera2907782009-10-19 19:56:26 +000035using namespace llvm;
36
Chandler Carruth84e68b22014-04-22 02:41:26 +000037#define DEBUG_TYPE "asm-printer"
38
Sjoerd Meijer9da258d2016-06-03 13:19:43 +000039#define PRINT_ALIAS_INSTR
Chris Lattnera2907782009-10-19 19:56:26 +000040#include "ARMGenAsmWriter.inc"
Chris Lattnera2907782009-10-19 19:56:26 +000041
Owen Andersone33c95d2011-08-11 18:41:59 +000042/// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
43///
Jim Grosbachd74c0e72011-10-12 16:36:01 +000044/// getSORegOffset returns an integer from 0-31, representing '32' as 0.
Owen Andersone33c95d2011-08-11 18:41:59 +000045static unsigned translateShiftImm(unsigned imm) {
Tim Northover0c97e762012-09-22 11:18:12 +000046 // lsr #32 and asr #32 exist, but should be encoded as a 0.
47 assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
48
Owen Andersone33c95d2011-08-11 18:41:59 +000049 if (imm == 0)
50 return 32;
51 return imm;
52}
53
Tim Northover0c97e762012-09-22 11:18:12 +000054/// Prints the shift value with an immediate value.
55static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
Akira Hatanakacfa1f612015-03-27 23:24:22 +000056 unsigned ShImm, bool UseMarkup) {
Tim Northover0c97e762012-09-22 11:18:12 +000057 if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
58 return;
59 O << ", ";
60
Akira Hatanakacfa1f612015-03-27 23:24:22 +000061 assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
Tim Northover0c97e762012-09-22 11:18:12 +000062 O << getShiftOpcStr(ShOpc);
63
Kevin Enderbydccdac62012-10-23 22:52:52 +000064 if (ShOpc != ARM_AM::rrx) {
Kevin Enderby62183c42012-10-22 22:31:46 +000065 O << " ";
66 if (UseMarkup)
67 O << "<imm:";
68 O << "#" << translateShiftImm(ShImm);
69 if (UseMarkup)
70 O << ">";
71 }
Tim Northover0c97e762012-09-22 11:18:12 +000072}
James Molloy4c493e82011-09-07 17:24:38 +000073
Akira Hatanakacfa1f612015-03-27 23:24:22 +000074ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
Eric Christopher7099d512015-03-30 21:52:28 +000075 const MCRegisterInfo &MRI)
Akira Hatanakaee974752015-03-27 23:41:42 +000076 : MCInstPrinter(MAI, MII, MRI) {}
James Molloy4c493e82011-09-07 17:24:38 +000077
Rafael Espindolad6860522011-06-02 02:34:55 +000078void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
Akira Hatanakacfa1f612015-03-27 23:24:22 +000079 OS << markup("<reg:") << getRegisterName(RegNo) << markup(">");
Anton Korobeynikove7410dd2011-03-05 18:43:32 +000080}
Chris Lattnerf20f7982010-10-28 21:37:33 +000081
Owen Andersona0c3b972011-09-15 23:38:46 +000082void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
Akira Hatanakab46d0232015-03-27 20:36:02 +000083 StringRef Annot, const MCSubtargetInfo &STI) {
Bill Wendlingf2fa04a2010-11-13 10:40:19 +000084 unsigned Opcode = MI->getOpcode();
85
Akira Hatanakacfa1f612015-03-27 23:24:22 +000086 switch (Opcode) {
Johnny Chen8f3004c2010-03-17 17:52:21 +000087 // Check for MOVs and print canonical forms, instead.
Richard Bartona661b442013-10-18 14:41:50 +000088 case ARM::MOVsr: {
Jim Grosbach7a6c37d2010-09-17 22:36:38 +000089 // FIXME: Thumb variants?
Johnny Chen8f3004c2010-03-17 17:52:21 +000090 const MCOperand &Dst = MI->getOperand(0);
91 const MCOperand &MO1 = MI->getOperand(1);
92 const MCOperand &MO2 = MI->getOperand(2);
93 const MCOperand &MO3 = MI->getOperand(3);
94
95 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
Akira Hatanakaee974752015-03-27 23:41:42 +000096 printSBitModifierOperand(MI, 6, STI, O);
97 printPredicateOperand(MI, 4, STI, O);
Johnny Chen8f3004c2010-03-17 17:52:21 +000098
Kevin Enderby62183c42012-10-22 22:31:46 +000099 O << '\t';
100 printRegName(O, Dst.getReg());
101 O << ", ";
102 printRegName(O, MO1.getReg());
Johnny Chen8f3004c2010-03-17 17:52:21 +0000103
Kevin Enderby62183c42012-10-22 22:31:46 +0000104 O << ", ";
105 printRegName(O, MO2.getReg());
Owen Anderson04912702011-07-21 23:38:37 +0000106 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
Owen Andersonbcc3fad2011-09-21 17:58:45 +0000107 printAnnotation(O, Annot);
Johnny Chen8f3004c2010-03-17 17:52:21 +0000108 return;
109 }
110
Richard Bartona661b442013-10-18 14:41:50 +0000111 case ARM::MOVsi: {
Owen Anderson04912702011-07-21 23:38:37 +0000112 // FIXME: Thumb variants?
113 const MCOperand &Dst = MI->getOperand(0);
114 const MCOperand &MO1 = MI->getOperand(1);
115 const MCOperand &MO2 = MI->getOperand(2);
116
117 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()));
Akira Hatanakaee974752015-03-27 23:41:42 +0000118 printSBitModifierOperand(MI, 5, STI, O);
119 printPredicateOperand(MI, 3, STI, O);
Owen Anderson04912702011-07-21 23:38:37 +0000120
Kevin Enderby62183c42012-10-22 22:31:46 +0000121 O << '\t';
122 printRegName(O, Dst.getReg());
123 O << ", ";
124 printRegName(O, MO1.getReg());
Owen Anderson04912702011-07-21 23:38:37 +0000125
Owen Andersond1814792011-09-15 18:36:29 +0000126 if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) {
Owen Andersonbcc3fad2011-09-21 17:58:45 +0000127 printAnnotation(O, Annot);
Owen Anderson04912702011-07-21 23:38:37 +0000128 return;
Owen Andersond1814792011-09-15 18:36:29 +0000129 }
Owen Anderson04912702011-07-21 23:38:37 +0000130
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000131 O << ", " << markup("<imm:") << "#"
132 << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())) << markup(">");
Owen Andersonbcc3fad2011-09-21 17:58:45 +0000133 printAnnotation(O, Annot);
Owen Anderson04912702011-07-21 23:38:37 +0000134 return;
135 }
136
Johnny Chen8f3004c2010-03-17 17:52:21 +0000137 // A8.6.123 PUSH
Richard Bartona661b442013-10-18 14:41:50 +0000138 case ARM::STMDB_UPD:
139 case ARM::t2STMDB_UPD:
140 if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
141 // Should only print PUSH if there are at least two registers in the list.
142 O << '\t' << "push";
Akira Hatanakaee974752015-03-27 23:41:42 +0000143 printPredicateOperand(MI, 2, STI, O);
Richard Bartona661b442013-10-18 14:41:50 +0000144 if (Opcode == ARM::t2STMDB_UPD)
145 O << ".w";
146 O << '\t';
Akira Hatanakaee974752015-03-27 23:41:42 +0000147 printRegisterList(MI, 4, STI, O);
Richard Bartona661b442013-10-18 14:41:50 +0000148 printAnnotation(O, Annot);
149 return;
150 } else
151 break;
152
153 case ARM::STR_PRE_IMM:
154 if (MI->getOperand(2).getReg() == ARM::SP &&
155 MI->getOperand(3).getImm() == -4) {
156 O << '\t' << "push";
Akira Hatanakaee974752015-03-27 23:41:42 +0000157 printPredicateOperand(MI, 4, STI, O);
Richard Bartona661b442013-10-18 14:41:50 +0000158 O << "\t{";
159 printRegName(O, MI->getOperand(1).getReg());
160 O << "}";
161 printAnnotation(O, Annot);
162 return;
163 } else
164 break;
Johnny Chen8f3004c2010-03-17 17:52:21 +0000165
166 // A8.6.122 POP
Richard Bartona661b442013-10-18 14:41:50 +0000167 case ARM::LDMIA_UPD:
168 case ARM::t2LDMIA_UPD:
169 if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
170 // Should only print POP if there are at least two registers in the list.
171 O << '\t' << "pop";
Akira Hatanakaee974752015-03-27 23:41:42 +0000172 printPredicateOperand(MI, 2, STI, O);
Richard Bartona661b442013-10-18 14:41:50 +0000173 if (Opcode == ARM::t2LDMIA_UPD)
174 O << ".w";
175 O << '\t';
Akira Hatanakaee974752015-03-27 23:41:42 +0000176 printRegisterList(MI, 4, STI, O);
Richard Bartona661b442013-10-18 14:41:50 +0000177 printAnnotation(O, Annot);
178 return;
179 } else
180 break;
Jim Grosbach8ba76c62011-08-11 17:35:48 +0000181
Richard Bartona661b442013-10-18 14:41:50 +0000182 case ARM::LDR_POST_IMM:
183 if (MI->getOperand(2).getReg() == ARM::SP &&
184 MI->getOperand(4).getImm() == 4) {
185 O << '\t' << "pop";
Akira Hatanakaee974752015-03-27 23:41:42 +0000186 printPredicateOperand(MI, 5, STI, O);
Richard Bartona661b442013-10-18 14:41:50 +0000187 O << "\t{";
188 printRegName(O, MI->getOperand(0).getReg());
189 O << "}";
190 printAnnotation(O, Annot);
191 return;
192 } else
193 break;
Johnny Chen8f3004c2010-03-17 17:52:21 +0000194
195 // A8.6.355 VPUSH
Richard Bartona661b442013-10-18 14:41:50 +0000196 case ARM::VSTMSDB_UPD:
197 case ARM::VSTMDDB_UPD:
198 if (MI->getOperand(0).getReg() == ARM::SP) {
199 O << '\t' << "vpush";
Akira Hatanakaee974752015-03-27 23:41:42 +0000200 printPredicateOperand(MI, 2, STI, O);
Richard Bartona661b442013-10-18 14:41:50 +0000201 O << '\t';
Akira Hatanakaee974752015-03-27 23:41:42 +0000202 printRegisterList(MI, 4, STI, O);
Richard Bartona661b442013-10-18 14:41:50 +0000203 printAnnotation(O, Annot);
204 return;
205 } else
206 break;
Johnny Chen8f3004c2010-03-17 17:52:21 +0000207
208 // A8.6.354 VPOP
Richard Bartona661b442013-10-18 14:41:50 +0000209 case ARM::VLDMSIA_UPD:
210 case ARM::VLDMDIA_UPD:
211 if (MI->getOperand(0).getReg() == ARM::SP) {
212 O << '\t' << "vpop";
Akira Hatanakaee974752015-03-27 23:41:42 +0000213 printPredicateOperand(MI, 2, STI, O);
Richard Bartona661b442013-10-18 14:41:50 +0000214 O << '\t';
Akira Hatanakaee974752015-03-27 23:41:42 +0000215 printRegisterList(MI, 4, STI, O);
Richard Bartona661b442013-10-18 14:41:50 +0000216 printAnnotation(O, Annot);
217 return;
218 } else
219 break;
Johnny Chen8f3004c2010-03-17 17:52:21 +0000220
Richard Bartona661b442013-10-18 14:41:50 +0000221 case ARM::tLDMIA: {
Owen Anderson83c6c4f2011-07-18 23:25:34 +0000222 bool Writeback = true;
223 unsigned BaseReg = MI->getOperand(0).getReg();
224 for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
225 if (MI->getOperand(i).getReg() == BaseReg)
226 Writeback = false;
227 }
228
Jim Grosbache364ad52011-08-23 17:41:15 +0000229 O << "\tldm";
Owen Anderson83c6c4f2011-07-18 23:25:34 +0000230
Akira Hatanakaee974752015-03-27 23:41:42 +0000231 printPredicateOperand(MI, 1, STI, O);
Kevin Enderby62183c42012-10-22 22:31:46 +0000232 O << '\t';
233 printRegName(O, BaseReg);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000234 if (Writeback)
235 O << "!";
Owen Anderson83c6c4f2011-07-18 23:25:34 +0000236 O << ", ";
Akira Hatanakaee974752015-03-27 23:41:42 +0000237 printRegisterList(MI, 3, STI, O);
Owen Andersonbcc3fad2011-09-21 17:58:45 +0000238 printAnnotation(O, Annot);
Owen Anderson83c6c4f2011-07-18 23:25:34 +0000239 return;
240 }
241
Weiming Zhao8f56f882012-11-16 21:55:34 +0000242 // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
243 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
244 // a single GPRPair reg operand is used in the .td file to replace the two
245 // GPRs. However, when decoding them, the two GRPs cannot be automatically
246 // expressed as a GPRPair, so we have to manually merge them.
247 // FIXME: We would really like to be able to tablegen'erate this.
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000248 case ARM::LDREXD:
249 case ARM::STREXD:
250 case ARM::LDAEXD:
251 case ARM::STLEXD: {
252 const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID);
Joey Goulye6d165c2013-08-27 17:38:16 +0000253 bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
Weiming Zhao8f56f882012-11-16 21:55:34 +0000254 unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
255 if (MRC.contains(Reg)) {
256 MCInst NewMI;
257 MCOperand NewReg;
258 NewMI.setOpcode(Opcode);
259
260 if (isStore)
261 NewMI.addOperand(MI->getOperand(0));
Jim Grosbache9119e42015-05-13 18:37:00 +0000262 NewReg = MCOperand::createReg(MRI.getMatchingSuperReg(
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000263 Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID)));
Weiming Zhao8f56f882012-11-16 21:55:34 +0000264 NewMI.addOperand(NewReg);
265
266 // Copy the rest operands into NewMI.
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000267 for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i)
Weiming Zhao8f56f882012-11-16 21:55:34 +0000268 NewMI.addOperand(MI->getOperand(i));
Akira Hatanakaee974752015-03-27 23:41:42 +0000269 printInstruction(&NewMI, STI, O);
Weiming Zhao8f56f882012-11-16 21:55:34 +0000270 return;
271 }
Charlie Turner4d88ae22014-12-01 08:33:28 +0000272 break;
273 }
Weiming Zhao8f56f882012-11-16 21:55:34 +0000274 }
275
Sjoerd Meijer9da258d2016-06-03 13:19:43 +0000276 if (!printAliasInstr(MI, STI, O))
277 printInstruction(MI, STI, O);
278
Owen Andersonbcc3fad2011-09-21 17:58:45 +0000279 printAnnotation(O, Annot);
Bill Wendlingf2fa04a2010-11-13 10:40:19 +0000280}
Chris Lattnera2907782009-10-19 19:56:26 +0000281
Chris Lattner93e3ef62009-10-19 20:59:55 +0000282void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
Akira Hatanakaee974752015-03-27 23:41:42 +0000283 const MCSubtargetInfo &STI, raw_ostream &O) {
Chris Lattner93e3ef62009-10-19 20:59:55 +0000284 const MCOperand &Op = MI->getOperand(OpNo);
285 if (Op.isReg()) {
Chris Lattner60d51312009-10-20 06:15:28 +0000286 unsigned Reg = Op.getReg();
Kevin Enderby62183c42012-10-22 22:31:46 +0000287 printRegName(O, Reg);
Chris Lattner93e3ef62009-10-19 20:59:55 +0000288 } else if (Op.isImm()) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000289 O << markup("<imm:") << '#' << formatImm(Op.getImm()) << markup(">");
Chris Lattner93e3ef62009-10-19 20:59:55 +0000290 } else {
291 assert(Op.isExpr() && "unknown operand kind in printOperand");
Saleem Abdulrasoold88affb2014-01-08 03:28:14 +0000292 const MCExpr *Expr = Op.getExpr();
293 switch (Expr->getKind()) {
294 case MCExpr::Binary:
Matt Arsenault8b643552015-06-09 00:31:39 +0000295 O << '#';
296 Expr->print(O, &MAI);
Saleem Abdulrasoold88affb2014-01-08 03:28:14 +0000297 break;
298 case MCExpr::Constant: {
299 // If a symbolic branch target was added as a constant expression then
300 // print that address in hex. And only print 32 unsigned bits for the
301 // address.
302 const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
303 int64_t TargetAddress;
Jim Grosbach13760bd2015-05-30 01:25:56 +0000304 if (!Constant->evaluateAsAbsolute(TargetAddress)) {
Matt Arsenault8b643552015-06-09 00:31:39 +0000305 O << '#';
306 Expr->print(O, &MAI);
Saleem Abdulrasoold88affb2014-01-08 03:28:14 +0000307 } else {
308 O << "0x";
309 O.write_hex(static_cast<uint32_t>(TargetAddress));
310 }
311 break;
Kevin Enderby5dcda642011-10-04 22:44:48 +0000312 }
Saleem Abdulrasoold88affb2014-01-08 03:28:14 +0000313 default:
314 // FIXME: Should we always treat this as if it is a constant literal and
315 // prefix it with '#'?
Matt Arsenault8b643552015-06-09 00:31:39 +0000316 Expr->print(O, &MAI);
Saleem Abdulrasoold88affb2014-01-08 03:28:14 +0000317 break;
Kevin Enderby5dcda642011-10-04 22:44:48 +0000318 }
Chris Lattner93e3ef62009-10-19 20:59:55 +0000319 }
320}
Chris Lattner89d47202009-10-19 21:21:39 +0000321
Jim Grosbach4739f2e2012-10-30 01:04:51 +0000322void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000323 const MCSubtargetInfo &STI,
Jim Grosbach4739f2e2012-10-30 01:04:51 +0000324 raw_ostream &O) {
Owen Andersonf52c68f2011-09-21 23:44:46 +0000325 const MCOperand &MO1 = MI->getOperand(OpNum);
Amaury de la Vieuville4d3e3f22013-06-18 08:03:06 +0000326 if (MO1.isExpr()) {
Matt Arsenault8b643552015-06-09 00:31:39 +0000327 MO1.getExpr()->print(O, &MAI);
Amaury de la Vieuville4d3e3f22013-06-18 08:03:06 +0000328 return;
Kevin Enderby62183c42012-10-22 22:31:46 +0000329 }
Amaury de la Vieuville4d3e3f22013-06-18 08:03:06 +0000330
331 O << markup("<mem:") << "[pc, ";
332
333 int32_t OffImm = (int32_t)MO1.getImm();
334 bool isSub = OffImm < 0;
335
336 // Special value for #-0. All others are normal.
337 if (OffImm == INT32_MIN)
338 OffImm = 0;
339 if (isSub) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000340 O << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
Amaury de la Vieuville4d3e3f22013-06-18 08:03:06 +0000341 } else {
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000342 O << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
Amaury de la Vieuville4d3e3f22013-06-18 08:03:06 +0000343 }
344 O << "]" << markup(">");
Owen Andersonf52c68f2011-09-21 23:44:46 +0000345}
346
Chris Lattner2f69ed82009-10-20 00:40:56 +0000347// so_reg is a 4-operand unit corresponding to register forms of the A5.1
348// "Addressing Mode 1 - Data-processing operands" forms. This includes:
349// REG 0 0 - e.g. R5
350// REG REG 0,SH_OPC - e.g. R5, ROR R3
351// REG 0 IMM,SH_OPC - e.g. R5, LSL #3
Owen Anderson04912702011-07-21 23:38:37 +0000352void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000353 const MCSubtargetInfo &STI,
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000354 raw_ostream &O) {
Chris Lattner2f69ed82009-10-20 00:40:56 +0000355 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000356 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
357 const MCOperand &MO3 = MI->getOperand(OpNum + 2);
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000358
Kevin Enderby62183c42012-10-22 22:31:46 +0000359 printRegName(O, MO1.getReg());
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000360
Chris Lattner2f69ed82009-10-20 00:40:56 +0000361 // Print the shift opc.
Bob Wilson97886d52010-08-05 00:34:42 +0000362 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
363 O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
Jim Grosbach7dcd1352011-07-13 17:50:29 +0000364 if (ShOpc == ARM_AM::rrx)
365 return;
Jim Grosbach20cb5052011-10-21 16:56:40 +0000366
Kevin Enderby62183c42012-10-22 22:31:46 +0000367 O << ' ';
368 printRegName(O, MO2.getReg());
Owen Anderson04912702011-07-21 23:38:37 +0000369 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
Chris Lattner2f69ed82009-10-20 00:40:56 +0000370}
Chris Lattner7ddfdc42009-10-19 21:57:05 +0000371
Owen Anderson04912702011-07-21 23:38:37 +0000372void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000373 const MCSubtargetInfo &STI,
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000374 raw_ostream &O) {
Owen Anderson04912702011-07-21 23:38:37 +0000375 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000376 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Owen Anderson04912702011-07-21 23:38:37 +0000377
Kevin Enderby62183c42012-10-22 22:31:46 +0000378 printRegName(O, MO1.getReg());
Owen Anderson04912702011-07-21 23:38:37 +0000379
380 // Print the shift opc.
Tim Northover2fdbdc52012-09-22 11:18:19 +0000381 printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
Kevin Enderby62183c42012-10-22 22:31:46 +0000382 ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
Owen Anderson04912702011-07-21 23:38:37 +0000383}
384
Bruno Cardoso Lopesbda36322011-04-04 17:18:19 +0000385//===--------------------------------------------------------------------===//
386// Addressing Mode #2
387//===--------------------------------------------------------------------===//
388
Bruno Cardoso Lopesab830502011-03-31 23:26:08 +0000389void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
Akira Hatanakaee974752015-03-27 23:41:42 +0000390 const MCSubtargetInfo &STI,
Bruno Cardoso Lopesab830502011-03-31 23:26:08 +0000391 raw_ostream &O) {
Chris Lattner7ddfdc42009-10-19 21:57:05 +0000392 const MCOperand &MO1 = MI->getOperand(Op);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000393 const MCOperand &MO2 = MI->getOperand(Op + 1);
394 const MCOperand &MO3 = MI->getOperand(Op + 2);
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000395
Kevin Enderbydccdac62012-10-23 22:52:52 +0000396 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +0000397 printRegName(O, MO1.getReg());
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000398
Chris Lattner7ddfdc42009-10-19 21:57:05 +0000399 if (!MO2.getReg()) {
Kevin Enderby62183c42012-10-22 22:31:46 +0000400 if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0.
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000401 O << ", " << markup("<imm:") << "#"
Kevin Enderbydccdac62012-10-23 22:52:52 +0000402 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000403 << ARM_AM::getAM2Offset(MO3.getImm()) << markup(">");
Kevin Enderby62183c42012-10-22 22:31:46 +0000404 }
Kevin Enderbydccdac62012-10-23 22:52:52 +0000405 O << "]" << markup(">");
Chris Lattner7ddfdc42009-10-19 21:57:05 +0000406 return;
407 }
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000408
Kevin Enderby62183c42012-10-22 22:31:46 +0000409 O << ", ";
410 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()));
411 printRegName(O, MO2.getReg());
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000412
Tim Northover0c97e762012-09-22 11:18:12 +0000413 printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()),
Kevin Enderby62183c42012-10-22 22:31:46 +0000414 ARM_AM::getAM2Offset(MO3.getImm()), UseMarkup);
Kevin Enderbydccdac62012-10-23 22:52:52 +0000415 O << "]" << markup(">");
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000416}
Chris Lattneref2979b2009-10-19 22:09:23 +0000417
Jim Grosbach05541f42011-09-19 22:21:13 +0000418void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op,
Akira Hatanakaee974752015-03-27 23:41:42 +0000419 const MCSubtargetInfo &STI,
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000420 raw_ostream &O) {
Jim Grosbach05541f42011-09-19 22:21:13 +0000421 const MCOperand &MO1 = MI->getOperand(Op);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000422 const MCOperand &MO2 = MI->getOperand(Op + 1);
Kevin Enderbydccdac62012-10-23 22:52:52 +0000423 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +0000424 printRegName(O, MO1.getReg());
425 O << ", ";
426 printRegName(O, MO2.getReg());
Kevin Enderbydccdac62012-10-23 22:52:52 +0000427 O << "]" << markup(">");
Jim Grosbach05541f42011-09-19 22:21:13 +0000428}
429
430void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op,
Akira Hatanakaee974752015-03-27 23:41:42 +0000431 const MCSubtargetInfo &STI,
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000432 raw_ostream &O) {
Jim Grosbach05541f42011-09-19 22:21:13 +0000433 const MCOperand &MO1 = MI->getOperand(Op);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000434 const MCOperand &MO2 = MI->getOperand(Op + 1);
Kevin Enderbydccdac62012-10-23 22:52:52 +0000435 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +0000436 printRegName(O, MO1.getReg());
437 O << ", ";
438 printRegName(O, MO2.getReg());
Kevin Enderbydccdac62012-10-23 22:52:52 +0000439 O << ", lsl " << markup("<imm:") << "#1" << markup(">") << "]" << markup(">");
Jim Grosbach05541f42011-09-19 22:21:13 +0000440}
441
Bruno Cardoso Lopesab830502011-03-31 23:26:08 +0000442void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
Akira Hatanakaee974752015-03-27 23:41:42 +0000443 const MCSubtargetInfo &STI,
Bruno Cardoso Lopesab830502011-03-31 23:26:08 +0000444 raw_ostream &O) {
445 const MCOperand &MO1 = MI->getOperand(Op);
446
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000447 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
Akira Hatanakaee974752015-03-27 23:41:42 +0000448 printOperand(MI, Op, STI, O);
Bruno Cardoso Lopesab830502011-03-31 23:26:08 +0000449 return;
450 }
451
NAKAMURA Takumi23b5b172012-09-22 13:12:28 +0000452#ifndef NDEBUG
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000453 const MCOperand &MO3 = MI->getOperand(Op + 2);
Bruno Cardoso Lopesab830502011-03-31 23:26:08 +0000454 unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000455 assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op");
NAKAMURA Takumi23b5b172012-09-22 13:12:28 +0000456#endif
Bruno Cardoso Lopesab830502011-03-31 23:26:08 +0000457
Akira Hatanakaee974752015-03-27 23:41:42 +0000458 printAM2PreOrOffsetIndexOp(MI, Op, STI, O);
Bruno Cardoso Lopesab830502011-03-31 23:26:08 +0000459}
460
Chris Lattner60d51312009-10-20 06:15:28 +0000461void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000462 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000463 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000464 raw_ostream &O) {
Chris Lattner60d51312009-10-20 06:15:28 +0000465 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000466 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000467
Chris Lattner60d51312009-10-20 06:15:28 +0000468 if (!MO1.getReg()) {
469 unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000470 O << markup("<imm:") << '#'
471 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) << ImmOffs
Kevin Enderbydccdac62012-10-23 22:52:52 +0000472 << markup(">");
Chris Lattner60d51312009-10-20 06:15:28 +0000473 return;
474 }
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000475
Kevin Enderby62183c42012-10-22 22:31:46 +0000476 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()));
477 printRegName(O, MO1.getReg());
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000478
Tim Northover0c97e762012-09-22 11:18:12 +0000479 printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()),
Kevin Enderby62183c42012-10-22 22:31:46 +0000480 ARM_AM::getAM2Offset(MO2.getImm()), UseMarkup);
Chris Lattner60d51312009-10-20 06:15:28 +0000481}
482
Bruno Cardoso Lopesbda36322011-04-04 17:18:19 +0000483//===--------------------------------------------------------------------===//
484// Addressing Mode #3
485//===--------------------------------------------------------------------===//
486
Bruno Cardoso Lopesbda36322011-04-04 17:18:19 +0000487void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
Quentin Colombetc3132202013-04-12 18:47:25 +0000488 raw_ostream &O,
489 bool AlwaysPrintImm0) {
Bruno Cardoso Lopesbda36322011-04-04 17:18:19 +0000490 const MCOperand &MO1 = MI->getOperand(Op);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000491 const MCOperand &MO2 = MI->getOperand(Op + 1);
492 const MCOperand &MO3 = MI->getOperand(Op + 2);
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000493
Kevin Enderbydccdac62012-10-23 22:52:52 +0000494 O << markup("<mem:") << '[';
Kevin Enderby62183c42012-10-22 22:31:46 +0000495 printRegName(O, MO1.getReg());
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000496
Chris Lattner60d51312009-10-20 06:15:28 +0000497 if (MO2.getReg()) {
Kevin Enderbydccdac62012-10-23 22:52:52 +0000498 O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()));
Kevin Enderby62183c42012-10-22 22:31:46 +0000499 printRegName(O, MO2.getReg());
Kevin Enderbydccdac62012-10-23 22:52:52 +0000500 O << ']' << markup(">");
Chris Lattner60d51312009-10-20 06:15:28 +0000501 return;
502 }
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000503
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000504 // If the op is sub we have to print the immediate even if it is 0
Silviu Baranga5a719f92012-05-11 09:10:54 +0000505 unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
506 ARM_AM::AddrOpc op = ARM_AM::getAM3Op(MO3.getImm());
NAKAMURA Takumi0ac2f2a2012-09-22 13:12:22 +0000507
Quentin Colombetc3132202013-04-12 18:47:25 +0000508 if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000509 O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs
Kevin Enderbydccdac62012-10-23 22:52:52 +0000510 << markup(">");
Kevin Enderby62183c42012-10-22 22:31:46 +0000511 }
Kevin Enderbydccdac62012-10-23 22:52:52 +0000512 O << ']' << markup(">");
Chris Lattner60d51312009-10-20 06:15:28 +0000513}
514
Quentin Colombetc3132202013-04-12 18:47:25 +0000515template <bool AlwaysPrintImm0>
Bruno Cardoso Lopesbda36322011-04-04 17:18:19 +0000516void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op,
Akira Hatanakaee974752015-03-27 23:41:42 +0000517 const MCSubtargetInfo &STI,
Bruno Cardoso Lopesbda36322011-04-04 17:18:19 +0000518 raw_ostream &O) {
Jim Grosbach8648c102011-12-19 23:06:24 +0000519 const MCOperand &MO1 = MI->getOperand(Op);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000520 if (!MO1.isReg()) { // For label symbolic references.
Akira Hatanakaee974752015-03-27 23:41:42 +0000521 printOperand(MI, Op, STI, O);
Jim Grosbach8648c102011-12-19 23:06:24 +0000522 return;
523 }
524
NAKAMURA Takumic62436c2014-10-06 23:48:04 +0000525 assert(ARM_AM::getAM3IdxMode(MI->getOperand(Op + 2).getImm()) !=
526 ARMII::IndexModePost &&
Tim Northoverea964f52014-10-06 17:26:36 +0000527 "unexpected idxmode");
Quentin Colombetc3132202013-04-12 18:47:25 +0000528 printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
Bruno Cardoso Lopesbda36322011-04-04 17:18:19 +0000529}
530
Chris Lattner60d51312009-10-20 06:15:28 +0000531void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000532 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000533 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000534 raw_ostream &O) {
Chris Lattner60d51312009-10-20 06:15:28 +0000535 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000536 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000537
Chris Lattner60d51312009-10-20 06:15:28 +0000538 if (MO1.getReg()) {
Kevin Enderby62183c42012-10-22 22:31:46 +0000539 O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()));
540 printRegName(O, MO1.getReg());
Chris Lattner60d51312009-10-20 06:15:28 +0000541 return;
542 }
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000543
Chris Lattner60d51312009-10-20 06:15:28 +0000544 unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000545 O << markup("<imm:") << '#'
546 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs
Kevin Enderbydccdac62012-10-23 22:52:52 +0000547 << markup(">");
Chris Lattner60d51312009-10-20 06:15:28 +0000548}
549
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000550void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000551 const MCSubtargetInfo &STI,
Jim Grosbachd3595712011-08-03 23:50:40 +0000552 raw_ostream &O) {
553 const MCOperand &MO = MI->getOperand(OpNum);
554 unsigned Imm = MO.getImm();
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000555 O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff)
Kevin Enderbydccdac62012-10-23 22:52:52 +0000556 << markup(">");
Jim Grosbachd3595712011-08-03 23:50:40 +0000557}
558
Jim Grosbachbafce842011-08-05 15:48:21 +0000559void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000560 const MCSubtargetInfo &STI,
Jim Grosbachbafce842011-08-05 15:48:21 +0000561 raw_ostream &O) {
562 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000563 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Jim Grosbachbafce842011-08-05 15:48:21 +0000564
Kevin Enderby62183c42012-10-22 22:31:46 +0000565 O << (MO2.getImm() ? "" : "-");
566 printRegName(O, MO1.getReg());
Jim Grosbachbafce842011-08-05 15:48:21 +0000567}
568
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000569void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000570 const MCSubtargetInfo &STI,
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000571 raw_ostream &O) {
Owen Andersonce519032011-08-04 18:24:14 +0000572 const MCOperand &MO = MI->getOperand(OpNum);
573 unsigned Imm = MO.getImm();
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000574 O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2)
Kevin Enderbydccdac62012-10-23 22:52:52 +0000575 << markup(">");
Owen Andersonce519032011-08-04 18:24:14 +0000576}
577
Jim Grosbachc6af2b42010-11-03 01:01:43 +0000578void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000579 const MCSubtargetInfo &STI,
Jim Grosbache7f7de92010-11-03 01:11:15 +0000580 raw_ostream &O) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000581 ARM_AM::AMSubMode Mode =
582 ARM_AM::getAM4SubMode(MI->getOperand(OpNum).getImm());
Jim Grosbachc6af2b42010-11-03 01:01:43 +0000583 O << ARM_AM::getAMSubModeStr(Mode);
Chris Lattneref2979b2009-10-19 22:09:23 +0000584}
585
Quentin Colombetc3132202013-04-12 18:47:25 +0000586template <bool AlwaysPrintImm0>
Chris Lattner60d51312009-10-20 06:15:28 +0000587void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000588 const MCSubtargetInfo &STI,
Jim Grosbache7f7de92010-11-03 01:11:15 +0000589 raw_ostream &O) {
Chris Lattner60d51312009-10-20 06:15:28 +0000590 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000591 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000592
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000593 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
Akira Hatanakaee974752015-03-27 23:41:42 +0000594 printOperand(MI, OpNum, STI, O);
Chris Lattner60d51312009-10-20 06:15:28 +0000595 return;
596 }
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000597
Kevin Enderbydccdac62012-10-23 22:52:52 +0000598 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +0000599 printRegName(O, MO1.getReg());
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000600
Owen Anderson967674d2011-08-29 19:36:44 +0000601 unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
Andrew Kaylor51fcf0f2015-03-25 21:33:24 +0000602 ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm());
Quentin Colombetc3132202013-04-12 18:47:25 +0000603 if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000604 O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(Op)
605 << ImmOffs * 4 << markup(">");
Chris Lattner60d51312009-10-20 06:15:28 +0000606 }
Kevin Enderbydccdac62012-10-23 22:52:52 +0000607 O << "]" << markup(">");
Chris Lattner60d51312009-10-20 06:15:28 +0000608}
609
Oliver Stannard65b85382016-01-25 10:26:26 +0000610template <bool AlwaysPrintImm0>
611void ARMInstPrinter::printAddrMode5FP16Operand(const MCInst *MI, unsigned OpNum,
612 const MCSubtargetInfo &STI,
613 raw_ostream &O) {
614 const MCOperand &MO1 = MI->getOperand(OpNum);
615 const MCOperand &MO2 = MI->getOperand(OpNum+1);
616
617 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
618 printOperand(MI, OpNum, STI, O);
619 return;
620 }
621
622 O << markup("<mem:") << "[";
623 printRegName(O, MO1.getReg());
624
625 unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
626 unsigned Op = ARM_AM::getAM5FP16Op(MO2.getImm());
627 if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
628 O << ", "
629 << markup("<imm:")
630 << "#"
631 << ARM_AM::getAddrOpcStr(ARM_AM::getAM5FP16Op(MO2.getImm()))
632 << ImmOffs * 2
633 << markup(">");
634 }
635 O << "]" << markup(">");
636}
637
Chris Lattner76c564b2010-04-04 04:47:45 +0000638void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000639 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000640 raw_ostream &O) {
Chris Lattner9351e4f2009-10-20 06:22:33 +0000641 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000642 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000643
Kevin Enderbydccdac62012-10-23 22:52:52 +0000644 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +0000645 printRegName(O, MO1.getReg());
Bob Wilsonae08a732010-03-20 22:13:40 +0000646 if (MO2.getImm()) {
Kristof Beyls0ba797e2013-02-22 10:01:33 +0000647 O << ":" << (MO2.getImm() << 3);
Chris Lattner9351e4f2009-10-20 06:22:33 +0000648 }
Kevin Enderbydccdac62012-10-23 22:52:52 +0000649 O << "]" << markup(">");
Bob Wilsonae08a732010-03-20 22:13:40 +0000650}
651
Bruno Cardoso Lopesf170f8b2011-03-24 21:04:58 +0000652void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000653 const MCSubtargetInfo &STI,
Bruno Cardoso Lopesf170f8b2011-03-24 21:04:58 +0000654 raw_ostream &O) {
655 const MCOperand &MO1 = MI->getOperand(OpNum);
Kevin Enderbydccdac62012-10-23 22:52:52 +0000656 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +0000657 printRegName(O, MO1.getReg());
Kevin Enderbydccdac62012-10-23 22:52:52 +0000658 O << "]" << markup(">");
Bruno Cardoso Lopesf170f8b2011-03-24 21:04:58 +0000659}
660
Bob Wilsonae08a732010-03-20 22:13:40 +0000661void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000662 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000663 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000664 raw_ostream &O) {
Bob Wilsonae08a732010-03-20 22:13:40 +0000665 const MCOperand &MO = MI->getOperand(OpNum);
666 if (MO.getReg() == 0)
667 O << "!";
Kevin Enderby62183c42012-10-22 22:31:46 +0000668 else {
669 O << ", ";
670 printRegName(O, MO.getReg());
671 }
Chris Lattner9351e4f2009-10-20 06:22:33 +0000672}
673
Bob Wilsonadd513112010-08-11 23:10:46 +0000674void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
675 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000676 const MCSubtargetInfo &STI,
Bob Wilsonadd513112010-08-11 23:10:46 +0000677 raw_ostream &O) {
Chris Lattner9351e4f2009-10-20 06:22:33 +0000678 const MCOperand &MO = MI->getOperand(OpNum);
679 uint32_t v = ~MO.getImm();
Michael J. Spencerdf1ecbd72013-05-24 22:23:49 +0000680 int32_t lsb = countTrailingZeros(v);
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000681 int32_t width = (32 - countLeadingZeros(v)) - lsb;
Chris Lattner9351e4f2009-10-20 06:22:33 +0000682 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000683 O << markup("<imm:") << '#' << lsb << markup(">") << ", " << markup("<imm:")
684 << '#' << width << markup(">");
Chris Lattner9351e4f2009-10-20 06:22:33 +0000685}
Chris Lattner60d51312009-10-20 06:15:28 +0000686
Johnny Chen8e8f1c12010-08-12 20:46:17 +0000687void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000688 const MCSubtargetInfo &STI,
Johnny Chen8e8f1c12010-08-12 20:46:17 +0000689 raw_ostream &O) {
690 unsigned val = MI->getOperand(OpNum).getImm();
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000691 O << ARM_MB::MemBOptToString(val, STI.getFeatureBits()[ARM::HasV8Ops]);
Johnny Chen8e8f1c12010-08-12 20:46:17 +0000692}
693
Amaury de la Vieuville43cb13a2013-06-10 14:17:08 +0000694void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000695 const MCSubtargetInfo &STI,
Amaury de la Vieuville43cb13a2013-06-10 14:17:08 +0000696 raw_ostream &O) {
697 unsigned val = MI->getOperand(OpNum).getImm();
698 O << ARM_ISB::InstSyncBOptToString(val);
699}
700
Bob Wilson481d7a92010-08-16 18:27:34 +0000701void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000702 const MCSubtargetInfo &STI,
Bob Wilsonadd513112010-08-11 23:10:46 +0000703 raw_ostream &O) {
704 unsigned ShiftOp = MI->getOperand(OpNum).getImm();
Jim Grosbach3a9cbee2011-07-25 22:20:28 +0000705 bool isASR = (ShiftOp & (1 << 5)) != 0;
706 unsigned Amt = ShiftOp & 0x1f;
Kevin Enderby62183c42012-10-22 22:31:46 +0000707 if (isASR) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000708 O << ", asr " << markup("<imm:") << "#" << (Amt == 0 ? 32 : Amt)
Kevin Enderbydccdac62012-10-23 22:52:52 +0000709 << markup(">");
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000710 } else if (Amt) {
711 O << ", lsl " << markup("<imm:") << "#" << Amt << markup(">");
Kevin Enderby62183c42012-10-22 22:31:46 +0000712 }
Bob Wilsonadd513112010-08-11 23:10:46 +0000713}
714
Jim Grosbacha288b1c2011-07-20 21:40:26 +0000715void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000716 const MCSubtargetInfo &STI,
Jim Grosbacha288b1c2011-07-20 21:40:26 +0000717 raw_ostream &O) {
718 unsigned Imm = MI->getOperand(OpNum).getImm();
719 if (Imm == 0)
720 return;
721 assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
Kevin Enderbydccdac62012-10-23 22:52:52 +0000722 O << ", lsl " << markup("<imm:") << "#" << Imm << markup(">");
Jim Grosbacha288b1c2011-07-20 21:40:26 +0000723}
724
725void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000726 const MCSubtargetInfo &STI,
Jim Grosbacha288b1c2011-07-20 21:40:26 +0000727 raw_ostream &O) {
728 unsigned Imm = MI->getOperand(OpNum).getImm();
729 // A shift amount of 32 is encoded as 0.
730 if (Imm == 0)
731 Imm = 32;
732 assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
Kevin Enderbydccdac62012-10-23 22:52:52 +0000733 O << ", asr " << markup("<imm:") << "#" << Imm << markup(">");
Jim Grosbacha288b1c2011-07-20 21:40:26 +0000734}
735
Chris Lattner76c564b2010-04-04 04:47:45 +0000736void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000737 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000738 raw_ostream &O) {
Tim Northover46a6f0f2016-11-14 20:28:24 +0000739 assert(std::is_sorted(MI->begin() + OpNum, MI->end(),
740 [&](const MCOperand &LHS, const MCOperand &RHS) {
741 return MRI.getEncodingValue(LHS.getReg()) <
742 MRI.getEncodingValue(RHS.getReg());
743 }));
744
Chris Lattneref2979b2009-10-19 22:09:23 +0000745 O << "{";
Peter Collingbourne6679fc12015-06-05 18:01:28 +0000746 for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
747 if (i != OpNum)
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000748 O << ", ";
Peter Collingbourne6679fc12015-06-05 18:01:28 +0000749 printRegName(O, MI->getOperand(i).getReg());
Chris Lattneref2979b2009-10-19 22:09:23 +0000750 }
751 O << "}";
752}
Chris Lattneradd57492009-10-19 22:23:04 +0000753
Weiming Zhao8f56f882012-11-16 21:55:34 +0000754void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000755 const MCSubtargetInfo &STI,
Weiming Zhao8f56f882012-11-16 21:55:34 +0000756 raw_ostream &O) {
757 unsigned Reg = MI->getOperand(OpNum).getReg();
758 printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
759 O << ", ";
760 printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
761}
762
Jim Grosbach7e72ec62010-10-13 21:00:04 +0000763void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000764 const MCSubtargetInfo &STI,
Jim Grosbach7e72ec62010-10-13 21:00:04 +0000765 raw_ostream &O) {
766 const MCOperand &Op = MI->getOperand(OpNum);
767 if (Op.getImm())
768 O << "be";
769 else
770 O << "le";
771}
772
Bruno Cardoso Lopes90d1dfe2011-02-14 13:09:44 +0000773void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000774 const MCSubtargetInfo &STI, raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +0000775 const MCOperand &Op = MI->getOperand(OpNum);
Bruno Cardoso Lopes90d1dfe2011-02-14 13:09:44 +0000776 O << ARM_PROC::IModToString(Op.getImm());
777}
778
779void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000780 const MCSubtargetInfo &STI, raw_ostream &O) {
Bruno Cardoso Lopes90d1dfe2011-02-14 13:09:44 +0000781 const MCOperand &Op = MI->getOperand(OpNum);
782 unsigned IFlags = Op.getImm();
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000783 for (int i = 2; i >= 0; --i)
Bruno Cardoso Lopes90d1dfe2011-02-14 13:09:44 +0000784 if (IFlags & (1 << i))
785 O << ARM_PROC::IFlagsToString(1 << i);
Owen Anderson10c5b122011-10-05 17:16:40 +0000786
787 if (IFlags == 0)
788 O << "none";
Johnny Chen8f3004c2010-03-17 17:52:21 +0000789}
790
Chris Lattner76c564b2010-04-04 04:47:45 +0000791void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000792 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000793 raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +0000794 const MCOperand &Op = MI->getOperand(OpNum);
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000795 const FeatureBitset &FeatureBits = STI.getFeatureBits();
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000796 if (FeatureBits[ARM::FeatureMClass]) {
Javed Absar2cb0c952017-07-19 12:57:16 +0000797
798 unsigned SYSm = Op.getImm() & 0xFFF; // 12-bit SYSm
Kevin Enderbyf1b225d2012-05-17 22:18:01 +0000799 unsigned Opcode = MI->getOpcode();
Renato Golin92c816c2014-09-01 11:25:07 +0000800
801 // For writes, handle extended mask bits if the DSP extension is present.
Artyom Skrobovcf296442015-09-24 17:31:16 +0000802 if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) {
Javed Absar2cb0c952017-07-19 12:57:16 +0000803 auto TheReg =ARMSysReg::lookupMClassSysRegBy12bitSYSmValue(SYSm);
804 if (TheReg && TheReg->isInRequiredFeatures({ARM::FeatureDSP})) {
805 O << TheReg->Name;
806 return;
Renato Golin92c816c2014-09-01 11:25:07 +0000807 }
808 }
809
810 // Handle the basic 8-bit mask.
811 SYSm &= 0xff;
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000812 if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
Renato Golin92c816c2014-09-01 11:25:07 +0000813 // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
814 // alias for MSR APSR_nzcvq.
Javed Absar2cb0c952017-07-19 12:57:16 +0000815 auto TheReg = ARMSysReg::lookupMClassSysRegAPSRNonDeprecated(SYSm);
816 if (TheReg) {
817 O << TheReg->Name;
818 return;
Renato Golin92c816c2014-09-01 11:25:07 +0000819 }
820 }
821
Javed Absar2cb0c952017-07-19 12:57:16 +0000822 auto TheReg = ARMSysReg::lookupMClassSysRegBy8bitSYSmValue(SYSm);
823 if (TheReg) {
824 O << TheReg->Name;
Bradley Smithf277c8a2016-01-25 11:25:36 +0000825 return;
James Molloy21efa7d2011-09-28 14:21:38 +0000826 }
Javed Absar2cb0c952017-07-19 12:57:16 +0000827
828 llvm_unreachable("Unexpected mask value!");
829 return;
James Molloy21efa7d2011-09-28 14:21:38 +0000830 }
831
Jim Grosbachd25c2cd2011-07-19 22:45:10 +0000832 // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
833 // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
Javed Absar2cb0c952017-07-19 12:57:16 +0000834 unsigned SpecRegRBit = Op.getImm() >> 4;
835 unsigned Mask = Op.getImm() & 0xf;
836
Jim Grosbachd25c2cd2011-07-19 22:45:10 +0000837 if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
838 O << "APSR_";
839 switch (Mask) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000840 default:
841 llvm_unreachable("Unexpected mask value!");
842 case 4:
843 O << "g";
844 return;
845 case 8:
846 O << "nzcvq";
847 return;
848 case 12:
849 O << "nzcvqg";
850 return;
Jim Grosbachd25c2cd2011-07-19 22:45:10 +0000851 }
Jim Grosbachd25c2cd2011-07-19 22:45:10 +0000852 }
853
Bruno Cardoso Lopes9cd43972011-02-18 19:45:59 +0000854 if (SpecRegRBit)
Jim Grosbachd25c2cd2011-07-19 22:45:10 +0000855 O << "SPSR";
Bruno Cardoso Lopes9cd43972011-02-18 19:45:59 +0000856 else
Jim Grosbachd25c2cd2011-07-19 22:45:10 +0000857 O << "CPSR";
Bruno Cardoso Lopes9cd43972011-02-18 19:45:59 +0000858
Johnny Chen8f3004c2010-03-17 17:52:21 +0000859 if (Mask) {
860 O << '_';
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000861 if (Mask & 8)
862 O << 'f';
863 if (Mask & 4)
864 O << 's';
865 if (Mask & 2)
866 O << 'x';
867 if (Mask & 1)
868 O << 'c';
Johnny Chen8f3004c2010-03-17 17:52:21 +0000869 }
870}
871
Tim Northoveree843ef2014-08-15 10:47:12 +0000872void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000873 const MCSubtargetInfo &STI,
Tim Northoveree843ef2014-08-15 10:47:12 +0000874 raw_ostream &O) {
875 uint32_t Banked = MI->getOperand(OpNum).getImm();
Javed Absar9cda5992017-08-04 17:10:11 +0000876 auto TheReg = ARMBankedReg::lookupBankedRegByEncoding(Banked);
877 assert(TheReg && "invalid banked register operand");
878 std::string Name = TheReg->Name;
Tim Northoveree843ef2014-08-15 10:47:12 +0000879
Javed Absar9cda5992017-08-04 17:10:11 +0000880 uint32_t isSPSR = (Banked & 0x20) >> 5;
881 if (isSPSR)
882 Name.replace(0, 4, "SPSR"); // convert 'spsr_' to 'SPSR_'
Tim Northoveree843ef2014-08-15 10:47:12 +0000883 O << Name;
884}
885
Chris Lattner76c564b2010-04-04 04:47:45 +0000886void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000887 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000888 raw_ostream &O) {
Chris Lattner19c52202009-10-20 00:42:49 +0000889 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
Kevin Enderbyf0269b42012-03-01 22:13:02 +0000890 // Handle the undefined 15 CC value here for printing so we don't abort().
891 if ((unsigned)CC == 15)
892 O << "<und>";
893 else if (CC != ARMCC::AL)
Chris Lattner19c52202009-10-20 00:42:49 +0000894 O << ARMCondCodeToString(CC);
895}
896
Jim Grosbach29cad6c2010-09-14 22:27:15 +0000897void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000898 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000899 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000900 raw_ostream &O) {
Johnny Chen0dae1cb2010-03-02 17:57:15 +0000901 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
902 O << ARMCondCodeToString(CC);
903}
904
Chris Lattner76c564b2010-04-04 04:47:45 +0000905void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000906 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000907 raw_ostream &O) {
Daniel Dunbara470eac2009-10-20 22:10:05 +0000908 if (MI->getOperand(OpNum).getReg()) {
909 assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
910 "Expect ARM CPSR register!");
Chris Lattner85ab6702009-10-20 00:46:11 +0000911 O << 's';
912 }
913}
914
Chris Lattner76c564b2010-04-04 04:47:45 +0000915void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000916 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000917 raw_ostream &O) {
Chris Lattner60d51312009-10-20 06:15:28 +0000918 O << MI->getOperand(OpNum).getImm();
919}
920
Owen Andersonc3c7f5d2011-01-13 21:46:02 +0000921void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000922 const MCSubtargetInfo &STI,
Jim Grosbach69664112011-10-12 16:34:37 +0000923 raw_ostream &O) {
Owen Andersonc3c7f5d2011-01-13 21:46:02 +0000924 O << "p" << MI->getOperand(OpNum).getImm();
925}
926
927void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000928 const MCSubtargetInfo &STI,
Jim Grosbach69664112011-10-12 16:34:37 +0000929 raw_ostream &O) {
Owen Andersonc3c7f5d2011-01-13 21:46:02 +0000930 O << "c" << MI->getOperand(OpNum).getImm();
931}
932
Jim Grosbach48399582011-10-12 17:34:41 +0000933void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000934 const MCSubtargetInfo &STI,
Jim Grosbach48399582011-10-12 17:34:41 +0000935 raw_ostream &O) {
936 O << "{" << MI->getOperand(OpNum).getImm() << "}";
937}
938
Chris Lattner76c564b2010-04-04 04:47:45 +0000939void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000940 const MCSubtargetInfo &STI, raw_ostream &O) {
Jim Grosbach8a5a6a62010-09-18 00:04:53 +0000941 llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
Chris Lattneradd57492009-10-19 22:23:04 +0000942}
Evan Chengb1852592009-11-19 06:57:41 +0000943
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000944template <unsigned scale>
Jiangning Liu10dd40e2012-08-02 08:13:13 +0000945void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000946 const MCSubtargetInfo &STI,
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000947 raw_ostream &O) {
Jiangning Liu10dd40e2012-08-02 08:13:13 +0000948 const MCOperand &MO = MI->getOperand(OpNum);
949
950 if (MO.isExpr()) {
Matt Arsenault8b643552015-06-09 00:31:39 +0000951 MO.getExpr()->print(O, &MAI);
Jiangning Liu10dd40e2012-08-02 08:13:13 +0000952 return;
953 }
954
Mihai Popad36cbaa2013-07-03 09:21:44 +0000955 int32_t OffImm = (int32_t)MO.getImm() << scale;
Jiangning Liu10dd40e2012-08-02 08:13:13 +0000956
Kevin Enderbydccdac62012-10-23 22:52:52 +0000957 O << markup("<imm:");
Jiangning Liu10dd40e2012-08-02 08:13:13 +0000958 if (OffImm == INT32_MIN)
959 O << "#-0";
960 else if (OffImm < 0)
961 O << "#-" << -OffImm;
962 else
963 O << "#" << OffImm;
Kevin Enderbydccdac62012-10-23 22:52:52 +0000964 O << markup(">");
Jiangning Liu10dd40e2012-08-02 08:13:13 +0000965}
966
Chris Lattner76c564b2010-04-04 04:47:45 +0000967void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000968 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000969 raw_ostream &O) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000970 O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4)
Kevin Enderbydccdac62012-10-23 22:52:52 +0000971 << markup(">");
Jim Grosbach46dd4132011-08-17 21:51:27 +0000972}
973
974void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000975 const MCSubtargetInfo &STI,
Jim Grosbach46dd4132011-08-17 21:51:27 +0000976 raw_ostream &O) {
977 unsigned Imm = MI->getOperand(OpNum).getImm();
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000978 O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm))
Kevin Enderbydccdac62012-10-23 22:52:52 +0000979 << markup(">");
Evan Chengb1852592009-11-19 06:57:41 +0000980}
Johnny Chen8f3004c2010-03-17 17:52:21 +0000981
Chris Lattner76c564b2010-04-04 04:47:45 +0000982void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +0000983 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +0000984 raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +0000985 // (3 - the number of trailing zeros) is the number of then / else.
986 unsigned Mask = MI->getOperand(OpNum).getImm();
Akira Hatanakacfa1f612015-03-27 23:24:22 +0000987 unsigned Firstcond = MI->getOperand(OpNum - 1).getImm();
Richard Bartonf435b092012-04-27 08:42:59 +0000988 unsigned CondBit0 = Firstcond & 1;
Michael J. Spencerdf1ecbd72013-05-24 22:23:49 +0000989 unsigned NumTZ = countTrailingZeros(Mask);
Johnny Chen8f3004c2010-03-17 17:52:21 +0000990 assert(NumTZ <= 3 && "Invalid IT mask!");
991 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
992 bool T = ((Mask >> Pos) & 1) == CondBit0;
993 if (T)
994 O << 't';
995 else
996 O << 'e';
997 }
998}
999
Chris Lattner76c564b2010-04-04 04:47:45 +00001000void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
Akira Hatanakaee974752015-03-27 23:41:42 +00001001 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +00001002 raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +00001003 const MCOperand &MO1 = MI->getOperand(Op);
Bill Wendling092a7bd2010-12-14 03:36:38 +00001004 const MCOperand &MO2 = MI->getOperand(Op + 1);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001005
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001006 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
Akira Hatanakaee974752015-03-27 23:41:42 +00001007 printOperand(MI, Op, STI, O);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001008 return;
1009 }
1010
Kevin Enderbydccdac62012-10-23 22:52:52 +00001011 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +00001012 printRegName(O, MO1.getReg());
1013 if (unsigned RegNum = MO2.getReg()) {
1014 O << ", ";
1015 printRegName(O, RegNum);
1016 }
Kevin Enderbydccdac62012-10-23 22:52:52 +00001017 O << "]" << markup(">");
Bill Wendling092a7bd2010-12-14 03:36:38 +00001018}
1019
1020void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI,
Akira Hatanakaee974752015-03-27 23:41:42 +00001021 unsigned Op,
1022 const MCSubtargetInfo &STI,
1023 raw_ostream &O,
Bill Wendling092a7bd2010-12-14 03:36:38 +00001024 unsigned Scale) {
1025 const MCOperand &MO1 = MI->getOperand(Op);
1026 const MCOperand &MO2 = MI->getOperand(Op + 1);
1027
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001028 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
Akira Hatanakaee974752015-03-27 23:41:42 +00001029 printOperand(MI, Op, STI, O);
Bill Wendling092a7bd2010-12-14 03:36:38 +00001030 return;
1031 }
1032
Kevin Enderbydccdac62012-10-23 22:52:52 +00001033 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +00001034 printRegName(O, MO1.getReg());
1035 if (unsigned ImmOffs = MO2.getImm()) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001036 O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale)
Kevin Enderbydccdac62012-10-23 22:52:52 +00001037 << markup(">");
Kevin Enderby62183c42012-10-22 22:31:46 +00001038 }
Kevin Enderbydccdac62012-10-23 22:52:52 +00001039 O << "]" << markup(">");
Johnny Chen8f3004c2010-03-17 17:52:21 +00001040}
1041
Bill Wendling092a7bd2010-12-14 03:36:38 +00001042void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI,
1043 unsigned Op,
Akira Hatanakaee974752015-03-27 23:41:42 +00001044 const MCSubtargetInfo &STI,
Bill Wendling092a7bd2010-12-14 03:36:38 +00001045 raw_ostream &O) {
Akira Hatanakaee974752015-03-27 23:41:42 +00001046 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001047}
1048
Bill Wendling092a7bd2010-12-14 03:36:38 +00001049void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI,
1050 unsigned Op,
Akira Hatanakaee974752015-03-27 23:41:42 +00001051 const MCSubtargetInfo &STI,
Bill Wendling092a7bd2010-12-14 03:36:38 +00001052 raw_ostream &O) {
Akira Hatanakaee974752015-03-27 23:41:42 +00001053 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001054}
1055
Bill Wendling092a7bd2010-12-14 03:36:38 +00001056void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI,
1057 unsigned Op,
Akira Hatanakaee974752015-03-27 23:41:42 +00001058 const MCSubtargetInfo &STI,
Bill Wendling092a7bd2010-12-14 03:36:38 +00001059 raw_ostream &O) {
Akira Hatanakaee974752015-03-27 23:41:42 +00001060 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001061}
1062
Chris Lattner76c564b2010-04-04 04:47:45 +00001063void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
Akira Hatanakaee974752015-03-27 23:41:42 +00001064 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +00001065 raw_ostream &O) {
Akira Hatanakaee974752015-03-27 23:41:42 +00001066 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001067}
1068
Johnny Chen8f3004c2010-03-17 17:52:21 +00001069// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1070// register with shift forms.
1071// REG 0 0 - e.g. R5
1072// REG IMM, SH_OPC - e.g. R5, LSL #3
Chris Lattner76c564b2010-04-04 04:47:45 +00001073void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001074 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +00001075 raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +00001076 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001077 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001078
1079 unsigned Reg = MO1.getReg();
Kevin Enderby62183c42012-10-22 22:31:46 +00001080 printRegName(O, Reg);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001081
1082 // Print the shift opc.
Johnny Chen8f3004c2010-03-17 17:52:21 +00001083 assert(MO2.isImm() && "Not a valid t2_so_reg value!");
Tim Northover2fdbdc52012-09-22 11:18:19 +00001084 printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
Kevin Enderby62183c42012-10-22 22:31:46 +00001085 ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001086}
1087
Quentin Colombetc3132202013-04-12 18:47:25 +00001088template <bool AlwaysPrintImm0>
Jim Grosbache6fe1a02010-10-25 20:00:01 +00001089void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001090 const MCSubtargetInfo &STI,
Jim Grosbache6fe1a02010-10-25 20:00:01 +00001091 raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +00001092 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001093 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001094
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001095 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
Akira Hatanakaee974752015-03-27 23:41:42 +00001096 printOperand(MI, OpNum, STI, O);
Jim Grosbach1e4d9a12010-10-26 22:37:02 +00001097 return;
1098 }
1099
Kevin Enderbydccdac62012-10-23 22:52:52 +00001100 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +00001101 printRegName(O, MO1.getReg());
Johnny Chen8f3004c2010-03-17 17:52:21 +00001102
Jim Grosbach9d2d1f02010-10-27 01:19:41 +00001103 int32_t OffImm = (int32_t)MO2.getImm();
Jim Grosbach505607e2010-10-28 18:34:10 +00001104 bool isSub = OffImm < 0;
1105 // Special value for #-0. All others are normal.
1106 if (OffImm == INT32_MIN)
1107 OffImm = 0;
Kevin Enderby62183c42012-10-22 22:31:46 +00001108 if (isSub) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001109 O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
1110 } else if (AlwaysPrintImm0 || OffImm > 0) {
1111 O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
Kevin Enderby62183c42012-10-22 22:31:46 +00001112 }
Kevin Enderbydccdac62012-10-23 22:52:52 +00001113 O << "]" << markup(">");
Johnny Chen8f3004c2010-03-17 17:52:21 +00001114}
1115
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001116template <bool AlwaysPrintImm0>
Johnny Chen8f3004c2010-03-17 17:52:21 +00001117void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
Chris Lattner76c564b2010-04-04 04:47:45 +00001118 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001119 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +00001120 raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +00001121 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001122 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001123
Kevin Enderbydccdac62012-10-23 22:52:52 +00001124 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +00001125 printRegName(O, MO1.getReg());
Johnny Chen8f3004c2010-03-17 17:52:21 +00001126
1127 int32_t OffImm = (int32_t)MO2.getImm();
Amaury de la Vieuvilleaa7fdf82013-06-18 08:12:51 +00001128 bool isSub = OffImm < 0;
Johnny Chen8f3004c2010-03-17 17:52:21 +00001129 // Don't print +0.
Owen Andersonfe823652011-09-16 21:08:33 +00001130 if (OffImm == INT32_MIN)
Amaury de la Vieuvilleaa7fdf82013-06-18 08:12:51 +00001131 OffImm = 0;
1132 if (isSub) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001133 O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
Amaury de la Vieuvilleaa7fdf82013-06-18 08:12:51 +00001134 } else if (AlwaysPrintImm0 || OffImm > 0) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001135 O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
Amaury de la Vieuvilleaa7fdf82013-06-18 08:12:51 +00001136 }
Kevin Enderbydccdac62012-10-23 22:52:52 +00001137 O << "]" << markup(">");
Johnny Chen8f3004c2010-03-17 17:52:21 +00001138}
1139
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001140template <bool AlwaysPrintImm0>
Johnny Chen8f3004c2010-03-17 17:52:21 +00001141void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
Chris Lattner76c564b2010-04-04 04:47:45 +00001142 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001143 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +00001144 raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +00001145 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001146 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001147
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001148 if (!MO1.isReg()) { // For label symbolic references.
Akira Hatanakaee974752015-03-27 23:41:42 +00001149 printOperand(MI, OpNum, STI, O);
Jim Grosbach8648c102011-12-19 23:06:24 +00001150 return;
1151 }
1152
Kevin Enderbydccdac62012-10-23 22:52:52 +00001153 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +00001154 printRegName(O, MO1.getReg());
Johnny Chen8f3004c2010-03-17 17:52:21 +00001155
Jiangning Liu6a43bf72012-08-02 08:29:50 +00001156 int32_t OffImm = (int32_t)MO2.getImm();
Amaury de la Vieuvilleaa7fdf82013-06-18 08:12:51 +00001157 bool isSub = OffImm < 0;
Jiangning Liu6a43bf72012-08-02 08:29:50 +00001158
1159 assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
1160
Johnny Chen8f3004c2010-03-17 17:52:21 +00001161 // Don't print +0.
Jiangning Liu6a43bf72012-08-02 08:29:50 +00001162 if (OffImm == INT32_MIN)
Amaury de la Vieuvilleaa7fdf82013-06-18 08:12:51 +00001163 OffImm = 0;
1164 if (isSub) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001165 O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
Amaury de la Vieuvilleaa7fdf82013-06-18 08:12:51 +00001166 } else if (AlwaysPrintImm0 || OffImm > 0) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001167 O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
Amaury de la Vieuvilleaa7fdf82013-06-18 08:12:51 +00001168 }
Kevin Enderbydccdac62012-10-23 22:52:52 +00001169 O << "]" << markup(">");
Johnny Chen8f3004c2010-03-17 17:52:21 +00001170}
1171
Akira Hatanakaee974752015-03-27 23:41:42 +00001172void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(
1173 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1174 raw_ostream &O) {
Jim Grosbacha05627e2011-09-09 18:37:27 +00001175 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001176 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
Jim Grosbacha05627e2011-09-09 18:37:27 +00001177
Kevin Enderbydccdac62012-10-23 22:52:52 +00001178 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +00001179 printRegName(O, MO1.getReg());
1180 if (MO2.getImm()) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001181 O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4)
Kevin Enderbydccdac62012-10-23 22:52:52 +00001182 << markup(">");
Kevin Enderby62183c42012-10-22 22:31:46 +00001183 }
Kevin Enderbydccdac62012-10-23 22:52:52 +00001184 O << "]" << markup(">");
Jim Grosbacha05627e2011-09-09 18:37:27 +00001185}
1186
Akira Hatanakaee974752015-03-27 23:41:42 +00001187void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(
1188 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1189 raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +00001190 const MCOperand &MO1 = MI->getOperand(OpNum);
1191 int32_t OffImm = (int32_t)MO1.getImm();
Kevin Enderbydccdac62012-10-23 22:52:52 +00001192 O << ", " << markup("<imm:");
Amaury de la Vieuville231ca2b2013-06-13 16:40:51 +00001193 if (OffImm == INT32_MIN)
1194 O << "#-0";
1195 else if (OffImm < 0)
Kevin Enderby62183c42012-10-22 22:31:46 +00001196 O << "#-" << -OffImm;
Owen Anderson737beaf2011-09-23 21:26:40 +00001197 else
Kevin Enderby62183c42012-10-22 22:31:46 +00001198 O << "#" << OffImm;
Kevin Enderbydccdac62012-10-23 22:52:52 +00001199 O << markup(">");
Johnny Chen8f3004c2010-03-17 17:52:21 +00001200}
1201
Akira Hatanakaee974752015-03-27 23:41:42 +00001202void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(
1203 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1204 raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +00001205 const MCOperand &MO1 = MI->getOperand(OpNum);
Jiangning Liu6a43bf72012-08-02 08:29:50 +00001206 int32_t OffImm = (int32_t)MO1.getImm();
1207
1208 assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
1209
Amaury de la Vieuvillea6f55422013-06-26 13:39:07 +00001210 O << ", " << markup("<imm:");
Jiangning Liu6a43bf72012-08-02 08:29:50 +00001211 if (OffImm == INT32_MIN)
Kevin Enderby62183c42012-10-22 22:31:46 +00001212 O << "#-0";
Jiangning Liu6a43bf72012-08-02 08:29:50 +00001213 else if (OffImm < 0)
Kevin Enderby62183c42012-10-22 22:31:46 +00001214 O << "#-" << -OffImm;
Amaury de la Vieuvillea6f55422013-06-26 13:39:07 +00001215 else
Kevin Enderby62183c42012-10-22 22:31:46 +00001216 O << "#" << OffImm;
Amaury de la Vieuvillea6f55422013-06-26 13:39:07 +00001217 O << markup(">");
Johnny Chen8f3004c2010-03-17 17:52:21 +00001218}
1219
1220void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
Chris Lattner76c564b2010-04-04 04:47:45 +00001221 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001222 const MCSubtargetInfo &STI,
Chris Lattner76c564b2010-04-04 04:47:45 +00001223 raw_ostream &O) {
Johnny Chen8f3004c2010-03-17 17:52:21 +00001224 const MCOperand &MO1 = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001225 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1226 const MCOperand &MO3 = MI->getOperand(OpNum + 2);
Johnny Chen8f3004c2010-03-17 17:52:21 +00001227
Kevin Enderbydccdac62012-10-23 22:52:52 +00001228 O << markup("<mem:") << "[";
Kevin Enderby62183c42012-10-22 22:31:46 +00001229 printRegName(O, MO1.getReg());
Johnny Chen8f3004c2010-03-17 17:52:21 +00001230
1231 assert(MO2.getReg() && "Invalid so_reg load / store address!");
Kevin Enderby62183c42012-10-22 22:31:46 +00001232 O << ", ";
1233 printRegName(O, MO2.getReg());
Johnny Chen8f3004c2010-03-17 17:52:21 +00001234
1235 unsigned ShAmt = MO3.getImm();
1236 if (ShAmt) {
1237 assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001238 O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">");
Johnny Chen8f3004c2010-03-17 17:52:21 +00001239 }
Kevin Enderbydccdac62012-10-23 22:52:52 +00001240 O << "]" << markup(">");
Johnny Chen8f3004c2010-03-17 17:52:21 +00001241}
1242
Jim Grosbachefc761a2011-09-30 00:50:06 +00001243void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001244 const MCSubtargetInfo &STI,
Jim Grosbachefc761a2011-09-30 00:50:06 +00001245 raw_ostream &O) {
Bill Wendling5a13d4f2011-01-26 20:57:43 +00001246 const MCOperand &MO = MI->getOperand(OpNum);
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001247 O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm())
Kevin Enderbydccdac62012-10-23 22:52:52 +00001248 << markup(">");
Johnny Chen8f3004c2010-03-17 17:52:21 +00001249}
1250
Bob Wilson6eae5202010-06-11 21:34:50 +00001251void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001252 const MCSubtargetInfo &STI,
Bob Wilson6eae5202010-06-11 21:34:50 +00001253 raw_ostream &O) {
Bob Wilsonc1c6f472010-07-13 04:44:34 +00001254 unsigned EncodedImm = MI->getOperand(OpNum).getImm();
1255 unsigned EltBits;
1256 uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001257 O << markup("<imm:") << "#0x";
Benjamin Kramer69d57cf2011-11-07 21:00:59 +00001258 O.write_hex(Val);
Kevin Enderbydccdac62012-10-23 22:52:52 +00001259 O << markup(">");
Johnny Chenb90b6f12010-04-16 22:40:20 +00001260}
Jim Grosbach801e0a32011-07-22 23:16:18 +00001261
Jim Grosbach475c6db2011-07-25 23:09:14 +00001262void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001263 const MCSubtargetInfo &STI,
Jim Grosbach475c6db2011-07-25 23:09:14 +00001264 raw_ostream &O) {
Jim Grosbach801e0a32011-07-22 23:16:18 +00001265 unsigned Imm = MI->getOperand(OpNum).getImm();
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001266 O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">");
Jim Grosbach801e0a32011-07-22 23:16:18 +00001267}
Jim Grosbachd2659132011-07-26 21:28:43 +00001268
1269void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001270 const MCSubtargetInfo &STI,
Jim Grosbachd2659132011-07-26 21:28:43 +00001271 raw_ostream &O) {
1272 unsigned Imm = MI->getOperand(OpNum).getImm();
1273 if (Imm == 0)
1274 return;
Benjamin Kramera44b37e2015-04-25 17:25:13 +00001275 assert(Imm <= 3 && "illegal ror immediate!");
1276 O << ", ror " << markup("<imm:") << "#" << 8 * Imm << markup(">");
Jim Grosbachd2659132011-07-26 21:28:43 +00001277}
Jim Grosbachd0637bf2011-10-07 23:56:00 +00001278
Asiri Rathnayakea0199b92014-12-02 10:53:20 +00001279void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001280 const MCSubtargetInfo &STI,
Asiri Rathnayakea0199b92014-12-02 10:53:20 +00001281 raw_ostream &O) {
1282 MCOperand Op = MI->getOperand(OpNum);
1283
1284 // Support for fixups (MCFixup)
1285 if (Op.isExpr())
Akira Hatanakaee974752015-03-27 23:41:42 +00001286 return printOperand(MI, OpNum, STI, O);
Asiri Rathnayakea0199b92014-12-02 10:53:20 +00001287
1288 unsigned Bits = Op.getImm() & 0xFF;
1289 unsigned Rot = (Op.getImm() & 0xF00) >> 7;
1290
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001291 bool PrintUnsigned = false;
1292 switch (MI->getOpcode()) {
Asiri Rathnayakea0199b92014-12-02 10:53:20 +00001293 case ARM::MOVi:
1294 // Movs to PC should be treated unsigned
1295 PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC);
1296 break;
1297 case ARM::MSRi:
1298 // Movs to special registers should be treated unsigned
1299 PrintUnsigned = true;
1300 break;
1301 }
1302
1303 int32_t Rotated = ARM_AM::rotr32(Bits, Rot);
1304 if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) {
1305 // #rot has the least possible value
1306 O << "#" << markup("<imm:");
1307 if (PrintUnsigned)
1308 O << static_cast<uint32_t>(Rotated);
1309 else
1310 O << Rotated;
1311 O << markup(">");
1312 return;
1313 }
1314
1315 // Explicit #bits, #rot implied
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001316 O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:")
1317 << Rot << markup(">");
Asiri Rathnayakea0199b92014-12-02 10:53:20 +00001318}
1319
Jim Grosbachea231912011-12-22 22:19:05 +00001320void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001321 const MCSubtargetInfo &STI, raw_ostream &O) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001322 O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm()
Kevin Enderbydccdac62012-10-23 22:52:52 +00001323 << markup(">");
Jim Grosbachea231912011-12-22 22:19:05 +00001324}
1325
1326void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001327 const MCSubtargetInfo &STI, raw_ostream &O) {
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001328 O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm()
Kevin Enderbydccdac62012-10-23 22:52:52 +00001329 << markup(">");
Jim Grosbachea231912011-12-22 22:19:05 +00001330}
1331
Jim Grosbachd0637bf2011-10-07 23:56:00 +00001332void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001333 const MCSubtargetInfo &STI,
Jim Grosbachd0637bf2011-10-07 23:56:00 +00001334 raw_ostream &O) {
1335 O << "[" << MI->getOperand(OpNum).getImm() << "]";
1336}
Jim Grosbachad47cfc2011-10-18 23:02:30 +00001337
1338void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001339 const MCSubtargetInfo &STI,
Jim Grosbachad47cfc2011-10-18 23:02:30 +00001340 raw_ostream &O) {
Kevin Enderby62183c42012-10-22 22:31:46 +00001341 O << "{";
1342 printRegName(O, MI->getOperand(OpNum).getReg());
1343 O << "}";
Jim Grosbachad47cfc2011-10-18 23:02:30 +00001344}
Jim Grosbach2f2e3c42011-10-21 18:54:25 +00001345
Jim Grosbach13a292c2012-03-06 22:01:44 +00001346void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001347 const MCSubtargetInfo &STI,
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001348 raw_ostream &O) {
Jim Grosbachc988e0c2012-03-05 19:33:30 +00001349 unsigned Reg = MI->getOperand(OpNum).getReg();
1350 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1351 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
Kevin Enderby62183c42012-10-22 22:31:46 +00001352 O << "{";
1353 printRegName(O, Reg0);
1354 O << ", ";
1355 printRegName(O, Reg1);
1356 O << "}";
Jim Grosbachc988e0c2012-03-05 19:33:30 +00001357}
1358
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001359void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001360 const MCSubtargetInfo &STI,
Jim Grosbach13a292c2012-03-06 22:01:44 +00001361 raw_ostream &O) {
Jim Grosbache5307f92012-03-05 21:43:40 +00001362 unsigned Reg = MI->getOperand(OpNum).getReg();
1363 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1364 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
Kevin Enderby62183c42012-10-22 22:31:46 +00001365 O << "{";
1366 printRegName(O, Reg0);
1367 O << ", ";
1368 printRegName(O, Reg1);
1369 O << "}";
Jim Grosbache5307f92012-03-05 21:43:40 +00001370}
1371
Jim Grosbachc4360fe2011-10-21 20:02:19 +00001372void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001373 const MCSubtargetInfo &STI,
Jim Grosbachc4360fe2011-10-21 20:02:19 +00001374 raw_ostream &O) {
1375 // Normally, it's not safe to use register enum values directly with
1376 // addition to get the next register, but for VFP registers, the
1377 // sort order is guaranteed because they're all of the form D<n>.
Kevin Enderby62183c42012-10-22 22:31:46 +00001378 O << "{";
1379 printRegName(O, MI->getOperand(OpNum).getReg());
1380 O << ", ";
1381 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1382 O << ", ";
1383 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1384 O << "}";
Jim Grosbachc4360fe2011-10-21 20:02:19 +00001385}
Jim Grosbach846bcff2011-10-21 20:35:01 +00001386
1387void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001388 const MCSubtargetInfo &STI,
Jim Grosbach846bcff2011-10-21 20:35:01 +00001389 raw_ostream &O) {
1390 // Normally, it's not safe to use register enum values directly with
1391 // addition to get the next register, but for VFP registers, the
1392 // sort order is guaranteed because they're all of the form D<n>.
Kevin Enderby62183c42012-10-22 22:31:46 +00001393 O << "{";
1394 printRegName(O, MI->getOperand(OpNum).getReg());
1395 O << ", ";
1396 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1397 O << ", ";
1398 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1399 O << ", ";
1400 printRegName(O, MI->getOperand(OpNum).getReg() + 3);
1401 O << "}";
Jim Grosbach846bcff2011-10-21 20:35:01 +00001402}
Jim Grosbachcd6f5e72011-11-30 01:09:44 +00001403
1404void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI,
1405 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001406 const MCSubtargetInfo &STI,
Jim Grosbachcd6f5e72011-11-30 01:09:44 +00001407 raw_ostream &O) {
Kevin Enderby62183c42012-10-22 22:31:46 +00001408 O << "{";
1409 printRegName(O, MI->getOperand(OpNum).getReg());
1410 O << "[]}";
Jim Grosbachcd6f5e72011-11-30 01:09:44 +00001411}
1412
Jim Grosbach3ecf9762011-11-30 18:21:25 +00001413void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI,
1414 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001415 const MCSubtargetInfo &STI,
Jim Grosbach3ecf9762011-11-30 18:21:25 +00001416 raw_ostream &O) {
Jim Grosbach13a292c2012-03-06 22:01:44 +00001417 unsigned Reg = MI->getOperand(OpNum).getReg();
1418 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1419 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
Kevin Enderby62183c42012-10-22 22:31:46 +00001420 O << "{";
1421 printRegName(O, Reg0);
1422 O << "[], ";
1423 printRegName(O, Reg1);
1424 O << "[]}";
Jim Grosbach3ecf9762011-11-30 18:21:25 +00001425}
Jim Grosbach8d246182011-12-14 19:35:22 +00001426
Jim Grosbachb78403c2012-01-24 23:47:04 +00001427void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI,
1428 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001429 const MCSubtargetInfo &STI,
Jim Grosbachb78403c2012-01-24 23:47:04 +00001430 raw_ostream &O) {
1431 // Normally, it's not safe to use register enum values directly with
1432 // addition to get the next register, but for VFP registers, the
1433 // sort order is guaranteed because they're all of the form D<n>.
Kevin Enderby62183c42012-10-22 22:31:46 +00001434 O << "{";
1435 printRegName(O, MI->getOperand(OpNum).getReg());
1436 O << "[], ";
1437 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1438 O << "[], ";
1439 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1440 O << "[]}";
Jim Grosbachb78403c2012-01-24 23:47:04 +00001441}
1442
Jim Grosbach086cbfa2012-01-25 00:01:08 +00001443void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001444 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001445 const MCSubtargetInfo &STI,
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001446 raw_ostream &O) {
Jim Grosbach086cbfa2012-01-25 00:01:08 +00001447 // Normally, it's not safe to use register enum values directly with
1448 // addition to get the next register, but for VFP registers, the
1449 // sort order is guaranteed because they're all of the form D<n>.
Kevin Enderby62183c42012-10-22 22:31:46 +00001450 O << "{";
1451 printRegName(O, MI->getOperand(OpNum).getReg());
1452 O << "[], ";
1453 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1454 O << "[], ";
1455 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1456 O << "[], ";
1457 printRegName(O, MI->getOperand(OpNum).getReg() + 3);
1458 O << "[]}";
Jim Grosbach086cbfa2012-01-25 00:01:08 +00001459}
1460
Akira Hatanakaee974752015-03-27 23:41:42 +00001461void ARMInstPrinter::printVectorListTwoSpacedAllLanes(
1462 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1463 raw_ostream &O) {
Jim Grosbached428bc2012-03-06 23:10:38 +00001464 unsigned Reg = MI->getOperand(OpNum).getReg();
1465 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1466 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
Kevin Enderby62183c42012-10-22 22:31:46 +00001467 O << "{";
1468 printRegName(O, Reg0);
1469 O << "[], ";
1470 printRegName(O, Reg1);
1471 O << "[]}";
Jim Grosbachc5af54e2011-12-21 00:38:54 +00001472}
1473
Akira Hatanakaee974752015-03-27 23:41:42 +00001474void ARMInstPrinter::printVectorListThreeSpacedAllLanes(
1475 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1476 raw_ostream &O) {
Jim Grosbachb78403c2012-01-24 23:47:04 +00001477 // Normally, it's not safe to use register enum values directly with
1478 // addition to get the next register, but for VFP registers, the
1479 // sort order is guaranteed because they're all of the form D<n>.
Kevin Enderby62183c42012-10-22 22:31:46 +00001480 O << "{";
1481 printRegName(O, MI->getOperand(OpNum).getReg());
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001482 O << "[], ";
Kevin Enderby62183c42012-10-22 22:31:46 +00001483 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1484 O << "[], ";
1485 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1486 O << "[]}";
Jim Grosbach086cbfa2012-01-25 00:01:08 +00001487}
1488
Akira Hatanakaee974752015-03-27 23:41:42 +00001489void ARMInstPrinter::printVectorListFourSpacedAllLanes(
1490 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1491 raw_ostream &O) {
Jim Grosbach086cbfa2012-01-25 00:01:08 +00001492 // Normally, it's not safe to use register enum values directly with
1493 // addition to get the next register, but for VFP registers, the
1494 // sort order is guaranteed because they're all of the form D<n>.
Kevin Enderby62183c42012-10-22 22:31:46 +00001495 O << "{";
1496 printRegName(O, MI->getOperand(OpNum).getReg());
1497 O << "[], ";
1498 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1499 O << "[], ";
1500 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1501 O << "[], ";
1502 printRegName(O, MI->getOperand(OpNum).getReg() + 6);
1503 O << "[]}";
Jim Grosbachb78403c2012-01-24 23:47:04 +00001504}
1505
Jim Grosbachac2af3f2012-01-23 23:20:46 +00001506void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI,
1507 unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001508 const MCSubtargetInfo &STI,
Jim Grosbachac2af3f2012-01-23 23:20:46 +00001509 raw_ostream &O) {
1510 // Normally, it's not safe to use register enum values directly with
1511 // addition to get the next register, but for VFP registers, the
1512 // sort order is guaranteed because they're all of the form D<n>.
Kevin Enderby62183c42012-10-22 22:31:46 +00001513 O << "{";
1514 printRegName(O, MI->getOperand(OpNum).getReg());
1515 O << ", ";
1516 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1517 O << ", ";
1518 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1519 O << "}";
Jim Grosbachac2af3f2012-01-23 23:20:46 +00001520}
Jim Grosbached561fc2012-01-24 00:43:17 +00001521
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001522void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, unsigned OpNum,
Akira Hatanakaee974752015-03-27 23:41:42 +00001523 const MCSubtargetInfo &STI,
Akira Hatanakacfa1f612015-03-27 23:24:22 +00001524 raw_ostream &O) {
Jim Grosbached561fc2012-01-24 00:43:17 +00001525 // Normally, it's not safe to use register enum values directly with
1526 // addition to get the next register, but for VFP registers, the
1527 // sort order is guaranteed because they're all of the form D<n>.
Kevin Enderby62183c42012-10-22 22:31:46 +00001528 O << "{";
1529 printRegName(O, MI->getOperand(OpNum).getReg());
1530 O << ", ";
1531 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1532 O << ", ";
1533 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1534 O << ", ";
1535 printRegName(O, MI->getOperand(OpNum).getReg() + 6);
1536 O << "}";
Jim Grosbached561fc2012-01-24 00:43:17 +00001537}
Sam Parker963da5b2017-09-29 13:11:33 +00001538
1539template<int64_t Angle, int64_t Remainder>
1540void ARMInstPrinter::printComplexRotationOp(const MCInst *MI, unsigned OpNo,
1541 const MCSubtargetInfo &STI,
1542 raw_ostream &O) {
1543 unsigned Val = MI->getOperand(OpNo).getImm();
1544 O << "#" << (Val * Angle) + Remainder;
1545}
1546