ARMInstPrinter.cpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677
  1. //===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
  2. //
  3. // 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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This class prints an ARM MCInst to a .s file.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "ARMInstPrinter.h"
  13. #include "Utils/ARMBaseInfo.h"
  14. #include "MCTargetDesc/ARMAddressingModes.h"
  15. #include "MCTargetDesc/ARMBaseInfo.h"
  16. #include "llvm/MC/MCAsmInfo.h"
  17. #include "llvm/MC/MCExpr.h"
  18. #include "llvm/MC/MCInst.h"
  19. #include "llvm/MC/MCInstrAnalysis.h"
  20. #include "llvm/MC/MCInstrInfo.h"
  21. #include "llvm/MC/MCRegisterInfo.h"
  22. #include "llvm/MC/MCSubtargetInfo.h"
  23. #include "llvm/MC/SubtargetFeature.h"
  24. #include "llvm/Support/Casting.h"
  25. #include "llvm/Support/ErrorHandling.h"
  26. #include "llvm/Support/MathExtras.h"
  27. #include "llvm/Support/raw_ostream.h"
  28. #include <algorithm>
  29. #include <cassert>
  30. #include <cstdint>
  31. using namespace llvm;
  32. #define DEBUG_TYPE "asm-printer"
  33. #define PRINT_ALIAS_INSTR
  34. #include "ARMGenAsmWriter.inc"
  35. /// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
  36. ///
  37. /// getSORegOffset returns an integer from 0-31, representing '32' as 0.
  38. static unsigned translateShiftImm(unsigned imm) {
  39. // lsr #32 and asr #32 exist, but should be encoded as a 0.
  40. assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
  41. if (imm == 0)
  42. return 32;
  43. return imm;
  44. }
  45. /// Prints the shift value with an immediate value.
  46. static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
  47. unsigned ShImm, bool UseMarkup) {
  48. if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
  49. return;
  50. O << ", ";
  51. assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
  52. O << getShiftOpcStr(ShOpc);
  53. if (ShOpc != ARM_AM::rrx) {
  54. O << " ";
  55. if (UseMarkup)
  56. O << "<imm:";
  57. O << "#" << translateShiftImm(ShImm);
  58. if (UseMarkup)
  59. O << ">";
  60. }
  61. }
  62. ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
  63. const MCRegisterInfo &MRI)
  64. : MCInstPrinter(MAI, MII, MRI) {}
  65. bool ARMInstPrinter::applyTargetSpecificCLOption(StringRef Opt) {
  66. if (Opt == "reg-names-std") {
  67. DefaultAltIdx = ARM::NoRegAltName;
  68. return true;
  69. }
  70. if (Opt == "reg-names-raw") {
  71. DefaultAltIdx = ARM::RegNamesRaw;
  72. return true;
  73. }
  74. return false;
  75. }
  76. void ARMInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
  77. OS << markup("<reg:") << getRegisterName(Reg, DefaultAltIdx) << markup(">");
  78. }
  79. void ARMInstPrinter::printInst(const MCInst *MI, uint64_t Address,
  80. StringRef Annot, const MCSubtargetInfo &STI,
  81. raw_ostream &O) {
  82. unsigned Opcode = MI->getOpcode();
  83. switch (Opcode) {
  84. // Check for MOVs and print canonical forms, instead.
  85. case ARM::MOVsr: {
  86. // FIXME: Thumb variants?
  87. const MCOperand &Dst = MI->getOperand(0);
  88. const MCOperand &MO1 = MI->getOperand(1);
  89. const MCOperand &MO2 = MI->getOperand(2);
  90. const MCOperand &MO3 = MI->getOperand(3);
  91. O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
  92. printSBitModifierOperand(MI, 6, STI, O);
  93. printPredicateOperand(MI, 4, STI, O);
  94. O << '\t';
  95. printRegName(O, Dst.getReg());
  96. O << ", ";
  97. printRegName(O, MO1.getReg());
  98. O << ", ";
  99. printRegName(O, MO2.getReg());
  100. assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
  101. printAnnotation(O, Annot);
  102. return;
  103. }
  104. case ARM::MOVsi: {
  105. // FIXME: Thumb variants?
  106. const MCOperand &Dst = MI->getOperand(0);
  107. const MCOperand &MO1 = MI->getOperand(1);
  108. const MCOperand &MO2 = MI->getOperand(2);
  109. O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()));
  110. printSBitModifierOperand(MI, 5, STI, O);
  111. printPredicateOperand(MI, 3, STI, O);
  112. O << '\t';
  113. printRegName(O, Dst.getReg());
  114. O << ", ";
  115. printRegName(O, MO1.getReg());
  116. if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) {
  117. printAnnotation(O, Annot);
  118. return;
  119. }
  120. O << ", " << markup("<imm:") << "#"
  121. << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())) << markup(">");
  122. printAnnotation(O, Annot);
  123. return;
  124. }
  125. // A8.6.123 PUSH
  126. case ARM::STMDB_UPD:
  127. case ARM::t2STMDB_UPD:
  128. if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
  129. // Should only print PUSH if there are at least two registers in the list.
  130. O << '\t' << "push";
  131. printPredicateOperand(MI, 2, STI, O);
  132. if (Opcode == ARM::t2STMDB_UPD)
  133. O << ".w";
  134. O << '\t';
  135. printRegisterList(MI, 4, STI, O);
  136. printAnnotation(O, Annot);
  137. return;
  138. } else
  139. break;
  140. case ARM::STR_PRE_IMM:
  141. if (MI->getOperand(2).getReg() == ARM::SP &&
  142. MI->getOperand(3).getImm() == -4) {
  143. O << '\t' << "push";
  144. printPredicateOperand(MI, 4, STI, O);
  145. O << "\t{";
  146. printRegName(O, MI->getOperand(1).getReg());
  147. O << "}";
  148. printAnnotation(O, Annot);
  149. return;
  150. } else
  151. break;
  152. // A8.6.122 POP
  153. case ARM::LDMIA_UPD:
  154. case ARM::t2LDMIA_UPD:
  155. if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
  156. // Should only print POP if there are at least two registers in the list.
  157. O << '\t' << "pop";
  158. printPredicateOperand(MI, 2, STI, O);
  159. if (Opcode == ARM::t2LDMIA_UPD)
  160. O << ".w";
  161. O << '\t';
  162. printRegisterList(MI, 4, STI, O);
  163. printAnnotation(O, Annot);
  164. return;
  165. } else
  166. break;
  167. case ARM::LDR_POST_IMM:
  168. if (MI->getOperand(2).getReg() == ARM::SP &&
  169. MI->getOperand(4).getImm() == 4) {
  170. O << '\t' << "pop";
  171. printPredicateOperand(MI, 5, STI, O);
  172. O << "\t{";
  173. printRegName(O, MI->getOperand(0).getReg());
  174. O << "}";
  175. printAnnotation(O, Annot);
  176. return;
  177. } else
  178. break;
  179. // A8.6.355 VPUSH
  180. case ARM::VSTMSDB_UPD:
  181. case ARM::VSTMDDB_UPD:
  182. if (MI->getOperand(0).getReg() == ARM::SP) {
  183. O << '\t' << "vpush";
  184. printPredicateOperand(MI, 2, STI, O);
  185. O << '\t';
  186. printRegisterList(MI, 4, STI, O);
  187. printAnnotation(O, Annot);
  188. return;
  189. } else
  190. break;
  191. // A8.6.354 VPOP
  192. case ARM::VLDMSIA_UPD:
  193. case ARM::VLDMDIA_UPD:
  194. if (MI->getOperand(0).getReg() == ARM::SP) {
  195. O << '\t' << "vpop";
  196. printPredicateOperand(MI, 2, STI, O);
  197. O << '\t';
  198. printRegisterList(MI, 4, STI, O);
  199. printAnnotation(O, Annot);
  200. return;
  201. } else
  202. break;
  203. case ARM::tLDMIA: {
  204. bool Writeback = true;
  205. unsigned BaseReg = MI->getOperand(0).getReg();
  206. for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
  207. if (MI->getOperand(i).getReg() == BaseReg)
  208. Writeback = false;
  209. }
  210. O << "\tldm";
  211. printPredicateOperand(MI, 1, STI, O);
  212. O << '\t';
  213. printRegName(O, BaseReg);
  214. if (Writeback)
  215. O << "!";
  216. O << ", ";
  217. printRegisterList(MI, 3, STI, O);
  218. printAnnotation(O, Annot);
  219. return;
  220. }
  221. // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
  222. // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
  223. // a single GPRPair reg operand is used in the .td file to replace the two
  224. // GPRs. However, when decoding them, the two GRPs cannot be automatically
  225. // expressed as a GPRPair, so we have to manually merge them.
  226. // FIXME: We would really like to be able to tablegen'erate this.
  227. case ARM::LDREXD:
  228. case ARM::STREXD:
  229. case ARM::LDAEXD:
  230. case ARM::STLEXD: {
  231. const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID);
  232. bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
  233. unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
  234. if (MRC.contains(Reg)) {
  235. MCInst NewMI;
  236. MCOperand NewReg;
  237. NewMI.setOpcode(Opcode);
  238. if (isStore)
  239. NewMI.addOperand(MI->getOperand(0));
  240. NewReg = MCOperand::createReg(MRI.getMatchingSuperReg(
  241. Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID)));
  242. NewMI.addOperand(NewReg);
  243. // Copy the rest operands into NewMI.
  244. for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i)
  245. NewMI.addOperand(MI->getOperand(i));
  246. printInstruction(&NewMI, Address, STI, O);
  247. return;
  248. }
  249. break;
  250. }
  251. case ARM::TSB:
  252. case ARM::t2TSB:
  253. O << "\ttsb\tcsync";
  254. return;
  255. case ARM::t2DSB:
  256. switch (MI->getOperand(0).getImm()) {
  257. default:
  258. if (!printAliasInstr(MI, Address, STI, O))
  259. printInstruction(MI, Address, STI, O);
  260. break;
  261. case 0:
  262. O << "\tssbb";
  263. break;
  264. case 4:
  265. O << "\tpssbb";
  266. break;
  267. }
  268. printAnnotation(O, Annot);
  269. return;
  270. }
  271. if (!printAliasInstr(MI, Address, STI, O))
  272. printInstruction(MI, Address, STI, O);
  273. printAnnotation(O, Annot);
  274. }
  275. void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
  276. const MCSubtargetInfo &STI, raw_ostream &O) {
  277. const MCOperand &Op = MI->getOperand(OpNo);
  278. if (Op.isReg()) {
  279. unsigned Reg = Op.getReg();
  280. printRegName(O, Reg);
  281. } else if (Op.isImm()) {
  282. O << markup("<imm:") << '#' << formatImm(Op.getImm()) << markup(">");
  283. } else {
  284. assert(Op.isExpr() && "unknown operand kind in printOperand");
  285. const MCExpr *Expr = Op.getExpr();
  286. switch (Expr->getKind()) {
  287. case MCExpr::Binary:
  288. O << '#';
  289. Expr->print(O, &MAI);
  290. break;
  291. case MCExpr::Constant: {
  292. // If a symbolic branch target was added as a constant expression then
  293. // print that address in hex. And only print 32 unsigned bits for the
  294. // address.
  295. const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
  296. int64_t TargetAddress;
  297. if (!Constant->evaluateAsAbsolute(TargetAddress)) {
  298. O << '#';
  299. Expr->print(O, &MAI);
  300. } else {
  301. O << "0x";
  302. O.write_hex(static_cast<uint32_t>(TargetAddress));
  303. }
  304. break;
  305. }
  306. default:
  307. // FIXME: Should we always treat this as if it is a constant literal and
  308. // prefix it with '#'?
  309. Expr->print(O, &MAI);
  310. break;
  311. }
  312. }
  313. }
  314. void ARMInstPrinter::printOperand(const MCInst *MI, uint64_t Address,
  315. unsigned OpNum, const MCSubtargetInfo &STI,
  316. raw_ostream &O) {
  317. const MCOperand &Op = MI->getOperand(OpNum);
  318. if (!Op.isImm() || !PrintBranchImmAsAddress || getUseMarkup())
  319. return printOperand(MI, OpNum, STI, O);
  320. uint64_t Target = ARM_MC::evaluateBranchTarget(MII.get(MI->getOpcode()),
  321. Address, Op.getImm());
  322. Target &= 0xffffffff;
  323. O << formatHex(Target);
  324. if (CommentStream)
  325. *CommentStream << "imm = #" << formatImm(Op.getImm()) << '\n';
  326. }
  327. void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum,
  328. const MCSubtargetInfo &STI,
  329. raw_ostream &O) {
  330. const MCOperand &MO1 = MI->getOperand(OpNum);
  331. if (MO1.isExpr()) {
  332. MO1.getExpr()->print(O, &MAI);
  333. return;
  334. }
  335. O << markup("<mem:") << "[pc, ";
  336. int32_t OffImm = (int32_t)MO1.getImm();
  337. bool isSub = OffImm < 0;
  338. // Special value for #-0. All others are normal.
  339. if (OffImm == INT32_MIN)
  340. OffImm = 0;
  341. if (isSub) {
  342. O << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
  343. } else {
  344. O << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
  345. }
  346. O << "]" << markup(">");
  347. }
  348. // so_reg is a 4-operand unit corresponding to register forms of the A5.1
  349. // "Addressing Mode 1 - Data-processing operands" forms. This includes:
  350. // REG 0 0 - e.g. R5
  351. // REG REG 0,SH_OPC - e.g. R5, ROR R3
  352. // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
  353. void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum,
  354. const MCSubtargetInfo &STI,
  355. raw_ostream &O) {
  356. const MCOperand &MO1 = MI->getOperand(OpNum);
  357. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  358. const MCOperand &MO3 = MI->getOperand(OpNum + 2);
  359. printRegName(O, MO1.getReg());
  360. // Print the shift opc.
  361. ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
  362. O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
  363. if (ShOpc == ARM_AM::rrx)
  364. return;
  365. O << ' ';
  366. printRegName(O, MO2.getReg());
  367. assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
  368. }
  369. void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
  370. const MCSubtargetInfo &STI,
  371. raw_ostream &O) {
  372. const MCOperand &MO1 = MI->getOperand(OpNum);
  373. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  374. printRegName(O, MO1.getReg());
  375. // Print the shift opc.
  376. printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
  377. ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
  378. }
  379. //===--------------------------------------------------------------------===//
  380. // Addressing Mode #2
  381. //===--------------------------------------------------------------------===//
  382. void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
  383. const MCSubtargetInfo &STI,
  384. raw_ostream &O) {
  385. const MCOperand &MO1 = MI->getOperand(Op);
  386. const MCOperand &MO2 = MI->getOperand(Op + 1);
  387. const MCOperand &MO3 = MI->getOperand(Op + 2);
  388. O << markup("<mem:") << "[";
  389. printRegName(O, MO1.getReg());
  390. if (!MO2.getReg()) {
  391. if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0.
  392. O << ", " << markup("<imm:") << "#"
  393. << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
  394. << ARM_AM::getAM2Offset(MO3.getImm()) << markup(">");
  395. }
  396. O << "]" << markup(">");
  397. return;
  398. }
  399. O << ", ";
  400. O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()));
  401. printRegName(O, MO2.getReg());
  402. printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()),
  403. ARM_AM::getAM2Offset(MO3.getImm()), UseMarkup);
  404. O << "]" << markup(">");
  405. }
  406. void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op,
  407. const MCSubtargetInfo &STI,
  408. raw_ostream &O) {
  409. const MCOperand &MO1 = MI->getOperand(Op);
  410. const MCOperand &MO2 = MI->getOperand(Op + 1);
  411. O << markup("<mem:") << "[";
  412. printRegName(O, MO1.getReg());
  413. O << ", ";
  414. printRegName(O, MO2.getReg());
  415. O << "]" << markup(">");
  416. }
  417. void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op,
  418. const MCSubtargetInfo &STI,
  419. raw_ostream &O) {
  420. const MCOperand &MO1 = MI->getOperand(Op);
  421. const MCOperand &MO2 = MI->getOperand(Op + 1);
  422. O << markup("<mem:") << "[";
  423. printRegName(O, MO1.getReg());
  424. O << ", ";
  425. printRegName(O, MO2.getReg());
  426. O << ", lsl " << markup("<imm:") << "#1" << markup(">") << "]" << markup(">");
  427. }
  428. void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
  429. const MCSubtargetInfo &STI,
  430. raw_ostream &O) {
  431. const MCOperand &MO1 = MI->getOperand(Op);
  432. if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
  433. printOperand(MI, Op, STI, O);
  434. return;
  435. }
  436. #ifndef NDEBUG
  437. const MCOperand &MO3 = MI->getOperand(Op + 2);
  438. unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
  439. assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op");
  440. #endif
  441. printAM2PreOrOffsetIndexOp(MI, Op, STI, O);
  442. }
  443. void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
  444. unsigned OpNum,
  445. const MCSubtargetInfo &STI,
  446. raw_ostream &O) {
  447. const MCOperand &MO1 = MI->getOperand(OpNum);
  448. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  449. if (!MO1.getReg()) {
  450. unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
  451. O << markup("<imm:") << '#'
  452. << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) << ImmOffs
  453. << markup(">");
  454. return;
  455. }
  456. O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()));
  457. printRegName(O, MO1.getReg());
  458. printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()),
  459. ARM_AM::getAM2Offset(MO2.getImm()), UseMarkup);
  460. }
  461. //===--------------------------------------------------------------------===//
  462. // Addressing Mode #3
  463. //===--------------------------------------------------------------------===//
  464. void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
  465. raw_ostream &O,
  466. bool AlwaysPrintImm0) {
  467. const MCOperand &MO1 = MI->getOperand(Op);
  468. const MCOperand &MO2 = MI->getOperand(Op + 1);
  469. const MCOperand &MO3 = MI->getOperand(Op + 2);
  470. O << markup("<mem:") << '[';
  471. printRegName(O, MO1.getReg());
  472. if (MO2.getReg()) {
  473. O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()));
  474. printRegName(O, MO2.getReg());
  475. O << ']' << markup(">");
  476. return;
  477. }
  478. // If the op is sub we have to print the immediate even if it is 0
  479. unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
  480. ARM_AM::AddrOpc op = ARM_AM::getAM3Op(MO3.getImm());
  481. if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) {
  482. O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs
  483. << markup(">");
  484. }
  485. O << ']' << markup(">");
  486. }
  487. template <bool AlwaysPrintImm0>
  488. void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op,
  489. const MCSubtargetInfo &STI,
  490. raw_ostream &O) {
  491. const MCOperand &MO1 = MI->getOperand(Op);
  492. if (!MO1.isReg()) { // For label symbolic references.
  493. printOperand(MI, Op, STI, O);
  494. return;
  495. }
  496. assert(ARM_AM::getAM3IdxMode(MI->getOperand(Op + 2).getImm()) !=
  497. ARMII::IndexModePost &&
  498. "unexpected idxmode");
  499. printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
  500. }
  501. void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
  502. unsigned OpNum,
  503. const MCSubtargetInfo &STI,
  504. raw_ostream &O) {
  505. const MCOperand &MO1 = MI->getOperand(OpNum);
  506. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  507. if (MO1.getReg()) {
  508. O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()));
  509. printRegName(O, MO1.getReg());
  510. return;
  511. }
  512. unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
  513. O << markup("<imm:") << '#'
  514. << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs
  515. << markup(">");
  516. }
  517. void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum,
  518. const MCSubtargetInfo &STI,
  519. raw_ostream &O) {
  520. const MCOperand &MO = MI->getOperand(OpNum);
  521. unsigned Imm = MO.getImm();
  522. O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff)
  523. << markup(">");
  524. }
  525. void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum,
  526. const MCSubtargetInfo &STI,
  527. raw_ostream &O) {
  528. const MCOperand &MO1 = MI->getOperand(OpNum);
  529. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  530. O << (MO2.getImm() ? "" : "-");
  531. printRegName(O, MO1.getReg());
  532. }
  533. void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum,
  534. const MCSubtargetInfo &STI,
  535. raw_ostream &O) {
  536. const MCOperand &MO = MI->getOperand(OpNum);
  537. unsigned Imm = MO.getImm();
  538. O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2)
  539. << markup(">");
  540. }
  541. template<int shift>
  542. void ARMInstPrinter::printMveAddrModeRQOperand(const MCInst *MI, unsigned OpNum,
  543. const MCSubtargetInfo &STI,
  544. raw_ostream &O) {
  545. const MCOperand &MO1 = MI->getOperand(OpNum);
  546. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  547. O << markup("<mem:") << "[";
  548. printRegName(O, MO1.getReg());
  549. O << ", ";
  550. printRegName(O, MO2.getReg());
  551. if (shift > 0)
  552. printRegImmShift(O, ARM_AM::uxtw, shift, UseMarkup);
  553. O << "]" << markup(">");
  554. }
  555. void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
  556. const MCSubtargetInfo &STI,
  557. raw_ostream &O) {
  558. ARM_AM::AMSubMode Mode =
  559. ARM_AM::getAM4SubMode(MI->getOperand(OpNum).getImm());
  560. O << ARM_AM::getAMSubModeStr(Mode);
  561. }
  562. template <bool AlwaysPrintImm0>
  563. void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
  564. const MCSubtargetInfo &STI,
  565. raw_ostream &O) {
  566. const MCOperand &MO1 = MI->getOperand(OpNum);
  567. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  568. if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
  569. printOperand(MI, OpNum, STI, O);
  570. return;
  571. }
  572. O << markup("<mem:") << "[";
  573. printRegName(O, MO1.getReg());
  574. unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
  575. ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm());
  576. if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
  577. O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(Op)
  578. << ImmOffs * 4 << markup(">");
  579. }
  580. O << "]" << markup(">");
  581. }
  582. template <bool AlwaysPrintImm0>
  583. void ARMInstPrinter::printAddrMode5FP16Operand(const MCInst *MI, unsigned OpNum,
  584. const MCSubtargetInfo &STI,
  585. raw_ostream &O) {
  586. const MCOperand &MO1 = MI->getOperand(OpNum);
  587. const MCOperand &MO2 = MI->getOperand(OpNum+1);
  588. if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
  589. printOperand(MI, OpNum, STI, O);
  590. return;
  591. }
  592. O << markup("<mem:") << "[";
  593. printRegName(O, MO1.getReg());
  594. unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
  595. unsigned Op = ARM_AM::getAM5FP16Op(MO2.getImm());
  596. if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
  597. O << ", "
  598. << markup("<imm:")
  599. << "#"
  600. << ARM_AM::getAddrOpcStr(ARM_AM::getAM5FP16Op(MO2.getImm()))
  601. << ImmOffs * 2
  602. << markup(">");
  603. }
  604. O << "]" << markup(">");
  605. }
  606. void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
  607. const MCSubtargetInfo &STI,
  608. raw_ostream &O) {
  609. const MCOperand &MO1 = MI->getOperand(OpNum);
  610. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  611. O << markup("<mem:") << "[";
  612. printRegName(O, MO1.getReg());
  613. if (MO2.getImm()) {
  614. O << ":" << (MO2.getImm() << 3);
  615. }
  616. O << "]" << markup(">");
  617. }
  618. void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
  619. const MCSubtargetInfo &STI,
  620. raw_ostream &O) {
  621. const MCOperand &MO1 = MI->getOperand(OpNum);
  622. O << markup("<mem:") << "[";
  623. printRegName(O, MO1.getReg());
  624. O << "]" << markup(">");
  625. }
  626. void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
  627. unsigned OpNum,
  628. const MCSubtargetInfo &STI,
  629. raw_ostream &O) {
  630. const MCOperand &MO = MI->getOperand(OpNum);
  631. if (MO.getReg() == 0)
  632. O << "!";
  633. else {
  634. O << ", ";
  635. printRegName(O, MO.getReg());
  636. }
  637. }
  638. void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
  639. unsigned OpNum,
  640. const MCSubtargetInfo &STI,
  641. raw_ostream &O) {
  642. const MCOperand &MO = MI->getOperand(OpNum);
  643. uint32_t v = ~MO.getImm();
  644. int32_t lsb = countTrailingZeros(v);
  645. int32_t width = llvm::bit_width(v) - lsb;
  646. assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
  647. O << markup("<imm:") << '#' << lsb << markup(">") << ", " << markup("<imm:")
  648. << '#' << width << markup(">");
  649. }
  650. void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
  651. const MCSubtargetInfo &STI,
  652. raw_ostream &O) {
  653. unsigned val = MI->getOperand(OpNum).getImm();
  654. O << ARM_MB::MemBOptToString(val, STI.getFeatureBits()[ARM::HasV8Ops]);
  655. }
  656. void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
  657. const MCSubtargetInfo &STI,
  658. raw_ostream &O) {
  659. unsigned val = MI->getOperand(OpNum).getImm();
  660. O << ARM_ISB::InstSyncBOptToString(val);
  661. }
  662. void ARMInstPrinter::printTraceSyncBOption(const MCInst *MI, unsigned OpNum,
  663. const MCSubtargetInfo &STI,
  664. raw_ostream &O) {
  665. unsigned val = MI->getOperand(OpNum).getImm();
  666. O << ARM_TSB::TraceSyncBOptToString(val);
  667. }
  668. void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
  669. const MCSubtargetInfo &STI,
  670. raw_ostream &O) {
  671. unsigned ShiftOp = MI->getOperand(OpNum).getImm();
  672. bool isASR = (ShiftOp & (1 << 5)) != 0;
  673. unsigned Amt = ShiftOp & 0x1f;
  674. if (isASR) {
  675. O << ", asr " << markup("<imm:") << "#" << (Amt == 0 ? 32 : Amt)
  676. << markup(">");
  677. } else if (Amt) {
  678. O << ", lsl " << markup("<imm:") << "#" << Amt << markup(">");
  679. }
  680. }
  681. void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
  682. const MCSubtargetInfo &STI,
  683. raw_ostream &O) {
  684. unsigned Imm = MI->getOperand(OpNum).getImm();
  685. if (Imm == 0)
  686. return;
  687. assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
  688. O << ", lsl " << markup("<imm:") << "#" << Imm << markup(">");
  689. }
  690. void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
  691. const MCSubtargetInfo &STI,
  692. raw_ostream &O) {
  693. unsigned Imm = MI->getOperand(OpNum).getImm();
  694. // A shift amount of 32 is encoded as 0.
  695. if (Imm == 0)
  696. Imm = 32;
  697. assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
  698. O << ", asr " << markup("<imm:") << "#" << Imm << markup(">");
  699. }
  700. void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
  701. const MCSubtargetInfo &STI,
  702. raw_ostream &O) {
  703. if (MI->getOpcode() != ARM::t2CLRM) {
  704. assert(is_sorted(drop_begin(*MI, OpNum),
  705. [&](const MCOperand &LHS, const MCOperand &RHS) {
  706. return MRI.getEncodingValue(LHS.getReg()) <
  707. MRI.getEncodingValue(RHS.getReg());
  708. }));
  709. }
  710. O << "{";
  711. for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
  712. if (i != OpNum)
  713. O << ", ";
  714. printRegName(O, MI->getOperand(i).getReg());
  715. }
  716. O << "}";
  717. }
  718. void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum,
  719. const MCSubtargetInfo &STI,
  720. raw_ostream &O) {
  721. unsigned Reg = MI->getOperand(OpNum).getReg();
  722. printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
  723. O << ", ";
  724. printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
  725. }
  726. void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
  727. const MCSubtargetInfo &STI,
  728. raw_ostream &O) {
  729. const MCOperand &Op = MI->getOperand(OpNum);
  730. if (Op.getImm())
  731. O << "be";
  732. else
  733. O << "le";
  734. }
  735. void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
  736. const MCSubtargetInfo &STI, raw_ostream &O) {
  737. const MCOperand &Op = MI->getOperand(OpNum);
  738. O << ARM_PROC::IModToString(Op.getImm());
  739. }
  740. void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
  741. const MCSubtargetInfo &STI, raw_ostream &O) {
  742. const MCOperand &Op = MI->getOperand(OpNum);
  743. unsigned IFlags = Op.getImm();
  744. for (int i = 2; i >= 0; --i)
  745. if (IFlags & (1 << i))
  746. O << ARM_PROC::IFlagsToString(1 << i);
  747. if (IFlags == 0)
  748. O << "none";
  749. }
  750. void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
  751. const MCSubtargetInfo &STI,
  752. raw_ostream &O) {
  753. const MCOperand &Op = MI->getOperand(OpNum);
  754. const FeatureBitset &FeatureBits = STI.getFeatureBits();
  755. if (FeatureBits[ARM::FeatureMClass]) {
  756. unsigned SYSm = Op.getImm() & 0xFFF; // 12-bit SYSm
  757. unsigned Opcode = MI->getOpcode();
  758. // For writes, handle extended mask bits if the DSP extension is present.
  759. if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) {
  760. auto TheReg =ARMSysReg::lookupMClassSysRegBy12bitSYSmValue(SYSm);
  761. if (TheReg && TheReg->isInRequiredFeatures({ARM::FeatureDSP})) {
  762. O << TheReg->Name;
  763. return;
  764. }
  765. }
  766. // Handle the basic 8-bit mask.
  767. SYSm &= 0xff;
  768. if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
  769. // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
  770. // alias for MSR APSR_nzcvq.
  771. auto TheReg = ARMSysReg::lookupMClassSysRegAPSRNonDeprecated(SYSm);
  772. if (TheReg) {
  773. O << TheReg->Name;
  774. return;
  775. }
  776. }
  777. auto TheReg = ARMSysReg::lookupMClassSysRegBy8bitSYSmValue(SYSm);
  778. if (TheReg) {
  779. O << TheReg->Name;
  780. return;
  781. }
  782. O << SYSm;
  783. return;
  784. }
  785. // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
  786. // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
  787. unsigned SpecRegRBit = Op.getImm() >> 4;
  788. unsigned Mask = Op.getImm() & 0xf;
  789. if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
  790. O << "APSR_";
  791. switch (Mask) {
  792. default:
  793. llvm_unreachable("Unexpected mask value!");
  794. case 4:
  795. O << "g";
  796. return;
  797. case 8:
  798. O << "nzcvq";
  799. return;
  800. case 12:
  801. O << "nzcvqg";
  802. return;
  803. }
  804. }
  805. if (SpecRegRBit)
  806. O << "SPSR";
  807. else
  808. O << "CPSR";
  809. if (Mask) {
  810. O << '_';
  811. if (Mask & 8)
  812. O << 'f';
  813. if (Mask & 4)
  814. O << 's';
  815. if (Mask & 2)
  816. O << 'x';
  817. if (Mask & 1)
  818. O << 'c';
  819. }
  820. }
  821. void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum,
  822. const MCSubtargetInfo &STI,
  823. raw_ostream &O) {
  824. uint32_t Banked = MI->getOperand(OpNum).getImm();
  825. auto TheReg = ARMBankedReg::lookupBankedRegByEncoding(Banked);
  826. assert(TheReg && "invalid banked register operand");
  827. std::string Name = TheReg->Name;
  828. uint32_t isSPSR = (Banked & 0x20) >> 5;
  829. if (isSPSR)
  830. Name.replace(0, 4, "SPSR"); // convert 'spsr_' to 'SPSR_'
  831. O << Name;
  832. }
  833. void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
  834. const MCSubtargetInfo &STI,
  835. raw_ostream &O) {
  836. ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
  837. // Handle the undefined 15 CC value here for printing so we don't abort().
  838. if ((unsigned)CC == 15)
  839. O << "<und>";
  840. else if (CC != ARMCC::AL)
  841. O << ARMCondCodeToString(CC);
  842. }
  843. void ARMInstPrinter::printMandatoryRestrictedPredicateOperand(
  844. const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
  845. raw_ostream &O) {
  846. if ((ARMCC::CondCodes)MI->getOperand(OpNum).getImm() == ARMCC::HS)
  847. O << "cs";
  848. else
  849. printMandatoryPredicateOperand(MI, OpNum, STI, O);
  850. }
  851. void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
  852. unsigned OpNum,
  853. const MCSubtargetInfo &STI,
  854. raw_ostream &O) {
  855. ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
  856. O << ARMCondCodeToString(CC);
  857. }
  858. void ARMInstPrinter::printMandatoryInvertedPredicateOperand(const MCInst *MI,
  859. unsigned OpNum,
  860. const MCSubtargetInfo &STI,
  861. raw_ostream &O) {
  862. ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
  863. O << ARMCondCodeToString(ARMCC::getOppositeCondition(CC));
  864. }
  865. void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
  866. const MCSubtargetInfo &STI,
  867. raw_ostream &O) {
  868. if (MI->getOperand(OpNum).getReg()) {
  869. assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
  870. "Expect ARM CPSR register!");
  871. O << 's';
  872. }
  873. }
  874. void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
  875. const MCSubtargetInfo &STI,
  876. raw_ostream &O) {
  877. O << MI->getOperand(OpNum).getImm();
  878. }
  879. void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
  880. const MCSubtargetInfo &STI,
  881. raw_ostream &O) {
  882. O << "p" << MI->getOperand(OpNum).getImm();
  883. }
  884. void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
  885. const MCSubtargetInfo &STI,
  886. raw_ostream &O) {
  887. O << "c" << MI->getOperand(OpNum).getImm();
  888. }
  889. void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum,
  890. const MCSubtargetInfo &STI,
  891. raw_ostream &O) {
  892. O << "{" << MI->getOperand(OpNum).getImm() << "}";
  893. }
  894. void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
  895. const MCSubtargetInfo &STI, raw_ostream &O) {
  896. llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
  897. }
  898. template <unsigned scale>
  899. void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
  900. const MCSubtargetInfo &STI,
  901. raw_ostream &O) {
  902. const MCOperand &MO = MI->getOperand(OpNum);
  903. if (MO.isExpr()) {
  904. MO.getExpr()->print(O, &MAI);
  905. return;
  906. }
  907. int32_t OffImm = (int32_t)MO.getImm() << scale;
  908. O << markup("<imm:");
  909. if (OffImm == INT32_MIN)
  910. O << "#-0";
  911. else if (OffImm < 0)
  912. O << "#-" << -OffImm;
  913. else
  914. O << "#" << OffImm;
  915. O << markup(">");
  916. }
  917. void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
  918. const MCSubtargetInfo &STI,
  919. raw_ostream &O) {
  920. O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4)
  921. << markup(">");
  922. }
  923. void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
  924. const MCSubtargetInfo &STI,
  925. raw_ostream &O) {
  926. unsigned Imm = MI->getOperand(OpNum).getImm();
  927. O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm))
  928. << markup(">");
  929. }
  930. void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
  931. const MCSubtargetInfo &STI,
  932. raw_ostream &O) {
  933. // (3 - the number of trailing zeros) is the number of then / else.
  934. unsigned Mask = MI->getOperand(OpNum).getImm();
  935. unsigned NumTZ = countTrailingZeros(Mask);
  936. assert(NumTZ <= 3 && "Invalid IT mask!");
  937. for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
  938. if ((Mask >> Pos) & 1)
  939. O << 'e';
  940. else
  941. O << 't';
  942. }
  943. }
  944. void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
  945. const MCSubtargetInfo &STI,
  946. raw_ostream &O) {
  947. const MCOperand &MO1 = MI->getOperand(Op);
  948. const MCOperand &MO2 = MI->getOperand(Op + 1);
  949. if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
  950. printOperand(MI, Op, STI, O);
  951. return;
  952. }
  953. O << markup("<mem:") << "[";
  954. printRegName(O, MO1.getReg());
  955. if (unsigned RegNum = MO2.getReg()) {
  956. O << ", ";
  957. printRegName(O, RegNum);
  958. }
  959. O << "]" << markup(">");
  960. }
  961. void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI,
  962. unsigned Op,
  963. const MCSubtargetInfo &STI,
  964. raw_ostream &O,
  965. unsigned Scale) {
  966. const MCOperand &MO1 = MI->getOperand(Op);
  967. const MCOperand &MO2 = MI->getOperand(Op + 1);
  968. if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
  969. printOperand(MI, Op, STI, O);
  970. return;
  971. }
  972. O << markup("<mem:") << "[";
  973. printRegName(O, MO1.getReg());
  974. if (unsigned ImmOffs = MO2.getImm()) {
  975. O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale)
  976. << markup(">");
  977. }
  978. O << "]" << markup(">");
  979. }
  980. void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI,
  981. unsigned Op,
  982. const MCSubtargetInfo &STI,
  983. raw_ostream &O) {
  984. printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1);
  985. }
  986. void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI,
  987. unsigned Op,
  988. const MCSubtargetInfo &STI,
  989. raw_ostream &O) {
  990. printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2);
  991. }
  992. void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI,
  993. unsigned Op,
  994. const MCSubtargetInfo &STI,
  995. raw_ostream &O) {
  996. printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
  997. }
  998. void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
  999. const MCSubtargetInfo &STI,
  1000. raw_ostream &O) {
  1001. printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
  1002. }
  1003. // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
  1004. // register with shift forms.
  1005. // REG 0 0 - e.g. R5
  1006. // REG IMM, SH_OPC - e.g. R5, LSL #3
  1007. void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
  1008. const MCSubtargetInfo &STI,
  1009. raw_ostream &O) {
  1010. const MCOperand &MO1 = MI->getOperand(OpNum);
  1011. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  1012. unsigned Reg = MO1.getReg();
  1013. printRegName(O, Reg);
  1014. // Print the shift opc.
  1015. assert(MO2.isImm() && "Not a valid t2_so_reg value!");
  1016. printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
  1017. ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
  1018. }
  1019. template <bool AlwaysPrintImm0>
  1020. void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
  1021. const MCSubtargetInfo &STI,
  1022. raw_ostream &O) {
  1023. const MCOperand &MO1 = MI->getOperand(OpNum);
  1024. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  1025. if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
  1026. printOperand(MI, OpNum, STI, O);
  1027. return;
  1028. }
  1029. O << markup("<mem:") << "[";
  1030. printRegName(O, MO1.getReg());
  1031. int32_t OffImm = (int32_t)MO2.getImm();
  1032. bool isSub = OffImm < 0;
  1033. // Special value for #-0. All others are normal.
  1034. if (OffImm == INT32_MIN)
  1035. OffImm = 0;
  1036. if (isSub) {
  1037. O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
  1038. } else if (AlwaysPrintImm0 || OffImm > 0) {
  1039. O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
  1040. }
  1041. O << "]" << markup(">");
  1042. }
  1043. template <bool AlwaysPrintImm0>
  1044. void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
  1045. unsigned OpNum,
  1046. const MCSubtargetInfo &STI,
  1047. raw_ostream &O) {
  1048. const MCOperand &MO1 = MI->getOperand(OpNum);
  1049. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  1050. O << markup("<mem:") << "[";
  1051. printRegName(O, MO1.getReg());
  1052. int32_t OffImm = (int32_t)MO2.getImm();
  1053. bool isSub = OffImm < 0;
  1054. // Don't print +0.
  1055. if (OffImm == INT32_MIN)
  1056. OffImm = 0;
  1057. if (isSub) {
  1058. O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
  1059. } else if (AlwaysPrintImm0 || OffImm > 0) {
  1060. O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
  1061. }
  1062. O << "]" << markup(">");
  1063. }
  1064. template <bool AlwaysPrintImm0>
  1065. void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
  1066. unsigned OpNum,
  1067. const MCSubtargetInfo &STI,
  1068. raw_ostream &O) {
  1069. const MCOperand &MO1 = MI->getOperand(OpNum);
  1070. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  1071. if (!MO1.isReg()) { // For label symbolic references.
  1072. printOperand(MI, OpNum, STI, O);
  1073. return;
  1074. }
  1075. O << markup("<mem:") << "[";
  1076. printRegName(O, MO1.getReg());
  1077. int32_t OffImm = (int32_t)MO2.getImm();
  1078. bool isSub = OffImm < 0;
  1079. assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
  1080. // Don't print +0.
  1081. if (OffImm == INT32_MIN)
  1082. OffImm = 0;
  1083. if (isSub) {
  1084. O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
  1085. } else if (AlwaysPrintImm0 || OffImm > 0) {
  1086. O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
  1087. }
  1088. O << "]" << markup(">");
  1089. }
  1090. void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(
  1091. const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
  1092. raw_ostream &O) {
  1093. const MCOperand &MO1 = MI->getOperand(OpNum);
  1094. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  1095. O << markup("<mem:") << "[";
  1096. printRegName(O, MO1.getReg());
  1097. if (MO2.getImm()) {
  1098. O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4)
  1099. << markup(">");
  1100. }
  1101. O << "]" << markup(">");
  1102. }
  1103. void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(
  1104. const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
  1105. raw_ostream &O) {
  1106. const MCOperand &MO1 = MI->getOperand(OpNum);
  1107. int32_t OffImm = (int32_t)MO1.getImm();
  1108. O << ", " << markup("<imm:");
  1109. if (OffImm == INT32_MIN)
  1110. O << "#-0";
  1111. else if (OffImm < 0)
  1112. O << "#-" << -OffImm;
  1113. else
  1114. O << "#" << OffImm;
  1115. O << markup(">");
  1116. }
  1117. void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(
  1118. const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
  1119. raw_ostream &O) {
  1120. const MCOperand &MO1 = MI->getOperand(OpNum);
  1121. int32_t OffImm = (int32_t)MO1.getImm();
  1122. assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
  1123. O << ", " << markup("<imm:");
  1124. if (OffImm == INT32_MIN)
  1125. O << "#-0";
  1126. else if (OffImm < 0)
  1127. O << "#-" << -OffImm;
  1128. else
  1129. O << "#" << OffImm;
  1130. O << markup(">");
  1131. }
  1132. void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
  1133. unsigned OpNum,
  1134. const MCSubtargetInfo &STI,
  1135. raw_ostream &O) {
  1136. const MCOperand &MO1 = MI->getOperand(OpNum);
  1137. const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  1138. const MCOperand &MO3 = MI->getOperand(OpNum + 2);
  1139. O << markup("<mem:") << "[";
  1140. printRegName(O, MO1.getReg());
  1141. assert(MO2.getReg() && "Invalid so_reg load / store address!");
  1142. O << ", ";
  1143. printRegName(O, MO2.getReg());
  1144. unsigned ShAmt = MO3.getImm();
  1145. if (ShAmt) {
  1146. assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
  1147. O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">");
  1148. }
  1149. O << "]" << markup(">");
  1150. }
  1151. void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
  1152. const MCSubtargetInfo &STI,
  1153. raw_ostream &O) {
  1154. const MCOperand &MO = MI->getOperand(OpNum);
  1155. O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm())
  1156. << markup(">");
  1157. }
  1158. void ARMInstPrinter::printVMOVModImmOperand(const MCInst *MI, unsigned OpNum,
  1159. const MCSubtargetInfo &STI,
  1160. raw_ostream &O) {
  1161. unsigned EncodedImm = MI->getOperand(OpNum).getImm();
  1162. unsigned EltBits;
  1163. uint64_t Val = ARM_AM::decodeVMOVModImm(EncodedImm, EltBits);
  1164. O << markup("<imm:") << "#0x";
  1165. O.write_hex(Val);
  1166. O << markup(">");
  1167. }
  1168. void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
  1169. const MCSubtargetInfo &STI,
  1170. raw_ostream &O) {
  1171. unsigned Imm = MI->getOperand(OpNum).getImm();
  1172. O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">");
  1173. }
  1174. void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
  1175. const MCSubtargetInfo &STI,
  1176. raw_ostream &O) {
  1177. unsigned Imm = MI->getOperand(OpNum).getImm();
  1178. if (Imm == 0)
  1179. return;
  1180. assert(Imm <= 3 && "illegal ror immediate!");
  1181. O << ", ror " << markup("<imm:") << "#" << 8 * Imm << markup(">");
  1182. }
  1183. void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum,
  1184. const MCSubtargetInfo &STI,
  1185. raw_ostream &O) {
  1186. MCOperand Op = MI->getOperand(OpNum);
  1187. // Support for fixups (MCFixup)
  1188. if (Op.isExpr())
  1189. return printOperand(MI, OpNum, STI, O);
  1190. unsigned Bits = Op.getImm() & 0xFF;
  1191. unsigned Rot = (Op.getImm() & 0xF00) >> 7;
  1192. bool PrintUnsigned = false;
  1193. switch (MI->getOpcode()) {
  1194. case ARM::MOVi:
  1195. // Movs to PC should be treated unsigned
  1196. PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC);
  1197. break;
  1198. case ARM::MSRi:
  1199. // Movs to special registers should be treated unsigned
  1200. PrintUnsigned = true;
  1201. break;
  1202. }
  1203. int32_t Rotated = ARM_AM::rotr32(Bits, Rot);
  1204. if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) {
  1205. // #rot has the least possible value
  1206. O << "#" << markup("<imm:");
  1207. if (PrintUnsigned)
  1208. O << static_cast<uint32_t>(Rotated);
  1209. else
  1210. O << Rotated;
  1211. O << markup(">");
  1212. return;
  1213. }
  1214. // Explicit #bits, #rot implied
  1215. O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:")
  1216. << Rot << markup(">");
  1217. }
  1218. void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
  1219. const MCSubtargetInfo &STI, raw_ostream &O) {
  1220. O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm()
  1221. << markup(">");
  1222. }
  1223. void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum,
  1224. const MCSubtargetInfo &STI, raw_ostream &O) {
  1225. O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm()
  1226. << markup(">");
  1227. }
  1228. void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
  1229. const MCSubtargetInfo &STI,
  1230. raw_ostream &O) {
  1231. O << "[" << MI->getOperand(OpNum).getImm() << "]";
  1232. }
  1233. void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
  1234. const MCSubtargetInfo &STI,
  1235. raw_ostream &O) {
  1236. O << "{";
  1237. printRegName(O, MI->getOperand(OpNum).getReg());
  1238. O << "}";
  1239. }
  1240. void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
  1241. const MCSubtargetInfo &STI,
  1242. raw_ostream &O) {
  1243. unsigned Reg = MI->getOperand(OpNum).getReg();
  1244. unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
  1245. unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
  1246. O << "{";
  1247. printRegName(O, Reg0);
  1248. O << ", ";
  1249. printRegName(O, Reg1);
  1250. O << "}";
  1251. }
  1252. void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum,
  1253. const MCSubtargetInfo &STI,
  1254. raw_ostream &O) {
  1255. unsigned Reg = MI->getOperand(OpNum).getReg();
  1256. unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
  1257. unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
  1258. O << "{";
  1259. printRegName(O, Reg0);
  1260. O << ", ";
  1261. printRegName(O, Reg1);
  1262. O << "}";
  1263. }
  1264. void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum,
  1265. const MCSubtargetInfo &STI,
  1266. raw_ostream &O) {
  1267. // Normally, it's not safe to use register enum values directly with
  1268. // addition to get the next register, but for VFP registers, the
  1269. // sort order is guaranteed because they're all of the form D<n>.
  1270. O << "{";
  1271. printRegName(O, MI->getOperand(OpNum).getReg());
  1272. O << ", ";
  1273. printRegName(O, MI->getOperand(OpNum).getReg() + 1);
  1274. O << ", ";
  1275. printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  1276. O << "}";
  1277. }
  1278. void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum,
  1279. const MCSubtargetInfo &STI,
  1280. raw_ostream &O) {
  1281. // Normally, it's not safe to use register enum values directly with
  1282. // addition to get the next register, but for VFP registers, the
  1283. // sort order is guaranteed because they're all of the form D<n>.
  1284. O << "{";
  1285. printRegName(O, MI->getOperand(OpNum).getReg());
  1286. O << ", ";
  1287. printRegName(O, MI->getOperand(OpNum).getReg() + 1);
  1288. O << ", ";
  1289. printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  1290. O << ", ";
  1291. printRegName(O, MI->getOperand(OpNum).getReg() + 3);
  1292. O << "}";
  1293. }
  1294. void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI,
  1295. unsigned OpNum,
  1296. const MCSubtargetInfo &STI,
  1297. raw_ostream &O) {
  1298. O << "{";
  1299. printRegName(O, MI->getOperand(OpNum).getReg());
  1300. O << "[]}";
  1301. }
  1302. void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI,
  1303. unsigned OpNum,
  1304. const MCSubtargetInfo &STI,
  1305. raw_ostream &O) {
  1306. unsigned Reg = MI->getOperand(OpNum).getReg();
  1307. unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
  1308. unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
  1309. O << "{";
  1310. printRegName(O, Reg0);
  1311. O << "[], ";
  1312. printRegName(O, Reg1);
  1313. O << "[]}";
  1314. }
  1315. void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI,
  1316. unsigned OpNum,
  1317. const MCSubtargetInfo &STI,
  1318. raw_ostream &O) {
  1319. // Normally, it's not safe to use register enum values directly with
  1320. // addition to get the next register, but for VFP registers, the
  1321. // sort order is guaranteed because they're all of the form D<n>.
  1322. O << "{";
  1323. printRegName(O, MI->getOperand(OpNum).getReg());
  1324. O << "[], ";
  1325. printRegName(O, MI->getOperand(OpNum).getReg() + 1);
  1326. O << "[], ";
  1327. printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  1328. O << "[]}";
  1329. }
  1330. void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
  1331. unsigned OpNum,
  1332. const MCSubtargetInfo &STI,
  1333. raw_ostream &O) {
  1334. // Normally, it's not safe to use register enum values directly with
  1335. // addition to get the next register, but for VFP registers, the
  1336. // sort order is guaranteed because they're all of the form D<n>.
  1337. O << "{";
  1338. printRegName(O, MI->getOperand(OpNum).getReg());
  1339. O << "[], ";
  1340. printRegName(O, MI->getOperand(OpNum).getReg() + 1);
  1341. O << "[], ";
  1342. printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  1343. O << "[], ";
  1344. printRegName(O, MI->getOperand(OpNum).getReg() + 3);
  1345. O << "[]}";
  1346. }
  1347. void ARMInstPrinter::printVectorListTwoSpacedAllLanes(
  1348. const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
  1349. raw_ostream &O) {
  1350. unsigned Reg = MI->getOperand(OpNum).getReg();
  1351. unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
  1352. unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
  1353. O << "{";
  1354. printRegName(O, Reg0);
  1355. O << "[], ";
  1356. printRegName(O, Reg1);
  1357. O << "[]}";
  1358. }
  1359. void ARMInstPrinter::printVectorListThreeSpacedAllLanes(
  1360. const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
  1361. raw_ostream &O) {
  1362. // Normally, it's not safe to use register enum values directly with
  1363. // addition to get the next register, but for VFP registers, the
  1364. // sort order is guaranteed because they're all of the form D<n>.
  1365. O << "{";
  1366. printRegName(O, MI->getOperand(OpNum).getReg());
  1367. O << "[], ";
  1368. printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  1369. O << "[], ";
  1370. printRegName(O, MI->getOperand(OpNum).getReg() + 4);
  1371. O << "[]}";
  1372. }
  1373. void ARMInstPrinter::printVectorListFourSpacedAllLanes(
  1374. const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
  1375. raw_ostream &O) {
  1376. // Normally, it's not safe to use register enum values directly with
  1377. // addition to get the next register, but for VFP registers, the
  1378. // sort order is guaranteed because they're all of the form D<n>.
  1379. O << "{";
  1380. printRegName(O, MI->getOperand(OpNum).getReg());
  1381. O << "[], ";
  1382. printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  1383. O << "[], ";
  1384. printRegName(O, MI->getOperand(OpNum).getReg() + 4);
  1385. O << "[], ";
  1386. printRegName(O, MI->getOperand(OpNum).getReg() + 6);
  1387. O << "[]}";
  1388. }
  1389. void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI,
  1390. unsigned OpNum,
  1391. const MCSubtargetInfo &STI,
  1392. raw_ostream &O) {
  1393. // Normally, it's not safe to use register enum values directly with
  1394. // addition to get the next register, but for VFP registers, the
  1395. // sort order is guaranteed because they're all of the form D<n>.
  1396. O << "{";
  1397. printRegName(O, MI->getOperand(OpNum).getReg());
  1398. O << ", ";
  1399. printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  1400. O << ", ";
  1401. printRegName(O, MI->getOperand(OpNum).getReg() + 4);
  1402. O << "}";
  1403. }
  1404. void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, unsigned OpNum,
  1405. const MCSubtargetInfo &STI,
  1406. raw_ostream &O) {
  1407. // Normally, it's not safe to use register enum values directly with
  1408. // addition to get the next register, but for VFP registers, the
  1409. // sort order is guaranteed because they're all of the form D<n>.
  1410. O << "{";
  1411. printRegName(O, MI->getOperand(OpNum).getReg());
  1412. O << ", ";
  1413. printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  1414. O << ", ";
  1415. printRegName(O, MI->getOperand(OpNum).getReg() + 4);
  1416. O << ", ";
  1417. printRegName(O, MI->getOperand(OpNum).getReg() + 6);
  1418. O << "}";
  1419. }
  1420. template<unsigned NumRegs>
  1421. void ARMInstPrinter::printMVEVectorList(const MCInst *MI, unsigned OpNum,
  1422. const MCSubtargetInfo &STI,
  1423. raw_ostream &O) {
  1424. unsigned Reg = MI->getOperand(OpNum).getReg();
  1425. const char *Prefix = "{";
  1426. for (unsigned i = 0; i < NumRegs; i++) {
  1427. O << Prefix;
  1428. printRegName(O, MRI.getSubReg(Reg, ARM::qsub_0 + i));
  1429. Prefix = ", ";
  1430. }
  1431. O << "}";
  1432. }
  1433. template<int64_t Angle, int64_t Remainder>
  1434. void ARMInstPrinter::printComplexRotationOp(const MCInst *MI, unsigned OpNo,
  1435. const MCSubtargetInfo &STI,
  1436. raw_ostream &O) {
  1437. unsigned Val = MI->getOperand(OpNo).getImm();
  1438. O << "#" << (Val * Angle) + Remainder;
  1439. }
  1440. void ARMInstPrinter::printVPTPredicateOperand(const MCInst *MI, unsigned OpNum,
  1441. const MCSubtargetInfo &STI,
  1442. raw_ostream &O) {
  1443. ARMVCC::VPTCodes CC = (ARMVCC::VPTCodes)MI->getOperand(OpNum).getImm();
  1444. if (CC != ARMVCC::None)
  1445. O << ARMVPTPredToString(CC);
  1446. }
  1447. void ARMInstPrinter::printVPTMask(const MCInst *MI, unsigned OpNum,
  1448. const MCSubtargetInfo &STI,
  1449. raw_ostream &O) {
  1450. // (3 - the number of trailing zeroes) is the number of them / else.
  1451. unsigned Mask = MI->getOperand(OpNum).getImm();
  1452. unsigned NumTZ = countTrailingZeros(Mask);
  1453. assert(NumTZ <= 3 && "Invalid VPT mask!");
  1454. for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
  1455. bool T = ((Mask >> Pos) & 1) == 0;
  1456. if (T)
  1457. O << 't';
  1458. else
  1459. O << 'e';
  1460. }
  1461. }
  1462. void ARMInstPrinter::printMveSaturateOp(const MCInst *MI, unsigned OpNum,
  1463. const MCSubtargetInfo &STI,
  1464. raw_ostream &O) {
  1465. uint32_t Val = MI->getOperand(OpNum).getImm();
  1466. assert(Val <= 1 && "Invalid MVE saturate operand");
  1467. O << "#" << (Val == 1 ? 48 : 64);
  1468. }