15e3ee4b8SRichard Trieu //===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
25e3ee4b8SRichard Trieu //
35e3ee4b8SRichard Trieu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45e3ee4b8SRichard Trieu // See https://llvm.org/LICENSE.txt for license information.
55e3ee4b8SRichard Trieu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65e3ee4b8SRichard Trieu //
75e3ee4b8SRichard Trieu //===----------------------------------------------------------------------===//
85e3ee4b8SRichard Trieu //
95e3ee4b8SRichard Trieu // This class prints an ARM MCInst to a .s file.
105e3ee4b8SRichard Trieu //
115e3ee4b8SRichard Trieu //===----------------------------------------------------------------------===//
125e3ee4b8SRichard Trieu
135e3ee4b8SRichard Trieu #include "ARMInstPrinter.h"
145e3ee4b8SRichard Trieu #include "Utils/ARMBaseInfo.h"
155e3ee4b8SRichard Trieu #include "MCTargetDesc/ARMAddressingModes.h"
165e3ee4b8SRichard Trieu #include "MCTargetDesc/ARMBaseInfo.h"
175e3ee4b8SRichard Trieu #include "llvm/MC/MCAsmInfo.h"
185e3ee4b8SRichard Trieu #include "llvm/MC/MCExpr.h"
195e3ee4b8SRichard Trieu #include "llvm/MC/MCInst.h"
20*657e067bSIgor Kudrin #include "llvm/MC/MCInstrAnalysis.h"
215e3ee4b8SRichard Trieu #include "llvm/MC/MCInstrInfo.h"
225e3ee4b8SRichard Trieu #include "llvm/MC/MCRegisterInfo.h"
235e3ee4b8SRichard Trieu #include "llvm/MC/MCSubtargetInfo.h"
245e3ee4b8SRichard Trieu #include "llvm/MC/SubtargetFeature.h"
255e3ee4b8SRichard Trieu #include "llvm/Support/Casting.h"
265e3ee4b8SRichard Trieu #include "llvm/Support/ErrorHandling.h"
275e3ee4b8SRichard Trieu #include "llvm/Support/MathExtras.h"
285e3ee4b8SRichard Trieu #include "llvm/Support/raw_ostream.h"
295e3ee4b8SRichard Trieu #include <algorithm>
305e3ee4b8SRichard Trieu #include <cassert>
315e3ee4b8SRichard Trieu #include <cstdint>
325e3ee4b8SRichard Trieu
335e3ee4b8SRichard Trieu using namespace llvm;
345e3ee4b8SRichard Trieu
355e3ee4b8SRichard Trieu #define DEBUG_TYPE "asm-printer"
365e3ee4b8SRichard Trieu
375e3ee4b8SRichard Trieu #define PRINT_ALIAS_INSTR
385e3ee4b8SRichard Trieu #include "ARMGenAsmWriter.inc"
395e3ee4b8SRichard Trieu
405e3ee4b8SRichard Trieu /// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
415e3ee4b8SRichard Trieu ///
425e3ee4b8SRichard Trieu /// getSORegOffset returns an integer from 0-31, representing '32' as 0.
translateShiftImm(unsigned imm)435e3ee4b8SRichard Trieu static unsigned translateShiftImm(unsigned imm) {
445e3ee4b8SRichard Trieu // lsr #32 and asr #32 exist, but should be encoded as a 0.
455e3ee4b8SRichard Trieu assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
465e3ee4b8SRichard Trieu
475e3ee4b8SRichard Trieu if (imm == 0)
485e3ee4b8SRichard Trieu return 32;
495e3ee4b8SRichard Trieu return imm;
505e3ee4b8SRichard Trieu }
515e3ee4b8SRichard Trieu
525e3ee4b8SRichard Trieu /// Prints the shift value with an immediate value.
printRegImmShift(raw_ostream & O,ARM_AM::ShiftOpc ShOpc,unsigned ShImm,bool UseMarkup)535e3ee4b8SRichard Trieu static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
545e3ee4b8SRichard Trieu unsigned ShImm, bool UseMarkup) {
555e3ee4b8SRichard Trieu if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
565e3ee4b8SRichard Trieu return;
575e3ee4b8SRichard Trieu O << ", ";
585e3ee4b8SRichard Trieu
595e3ee4b8SRichard Trieu assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
605e3ee4b8SRichard Trieu O << getShiftOpcStr(ShOpc);
615e3ee4b8SRichard Trieu
625e3ee4b8SRichard Trieu if (ShOpc != ARM_AM::rrx) {
635e3ee4b8SRichard Trieu O << " ";
645e3ee4b8SRichard Trieu if (UseMarkup)
655e3ee4b8SRichard Trieu O << "<imm:";
665e3ee4b8SRichard Trieu O << "#" << translateShiftImm(ShImm);
675e3ee4b8SRichard Trieu if (UseMarkup)
685e3ee4b8SRichard Trieu O << ">";
695e3ee4b8SRichard Trieu }
705e3ee4b8SRichard Trieu }
715e3ee4b8SRichard Trieu
ARMInstPrinter(const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)725e3ee4b8SRichard Trieu ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
735e3ee4b8SRichard Trieu const MCRegisterInfo &MRI)
745e3ee4b8SRichard Trieu : MCInstPrinter(MAI, MII, MRI) {}
755e3ee4b8SRichard Trieu
applyTargetSpecificCLOption(StringRef Opt)765e3ee4b8SRichard Trieu bool ARMInstPrinter::applyTargetSpecificCLOption(StringRef Opt) {
775e3ee4b8SRichard Trieu if (Opt == "reg-names-std") {
785e3ee4b8SRichard Trieu DefaultAltIdx = ARM::NoRegAltName;
795e3ee4b8SRichard Trieu return true;
805e3ee4b8SRichard Trieu }
815e3ee4b8SRichard Trieu if (Opt == "reg-names-raw") {
825e3ee4b8SRichard Trieu DefaultAltIdx = ARM::RegNamesRaw;
835e3ee4b8SRichard Trieu return true;
845e3ee4b8SRichard Trieu }
855e3ee4b8SRichard Trieu return false;
865e3ee4b8SRichard Trieu }
875e3ee4b8SRichard Trieu
printRegName(raw_ostream & OS,unsigned RegNo) const885e3ee4b8SRichard Trieu void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
895e3ee4b8SRichard Trieu OS << markup("<reg:") << getRegisterName(RegNo, DefaultAltIdx) << markup(">");
905e3ee4b8SRichard Trieu }
915e3ee4b8SRichard Trieu
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & O)92aa708763SFangrui Song void ARMInstPrinter::printInst(const MCInst *MI, uint64_t Address,
93aa708763SFangrui Song StringRef Annot, const MCSubtargetInfo &STI,
94aa708763SFangrui Song raw_ostream &O) {
955e3ee4b8SRichard Trieu unsigned Opcode = MI->getOpcode();
965e3ee4b8SRichard Trieu
975e3ee4b8SRichard Trieu switch (Opcode) {
985e3ee4b8SRichard Trieu // Check for MOVs and print canonical forms, instead.
995e3ee4b8SRichard Trieu case ARM::MOVsr: {
1005e3ee4b8SRichard Trieu // FIXME: Thumb variants?
1015e3ee4b8SRichard Trieu const MCOperand &Dst = MI->getOperand(0);
1025e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(1);
1035e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(2);
1045e3ee4b8SRichard Trieu const MCOperand &MO3 = MI->getOperand(3);
1055e3ee4b8SRichard Trieu
1065e3ee4b8SRichard Trieu O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
1075e3ee4b8SRichard Trieu printSBitModifierOperand(MI, 6, STI, O);
1085e3ee4b8SRichard Trieu printPredicateOperand(MI, 4, STI, O);
1095e3ee4b8SRichard Trieu
1105e3ee4b8SRichard Trieu O << '\t';
1115e3ee4b8SRichard Trieu printRegName(O, Dst.getReg());
1125e3ee4b8SRichard Trieu O << ", ";
1135e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
1145e3ee4b8SRichard Trieu
1155e3ee4b8SRichard Trieu O << ", ";
1165e3ee4b8SRichard Trieu printRegName(O, MO2.getReg());
1175e3ee4b8SRichard Trieu assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
1185e3ee4b8SRichard Trieu printAnnotation(O, Annot);
1195e3ee4b8SRichard Trieu return;
1205e3ee4b8SRichard Trieu }
1215e3ee4b8SRichard Trieu
1225e3ee4b8SRichard Trieu case ARM::MOVsi: {
1235e3ee4b8SRichard Trieu // FIXME: Thumb variants?
1245e3ee4b8SRichard Trieu const MCOperand &Dst = MI->getOperand(0);
1255e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(1);
1265e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(2);
1275e3ee4b8SRichard Trieu
1285e3ee4b8SRichard Trieu O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()));
1295e3ee4b8SRichard Trieu printSBitModifierOperand(MI, 5, STI, O);
1305e3ee4b8SRichard Trieu printPredicateOperand(MI, 3, STI, O);
1315e3ee4b8SRichard Trieu
1325e3ee4b8SRichard Trieu O << '\t';
1335e3ee4b8SRichard Trieu printRegName(O, Dst.getReg());
1345e3ee4b8SRichard Trieu O << ", ";
1355e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
1365e3ee4b8SRichard Trieu
1375e3ee4b8SRichard Trieu if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) {
1385e3ee4b8SRichard Trieu printAnnotation(O, Annot);
1395e3ee4b8SRichard Trieu return;
1405e3ee4b8SRichard Trieu }
1415e3ee4b8SRichard Trieu
1425e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#"
1435e3ee4b8SRichard Trieu << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())) << markup(">");
1445e3ee4b8SRichard Trieu printAnnotation(O, Annot);
1455e3ee4b8SRichard Trieu return;
1465e3ee4b8SRichard Trieu }
1475e3ee4b8SRichard Trieu
1485e3ee4b8SRichard Trieu // A8.6.123 PUSH
1495e3ee4b8SRichard Trieu case ARM::STMDB_UPD:
1505e3ee4b8SRichard Trieu case ARM::t2STMDB_UPD:
1515e3ee4b8SRichard Trieu if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
1525e3ee4b8SRichard Trieu // Should only print PUSH if there are at least two registers in the list.
1535e3ee4b8SRichard Trieu O << '\t' << "push";
1545e3ee4b8SRichard Trieu printPredicateOperand(MI, 2, STI, O);
1555e3ee4b8SRichard Trieu if (Opcode == ARM::t2STMDB_UPD)
1565e3ee4b8SRichard Trieu O << ".w";
1575e3ee4b8SRichard Trieu O << '\t';
1585e3ee4b8SRichard Trieu printRegisterList(MI, 4, STI, O);
1595e3ee4b8SRichard Trieu printAnnotation(O, Annot);
1605e3ee4b8SRichard Trieu return;
1615e3ee4b8SRichard Trieu } else
1625e3ee4b8SRichard Trieu break;
1635e3ee4b8SRichard Trieu
1645e3ee4b8SRichard Trieu case ARM::STR_PRE_IMM:
1655e3ee4b8SRichard Trieu if (MI->getOperand(2).getReg() == ARM::SP &&
1665e3ee4b8SRichard Trieu MI->getOperand(3).getImm() == -4) {
1675e3ee4b8SRichard Trieu O << '\t' << "push";
1685e3ee4b8SRichard Trieu printPredicateOperand(MI, 4, STI, O);
1695e3ee4b8SRichard Trieu O << "\t{";
1705e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(1).getReg());
1715e3ee4b8SRichard Trieu O << "}";
1725e3ee4b8SRichard Trieu printAnnotation(O, Annot);
1735e3ee4b8SRichard Trieu return;
1745e3ee4b8SRichard Trieu } else
1755e3ee4b8SRichard Trieu break;
1765e3ee4b8SRichard Trieu
1775e3ee4b8SRichard Trieu // A8.6.122 POP
1785e3ee4b8SRichard Trieu case ARM::LDMIA_UPD:
1795e3ee4b8SRichard Trieu case ARM::t2LDMIA_UPD:
1805e3ee4b8SRichard Trieu if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
1815e3ee4b8SRichard Trieu // Should only print POP if there are at least two registers in the list.
1825e3ee4b8SRichard Trieu O << '\t' << "pop";
1835e3ee4b8SRichard Trieu printPredicateOperand(MI, 2, STI, O);
1845e3ee4b8SRichard Trieu if (Opcode == ARM::t2LDMIA_UPD)
1855e3ee4b8SRichard Trieu O << ".w";
1865e3ee4b8SRichard Trieu O << '\t';
1875e3ee4b8SRichard Trieu printRegisterList(MI, 4, STI, O);
1885e3ee4b8SRichard Trieu printAnnotation(O, Annot);
1895e3ee4b8SRichard Trieu return;
1905e3ee4b8SRichard Trieu } else
1915e3ee4b8SRichard Trieu break;
1925e3ee4b8SRichard Trieu
1935e3ee4b8SRichard Trieu case ARM::LDR_POST_IMM:
1945e3ee4b8SRichard Trieu if (MI->getOperand(2).getReg() == ARM::SP &&
1955e3ee4b8SRichard Trieu MI->getOperand(4).getImm() == 4) {
1965e3ee4b8SRichard Trieu O << '\t' << "pop";
1975e3ee4b8SRichard Trieu printPredicateOperand(MI, 5, STI, O);
1985e3ee4b8SRichard Trieu O << "\t{";
1995e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(0).getReg());
2005e3ee4b8SRichard Trieu O << "}";
2015e3ee4b8SRichard Trieu printAnnotation(O, Annot);
2025e3ee4b8SRichard Trieu return;
2035e3ee4b8SRichard Trieu } else
2045e3ee4b8SRichard Trieu break;
2055e3ee4b8SRichard Trieu
2065e3ee4b8SRichard Trieu // A8.6.355 VPUSH
2075e3ee4b8SRichard Trieu case ARM::VSTMSDB_UPD:
2085e3ee4b8SRichard Trieu case ARM::VSTMDDB_UPD:
2095e3ee4b8SRichard Trieu if (MI->getOperand(0).getReg() == ARM::SP) {
2105e3ee4b8SRichard Trieu O << '\t' << "vpush";
2115e3ee4b8SRichard Trieu printPredicateOperand(MI, 2, STI, O);
2125e3ee4b8SRichard Trieu O << '\t';
2135e3ee4b8SRichard Trieu printRegisterList(MI, 4, STI, O);
2145e3ee4b8SRichard Trieu printAnnotation(O, Annot);
2155e3ee4b8SRichard Trieu return;
2165e3ee4b8SRichard Trieu } else
2175e3ee4b8SRichard Trieu break;
2185e3ee4b8SRichard Trieu
2195e3ee4b8SRichard Trieu // A8.6.354 VPOP
2205e3ee4b8SRichard Trieu case ARM::VLDMSIA_UPD:
2215e3ee4b8SRichard Trieu case ARM::VLDMDIA_UPD:
2225e3ee4b8SRichard Trieu if (MI->getOperand(0).getReg() == ARM::SP) {
2235e3ee4b8SRichard Trieu O << '\t' << "vpop";
2245e3ee4b8SRichard Trieu printPredicateOperand(MI, 2, STI, O);
2255e3ee4b8SRichard Trieu O << '\t';
2265e3ee4b8SRichard Trieu printRegisterList(MI, 4, STI, O);
2275e3ee4b8SRichard Trieu printAnnotation(O, Annot);
2285e3ee4b8SRichard Trieu return;
2295e3ee4b8SRichard Trieu } else
2305e3ee4b8SRichard Trieu break;
2315e3ee4b8SRichard Trieu
2325e3ee4b8SRichard Trieu case ARM::tLDMIA: {
2335e3ee4b8SRichard Trieu bool Writeback = true;
2345e3ee4b8SRichard Trieu unsigned BaseReg = MI->getOperand(0).getReg();
2355e3ee4b8SRichard Trieu for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
2365e3ee4b8SRichard Trieu if (MI->getOperand(i).getReg() == BaseReg)
2375e3ee4b8SRichard Trieu Writeback = false;
2385e3ee4b8SRichard Trieu }
2395e3ee4b8SRichard Trieu
2405e3ee4b8SRichard Trieu O << "\tldm";
2415e3ee4b8SRichard Trieu
2425e3ee4b8SRichard Trieu printPredicateOperand(MI, 1, STI, O);
2435e3ee4b8SRichard Trieu O << '\t';
2445e3ee4b8SRichard Trieu printRegName(O, BaseReg);
2455e3ee4b8SRichard Trieu if (Writeback)
2465e3ee4b8SRichard Trieu O << "!";
2475e3ee4b8SRichard Trieu O << ", ";
2485e3ee4b8SRichard Trieu printRegisterList(MI, 3, STI, O);
2495e3ee4b8SRichard Trieu printAnnotation(O, Annot);
2505e3ee4b8SRichard Trieu return;
2515e3ee4b8SRichard Trieu }
2525e3ee4b8SRichard Trieu
2535e3ee4b8SRichard Trieu // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
2545e3ee4b8SRichard Trieu // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
2555e3ee4b8SRichard Trieu // a single GPRPair reg operand is used in the .td file to replace the two
2565e3ee4b8SRichard Trieu // GPRs. However, when decoding them, the two GRPs cannot be automatically
2575e3ee4b8SRichard Trieu // expressed as a GPRPair, so we have to manually merge them.
2585e3ee4b8SRichard Trieu // FIXME: We would really like to be able to tablegen'erate this.
2595e3ee4b8SRichard Trieu case ARM::LDREXD:
2605e3ee4b8SRichard Trieu case ARM::STREXD:
2615e3ee4b8SRichard Trieu case ARM::LDAEXD:
2625e3ee4b8SRichard Trieu case ARM::STLEXD: {
2635e3ee4b8SRichard Trieu const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID);
2645e3ee4b8SRichard Trieu bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
2655e3ee4b8SRichard Trieu unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
2665e3ee4b8SRichard Trieu if (MRC.contains(Reg)) {
2675e3ee4b8SRichard Trieu MCInst NewMI;
2685e3ee4b8SRichard Trieu MCOperand NewReg;
2695e3ee4b8SRichard Trieu NewMI.setOpcode(Opcode);
2705e3ee4b8SRichard Trieu
2715e3ee4b8SRichard Trieu if (isStore)
2725e3ee4b8SRichard Trieu NewMI.addOperand(MI->getOperand(0));
2735e3ee4b8SRichard Trieu NewReg = MCOperand::createReg(MRI.getMatchingSuperReg(
2745e3ee4b8SRichard Trieu Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID)));
2755e3ee4b8SRichard Trieu NewMI.addOperand(NewReg);
2765e3ee4b8SRichard Trieu
2775e3ee4b8SRichard Trieu // Copy the rest operands into NewMI.
2785e3ee4b8SRichard Trieu for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i)
2795e3ee4b8SRichard Trieu NewMI.addOperand(MI->getOperand(i));
2803d87d0b9SFangrui Song printInstruction(&NewMI, Address, STI, O);
2815e3ee4b8SRichard Trieu return;
2825e3ee4b8SRichard Trieu }
2835e3ee4b8SRichard Trieu break;
2845e3ee4b8SRichard Trieu }
2855e3ee4b8SRichard Trieu case ARM::TSB:
2865e3ee4b8SRichard Trieu case ARM::t2TSB:
2875e3ee4b8SRichard Trieu O << "\ttsb\tcsync";
2885e3ee4b8SRichard Trieu return;
2895e3ee4b8SRichard Trieu case ARM::t2DSB:
2905e3ee4b8SRichard Trieu switch (MI->getOperand(0).getImm()) {
2915e3ee4b8SRichard Trieu default:
292b3cc5dceSFangrui Song if (!printAliasInstr(MI, Address, STI, O))
2933d87d0b9SFangrui Song printInstruction(MI, Address, STI, O);
2945e3ee4b8SRichard Trieu break;
2955e3ee4b8SRichard Trieu case 0:
2965e3ee4b8SRichard Trieu O << "\tssbb";
2975e3ee4b8SRichard Trieu break;
2985e3ee4b8SRichard Trieu case 4:
2995e3ee4b8SRichard Trieu O << "\tpssbb";
3005e3ee4b8SRichard Trieu break;
3015e3ee4b8SRichard Trieu }
3025e3ee4b8SRichard Trieu printAnnotation(O, Annot);
3035e3ee4b8SRichard Trieu return;
3045e3ee4b8SRichard Trieu }
3055e3ee4b8SRichard Trieu
306b3cc5dceSFangrui Song if (!printAliasInstr(MI, Address, STI, O))
3073d87d0b9SFangrui Song printInstruction(MI, Address, STI, O);
3085e3ee4b8SRichard Trieu
3095e3ee4b8SRichard Trieu printAnnotation(O, Annot);
3105e3ee4b8SRichard Trieu }
3115e3ee4b8SRichard Trieu
printOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3125e3ee4b8SRichard Trieu void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
3135e3ee4b8SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
3145e3ee4b8SRichard Trieu const MCOperand &Op = MI->getOperand(OpNo);
3155e3ee4b8SRichard Trieu if (Op.isReg()) {
3165e3ee4b8SRichard Trieu unsigned Reg = Op.getReg();
3175e3ee4b8SRichard Trieu printRegName(O, Reg);
3185e3ee4b8SRichard Trieu } else if (Op.isImm()) {
3195e3ee4b8SRichard Trieu O << markup("<imm:") << '#' << formatImm(Op.getImm()) << markup(">");
3205e3ee4b8SRichard Trieu } else {
3215e3ee4b8SRichard Trieu assert(Op.isExpr() && "unknown operand kind in printOperand");
3225e3ee4b8SRichard Trieu const MCExpr *Expr = Op.getExpr();
3235e3ee4b8SRichard Trieu switch (Expr->getKind()) {
3245e3ee4b8SRichard Trieu case MCExpr::Binary:
3255e3ee4b8SRichard Trieu O << '#';
3265e3ee4b8SRichard Trieu Expr->print(O, &MAI);
3275e3ee4b8SRichard Trieu break;
3285e3ee4b8SRichard Trieu case MCExpr::Constant: {
3295e3ee4b8SRichard Trieu // If a symbolic branch target was added as a constant expression then
3305e3ee4b8SRichard Trieu // print that address in hex. And only print 32 unsigned bits for the
3315e3ee4b8SRichard Trieu // address.
3325e3ee4b8SRichard Trieu const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
3335e3ee4b8SRichard Trieu int64_t TargetAddress;
3345e3ee4b8SRichard Trieu if (!Constant->evaluateAsAbsolute(TargetAddress)) {
3355e3ee4b8SRichard Trieu O << '#';
3365e3ee4b8SRichard Trieu Expr->print(O, &MAI);
3375e3ee4b8SRichard Trieu } else {
3385e3ee4b8SRichard Trieu O << "0x";
3395e3ee4b8SRichard Trieu O.write_hex(static_cast<uint32_t>(TargetAddress));
3405e3ee4b8SRichard Trieu }
3415e3ee4b8SRichard Trieu break;
3425e3ee4b8SRichard Trieu }
3435e3ee4b8SRichard Trieu default:
3445e3ee4b8SRichard Trieu // FIXME: Should we always treat this as if it is a constant literal and
3455e3ee4b8SRichard Trieu // prefix it with '#'?
3465e3ee4b8SRichard Trieu Expr->print(O, &MAI);
3475e3ee4b8SRichard Trieu break;
3485e3ee4b8SRichard Trieu }
3495e3ee4b8SRichard Trieu }
3505e3ee4b8SRichard Trieu }
3515e3ee4b8SRichard Trieu
printOperand(const MCInst * MI,uint64_t Address,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)352*657e067bSIgor Kudrin void ARMInstPrinter::printOperand(const MCInst *MI, uint64_t Address,
353*657e067bSIgor Kudrin unsigned OpNum, const MCSubtargetInfo &STI,
354*657e067bSIgor Kudrin raw_ostream &O) {
355*657e067bSIgor Kudrin const MCOperand &Op = MI->getOperand(OpNum);
356*657e067bSIgor Kudrin if (!Op.isImm() || !PrintBranchImmAsAddress || getUseMarkup())
357*657e067bSIgor Kudrin return printOperand(MI, OpNum, STI, O);
358*657e067bSIgor Kudrin uint64_t Target = ARM_MC::evaluateBranchTarget(MII.get(MI->getOpcode()),
359*657e067bSIgor Kudrin Address, Op.getImm());
360*657e067bSIgor Kudrin Target &= 0xffffffff;
361*657e067bSIgor Kudrin O << formatHex(Target);
362*657e067bSIgor Kudrin if (CommentStream)
363*657e067bSIgor Kudrin *CommentStream << "imm = #" << formatImm(Op.getImm()) << '\n';
364*657e067bSIgor Kudrin }
365*657e067bSIgor Kudrin
printThumbLdrLabelOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)3665e3ee4b8SRichard Trieu void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum,
3675e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
3685e3ee4b8SRichard Trieu raw_ostream &O) {
3695e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
3705e3ee4b8SRichard Trieu if (MO1.isExpr()) {
3715e3ee4b8SRichard Trieu MO1.getExpr()->print(O, &MAI);
3725e3ee4b8SRichard Trieu return;
3735e3ee4b8SRichard Trieu }
3745e3ee4b8SRichard Trieu
3755e3ee4b8SRichard Trieu O << markup("<mem:") << "[pc, ";
3765e3ee4b8SRichard Trieu
3775e3ee4b8SRichard Trieu int32_t OffImm = (int32_t)MO1.getImm();
3785e3ee4b8SRichard Trieu bool isSub = OffImm < 0;
3795e3ee4b8SRichard Trieu
3805e3ee4b8SRichard Trieu // Special value for #-0. All others are normal.
3815e3ee4b8SRichard Trieu if (OffImm == INT32_MIN)
3825e3ee4b8SRichard Trieu OffImm = 0;
3835e3ee4b8SRichard Trieu if (isSub) {
3845e3ee4b8SRichard Trieu O << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
3855e3ee4b8SRichard Trieu } else {
3865e3ee4b8SRichard Trieu O << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
3875e3ee4b8SRichard Trieu }
3885e3ee4b8SRichard Trieu O << "]" << markup(">");
3895e3ee4b8SRichard Trieu }
3905e3ee4b8SRichard Trieu
3915e3ee4b8SRichard Trieu // so_reg is a 4-operand unit corresponding to register forms of the A5.1
3925e3ee4b8SRichard Trieu // "Addressing Mode 1 - Data-processing operands" forms. This includes:
3935e3ee4b8SRichard Trieu // REG 0 0 - e.g. R5
3945e3ee4b8SRichard Trieu // REG REG 0,SH_OPC - e.g. R5, ROR R3
3955e3ee4b8SRichard Trieu // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
printSORegRegOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)3965e3ee4b8SRichard Trieu void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum,
3975e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
3985e3ee4b8SRichard Trieu raw_ostream &O) {
3995e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
4005e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
4015e3ee4b8SRichard Trieu const MCOperand &MO3 = MI->getOperand(OpNum + 2);
4025e3ee4b8SRichard Trieu
4035e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
4045e3ee4b8SRichard Trieu
4055e3ee4b8SRichard Trieu // Print the shift opc.
4065e3ee4b8SRichard Trieu ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
4075e3ee4b8SRichard Trieu O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
4085e3ee4b8SRichard Trieu if (ShOpc == ARM_AM::rrx)
4095e3ee4b8SRichard Trieu return;
4105e3ee4b8SRichard Trieu
4115e3ee4b8SRichard Trieu O << ' ';
4125e3ee4b8SRichard Trieu printRegName(O, MO2.getReg());
4135e3ee4b8SRichard Trieu assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
4145e3ee4b8SRichard Trieu }
4155e3ee4b8SRichard Trieu
printSORegImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)4165e3ee4b8SRichard Trieu void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
4175e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
4185e3ee4b8SRichard Trieu raw_ostream &O) {
4195e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
4205e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
4215e3ee4b8SRichard Trieu
4225e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
4235e3ee4b8SRichard Trieu
4245e3ee4b8SRichard Trieu // Print the shift opc.
4255e3ee4b8SRichard Trieu printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
4265e3ee4b8SRichard Trieu ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
4275e3ee4b8SRichard Trieu }
4285e3ee4b8SRichard Trieu
4295e3ee4b8SRichard Trieu //===--------------------------------------------------------------------===//
4305e3ee4b8SRichard Trieu // Addressing Mode #2
4315e3ee4b8SRichard Trieu //===--------------------------------------------------------------------===//
4325e3ee4b8SRichard Trieu
printAM2PreOrOffsetIndexOp(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)4335e3ee4b8SRichard Trieu void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
4345e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
4355e3ee4b8SRichard Trieu raw_ostream &O) {
4365e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(Op);
4375e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(Op + 1);
4385e3ee4b8SRichard Trieu const MCOperand &MO3 = MI->getOperand(Op + 2);
4395e3ee4b8SRichard Trieu
4405e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
4415e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
4425e3ee4b8SRichard Trieu
4435e3ee4b8SRichard Trieu if (!MO2.getReg()) {
4445e3ee4b8SRichard Trieu if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0.
4455e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#"
4465e3ee4b8SRichard Trieu << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
4475e3ee4b8SRichard Trieu << ARM_AM::getAM2Offset(MO3.getImm()) << markup(">");
4485e3ee4b8SRichard Trieu }
4495e3ee4b8SRichard Trieu O << "]" << markup(">");
4505e3ee4b8SRichard Trieu return;
4515e3ee4b8SRichard Trieu }
4525e3ee4b8SRichard Trieu
4535e3ee4b8SRichard Trieu O << ", ";
4545e3ee4b8SRichard Trieu O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()));
4555e3ee4b8SRichard Trieu printRegName(O, MO2.getReg());
4565e3ee4b8SRichard Trieu
4575e3ee4b8SRichard Trieu printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()),
4585e3ee4b8SRichard Trieu ARM_AM::getAM2Offset(MO3.getImm()), UseMarkup);
4595e3ee4b8SRichard Trieu O << "]" << markup(">");
4605e3ee4b8SRichard Trieu }
4615e3ee4b8SRichard Trieu
printAddrModeTBB(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)4625e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op,
4635e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
4645e3ee4b8SRichard Trieu raw_ostream &O) {
4655e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(Op);
4665e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(Op + 1);
4675e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
4685e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
4695e3ee4b8SRichard Trieu O << ", ";
4705e3ee4b8SRichard Trieu printRegName(O, MO2.getReg());
4715e3ee4b8SRichard Trieu O << "]" << markup(">");
4725e3ee4b8SRichard Trieu }
4735e3ee4b8SRichard Trieu
printAddrModeTBH(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)4745e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op,
4755e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
4765e3ee4b8SRichard Trieu raw_ostream &O) {
4775e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(Op);
4785e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(Op + 1);
4795e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
4805e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
4815e3ee4b8SRichard Trieu O << ", ";
4825e3ee4b8SRichard Trieu printRegName(O, MO2.getReg());
4835e3ee4b8SRichard Trieu O << ", lsl " << markup("<imm:") << "#1" << markup(">") << "]" << markup(">");
4845e3ee4b8SRichard Trieu }
4855e3ee4b8SRichard Trieu
printAddrMode2Operand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)4865e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
4875e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
4885e3ee4b8SRichard Trieu raw_ostream &O) {
4895e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(Op);
4905e3ee4b8SRichard Trieu
4915e3ee4b8SRichard Trieu if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
4925e3ee4b8SRichard Trieu printOperand(MI, Op, STI, O);
4935e3ee4b8SRichard Trieu return;
4945e3ee4b8SRichard Trieu }
4955e3ee4b8SRichard Trieu
4965e3ee4b8SRichard Trieu #ifndef NDEBUG
4975e3ee4b8SRichard Trieu const MCOperand &MO3 = MI->getOperand(Op + 2);
4985e3ee4b8SRichard Trieu unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
4995e3ee4b8SRichard Trieu assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op");
5005e3ee4b8SRichard Trieu #endif
5015e3ee4b8SRichard Trieu
5025e3ee4b8SRichard Trieu printAM2PreOrOffsetIndexOp(MI, Op, STI, O);
5035e3ee4b8SRichard Trieu }
5045e3ee4b8SRichard Trieu
printAddrMode2OffsetOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)5055e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
5065e3ee4b8SRichard Trieu unsigned OpNum,
5075e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
5085e3ee4b8SRichard Trieu raw_ostream &O) {
5095e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
5105e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
5115e3ee4b8SRichard Trieu
5125e3ee4b8SRichard Trieu if (!MO1.getReg()) {
5135e3ee4b8SRichard Trieu unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
5145e3ee4b8SRichard Trieu O << markup("<imm:") << '#'
5155e3ee4b8SRichard Trieu << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) << ImmOffs
5165e3ee4b8SRichard Trieu << markup(">");
5175e3ee4b8SRichard Trieu return;
5185e3ee4b8SRichard Trieu }
5195e3ee4b8SRichard Trieu
5205e3ee4b8SRichard Trieu O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()));
5215e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
5225e3ee4b8SRichard Trieu
5235e3ee4b8SRichard Trieu printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()),
5245e3ee4b8SRichard Trieu ARM_AM::getAM2Offset(MO2.getImm()), UseMarkup);
5255e3ee4b8SRichard Trieu }
5265e3ee4b8SRichard Trieu
5275e3ee4b8SRichard Trieu //===--------------------------------------------------------------------===//
5285e3ee4b8SRichard Trieu // Addressing Mode #3
5295e3ee4b8SRichard Trieu //===--------------------------------------------------------------------===//
5305e3ee4b8SRichard Trieu
printAM3PreOrOffsetIndexOp(const MCInst * MI,unsigned Op,raw_ostream & O,bool AlwaysPrintImm0)5315e3ee4b8SRichard Trieu void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
5325e3ee4b8SRichard Trieu raw_ostream &O,
5335e3ee4b8SRichard Trieu bool AlwaysPrintImm0) {
5345e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(Op);
5355e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(Op + 1);
5365e3ee4b8SRichard Trieu const MCOperand &MO3 = MI->getOperand(Op + 2);
5375e3ee4b8SRichard Trieu
5385e3ee4b8SRichard Trieu O << markup("<mem:") << '[';
5395e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
5405e3ee4b8SRichard Trieu
5415e3ee4b8SRichard Trieu if (MO2.getReg()) {
5425e3ee4b8SRichard Trieu O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()));
5435e3ee4b8SRichard Trieu printRegName(O, MO2.getReg());
5445e3ee4b8SRichard Trieu O << ']' << markup(">");
5455e3ee4b8SRichard Trieu return;
5465e3ee4b8SRichard Trieu }
5475e3ee4b8SRichard Trieu
5485e3ee4b8SRichard Trieu // If the op is sub we have to print the immediate even if it is 0
5495e3ee4b8SRichard Trieu unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
5505e3ee4b8SRichard Trieu ARM_AM::AddrOpc op = ARM_AM::getAM3Op(MO3.getImm());
5515e3ee4b8SRichard Trieu
5525e3ee4b8SRichard Trieu if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) {
5535e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs
5545e3ee4b8SRichard Trieu << markup(">");
5555e3ee4b8SRichard Trieu }
5565e3ee4b8SRichard Trieu O << ']' << markup(">");
5575e3ee4b8SRichard Trieu }
5585e3ee4b8SRichard Trieu
5595e3ee4b8SRichard Trieu template <bool AlwaysPrintImm0>
printAddrMode3Operand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)5605e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op,
5615e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
5625e3ee4b8SRichard Trieu raw_ostream &O) {
5635e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(Op);
5645e3ee4b8SRichard Trieu if (!MO1.isReg()) { // For label symbolic references.
5655e3ee4b8SRichard Trieu printOperand(MI, Op, STI, O);
5665e3ee4b8SRichard Trieu return;
5675e3ee4b8SRichard Trieu }
5685e3ee4b8SRichard Trieu
5695e3ee4b8SRichard Trieu assert(ARM_AM::getAM3IdxMode(MI->getOperand(Op + 2).getImm()) !=
5705e3ee4b8SRichard Trieu ARMII::IndexModePost &&
5715e3ee4b8SRichard Trieu "unexpected idxmode");
5725e3ee4b8SRichard Trieu printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
5735e3ee4b8SRichard Trieu }
5745e3ee4b8SRichard Trieu
printAddrMode3OffsetOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)5755e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
5765e3ee4b8SRichard Trieu unsigned OpNum,
5775e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
5785e3ee4b8SRichard Trieu raw_ostream &O) {
5795e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
5805e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
5815e3ee4b8SRichard Trieu
5825e3ee4b8SRichard Trieu if (MO1.getReg()) {
5835e3ee4b8SRichard Trieu O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()));
5845e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
5855e3ee4b8SRichard Trieu return;
5865e3ee4b8SRichard Trieu }
5875e3ee4b8SRichard Trieu
5885e3ee4b8SRichard Trieu unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
5895e3ee4b8SRichard Trieu O << markup("<imm:") << '#'
5905e3ee4b8SRichard Trieu << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs
5915e3ee4b8SRichard Trieu << markup(">");
5925e3ee4b8SRichard Trieu }
5935e3ee4b8SRichard Trieu
printPostIdxImm8Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)5945e3ee4b8SRichard Trieu void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum,
5955e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
5965e3ee4b8SRichard Trieu raw_ostream &O) {
5975e3ee4b8SRichard Trieu const MCOperand &MO = MI->getOperand(OpNum);
5985e3ee4b8SRichard Trieu unsigned Imm = MO.getImm();
5995e3ee4b8SRichard Trieu O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff)
6005e3ee4b8SRichard Trieu << markup(">");
6015e3ee4b8SRichard Trieu }
6025e3ee4b8SRichard Trieu
printPostIdxRegOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)6035e3ee4b8SRichard Trieu void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum,
6045e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
6055e3ee4b8SRichard Trieu raw_ostream &O) {
6065e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
6075e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
6085e3ee4b8SRichard Trieu
6095e3ee4b8SRichard Trieu O << (MO2.getImm() ? "" : "-");
6105e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
6115e3ee4b8SRichard Trieu }
6125e3ee4b8SRichard Trieu
printPostIdxImm8s4Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)6135e3ee4b8SRichard Trieu void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum,
6145e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
6155e3ee4b8SRichard Trieu raw_ostream &O) {
6165e3ee4b8SRichard Trieu const MCOperand &MO = MI->getOperand(OpNum);
6175e3ee4b8SRichard Trieu unsigned Imm = MO.getImm();
6185e3ee4b8SRichard Trieu O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2)
6195e3ee4b8SRichard Trieu << markup(">");
6205e3ee4b8SRichard Trieu }
6215e3ee4b8SRichard Trieu
622e6824160SSimon Tatham template<int shift>
printMveAddrModeRQOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)623e6824160SSimon Tatham void ARMInstPrinter::printMveAddrModeRQOperand(const MCInst *MI, unsigned OpNum,
624e6824160SSimon Tatham const MCSubtargetInfo &STI,
625e6824160SSimon Tatham raw_ostream &O) {
626e6824160SSimon Tatham const MCOperand &MO1 = MI->getOperand(OpNum);
627e6824160SSimon Tatham const MCOperand &MO2 = MI->getOperand(OpNum + 1);
628e6824160SSimon Tatham
629e6824160SSimon Tatham O << markup("<mem:") << "[";
630e6824160SSimon Tatham printRegName(O, MO1.getReg());
631e6824160SSimon Tatham O << ", ";
632e6824160SSimon Tatham printRegName(O, MO2.getReg());
633e6824160SSimon Tatham
634e6824160SSimon Tatham if (shift > 0)
635e6824160SSimon Tatham printRegImmShift(O, ARM_AM::uxtw, shift, UseMarkup);
636e6824160SSimon Tatham
637e6824160SSimon Tatham O << "]" << markup(">");
638e6824160SSimon Tatham }
639e6824160SSimon Tatham
printLdStmModeOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)6405e3ee4b8SRichard Trieu void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
6415e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
6425e3ee4b8SRichard Trieu raw_ostream &O) {
6435e3ee4b8SRichard Trieu ARM_AM::AMSubMode Mode =
6445e3ee4b8SRichard Trieu ARM_AM::getAM4SubMode(MI->getOperand(OpNum).getImm());
6455e3ee4b8SRichard Trieu O << ARM_AM::getAMSubModeStr(Mode);
6465e3ee4b8SRichard Trieu }
6475e3ee4b8SRichard Trieu
6485e3ee4b8SRichard Trieu template <bool AlwaysPrintImm0>
printAddrMode5Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)6495e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
6505e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
6515e3ee4b8SRichard Trieu raw_ostream &O) {
6525e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
6535e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
6545e3ee4b8SRichard Trieu
6555e3ee4b8SRichard Trieu if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
6565e3ee4b8SRichard Trieu printOperand(MI, OpNum, STI, O);
6575e3ee4b8SRichard Trieu return;
6585e3ee4b8SRichard Trieu }
6595e3ee4b8SRichard Trieu
6605e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
6615e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
6625e3ee4b8SRichard Trieu
6635e3ee4b8SRichard Trieu unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
6645e3ee4b8SRichard Trieu ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm());
6655e3ee4b8SRichard Trieu if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
6665e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(Op)
6675e3ee4b8SRichard Trieu << ImmOffs * 4 << markup(">");
6685e3ee4b8SRichard Trieu }
6695e3ee4b8SRichard Trieu O << "]" << markup(">");
6705e3ee4b8SRichard Trieu }
6715e3ee4b8SRichard Trieu
6725e3ee4b8SRichard Trieu template <bool AlwaysPrintImm0>
printAddrMode5FP16Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)6735e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrMode5FP16Operand(const MCInst *MI, unsigned OpNum,
6745e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
6755e3ee4b8SRichard Trieu raw_ostream &O) {
6765e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
6775e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum+1);
6785e3ee4b8SRichard Trieu
6795e3ee4b8SRichard Trieu if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
6805e3ee4b8SRichard Trieu printOperand(MI, OpNum, STI, O);
6815e3ee4b8SRichard Trieu return;
6825e3ee4b8SRichard Trieu }
6835e3ee4b8SRichard Trieu
6845e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
6855e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
6865e3ee4b8SRichard Trieu
6875e3ee4b8SRichard Trieu unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
6885e3ee4b8SRichard Trieu unsigned Op = ARM_AM::getAM5FP16Op(MO2.getImm());
6895e3ee4b8SRichard Trieu if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
6905e3ee4b8SRichard Trieu O << ", "
6915e3ee4b8SRichard Trieu << markup("<imm:")
6925e3ee4b8SRichard Trieu << "#"
6935e3ee4b8SRichard Trieu << ARM_AM::getAddrOpcStr(ARM_AM::getAM5FP16Op(MO2.getImm()))
6945e3ee4b8SRichard Trieu << ImmOffs * 2
6955e3ee4b8SRichard Trieu << markup(">");
6965e3ee4b8SRichard Trieu }
6975e3ee4b8SRichard Trieu O << "]" << markup(">");
6985e3ee4b8SRichard Trieu }
6995e3ee4b8SRichard Trieu
printAddrMode6Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)7005e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
7015e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
7025e3ee4b8SRichard Trieu raw_ostream &O) {
7035e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
7045e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
7055e3ee4b8SRichard Trieu
7065e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
7075e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
7085e3ee4b8SRichard Trieu if (MO2.getImm()) {
7095e3ee4b8SRichard Trieu O << ":" << (MO2.getImm() << 3);
7105e3ee4b8SRichard Trieu }
7115e3ee4b8SRichard Trieu O << "]" << markup(">");
7125e3ee4b8SRichard Trieu }
7135e3ee4b8SRichard Trieu
printAddrMode7Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)7145e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
7155e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
7165e3ee4b8SRichard Trieu raw_ostream &O) {
7175e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
7185e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
7195e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
7205e3ee4b8SRichard Trieu O << "]" << markup(">");
7215e3ee4b8SRichard Trieu }
7225e3ee4b8SRichard Trieu
printAddrMode6OffsetOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)7235e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
7245e3ee4b8SRichard Trieu unsigned OpNum,
7255e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
7265e3ee4b8SRichard Trieu raw_ostream &O) {
7275e3ee4b8SRichard Trieu const MCOperand &MO = MI->getOperand(OpNum);
7285e3ee4b8SRichard Trieu if (MO.getReg() == 0)
7295e3ee4b8SRichard Trieu O << "!";
7305e3ee4b8SRichard Trieu else {
7315e3ee4b8SRichard Trieu O << ", ";
7325e3ee4b8SRichard Trieu printRegName(O, MO.getReg());
7335e3ee4b8SRichard Trieu }
7345e3ee4b8SRichard Trieu }
7355e3ee4b8SRichard Trieu
printBitfieldInvMaskImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)7365e3ee4b8SRichard Trieu void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
7375e3ee4b8SRichard Trieu unsigned OpNum,
7385e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
7395e3ee4b8SRichard Trieu raw_ostream &O) {
7405e3ee4b8SRichard Trieu const MCOperand &MO = MI->getOperand(OpNum);
7415e3ee4b8SRichard Trieu uint32_t v = ~MO.getImm();
7425e3ee4b8SRichard Trieu int32_t lsb = countTrailingZeros(v);
7435e3ee4b8SRichard Trieu int32_t width = (32 - countLeadingZeros(v)) - lsb;
7445e3ee4b8SRichard Trieu assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
7455e3ee4b8SRichard Trieu O << markup("<imm:") << '#' << lsb << markup(">") << ", " << markup("<imm:")
7465e3ee4b8SRichard Trieu << '#' << width << markup(">");
7475e3ee4b8SRichard Trieu }
7485e3ee4b8SRichard Trieu
printMemBOption(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)7495e3ee4b8SRichard Trieu void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
7505e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
7515e3ee4b8SRichard Trieu raw_ostream &O) {
7525e3ee4b8SRichard Trieu unsigned val = MI->getOperand(OpNum).getImm();
7535e3ee4b8SRichard Trieu O << ARM_MB::MemBOptToString(val, STI.getFeatureBits()[ARM::HasV8Ops]);
7545e3ee4b8SRichard Trieu }
7555e3ee4b8SRichard Trieu
printInstSyncBOption(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)7565e3ee4b8SRichard Trieu void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
7575e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
7585e3ee4b8SRichard Trieu raw_ostream &O) {
7595e3ee4b8SRichard Trieu unsigned val = MI->getOperand(OpNum).getImm();
7605e3ee4b8SRichard Trieu O << ARM_ISB::InstSyncBOptToString(val);
7615e3ee4b8SRichard Trieu }
7625e3ee4b8SRichard Trieu
printTraceSyncBOption(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)7635e3ee4b8SRichard Trieu void ARMInstPrinter::printTraceSyncBOption(const MCInst *MI, unsigned OpNum,
7645e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
7655e3ee4b8SRichard Trieu raw_ostream &O) {
7665e3ee4b8SRichard Trieu unsigned val = MI->getOperand(OpNum).getImm();
7675e3ee4b8SRichard Trieu O << ARM_TSB::TraceSyncBOptToString(val);
7685e3ee4b8SRichard Trieu }
7695e3ee4b8SRichard Trieu
printShiftImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)7705e3ee4b8SRichard Trieu void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
7715e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
7725e3ee4b8SRichard Trieu raw_ostream &O) {
7735e3ee4b8SRichard Trieu unsigned ShiftOp = MI->getOperand(OpNum).getImm();
7745e3ee4b8SRichard Trieu bool isASR = (ShiftOp & (1 << 5)) != 0;
7755e3ee4b8SRichard Trieu unsigned Amt = ShiftOp & 0x1f;
7765e3ee4b8SRichard Trieu if (isASR) {
7775e3ee4b8SRichard Trieu O << ", asr " << markup("<imm:") << "#" << (Amt == 0 ? 32 : Amt)
7785e3ee4b8SRichard Trieu << markup(">");
7795e3ee4b8SRichard Trieu } else if (Amt) {
7805e3ee4b8SRichard Trieu O << ", lsl " << markup("<imm:") << "#" << Amt << markup(">");
7815e3ee4b8SRichard Trieu }
7825e3ee4b8SRichard Trieu }
7835e3ee4b8SRichard Trieu
printPKHLSLShiftImm(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)7845e3ee4b8SRichard Trieu void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
7855e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
7865e3ee4b8SRichard Trieu raw_ostream &O) {
7875e3ee4b8SRichard Trieu unsigned Imm = MI->getOperand(OpNum).getImm();
7885e3ee4b8SRichard Trieu if (Imm == 0)
7895e3ee4b8SRichard Trieu return;
7905e3ee4b8SRichard Trieu assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
7915e3ee4b8SRichard Trieu O << ", lsl " << markup("<imm:") << "#" << Imm << markup(">");
7925e3ee4b8SRichard Trieu }
7935e3ee4b8SRichard Trieu
printPKHASRShiftImm(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)7945e3ee4b8SRichard Trieu void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
7955e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
7965e3ee4b8SRichard Trieu raw_ostream &O) {
7975e3ee4b8SRichard Trieu unsigned Imm = MI->getOperand(OpNum).getImm();
7985e3ee4b8SRichard Trieu // A shift amount of 32 is encoded as 0.
7995e3ee4b8SRichard Trieu if (Imm == 0)
8005e3ee4b8SRichard Trieu Imm = 32;
8015e3ee4b8SRichard Trieu assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
8025e3ee4b8SRichard Trieu O << ", asr " << markup("<imm:") << "#" << Imm << markup(">");
8035e3ee4b8SRichard Trieu }
8045e3ee4b8SRichard Trieu
printRegisterList(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)8055e3ee4b8SRichard Trieu void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
8065e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
8075e3ee4b8SRichard Trieu raw_ostream &O) {
8088c865cacSSimon Tatham if (MI->getOpcode() != ARM::t2CLRM) {
809f890fd5fSKazu Hirata assert(is_sorted(drop_begin(*MI, OpNum),
8105e3ee4b8SRichard Trieu [&](const MCOperand &LHS, const MCOperand &RHS) {
8115e3ee4b8SRichard Trieu return MRI.getEncodingValue(LHS.getReg()) <
8125e3ee4b8SRichard Trieu MRI.getEncodingValue(RHS.getReg());
8135e3ee4b8SRichard Trieu }));
8148c865cacSSimon Tatham }
8155e3ee4b8SRichard Trieu
8165e3ee4b8SRichard Trieu O << "{";
8175e3ee4b8SRichard Trieu for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
8185e3ee4b8SRichard Trieu if (i != OpNum)
8195e3ee4b8SRichard Trieu O << ", ";
8205e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(i).getReg());
8215e3ee4b8SRichard Trieu }
8225e3ee4b8SRichard Trieu O << "}";
8235e3ee4b8SRichard Trieu }
8245e3ee4b8SRichard Trieu
printGPRPairOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)8255e3ee4b8SRichard Trieu void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum,
8265e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
8275e3ee4b8SRichard Trieu raw_ostream &O) {
8285e3ee4b8SRichard Trieu unsigned Reg = MI->getOperand(OpNum).getReg();
8295e3ee4b8SRichard Trieu printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
8305e3ee4b8SRichard Trieu O << ", ";
8315e3ee4b8SRichard Trieu printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
8325e3ee4b8SRichard Trieu }
8335e3ee4b8SRichard Trieu
printSetendOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)8345e3ee4b8SRichard Trieu void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
8355e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
8365e3ee4b8SRichard Trieu raw_ostream &O) {
8375e3ee4b8SRichard Trieu const MCOperand &Op = MI->getOperand(OpNum);
8385e3ee4b8SRichard Trieu if (Op.getImm())
8395e3ee4b8SRichard Trieu O << "be";
8405e3ee4b8SRichard Trieu else
8415e3ee4b8SRichard Trieu O << "le";
8425e3ee4b8SRichard Trieu }
8435e3ee4b8SRichard Trieu
printCPSIMod(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)8445e3ee4b8SRichard Trieu void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
8455e3ee4b8SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
8465e3ee4b8SRichard Trieu const MCOperand &Op = MI->getOperand(OpNum);
8475e3ee4b8SRichard Trieu O << ARM_PROC::IModToString(Op.getImm());
8485e3ee4b8SRichard Trieu }
8495e3ee4b8SRichard Trieu
printCPSIFlag(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)8505e3ee4b8SRichard Trieu void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
8515e3ee4b8SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
8525e3ee4b8SRichard Trieu const MCOperand &Op = MI->getOperand(OpNum);
8535e3ee4b8SRichard Trieu unsigned IFlags = Op.getImm();
8545e3ee4b8SRichard Trieu for (int i = 2; i >= 0; --i)
8555e3ee4b8SRichard Trieu if (IFlags & (1 << i))
8565e3ee4b8SRichard Trieu O << ARM_PROC::IFlagsToString(1 << i);
8575e3ee4b8SRichard Trieu
8585e3ee4b8SRichard Trieu if (IFlags == 0)
8595e3ee4b8SRichard Trieu O << "none";
8605e3ee4b8SRichard Trieu }
8615e3ee4b8SRichard Trieu
printMSRMaskOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)8625e3ee4b8SRichard Trieu void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
8635e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
8645e3ee4b8SRichard Trieu raw_ostream &O) {
8655e3ee4b8SRichard Trieu const MCOperand &Op = MI->getOperand(OpNum);
8665e3ee4b8SRichard Trieu const FeatureBitset &FeatureBits = STI.getFeatureBits();
8675e3ee4b8SRichard Trieu if (FeatureBits[ARM::FeatureMClass]) {
8685e3ee4b8SRichard Trieu
8695e3ee4b8SRichard Trieu unsigned SYSm = Op.getImm() & 0xFFF; // 12-bit SYSm
8705e3ee4b8SRichard Trieu unsigned Opcode = MI->getOpcode();
8715e3ee4b8SRichard Trieu
8725e3ee4b8SRichard Trieu // For writes, handle extended mask bits if the DSP extension is present.
8735e3ee4b8SRichard Trieu if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) {
8745e3ee4b8SRichard Trieu auto TheReg =ARMSysReg::lookupMClassSysRegBy12bitSYSmValue(SYSm);
8755e3ee4b8SRichard Trieu if (TheReg && TheReg->isInRequiredFeatures({ARM::FeatureDSP})) {
8765e3ee4b8SRichard Trieu O << TheReg->Name;
8775e3ee4b8SRichard Trieu return;
8785e3ee4b8SRichard Trieu }
8795e3ee4b8SRichard Trieu }
8805e3ee4b8SRichard Trieu
8815e3ee4b8SRichard Trieu // Handle the basic 8-bit mask.
8825e3ee4b8SRichard Trieu SYSm &= 0xff;
8835e3ee4b8SRichard Trieu if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
8845e3ee4b8SRichard Trieu // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
8855e3ee4b8SRichard Trieu // alias for MSR APSR_nzcvq.
8865e3ee4b8SRichard Trieu auto TheReg = ARMSysReg::lookupMClassSysRegAPSRNonDeprecated(SYSm);
8875e3ee4b8SRichard Trieu if (TheReg) {
8885e3ee4b8SRichard Trieu O << TheReg->Name;
8895e3ee4b8SRichard Trieu return;
8905e3ee4b8SRichard Trieu }
8915e3ee4b8SRichard Trieu }
8925e3ee4b8SRichard Trieu
8935e3ee4b8SRichard Trieu auto TheReg = ARMSysReg::lookupMClassSysRegBy8bitSYSmValue(SYSm);
8945e3ee4b8SRichard Trieu if (TheReg) {
8955e3ee4b8SRichard Trieu O << TheReg->Name;
8965e3ee4b8SRichard Trieu return;
8975e3ee4b8SRichard Trieu }
8985e3ee4b8SRichard Trieu
8995e3ee4b8SRichard Trieu O << SYSm;
9005e3ee4b8SRichard Trieu
9015e3ee4b8SRichard Trieu return;
9025e3ee4b8SRichard Trieu }
9035e3ee4b8SRichard Trieu
9045e3ee4b8SRichard Trieu // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
9055e3ee4b8SRichard Trieu // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
9065e3ee4b8SRichard Trieu unsigned SpecRegRBit = Op.getImm() >> 4;
9075e3ee4b8SRichard Trieu unsigned Mask = Op.getImm() & 0xf;
9085e3ee4b8SRichard Trieu
9095e3ee4b8SRichard Trieu if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
9105e3ee4b8SRichard Trieu O << "APSR_";
9115e3ee4b8SRichard Trieu switch (Mask) {
9125e3ee4b8SRichard Trieu default:
9135e3ee4b8SRichard Trieu llvm_unreachable("Unexpected mask value!");
9145e3ee4b8SRichard Trieu case 4:
9155e3ee4b8SRichard Trieu O << "g";
9165e3ee4b8SRichard Trieu return;
9175e3ee4b8SRichard Trieu case 8:
9185e3ee4b8SRichard Trieu O << "nzcvq";
9195e3ee4b8SRichard Trieu return;
9205e3ee4b8SRichard Trieu case 12:
9215e3ee4b8SRichard Trieu O << "nzcvqg";
9225e3ee4b8SRichard Trieu return;
9235e3ee4b8SRichard Trieu }
9245e3ee4b8SRichard Trieu }
9255e3ee4b8SRichard Trieu
9265e3ee4b8SRichard Trieu if (SpecRegRBit)
9275e3ee4b8SRichard Trieu O << "SPSR";
9285e3ee4b8SRichard Trieu else
9295e3ee4b8SRichard Trieu O << "CPSR";
9305e3ee4b8SRichard Trieu
9315e3ee4b8SRichard Trieu if (Mask) {
9325e3ee4b8SRichard Trieu O << '_';
9335e3ee4b8SRichard Trieu if (Mask & 8)
9345e3ee4b8SRichard Trieu O << 'f';
9355e3ee4b8SRichard Trieu if (Mask & 4)
9365e3ee4b8SRichard Trieu O << 's';
9375e3ee4b8SRichard Trieu if (Mask & 2)
9385e3ee4b8SRichard Trieu O << 'x';
9395e3ee4b8SRichard Trieu if (Mask & 1)
9405e3ee4b8SRichard Trieu O << 'c';
9415e3ee4b8SRichard Trieu }
9425e3ee4b8SRichard Trieu }
9435e3ee4b8SRichard Trieu
printBankedRegOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)9445e3ee4b8SRichard Trieu void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum,
9455e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
9465e3ee4b8SRichard Trieu raw_ostream &O) {
9475e3ee4b8SRichard Trieu uint32_t Banked = MI->getOperand(OpNum).getImm();
9485e3ee4b8SRichard Trieu auto TheReg = ARMBankedReg::lookupBankedRegByEncoding(Banked);
9495e3ee4b8SRichard Trieu assert(TheReg && "invalid banked register operand");
9505e3ee4b8SRichard Trieu std::string Name = TheReg->Name;
9515e3ee4b8SRichard Trieu
9525e3ee4b8SRichard Trieu uint32_t isSPSR = (Banked & 0x20) >> 5;
9535e3ee4b8SRichard Trieu if (isSPSR)
9545e3ee4b8SRichard Trieu Name.replace(0, 4, "SPSR"); // convert 'spsr_' to 'SPSR_'
9555e3ee4b8SRichard Trieu O << Name;
9565e3ee4b8SRichard Trieu }
9575e3ee4b8SRichard Trieu
printPredicateOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)9585e3ee4b8SRichard Trieu void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
9595e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
9605e3ee4b8SRichard Trieu raw_ostream &O) {
9615e3ee4b8SRichard Trieu ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
9625e3ee4b8SRichard Trieu // Handle the undefined 15 CC value here for printing so we don't abort().
9635e3ee4b8SRichard Trieu if ((unsigned)CC == 15)
9645e3ee4b8SRichard Trieu O << "<und>";
9655e3ee4b8SRichard Trieu else if (CC != ARMCC::AL)
9665e3ee4b8SRichard Trieu O << ARMCondCodeToString(CC);
9675e3ee4b8SRichard Trieu }
9685e3ee4b8SRichard Trieu
printMandatoryRestrictedPredicateOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)9698c865cacSSimon Tatham void ARMInstPrinter::printMandatoryRestrictedPredicateOperand(
9708c865cacSSimon Tatham const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
9718c865cacSSimon Tatham raw_ostream &O) {
9728c865cacSSimon Tatham if ((ARMCC::CondCodes)MI->getOperand(OpNum).getImm() == ARMCC::HS)
9738c865cacSSimon Tatham O << "cs";
9748c865cacSSimon Tatham else
9758c865cacSSimon Tatham printMandatoryPredicateOperand(MI, OpNum, STI, O);
9768c865cacSSimon Tatham }
9778c865cacSSimon Tatham
printMandatoryPredicateOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)9785e3ee4b8SRichard Trieu void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
9795e3ee4b8SRichard Trieu unsigned OpNum,
9805e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
9815e3ee4b8SRichard Trieu raw_ostream &O) {
9825e3ee4b8SRichard Trieu ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
9835e3ee4b8SRichard Trieu O << ARMCondCodeToString(CC);
9845e3ee4b8SRichard Trieu }
9855e3ee4b8SRichard Trieu
printMandatoryInvertedPredicateOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)9868c865cacSSimon Tatham void ARMInstPrinter::printMandatoryInvertedPredicateOperand(const MCInst *MI,
9878c865cacSSimon Tatham unsigned OpNum,
9888c865cacSSimon Tatham const MCSubtargetInfo &STI,
9898c865cacSSimon Tatham raw_ostream &O) {
9908c865cacSSimon Tatham ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
9918c865cacSSimon Tatham O << ARMCondCodeToString(ARMCC::getOppositeCondition(CC));
9928c865cacSSimon Tatham }
9938c865cacSSimon Tatham
printSBitModifierOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)9945e3ee4b8SRichard Trieu void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
9955e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
9965e3ee4b8SRichard Trieu raw_ostream &O) {
9975e3ee4b8SRichard Trieu if (MI->getOperand(OpNum).getReg()) {
9985e3ee4b8SRichard Trieu assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
9995e3ee4b8SRichard Trieu "Expect ARM CPSR register!");
10005e3ee4b8SRichard Trieu O << 's';
10015e3ee4b8SRichard Trieu }
10025e3ee4b8SRichard Trieu }
10035e3ee4b8SRichard Trieu
printNoHashImmediate(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)10045e3ee4b8SRichard Trieu void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
10055e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
10065e3ee4b8SRichard Trieu raw_ostream &O) {
10075e3ee4b8SRichard Trieu O << MI->getOperand(OpNum).getImm();
10085e3ee4b8SRichard Trieu }
10095e3ee4b8SRichard Trieu
printPImmediate(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)10105e3ee4b8SRichard Trieu void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
10115e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
10125e3ee4b8SRichard Trieu raw_ostream &O) {
10135e3ee4b8SRichard Trieu O << "p" << MI->getOperand(OpNum).getImm();
10145e3ee4b8SRichard Trieu }
10155e3ee4b8SRichard Trieu
printCImmediate(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)10165e3ee4b8SRichard Trieu void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
10175e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
10185e3ee4b8SRichard Trieu raw_ostream &O) {
10195e3ee4b8SRichard Trieu O << "c" << MI->getOperand(OpNum).getImm();
10205e3ee4b8SRichard Trieu }
10215e3ee4b8SRichard Trieu
printCoprocOptionImm(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)10225e3ee4b8SRichard Trieu void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum,
10235e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
10245e3ee4b8SRichard Trieu raw_ostream &O) {
10255e3ee4b8SRichard Trieu O << "{" << MI->getOperand(OpNum).getImm() << "}";
10265e3ee4b8SRichard Trieu }
10275e3ee4b8SRichard Trieu
printPCLabel(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)10285e3ee4b8SRichard Trieu void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
10295e3ee4b8SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
10305e3ee4b8SRichard Trieu llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
10315e3ee4b8SRichard Trieu }
10325e3ee4b8SRichard Trieu
10335e3ee4b8SRichard Trieu template <unsigned scale>
printAdrLabelOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)10345e3ee4b8SRichard Trieu void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
10355e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
10365e3ee4b8SRichard Trieu raw_ostream &O) {
10375e3ee4b8SRichard Trieu const MCOperand &MO = MI->getOperand(OpNum);
10385e3ee4b8SRichard Trieu
10395e3ee4b8SRichard Trieu if (MO.isExpr()) {
10405e3ee4b8SRichard Trieu MO.getExpr()->print(O, &MAI);
10415e3ee4b8SRichard Trieu return;
10425e3ee4b8SRichard Trieu }
10435e3ee4b8SRichard Trieu
10445e3ee4b8SRichard Trieu int32_t OffImm = (int32_t)MO.getImm() << scale;
10455e3ee4b8SRichard Trieu
10465e3ee4b8SRichard Trieu O << markup("<imm:");
10475e3ee4b8SRichard Trieu if (OffImm == INT32_MIN)
10485e3ee4b8SRichard Trieu O << "#-0";
10495e3ee4b8SRichard Trieu else if (OffImm < 0)
10505e3ee4b8SRichard Trieu O << "#-" << -OffImm;
10515e3ee4b8SRichard Trieu else
10525e3ee4b8SRichard Trieu O << "#" << OffImm;
10535e3ee4b8SRichard Trieu O << markup(">");
10545e3ee4b8SRichard Trieu }
10555e3ee4b8SRichard Trieu
printThumbS4ImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)10565e3ee4b8SRichard Trieu void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
10575e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
10585e3ee4b8SRichard Trieu raw_ostream &O) {
10595e3ee4b8SRichard Trieu O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4)
10605e3ee4b8SRichard Trieu << markup(">");
10615e3ee4b8SRichard Trieu }
10625e3ee4b8SRichard Trieu
printThumbSRImm(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)10635e3ee4b8SRichard Trieu void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
10645e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
10655e3ee4b8SRichard Trieu raw_ostream &O) {
10665e3ee4b8SRichard Trieu unsigned Imm = MI->getOperand(OpNum).getImm();
10675e3ee4b8SRichard Trieu O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm))
10685e3ee4b8SRichard Trieu << markup(">");
10695e3ee4b8SRichard Trieu }
10705e3ee4b8SRichard Trieu
printThumbITMask(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)10715e3ee4b8SRichard Trieu void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
10725e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
10735e3ee4b8SRichard Trieu raw_ostream &O) {
10745e3ee4b8SRichard Trieu // (3 - the number of trailing zeros) is the number of then / else.
10755e3ee4b8SRichard Trieu unsigned Mask = MI->getOperand(OpNum).getImm();
10765e3ee4b8SRichard Trieu unsigned NumTZ = countTrailingZeros(Mask);
10775e3ee4b8SRichard Trieu assert(NumTZ <= 3 && "Invalid IT mask!");
10785e3ee4b8SRichard Trieu for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
1079848d3d0dSSimon Tatham if ((Mask >> Pos) & 1)
10805e3ee4b8SRichard Trieu O << 'e';
1081848d3d0dSSimon Tatham else
1082848d3d0dSSimon Tatham O << 't';
10835e3ee4b8SRichard Trieu }
10845e3ee4b8SRichard Trieu }
10855e3ee4b8SRichard Trieu
printThumbAddrModeRROperand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)10865e3ee4b8SRichard Trieu void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
10875e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
10885e3ee4b8SRichard Trieu raw_ostream &O) {
10895e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(Op);
10905e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(Op + 1);
10915e3ee4b8SRichard Trieu
10925e3ee4b8SRichard Trieu if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
10935e3ee4b8SRichard Trieu printOperand(MI, Op, STI, O);
10945e3ee4b8SRichard Trieu return;
10955e3ee4b8SRichard Trieu }
10965e3ee4b8SRichard Trieu
10975e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
10985e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
10995e3ee4b8SRichard Trieu if (unsigned RegNum = MO2.getReg()) {
11005e3ee4b8SRichard Trieu O << ", ";
11015e3ee4b8SRichard Trieu printRegName(O, RegNum);
11025e3ee4b8SRichard Trieu }
11035e3ee4b8SRichard Trieu O << "]" << markup(">");
11045e3ee4b8SRichard Trieu }
11055e3ee4b8SRichard Trieu
printThumbAddrModeImm5SOperand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O,unsigned Scale)11065e3ee4b8SRichard Trieu void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI,
11075e3ee4b8SRichard Trieu unsigned Op,
11085e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
11095e3ee4b8SRichard Trieu raw_ostream &O,
11105e3ee4b8SRichard Trieu unsigned Scale) {
11115e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(Op);
11125e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(Op + 1);
11135e3ee4b8SRichard Trieu
11145e3ee4b8SRichard Trieu if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
11155e3ee4b8SRichard Trieu printOperand(MI, Op, STI, O);
11165e3ee4b8SRichard Trieu return;
11175e3ee4b8SRichard Trieu }
11185e3ee4b8SRichard Trieu
11195e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
11205e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
11215e3ee4b8SRichard Trieu if (unsigned ImmOffs = MO2.getImm()) {
11225e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale)
11235e3ee4b8SRichard Trieu << markup(">");
11245e3ee4b8SRichard Trieu }
11255e3ee4b8SRichard Trieu O << "]" << markup(">");
11265e3ee4b8SRichard Trieu }
11275e3ee4b8SRichard Trieu
printThumbAddrModeImm5S1Operand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)11285e3ee4b8SRichard Trieu void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI,
11295e3ee4b8SRichard Trieu unsigned Op,
11305e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
11315e3ee4b8SRichard Trieu raw_ostream &O) {
11325e3ee4b8SRichard Trieu printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1);
11335e3ee4b8SRichard Trieu }
11345e3ee4b8SRichard Trieu
printThumbAddrModeImm5S2Operand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)11355e3ee4b8SRichard Trieu void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI,
11365e3ee4b8SRichard Trieu unsigned Op,
11375e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
11385e3ee4b8SRichard Trieu raw_ostream &O) {
11395e3ee4b8SRichard Trieu printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2);
11405e3ee4b8SRichard Trieu }
11415e3ee4b8SRichard Trieu
printThumbAddrModeImm5S4Operand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)11425e3ee4b8SRichard Trieu void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI,
11435e3ee4b8SRichard Trieu unsigned Op,
11445e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
11455e3ee4b8SRichard Trieu raw_ostream &O) {
11465e3ee4b8SRichard Trieu printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
11475e3ee4b8SRichard Trieu }
11485e3ee4b8SRichard Trieu
printThumbAddrModeSPOperand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)11495e3ee4b8SRichard Trieu void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
11505e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
11515e3ee4b8SRichard Trieu raw_ostream &O) {
11525e3ee4b8SRichard Trieu printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
11535e3ee4b8SRichard Trieu }
11545e3ee4b8SRichard Trieu
11555e3ee4b8SRichard Trieu // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
11565e3ee4b8SRichard Trieu // register with shift forms.
11575e3ee4b8SRichard Trieu // REG 0 0 - e.g. R5
11585e3ee4b8SRichard Trieu // REG IMM, SH_OPC - e.g. R5, LSL #3
printT2SOOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)11595e3ee4b8SRichard Trieu void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
11605e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
11615e3ee4b8SRichard Trieu raw_ostream &O) {
11625e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
11635e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
11645e3ee4b8SRichard Trieu
11655e3ee4b8SRichard Trieu unsigned Reg = MO1.getReg();
11665e3ee4b8SRichard Trieu printRegName(O, Reg);
11675e3ee4b8SRichard Trieu
11685e3ee4b8SRichard Trieu // Print the shift opc.
11695e3ee4b8SRichard Trieu assert(MO2.isImm() && "Not a valid t2_so_reg value!");
11705e3ee4b8SRichard Trieu printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
11715e3ee4b8SRichard Trieu ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
11725e3ee4b8SRichard Trieu }
11735e3ee4b8SRichard Trieu
11745e3ee4b8SRichard Trieu template <bool AlwaysPrintImm0>
printAddrModeImm12Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)11755e3ee4b8SRichard Trieu void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
11765e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
11775e3ee4b8SRichard Trieu raw_ostream &O) {
11785e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
11795e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
11805e3ee4b8SRichard Trieu
11815e3ee4b8SRichard Trieu if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
11825e3ee4b8SRichard Trieu printOperand(MI, OpNum, STI, O);
11835e3ee4b8SRichard Trieu return;
11845e3ee4b8SRichard Trieu }
11855e3ee4b8SRichard Trieu
11865e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
11875e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
11885e3ee4b8SRichard Trieu
11895e3ee4b8SRichard Trieu int32_t OffImm = (int32_t)MO2.getImm();
11905e3ee4b8SRichard Trieu bool isSub = OffImm < 0;
11915e3ee4b8SRichard Trieu // Special value for #-0. All others are normal.
11925e3ee4b8SRichard Trieu if (OffImm == INT32_MIN)
11935e3ee4b8SRichard Trieu OffImm = 0;
11945e3ee4b8SRichard Trieu if (isSub) {
11955e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
11965e3ee4b8SRichard Trieu } else if (AlwaysPrintImm0 || OffImm > 0) {
11975e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
11985e3ee4b8SRichard Trieu }
11995e3ee4b8SRichard Trieu O << "]" << markup(">");
12005e3ee4b8SRichard Trieu }
12015e3ee4b8SRichard Trieu
12025e3ee4b8SRichard Trieu template <bool AlwaysPrintImm0>
printT2AddrModeImm8Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)12035e3ee4b8SRichard Trieu void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
12045e3ee4b8SRichard Trieu unsigned OpNum,
12055e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
12065e3ee4b8SRichard Trieu raw_ostream &O) {
12075e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
12085e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
12095e3ee4b8SRichard Trieu
12105e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
12115e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
12125e3ee4b8SRichard Trieu
12135e3ee4b8SRichard Trieu int32_t OffImm = (int32_t)MO2.getImm();
12145e3ee4b8SRichard Trieu bool isSub = OffImm < 0;
12155e3ee4b8SRichard Trieu // Don't print +0.
12165e3ee4b8SRichard Trieu if (OffImm == INT32_MIN)
12175e3ee4b8SRichard Trieu OffImm = 0;
12185e3ee4b8SRichard Trieu if (isSub) {
12195e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
12205e3ee4b8SRichard Trieu } else if (AlwaysPrintImm0 || OffImm > 0) {
12215e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
12225e3ee4b8SRichard Trieu }
12235e3ee4b8SRichard Trieu O << "]" << markup(">");
12245e3ee4b8SRichard Trieu }
12255e3ee4b8SRichard Trieu
12265e3ee4b8SRichard Trieu template <bool AlwaysPrintImm0>
printT2AddrModeImm8s4Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)12275e3ee4b8SRichard Trieu void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
12285e3ee4b8SRichard Trieu unsigned OpNum,
12295e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
12305e3ee4b8SRichard Trieu raw_ostream &O) {
12315e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
12325e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
12335e3ee4b8SRichard Trieu
12345e3ee4b8SRichard Trieu if (!MO1.isReg()) { // For label symbolic references.
12355e3ee4b8SRichard Trieu printOperand(MI, OpNum, STI, O);
12365e3ee4b8SRichard Trieu return;
12375e3ee4b8SRichard Trieu }
12385e3ee4b8SRichard Trieu
12395e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
12405e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
12415e3ee4b8SRichard Trieu
12425e3ee4b8SRichard Trieu int32_t OffImm = (int32_t)MO2.getImm();
12435e3ee4b8SRichard Trieu bool isSub = OffImm < 0;
12445e3ee4b8SRichard Trieu
12455e3ee4b8SRichard Trieu assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
12465e3ee4b8SRichard Trieu
12475e3ee4b8SRichard Trieu // Don't print +0.
12485e3ee4b8SRichard Trieu if (OffImm == INT32_MIN)
12495e3ee4b8SRichard Trieu OffImm = 0;
12505e3ee4b8SRichard Trieu if (isSub) {
12515e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
12525e3ee4b8SRichard Trieu } else if (AlwaysPrintImm0 || OffImm > 0) {
12535e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
12545e3ee4b8SRichard Trieu }
12555e3ee4b8SRichard Trieu O << "]" << markup(">");
12565e3ee4b8SRichard Trieu }
12575e3ee4b8SRichard Trieu
printT2AddrModeImm0_1020s4Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)12585e3ee4b8SRichard Trieu void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(
12595e3ee4b8SRichard Trieu const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
12605e3ee4b8SRichard Trieu raw_ostream &O) {
12615e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
12625e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
12635e3ee4b8SRichard Trieu
12645e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
12655e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
12665e3ee4b8SRichard Trieu if (MO2.getImm()) {
12675e3ee4b8SRichard Trieu O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4)
12685e3ee4b8SRichard Trieu << markup(">");
12695e3ee4b8SRichard Trieu }
12705e3ee4b8SRichard Trieu O << "]" << markup(">");
12715e3ee4b8SRichard Trieu }
12725e3ee4b8SRichard Trieu
printT2AddrModeImm8OffsetOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)12735e3ee4b8SRichard Trieu void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(
12745e3ee4b8SRichard Trieu const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
12755e3ee4b8SRichard Trieu raw_ostream &O) {
12765e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
12775e3ee4b8SRichard Trieu int32_t OffImm = (int32_t)MO1.getImm();
12785e3ee4b8SRichard Trieu O << ", " << markup("<imm:");
12795e3ee4b8SRichard Trieu if (OffImm == INT32_MIN)
12805e3ee4b8SRichard Trieu O << "#-0";
12815e3ee4b8SRichard Trieu else if (OffImm < 0)
12825e3ee4b8SRichard Trieu O << "#-" << -OffImm;
12835e3ee4b8SRichard Trieu else
12845e3ee4b8SRichard Trieu O << "#" << OffImm;
12855e3ee4b8SRichard Trieu O << markup(">");
12865e3ee4b8SRichard Trieu }
12875e3ee4b8SRichard Trieu
printT2AddrModeImm8s4OffsetOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)12885e3ee4b8SRichard Trieu void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(
12895e3ee4b8SRichard Trieu const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
12905e3ee4b8SRichard Trieu raw_ostream &O) {
12915e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
12925e3ee4b8SRichard Trieu int32_t OffImm = (int32_t)MO1.getImm();
12935e3ee4b8SRichard Trieu
12945e3ee4b8SRichard Trieu assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
12955e3ee4b8SRichard Trieu
12965e3ee4b8SRichard Trieu O << ", " << markup("<imm:");
12975e3ee4b8SRichard Trieu if (OffImm == INT32_MIN)
12985e3ee4b8SRichard Trieu O << "#-0";
12995e3ee4b8SRichard Trieu else if (OffImm < 0)
13005e3ee4b8SRichard Trieu O << "#-" << -OffImm;
13015e3ee4b8SRichard Trieu else
13025e3ee4b8SRichard Trieu O << "#" << OffImm;
13035e3ee4b8SRichard Trieu O << markup(">");
13045e3ee4b8SRichard Trieu }
13055e3ee4b8SRichard Trieu
printT2AddrModeSoRegOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)13065e3ee4b8SRichard Trieu void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
13075e3ee4b8SRichard Trieu unsigned OpNum,
13085e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
13095e3ee4b8SRichard Trieu raw_ostream &O) {
13105e3ee4b8SRichard Trieu const MCOperand &MO1 = MI->getOperand(OpNum);
13115e3ee4b8SRichard Trieu const MCOperand &MO2 = MI->getOperand(OpNum + 1);
13125e3ee4b8SRichard Trieu const MCOperand &MO3 = MI->getOperand(OpNum + 2);
13135e3ee4b8SRichard Trieu
13145e3ee4b8SRichard Trieu O << markup("<mem:") << "[";
13155e3ee4b8SRichard Trieu printRegName(O, MO1.getReg());
13165e3ee4b8SRichard Trieu
13175e3ee4b8SRichard Trieu assert(MO2.getReg() && "Invalid so_reg load / store address!");
13185e3ee4b8SRichard Trieu O << ", ";
13195e3ee4b8SRichard Trieu printRegName(O, MO2.getReg());
13205e3ee4b8SRichard Trieu
13215e3ee4b8SRichard Trieu unsigned ShAmt = MO3.getImm();
13225e3ee4b8SRichard Trieu if (ShAmt) {
13235e3ee4b8SRichard Trieu assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
13245e3ee4b8SRichard Trieu O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">");
13255e3ee4b8SRichard Trieu }
13265e3ee4b8SRichard Trieu O << "]" << markup(">");
13275e3ee4b8SRichard Trieu }
13285e3ee4b8SRichard Trieu
printFPImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)13295e3ee4b8SRichard Trieu void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
13305e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
13315e3ee4b8SRichard Trieu raw_ostream &O) {
13325e3ee4b8SRichard Trieu const MCOperand &MO = MI->getOperand(OpNum);
13335e3ee4b8SRichard Trieu O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm())
13345e3ee4b8SRichard Trieu << markup(">");
13355e3ee4b8SRichard Trieu }
13365e3ee4b8SRichard Trieu
printVMOVModImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1337fdedf240SDavid Green void ARMInstPrinter::printVMOVModImmOperand(const MCInst *MI, unsigned OpNum,
13385e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
13395e3ee4b8SRichard Trieu raw_ostream &O) {
13405e3ee4b8SRichard Trieu unsigned EncodedImm = MI->getOperand(OpNum).getImm();
13415e3ee4b8SRichard Trieu unsigned EltBits;
1342fdedf240SDavid Green uint64_t Val = ARM_AM::decodeVMOVModImm(EncodedImm, EltBits);
13435e3ee4b8SRichard Trieu O << markup("<imm:") << "#0x";
13445e3ee4b8SRichard Trieu O.write_hex(Val);
13455e3ee4b8SRichard Trieu O << markup(">");
13465e3ee4b8SRichard Trieu }
13475e3ee4b8SRichard Trieu
printImmPlusOneOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)13485e3ee4b8SRichard Trieu void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
13495e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
13505e3ee4b8SRichard Trieu raw_ostream &O) {
13515e3ee4b8SRichard Trieu unsigned Imm = MI->getOperand(OpNum).getImm();
13525e3ee4b8SRichard Trieu O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">");
13535e3ee4b8SRichard Trieu }
13545e3ee4b8SRichard Trieu
printRotImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)13555e3ee4b8SRichard Trieu void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
13565e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
13575e3ee4b8SRichard Trieu raw_ostream &O) {
13585e3ee4b8SRichard Trieu unsigned Imm = MI->getOperand(OpNum).getImm();
13595e3ee4b8SRichard Trieu if (Imm == 0)
13605e3ee4b8SRichard Trieu return;
13615e3ee4b8SRichard Trieu assert(Imm <= 3 && "illegal ror immediate!");
13625e3ee4b8SRichard Trieu O << ", ror " << markup("<imm:") << "#" << 8 * Imm << markup(">");
13635e3ee4b8SRichard Trieu }
13645e3ee4b8SRichard Trieu
printModImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)13655e3ee4b8SRichard Trieu void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum,
13665e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
13675e3ee4b8SRichard Trieu raw_ostream &O) {
13685e3ee4b8SRichard Trieu MCOperand Op = MI->getOperand(OpNum);
13695e3ee4b8SRichard Trieu
13705e3ee4b8SRichard Trieu // Support for fixups (MCFixup)
13715e3ee4b8SRichard Trieu if (Op.isExpr())
13725e3ee4b8SRichard Trieu return printOperand(MI, OpNum, STI, O);
13735e3ee4b8SRichard Trieu
13745e3ee4b8SRichard Trieu unsigned Bits = Op.getImm() & 0xFF;
13755e3ee4b8SRichard Trieu unsigned Rot = (Op.getImm() & 0xF00) >> 7;
13765e3ee4b8SRichard Trieu
13775e3ee4b8SRichard Trieu bool PrintUnsigned = false;
13785e3ee4b8SRichard Trieu switch (MI->getOpcode()) {
13795e3ee4b8SRichard Trieu case ARM::MOVi:
13805e3ee4b8SRichard Trieu // Movs to PC should be treated unsigned
13815e3ee4b8SRichard Trieu PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC);
13825e3ee4b8SRichard Trieu break;
13835e3ee4b8SRichard Trieu case ARM::MSRi:
13845e3ee4b8SRichard Trieu // Movs to special registers should be treated unsigned
13855e3ee4b8SRichard Trieu PrintUnsigned = true;
13865e3ee4b8SRichard Trieu break;
13875e3ee4b8SRichard Trieu }
13885e3ee4b8SRichard Trieu
13895e3ee4b8SRichard Trieu int32_t Rotated = ARM_AM::rotr32(Bits, Rot);
13905e3ee4b8SRichard Trieu if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) {
13915e3ee4b8SRichard Trieu // #rot has the least possible value
13925e3ee4b8SRichard Trieu O << "#" << markup("<imm:");
13935e3ee4b8SRichard Trieu if (PrintUnsigned)
13945e3ee4b8SRichard Trieu O << static_cast<uint32_t>(Rotated);
13955e3ee4b8SRichard Trieu else
13965e3ee4b8SRichard Trieu O << Rotated;
13975e3ee4b8SRichard Trieu O << markup(">");
13985e3ee4b8SRichard Trieu return;
13995e3ee4b8SRichard Trieu }
14005e3ee4b8SRichard Trieu
14015e3ee4b8SRichard Trieu // Explicit #bits, #rot implied
14025e3ee4b8SRichard Trieu O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:")
14035e3ee4b8SRichard Trieu << Rot << markup(">");
14045e3ee4b8SRichard Trieu }
14055e3ee4b8SRichard Trieu
printFBits16(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)14065e3ee4b8SRichard Trieu void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
14075e3ee4b8SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
14085e3ee4b8SRichard Trieu O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm()
14095e3ee4b8SRichard Trieu << markup(">");
14105e3ee4b8SRichard Trieu }
14115e3ee4b8SRichard Trieu
printFBits32(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)14125e3ee4b8SRichard Trieu void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum,
14135e3ee4b8SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
14145e3ee4b8SRichard Trieu O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm()
14155e3ee4b8SRichard Trieu << markup(">");
14165e3ee4b8SRichard Trieu }
14175e3ee4b8SRichard Trieu
printVectorIndex(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)14185e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
14195e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
14205e3ee4b8SRichard Trieu raw_ostream &O) {
14215e3ee4b8SRichard Trieu O << "[" << MI->getOperand(OpNum).getImm() << "]";
14225e3ee4b8SRichard Trieu }
14235e3ee4b8SRichard Trieu
printVectorListOne(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)14245e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
14255e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
14265e3ee4b8SRichard Trieu raw_ostream &O) {
14275e3ee4b8SRichard Trieu O << "{";
14285e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg());
14295e3ee4b8SRichard Trieu O << "}";
14305e3ee4b8SRichard Trieu }
14315e3ee4b8SRichard Trieu
printVectorListTwo(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)14325e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
14335e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
14345e3ee4b8SRichard Trieu raw_ostream &O) {
14355e3ee4b8SRichard Trieu unsigned Reg = MI->getOperand(OpNum).getReg();
14365e3ee4b8SRichard Trieu unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
14375e3ee4b8SRichard Trieu unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
14385e3ee4b8SRichard Trieu O << "{";
14395e3ee4b8SRichard Trieu printRegName(O, Reg0);
14405e3ee4b8SRichard Trieu O << ", ";
14415e3ee4b8SRichard Trieu printRegName(O, Reg1);
14425e3ee4b8SRichard Trieu O << "}";
14435e3ee4b8SRichard Trieu }
14445e3ee4b8SRichard Trieu
printVectorListTwoSpaced(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)14455e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum,
14465e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
14475e3ee4b8SRichard Trieu raw_ostream &O) {
14485e3ee4b8SRichard Trieu unsigned Reg = MI->getOperand(OpNum).getReg();
14495e3ee4b8SRichard Trieu unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
14505e3ee4b8SRichard Trieu unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
14515e3ee4b8SRichard Trieu O << "{";
14525e3ee4b8SRichard Trieu printRegName(O, Reg0);
14535e3ee4b8SRichard Trieu O << ", ";
14545e3ee4b8SRichard Trieu printRegName(O, Reg1);
14555e3ee4b8SRichard Trieu O << "}";
14565e3ee4b8SRichard Trieu }
14575e3ee4b8SRichard Trieu
printVectorListThree(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)14585e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum,
14595e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
14605e3ee4b8SRichard Trieu raw_ostream &O) {
14615e3ee4b8SRichard Trieu // Normally, it's not safe to use register enum values directly with
14625e3ee4b8SRichard Trieu // addition to get the next register, but for VFP registers, the
14635e3ee4b8SRichard Trieu // sort order is guaranteed because they're all of the form D<n>.
14645e3ee4b8SRichard Trieu O << "{";
14655e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg());
14665e3ee4b8SRichard Trieu O << ", ";
14675e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 1);
14685e3ee4b8SRichard Trieu O << ", ";
14695e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 2);
14705e3ee4b8SRichard Trieu O << "}";
14715e3ee4b8SRichard Trieu }
14725e3ee4b8SRichard Trieu
printVectorListFour(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)14735e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum,
14745e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
14755e3ee4b8SRichard Trieu raw_ostream &O) {
14765e3ee4b8SRichard Trieu // Normally, it's not safe to use register enum values directly with
14775e3ee4b8SRichard Trieu // addition to get the next register, but for VFP registers, the
14785e3ee4b8SRichard Trieu // sort order is guaranteed because they're all of the form D<n>.
14795e3ee4b8SRichard Trieu O << "{";
14805e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg());
14815e3ee4b8SRichard Trieu O << ", ";
14825e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 1);
14835e3ee4b8SRichard Trieu O << ", ";
14845e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 2);
14855e3ee4b8SRichard Trieu O << ", ";
14865e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 3);
14875e3ee4b8SRichard Trieu O << "}";
14885e3ee4b8SRichard Trieu }
14895e3ee4b8SRichard Trieu
printVectorListOneAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)14905e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI,
14915e3ee4b8SRichard Trieu unsigned OpNum,
14925e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
14935e3ee4b8SRichard Trieu raw_ostream &O) {
14945e3ee4b8SRichard Trieu O << "{";
14955e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg());
14965e3ee4b8SRichard Trieu O << "[]}";
14975e3ee4b8SRichard Trieu }
14985e3ee4b8SRichard Trieu
printVectorListTwoAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)14995e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI,
15005e3ee4b8SRichard Trieu unsigned OpNum,
15015e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
15025e3ee4b8SRichard Trieu raw_ostream &O) {
15035e3ee4b8SRichard Trieu unsigned Reg = MI->getOperand(OpNum).getReg();
15045e3ee4b8SRichard Trieu unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
15055e3ee4b8SRichard Trieu unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
15065e3ee4b8SRichard Trieu O << "{";
15075e3ee4b8SRichard Trieu printRegName(O, Reg0);
15085e3ee4b8SRichard Trieu O << "[], ";
15095e3ee4b8SRichard Trieu printRegName(O, Reg1);
15105e3ee4b8SRichard Trieu O << "[]}";
15115e3ee4b8SRichard Trieu }
15125e3ee4b8SRichard Trieu
printVectorListThreeAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)15135e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI,
15145e3ee4b8SRichard Trieu unsigned OpNum,
15155e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
15165e3ee4b8SRichard Trieu raw_ostream &O) {
15175e3ee4b8SRichard Trieu // Normally, it's not safe to use register enum values directly with
15185e3ee4b8SRichard Trieu // addition to get the next register, but for VFP registers, the
15195e3ee4b8SRichard Trieu // sort order is guaranteed because they're all of the form D<n>.
15205e3ee4b8SRichard Trieu O << "{";
15215e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg());
15225e3ee4b8SRichard Trieu O << "[], ";
15235e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 1);
15245e3ee4b8SRichard Trieu O << "[], ";
15255e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 2);
15265e3ee4b8SRichard Trieu O << "[]}";
15275e3ee4b8SRichard Trieu }
15285e3ee4b8SRichard Trieu
printVectorListFourAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)15295e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
15305e3ee4b8SRichard Trieu unsigned OpNum,
15315e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
15325e3ee4b8SRichard Trieu raw_ostream &O) {
15335e3ee4b8SRichard Trieu // Normally, it's not safe to use register enum values directly with
15345e3ee4b8SRichard Trieu // addition to get the next register, but for VFP registers, the
15355e3ee4b8SRichard Trieu // sort order is guaranteed because they're all of the form D<n>.
15365e3ee4b8SRichard Trieu O << "{";
15375e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg());
15385e3ee4b8SRichard Trieu O << "[], ";
15395e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 1);
15405e3ee4b8SRichard Trieu O << "[], ";
15415e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 2);
15425e3ee4b8SRichard Trieu O << "[], ";
15435e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 3);
15445e3ee4b8SRichard Trieu O << "[]}";
15455e3ee4b8SRichard Trieu }
15465e3ee4b8SRichard Trieu
printVectorListTwoSpacedAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)15475e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListTwoSpacedAllLanes(
15485e3ee4b8SRichard Trieu const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
15495e3ee4b8SRichard Trieu raw_ostream &O) {
15505e3ee4b8SRichard Trieu unsigned Reg = MI->getOperand(OpNum).getReg();
15515e3ee4b8SRichard Trieu unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
15525e3ee4b8SRichard Trieu unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
15535e3ee4b8SRichard Trieu O << "{";
15545e3ee4b8SRichard Trieu printRegName(O, Reg0);
15555e3ee4b8SRichard Trieu O << "[], ";
15565e3ee4b8SRichard Trieu printRegName(O, Reg1);
15575e3ee4b8SRichard Trieu O << "[]}";
15585e3ee4b8SRichard Trieu }
15595e3ee4b8SRichard Trieu
printVectorListThreeSpacedAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)15605e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListThreeSpacedAllLanes(
15615e3ee4b8SRichard Trieu const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
15625e3ee4b8SRichard Trieu raw_ostream &O) {
15635e3ee4b8SRichard Trieu // Normally, it's not safe to use register enum values directly with
15645e3ee4b8SRichard Trieu // addition to get the next register, but for VFP registers, the
15655e3ee4b8SRichard Trieu // sort order is guaranteed because they're all of the form D<n>.
15665e3ee4b8SRichard Trieu O << "{";
15675e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg());
15685e3ee4b8SRichard Trieu O << "[], ";
15695e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 2);
15705e3ee4b8SRichard Trieu O << "[], ";
15715e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 4);
15725e3ee4b8SRichard Trieu O << "[]}";
15735e3ee4b8SRichard Trieu }
15745e3ee4b8SRichard Trieu
printVectorListFourSpacedAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)15755e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListFourSpacedAllLanes(
15765e3ee4b8SRichard Trieu const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
15775e3ee4b8SRichard Trieu raw_ostream &O) {
15785e3ee4b8SRichard Trieu // Normally, it's not safe to use register enum values directly with
15795e3ee4b8SRichard Trieu // addition to get the next register, but for VFP registers, the
15805e3ee4b8SRichard Trieu // sort order is guaranteed because they're all of the form D<n>.
15815e3ee4b8SRichard Trieu O << "{";
15825e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg());
15835e3ee4b8SRichard Trieu O << "[], ";
15845e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 2);
15855e3ee4b8SRichard Trieu O << "[], ";
15865e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 4);
15875e3ee4b8SRichard Trieu O << "[], ";
15885e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 6);
15895e3ee4b8SRichard Trieu O << "[]}";
15905e3ee4b8SRichard Trieu }
15915e3ee4b8SRichard Trieu
printVectorListThreeSpaced(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)15925e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI,
15935e3ee4b8SRichard Trieu unsigned OpNum,
15945e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
15955e3ee4b8SRichard Trieu raw_ostream &O) {
15965e3ee4b8SRichard Trieu // Normally, it's not safe to use register enum values directly with
15975e3ee4b8SRichard Trieu // addition to get the next register, but for VFP registers, the
15985e3ee4b8SRichard Trieu // sort order is guaranteed because they're all of the form D<n>.
15995e3ee4b8SRichard Trieu O << "{";
16005e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg());
16015e3ee4b8SRichard Trieu O << ", ";
16025e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 2);
16035e3ee4b8SRichard Trieu O << ", ";
16045e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 4);
16055e3ee4b8SRichard Trieu O << "}";
16065e3ee4b8SRichard Trieu }
16075e3ee4b8SRichard Trieu
printVectorListFourSpaced(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)16085e3ee4b8SRichard Trieu void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, unsigned OpNum,
16095e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
16105e3ee4b8SRichard Trieu raw_ostream &O) {
16115e3ee4b8SRichard Trieu // Normally, it's not safe to use register enum values directly with
16125e3ee4b8SRichard Trieu // addition to get the next register, but for VFP registers, the
16135e3ee4b8SRichard Trieu // sort order is guaranteed because they're all of the form D<n>.
16145e3ee4b8SRichard Trieu O << "{";
16155e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg());
16165e3ee4b8SRichard Trieu O << ", ";
16175e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 2);
16185e3ee4b8SRichard Trieu O << ", ";
16195e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 4);
16205e3ee4b8SRichard Trieu O << ", ";
16215e3ee4b8SRichard Trieu printRegName(O, MI->getOperand(OpNum).getReg() + 6);
16225e3ee4b8SRichard Trieu O << "}";
16235e3ee4b8SRichard Trieu }
16245e3ee4b8SRichard Trieu
1625fe801762SSimon Tatham template<unsigned NumRegs>
printMVEVectorList(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1626fe801762SSimon Tatham void ARMInstPrinter::printMVEVectorList(const MCInst *MI, unsigned OpNum,
1627fe801762SSimon Tatham const MCSubtargetInfo &STI,
1628fe801762SSimon Tatham raw_ostream &O) {
1629fe801762SSimon Tatham unsigned Reg = MI->getOperand(OpNum).getReg();
1630fe801762SSimon Tatham const char *Prefix = "{";
1631fe801762SSimon Tatham for (unsigned i = 0; i < NumRegs; i++) {
1632fe801762SSimon Tatham O << Prefix;
1633fe801762SSimon Tatham printRegName(O, MRI.getSubReg(Reg, ARM::qsub_0 + i));
1634fe801762SSimon Tatham Prefix = ", ";
1635fe801762SSimon Tatham }
1636fe801762SSimon Tatham O << "}";
1637fe801762SSimon Tatham }
1638fe801762SSimon Tatham
16395e3ee4b8SRichard Trieu template<int64_t Angle, int64_t Remainder>
printComplexRotationOp(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)16405e3ee4b8SRichard Trieu void ARMInstPrinter::printComplexRotationOp(const MCInst *MI, unsigned OpNo,
16415e3ee4b8SRichard Trieu const MCSubtargetInfo &STI,
16425e3ee4b8SRichard Trieu raw_ostream &O) {
16435e3ee4b8SRichard Trieu unsigned Val = MI->getOperand(OpNo).getImm();
16445e3ee4b8SRichard Trieu O << "#" << (Val * Angle) + Remainder;
16455e3ee4b8SRichard Trieu }
16465e3ee4b8SRichard Trieu
printVPTPredicateOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1647286e1d2cSSimon Tatham void ARMInstPrinter::printVPTPredicateOperand(const MCInst *MI, unsigned OpNum,
1648286e1d2cSSimon Tatham const MCSubtargetInfo &STI,
1649286e1d2cSSimon Tatham raw_ostream &O) {
1650286e1d2cSSimon Tatham ARMVCC::VPTCodes CC = (ARMVCC::VPTCodes)MI->getOperand(OpNum).getImm();
1651286e1d2cSSimon Tatham if (CC != ARMVCC::None)
1652286e1d2cSSimon Tatham O << ARMVPTPredToString(CC);
1653286e1d2cSSimon Tatham }
1654286e1d2cSSimon Tatham
printVPTMask(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1655286e1d2cSSimon Tatham void ARMInstPrinter::printVPTMask(const MCInst *MI, unsigned OpNum,
1656286e1d2cSSimon Tatham const MCSubtargetInfo &STI,
1657286e1d2cSSimon Tatham raw_ostream &O) {
1658286e1d2cSSimon Tatham // (3 - the number of trailing zeroes) is the number of them / else.
1659286e1d2cSSimon Tatham unsigned Mask = MI->getOperand(OpNum).getImm();
1660286e1d2cSSimon Tatham unsigned NumTZ = countTrailingZeros(Mask);
1661286e1d2cSSimon Tatham assert(NumTZ <= 3 && "Invalid VPT mask!");
1662286e1d2cSSimon Tatham for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
1663286e1d2cSSimon Tatham bool T = ((Mask >> Pos) & 1) == 0;
1664286e1d2cSSimon Tatham if (T)
1665286e1d2cSSimon Tatham O << 't';
1666286e1d2cSSimon Tatham else
1667286e1d2cSSimon Tatham O << 'e';
1668286e1d2cSSimon Tatham }
1669286e1d2cSSimon Tatham }
1670286e1d2cSSimon Tatham
printMveSaturateOp(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)16710b001f94SMikhail Maltsev void ARMInstPrinter::printMveSaturateOp(const MCInst *MI, unsigned OpNum,
16720b001f94SMikhail Maltsev const MCSubtargetInfo &STI,
16730b001f94SMikhail Maltsev raw_ostream &O) {
16740b001f94SMikhail Maltsev uint32_t Val = MI->getOperand(OpNum).getImm();
16750b001f94SMikhail Maltsev assert(Val <= 1 && "Invalid MVE saturate operand");
16760b001f94SMikhail Maltsev O << "#" << (Val == 1 ? 48 : 64);
16770b001f94SMikhail Maltsev }
1678