LLVM API Documentation
00001 //==-- AArch64InstPrinter.cpp - Convert AArch64 MCInst to assembly syntax --==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This class prints an AArch64 MCInst to a .s file. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "AArch64InstPrinter.h" 00015 #include "MCTargetDesc/AArch64AddressingModes.h" 00016 #include "Utils/AArch64BaseInfo.h" 00017 #include "llvm/ADT/STLExtras.h" 00018 #include "llvm/ADT/StringExtras.h" 00019 #include "llvm/MC/MCExpr.h" 00020 #include "llvm/MC/MCInst.h" 00021 #include "llvm/MC/MCRegisterInfo.h" 00022 #include "llvm/Support/Format.h" 00023 #include "llvm/Support/raw_ostream.h" 00024 using namespace llvm; 00025 00026 #define DEBUG_TYPE "asm-printer" 00027 00028 #define GET_INSTRUCTION_NAME 00029 #define PRINT_ALIAS_INSTR 00030 #include "AArch64GenAsmWriter.inc" 00031 #define GET_INSTRUCTION_NAME 00032 #define PRINT_ALIAS_INSTR 00033 #include "AArch64GenAsmWriter1.inc" 00034 00035 AArch64InstPrinter::AArch64InstPrinter(const MCAsmInfo &MAI, 00036 const MCInstrInfo &MII, 00037 const MCRegisterInfo &MRI, 00038 const MCSubtargetInfo &STI) 00039 : MCInstPrinter(MAI, MII, MRI) { 00040 // Initialize the set of available features. 00041 setAvailableFeatures(STI.getFeatureBits()); 00042 } 00043 00044 AArch64AppleInstPrinter::AArch64AppleInstPrinter(const MCAsmInfo &MAI, 00045 const MCInstrInfo &MII, 00046 const MCRegisterInfo &MRI, 00047 const MCSubtargetInfo &STI) 00048 : AArch64InstPrinter(MAI, MII, MRI, STI) {} 00049 00050 void AArch64InstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 00051 // This is for .cfi directives. 00052 OS << getRegisterName(RegNo); 00053 } 00054 00055 void AArch64InstPrinter::printInst(const MCInst *MI, raw_ostream &O, 00056 StringRef Annot) { 00057 // Check for special encodings and print the canonical alias instead. 00058 00059 unsigned Opcode = MI->getOpcode(); 00060 00061 if (Opcode == AArch64::SYSxt) 00062 if (printSysAlias(MI, O)) { 00063 printAnnotation(O, Annot); 00064 return; 00065 } 00066 00067 // SBFM/UBFM should print to a nicer aliased form if possible. 00068 if (Opcode == AArch64::SBFMXri || Opcode == AArch64::SBFMWri || 00069 Opcode == AArch64::UBFMXri || Opcode == AArch64::UBFMWri) { 00070 const MCOperand &Op0 = MI->getOperand(0); 00071 const MCOperand &Op1 = MI->getOperand(1); 00072 const MCOperand &Op2 = MI->getOperand(2); 00073 const MCOperand &Op3 = MI->getOperand(3); 00074 00075 bool IsSigned = (Opcode == AArch64::SBFMXri || Opcode == AArch64::SBFMWri); 00076 bool Is64Bit = (Opcode == AArch64::SBFMXri || Opcode == AArch64::UBFMXri); 00077 if (Op2.isImm() && Op2.getImm() == 0 && Op3.isImm()) { 00078 const char *AsmMnemonic = nullptr; 00079 00080 switch (Op3.getImm()) { 00081 default: 00082 break; 00083 case 7: 00084 if (IsSigned) 00085 AsmMnemonic = "sxtb"; 00086 else if (!Is64Bit) 00087 AsmMnemonic = "uxtb"; 00088 break; 00089 case 15: 00090 if (IsSigned) 00091 AsmMnemonic = "sxth"; 00092 else if (!Is64Bit) 00093 AsmMnemonic = "uxth"; 00094 break; 00095 case 31: 00096 // *xtw is only valid for signed 64-bit operations. 00097 if (Is64Bit && IsSigned) 00098 AsmMnemonic = "sxtw"; 00099 break; 00100 } 00101 00102 if (AsmMnemonic) { 00103 O << '\t' << AsmMnemonic << '\t' << getRegisterName(Op0.getReg()) 00104 << ", " << getRegisterName(getWRegFromXReg(Op1.getReg())); 00105 printAnnotation(O, Annot); 00106 return; 00107 } 00108 } 00109 00110 // All immediate shifts are aliases, implemented using the Bitfield 00111 // instruction. In all cases the immediate shift amount shift must be in 00112 // the range 0 to (reg.size -1). 00113 if (Op2.isImm() && Op3.isImm()) { 00114 const char *AsmMnemonic = nullptr; 00115 int shift = 0; 00116 int64_t immr = Op2.getImm(); 00117 int64_t imms = Op3.getImm(); 00118 if (Opcode == AArch64::UBFMWri && imms != 0x1F && ((imms + 1) == immr)) { 00119 AsmMnemonic = "lsl"; 00120 shift = 31 - imms; 00121 } else if (Opcode == AArch64::UBFMXri && imms != 0x3f && 00122 ((imms + 1 == immr))) { 00123 AsmMnemonic = "lsl"; 00124 shift = 63 - imms; 00125 } else if (Opcode == AArch64::UBFMWri && imms == 0x1f) { 00126 AsmMnemonic = "lsr"; 00127 shift = immr; 00128 } else if (Opcode == AArch64::UBFMXri && imms == 0x3f) { 00129 AsmMnemonic = "lsr"; 00130 shift = immr; 00131 } else if (Opcode == AArch64::SBFMWri && imms == 0x1f) { 00132 AsmMnemonic = "asr"; 00133 shift = immr; 00134 } else if (Opcode == AArch64::SBFMXri && imms == 0x3f) { 00135 AsmMnemonic = "asr"; 00136 shift = immr; 00137 } 00138 if (AsmMnemonic) { 00139 O << '\t' << AsmMnemonic << '\t' << getRegisterName(Op0.getReg()) 00140 << ", " << getRegisterName(Op1.getReg()) << ", #" << shift; 00141 printAnnotation(O, Annot); 00142 return; 00143 } 00144 } 00145 00146 // SBFIZ/UBFIZ aliases 00147 if (Op2.getImm() > Op3.getImm()) { 00148 O << '\t' << (IsSigned ? "sbfiz" : "ubfiz") << '\t' 00149 << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op1.getReg()) 00150 << ", #" << (Is64Bit ? 64 : 32) - Op2.getImm() << ", #" << Op3.getImm() + 1; 00151 printAnnotation(O, Annot); 00152 return; 00153 } 00154 00155 // Otherwise SBFX/UBFX is the preferred form 00156 O << '\t' << (IsSigned ? "sbfx" : "ubfx") << '\t' 00157 << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op1.getReg()) 00158 << ", #" << Op2.getImm() << ", #" << Op3.getImm() - Op2.getImm() + 1; 00159 printAnnotation(O, Annot); 00160 return; 00161 } 00162 00163 if (Opcode == AArch64::BFMXri || Opcode == AArch64::BFMWri) { 00164 const MCOperand &Op0 = MI->getOperand(0); // Op1 == Op0 00165 const MCOperand &Op2 = MI->getOperand(2); 00166 int ImmR = MI->getOperand(3).getImm(); 00167 int ImmS = MI->getOperand(4).getImm(); 00168 00169 // BFI alias 00170 if (ImmS < ImmR) { 00171 int BitWidth = Opcode == AArch64::BFMXri ? 64 : 32; 00172 int LSB = (BitWidth - ImmR) % BitWidth; 00173 int Width = ImmS + 1; 00174 O << "\tbfi\t" << getRegisterName(Op0.getReg()) << ", " 00175 << getRegisterName(Op2.getReg()) << ", #" << LSB << ", #" << Width; 00176 printAnnotation(O, Annot); 00177 return; 00178 } 00179 00180 int LSB = ImmR; 00181 int Width = ImmS - ImmR + 1; 00182 // Otherwise BFXIL the preferred form 00183 O << "\tbfxil\t" 00184 << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op2.getReg()) 00185 << ", #" << LSB << ", #" << Width; 00186 printAnnotation(O, Annot); 00187 return; 00188 } 00189 00190 // Symbolic operands for MOVZ, MOVN and MOVK already imply a shift 00191 // (e.g. :gottprel_g1: is always going to be "lsl #16") so it should not be 00192 // printed. 00193 if ((Opcode == AArch64::MOVZXi || Opcode == AArch64::MOVZWi || 00194 Opcode == AArch64::MOVNXi || Opcode == AArch64::MOVNWi) && 00195 MI->getOperand(1).isExpr()) { 00196 if (Opcode == AArch64::MOVZXi || Opcode == AArch64::MOVZWi) 00197 O << "\tmovz\t"; 00198 else 00199 O << "\tmovn\t"; 00200 00201 O << getRegisterName(MI->getOperand(0).getReg()) << ", #" 00202 << *MI->getOperand(1).getExpr(); 00203 return; 00204 } 00205 00206 if ((Opcode == AArch64::MOVKXi || Opcode == AArch64::MOVKWi) && 00207 MI->getOperand(2).isExpr()) { 00208 O << "\tmovk\t" << getRegisterName(MI->getOperand(0).getReg()) << ", #" 00209 << *MI->getOperand(2).getExpr(); 00210 return; 00211 } 00212 00213 if (!printAliasInstr(MI, O)) 00214 printInstruction(MI, O); 00215 00216 printAnnotation(O, Annot); 00217 } 00218 00219 static bool isTblTbxInstruction(unsigned Opcode, StringRef &Layout, 00220 bool &IsTbx) { 00221 switch (Opcode) { 00222 case AArch64::TBXv8i8One: 00223 case AArch64::TBXv8i8Two: 00224 case AArch64::TBXv8i8Three: 00225 case AArch64::TBXv8i8Four: 00226 IsTbx = true; 00227 Layout = ".8b"; 00228 return true; 00229 case AArch64::TBLv8i8One: 00230 case AArch64::TBLv8i8Two: 00231 case AArch64::TBLv8i8Three: 00232 case AArch64::TBLv8i8Four: 00233 IsTbx = false; 00234 Layout = ".8b"; 00235 return true; 00236 case AArch64::TBXv16i8One: 00237 case AArch64::TBXv16i8Two: 00238 case AArch64::TBXv16i8Three: 00239 case AArch64::TBXv16i8Four: 00240 IsTbx = true; 00241 Layout = ".16b"; 00242 return true; 00243 case AArch64::TBLv16i8One: 00244 case AArch64::TBLv16i8Two: 00245 case AArch64::TBLv16i8Three: 00246 case AArch64::TBLv16i8Four: 00247 IsTbx = false; 00248 Layout = ".16b"; 00249 return true; 00250 default: 00251 return false; 00252 } 00253 } 00254 00255 struct LdStNInstrDesc { 00256 unsigned Opcode; 00257 const char *Mnemonic; 00258 const char *Layout; 00259 int ListOperand; 00260 bool HasLane; 00261 int NaturalOffset; 00262 }; 00263 00264 static LdStNInstrDesc LdStNInstInfo[] = { 00265 { AArch64::LD1i8, "ld1", ".b", 1, true, 0 }, 00266 { AArch64::LD1i16, "ld1", ".h", 1, true, 0 }, 00267 { AArch64::LD1i32, "ld1", ".s", 1, true, 0 }, 00268 { AArch64::LD1i64, "ld1", ".d", 1, true, 0 }, 00269 { AArch64::LD1i8_POST, "ld1", ".b", 2, true, 1 }, 00270 { AArch64::LD1i16_POST, "ld1", ".h", 2, true, 2 }, 00271 { AArch64::LD1i32_POST, "ld1", ".s", 2, true, 4 }, 00272 { AArch64::LD1i64_POST, "ld1", ".d", 2, true, 8 }, 00273 { AArch64::LD1Rv16b, "ld1r", ".16b", 0, false, 0 }, 00274 { AArch64::LD1Rv8h, "ld1r", ".8h", 0, false, 0 }, 00275 { AArch64::LD1Rv4s, "ld1r", ".4s", 0, false, 0 }, 00276 { AArch64::LD1Rv2d, "ld1r", ".2d", 0, false, 0 }, 00277 { AArch64::LD1Rv8b, "ld1r", ".8b", 0, false, 0 }, 00278 { AArch64::LD1Rv4h, "ld1r", ".4h", 0, false, 0 }, 00279 { AArch64::LD1Rv2s, "ld1r", ".2s", 0, false, 0 }, 00280 { AArch64::LD1Rv1d, "ld1r", ".1d", 0, false, 0 }, 00281 { AArch64::LD1Rv16b_POST, "ld1r", ".16b", 1, false, 1 }, 00282 { AArch64::LD1Rv8h_POST, "ld1r", ".8h", 1, false, 2 }, 00283 { AArch64::LD1Rv4s_POST, "ld1r", ".4s", 1, false, 4 }, 00284 { AArch64::LD1Rv2d_POST, "ld1r", ".2d", 1, false, 8 }, 00285 { AArch64::LD1Rv8b_POST, "ld1r", ".8b", 1, false, 1 }, 00286 { AArch64::LD1Rv4h_POST, "ld1r", ".4h", 1, false, 2 }, 00287 { AArch64::LD1Rv2s_POST, "ld1r", ".2s", 1, false, 4 }, 00288 { AArch64::LD1Rv1d_POST, "ld1r", ".1d", 1, false, 8 }, 00289 { AArch64::LD1Onev16b, "ld1", ".16b", 0, false, 0 }, 00290 { AArch64::LD1Onev8h, "ld1", ".8h", 0, false, 0 }, 00291 { AArch64::LD1Onev4s, "ld1", ".4s", 0, false, 0 }, 00292 { AArch64::LD1Onev2d, "ld1", ".2d", 0, false, 0 }, 00293 { AArch64::LD1Onev8b, "ld1", ".8b", 0, false, 0 }, 00294 { AArch64::LD1Onev4h, "ld1", ".4h", 0, false, 0 }, 00295 { AArch64::LD1Onev2s, "ld1", ".2s", 0, false, 0 }, 00296 { AArch64::LD1Onev1d, "ld1", ".1d", 0, false, 0 }, 00297 { AArch64::LD1Onev16b_POST, "ld1", ".16b", 1, false, 16 }, 00298 { AArch64::LD1Onev8h_POST, "ld1", ".8h", 1, false, 16 }, 00299 { AArch64::LD1Onev4s_POST, "ld1", ".4s", 1, false, 16 }, 00300 { AArch64::LD1Onev2d_POST, "ld1", ".2d", 1, false, 16 }, 00301 { AArch64::LD1Onev8b_POST, "ld1", ".8b", 1, false, 8 }, 00302 { AArch64::LD1Onev4h_POST, "ld1", ".4h", 1, false, 8 }, 00303 { AArch64::LD1Onev2s_POST, "ld1", ".2s", 1, false, 8 }, 00304 { AArch64::LD1Onev1d_POST, "ld1", ".1d", 1, false, 8 }, 00305 { AArch64::LD1Twov16b, "ld1", ".16b", 0, false, 0 }, 00306 { AArch64::LD1Twov8h, "ld1", ".8h", 0, false, 0 }, 00307 { AArch64::LD1Twov4s, "ld1", ".4s", 0, false, 0 }, 00308 { AArch64::LD1Twov2d, "ld1", ".2d", 0, false, 0 }, 00309 { AArch64::LD1Twov8b, "ld1", ".8b", 0, false, 0 }, 00310 { AArch64::LD1Twov4h, "ld1", ".4h", 0, false, 0 }, 00311 { AArch64::LD1Twov2s, "ld1", ".2s", 0, false, 0 }, 00312 { AArch64::LD1Twov1d, "ld1", ".1d", 0, false, 0 }, 00313 { AArch64::LD1Twov16b_POST, "ld1", ".16b", 1, false, 32 }, 00314 { AArch64::LD1Twov8h_POST, "ld1", ".8h", 1, false, 32 }, 00315 { AArch64::LD1Twov4s_POST, "ld1", ".4s", 1, false, 32 }, 00316 { AArch64::LD1Twov2d_POST, "ld1", ".2d", 1, false, 32 }, 00317 { AArch64::LD1Twov8b_POST, "ld1", ".8b", 1, false, 16 }, 00318 { AArch64::LD1Twov4h_POST, "ld1", ".4h", 1, false, 16 }, 00319 { AArch64::LD1Twov2s_POST, "ld1", ".2s", 1, false, 16 }, 00320 { AArch64::LD1Twov1d_POST, "ld1", ".1d", 1, false, 16 }, 00321 { AArch64::LD1Threev16b, "ld1", ".16b", 0, false, 0 }, 00322 { AArch64::LD1Threev8h, "ld1", ".8h", 0, false, 0 }, 00323 { AArch64::LD1Threev4s, "ld1", ".4s", 0, false, 0 }, 00324 { AArch64::LD1Threev2d, "ld1", ".2d", 0, false, 0 }, 00325 { AArch64::LD1Threev8b, "ld1", ".8b", 0, false, 0 }, 00326 { AArch64::LD1Threev4h, "ld1", ".4h", 0, false, 0 }, 00327 { AArch64::LD1Threev2s, "ld1", ".2s", 0, false, 0 }, 00328 { AArch64::LD1Threev1d, "ld1", ".1d", 0, false, 0 }, 00329 { AArch64::LD1Threev16b_POST, "ld1", ".16b", 1, false, 48 }, 00330 { AArch64::LD1Threev8h_POST, "ld1", ".8h", 1, false, 48 }, 00331 { AArch64::LD1Threev4s_POST, "ld1", ".4s", 1, false, 48 }, 00332 { AArch64::LD1Threev2d_POST, "ld1", ".2d", 1, false, 48 }, 00333 { AArch64::LD1Threev8b_POST, "ld1", ".8b", 1, false, 24 }, 00334 { AArch64::LD1Threev4h_POST, "ld1", ".4h", 1, false, 24 }, 00335 { AArch64::LD1Threev2s_POST, "ld1", ".2s", 1, false, 24 }, 00336 { AArch64::LD1Threev1d_POST, "ld1", ".1d", 1, false, 24 }, 00337 { AArch64::LD1Fourv16b, "ld1", ".16b", 0, false, 0 }, 00338 { AArch64::LD1Fourv8h, "ld1", ".8h", 0, false, 0 }, 00339 { AArch64::LD1Fourv4s, "ld1", ".4s", 0, false, 0 }, 00340 { AArch64::LD1Fourv2d, "ld1", ".2d", 0, false, 0 }, 00341 { AArch64::LD1Fourv8b, "ld1", ".8b", 0, false, 0 }, 00342 { AArch64::LD1Fourv4h, "ld1", ".4h", 0, false, 0 }, 00343 { AArch64::LD1Fourv2s, "ld1", ".2s", 0, false, 0 }, 00344 { AArch64::LD1Fourv1d, "ld1", ".1d", 0, false, 0 }, 00345 { AArch64::LD1Fourv16b_POST, "ld1", ".16b", 1, false, 64 }, 00346 { AArch64::LD1Fourv8h_POST, "ld1", ".8h", 1, false, 64 }, 00347 { AArch64::LD1Fourv4s_POST, "ld1", ".4s", 1, false, 64 }, 00348 { AArch64::LD1Fourv2d_POST, "ld1", ".2d", 1, false, 64 }, 00349 { AArch64::LD1Fourv8b_POST, "ld1", ".8b", 1, false, 32 }, 00350 { AArch64::LD1Fourv4h_POST, "ld1", ".4h", 1, false, 32 }, 00351 { AArch64::LD1Fourv2s_POST, "ld1", ".2s", 1, false, 32 }, 00352 { AArch64::LD1Fourv1d_POST, "ld1", ".1d", 1, false, 32 }, 00353 { AArch64::LD2i8, "ld2", ".b", 1, true, 0 }, 00354 { AArch64::LD2i16, "ld2", ".h", 1, true, 0 }, 00355 { AArch64::LD2i32, "ld2", ".s", 1, true, 0 }, 00356 { AArch64::LD2i64, "ld2", ".d", 1, true, 0 }, 00357 { AArch64::LD2i8_POST, "ld2", ".b", 2, true, 2 }, 00358 { AArch64::LD2i16_POST, "ld2", ".h", 2, true, 4 }, 00359 { AArch64::LD2i32_POST, "ld2", ".s", 2, true, 8 }, 00360 { AArch64::LD2i64_POST, "ld2", ".d", 2, true, 16 }, 00361 { AArch64::LD2Rv16b, "ld2r", ".16b", 0, false, 0 }, 00362 { AArch64::LD2Rv8h, "ld2r", ".8h", 0, false, 0 }, 00363 { AArch64::LD2Rv4s, "ld2r", ".4s", 0, false, 0 }, 00364 { AArch64::LD2Rv2d, "ld2r", ".2d", 0, false, 0 }, 00365 { AArch64::LD2Rv8b, "ld2r", ".8b", 0, false, 0 }, 00366 { AArch64::LD2Rv4h, "ld2r", ".4h", 0, false, 0 }, 00367 { AArch64::LD2Rv2s, "ld2r", ".2s", 0, false, 0 }, 00368 { AArch64::LD2Rv1d, "ld2r", ".1d", 0, false, 0 }, 00369 { AArch64::LD2Rv16b_POST, "ld2r", ".16b", 1, false, 2 }, 00370 { AArch64::LD2Rv8h_POST, "ld2r", ".8h", 1, false, 4 }, 00371 { AArch64::LD2Rv4s_POST, "ld2r", ".4s", 1, false, 8 }, 00372 { AArch64::LD2Rv2d_POST, "ld2r", ".2d", 1, false, 16 }, 00373 { AArch64::LD2Rv8b_POST, "ld2r", ".8b", 1, false, 2 }, 00374 { AArch64::LD2Rv4h_POST, "ld2r", ".4h", 1, false, 4 }, 00375 { AArch64::LD2Rv2s_POST, "ld2r", ".2s", 1, false, 8 }, 00376 { AArch64::LD2Rv1d_POST, "ld2r", ".1d", 1, false, 16 }, 00377 { AArch64::LD2Twov16b, "ld2", ".16b", 0, false, 0 }, 00378 { AArch64::LD2Twov8h, "ld2", ".8h", 0, false, 0 }, 00379 { AArch64::LD2Twov4s, "ld2", ".4s", 0, false, 0 }, 00380 { AArch64::LD2Twov2d, "ld2", ".2d", 0, false, 0 }, 00381 { AArch64::LD2Twov8b, "ld2", ".8b", 0, false, 0 }, 00382 { AArch64::LD2Twov4h, "ld2", ".4h", 0, false, 0 }, 00383 { AArch64::LD2Twov2s, "ld2", ".2s", 0, false, 0 }, 00384 { AArch64::LD2Twov16b_POST, "ld2", ".16b", 1, false, 32 }, 00385 { AArch64::LD2Twov8h_POST, "ld2", ".8h", 1, false, 32 }, 00386 { AArch64::LD2Twov4s_POST, "ld2", ".4s", 1, false, 32 }, 00387 { AArch64::LD2Twov2d_POST, "ld2", ".2d", 1, false, 32 }, 00388 { AArch64::LD2Twov8b_POST, "ld2", ".8b", 1, false, 16 }, 00389 { AArch64::LD2Twov4h_POST, "ld2", ".4h", 1, false, 16 }, 00390 { AArch64::LD2Twov2s_POST, "ld2", ".2s", 1, false, 16 }, 00391 { AArch64::LD3i8, "ld3", ".b", 1, true, 0 }, 00392 { AArch64::LD3i16, "ld3", ".h", 1, true, 0 }, 00393 { AArch64::LD3i32, "ld3", ".s", 1, true, 0 }, 00394 { AArch64::LD3i64, "ld3", ".d", 1, true, 0 }, 00395 { AArch64::LD3i8_POST, "ld3", ".b", 2, true, 3 }, 00396 { AArch64::LD3i16_POST, "ld3", ".h", 2, true, 6 }, 00397 { AArch64::LD3i32_POST, "ld3", ".s", 2, true, 12 }, 00398 { AArch64::LD3i64_POST, "ld3", ".d", 2, true, 24 }, 00399 { AArch64::LD3Rv16b, "ld3r", ".16b", 0, false, 0 }, 00400 { AArch64::LD3Rv8h, "ld3r", ".8h", 0, false, 0 }, 00401 { AArch64::LD3Rv4s, "ld3r", ".4s", 0, false, 0 }, 00402 { AArch64::LD3Rv2d, "ld3r", ".2d", 0, false, 0 }, 00403 { AArch64::LD3Rv8b, "ld3r", ".8b", 0, false, 0 }, 00404 { AArch64::LD3Rv4h, "ld3r", ".4h", 0, false, 0 }, 00405 { AArch64::LD3Rv2s, "ld3r", ".2s", 0, false, 0 }, 00406 { AArch64::LD3Rv1d, "ld3r", ".1d", 0, false, 0 }, 00407 { AArch64::LD3Rv16b_POST, "ld3r", ".16b", 1, false, 3 }, 00408 { AArch64::LD3Rv8h_POST, "ld3r", ".8h", 1, false, 6 }, 00409 { AArch64::LD3Rv4s_POST, "ld3r", ".4s", 1, false, 12 }, 00410 { AArch64::LD3Rv2d_POST, "ld3r", ".2d", 1, false, 24 }, 00411 { AArch64::LD3Rv8b_POST, "ld3r", ".8b", 1, false, 3 }, 00412 { AArch64::LD3Rv4h_POST, "ld3r", ".4h", 1, false, 6 }, 00413 { AArch64::LD3Rv2s_POST, "ld3r", ".2s", 1, false, 12 }, 00414 { AArch64::LD3Rv1d_POST, "ld3r", ".1d", 1, false, 24 }, 00415 { AArch64::LD3Threev16b, "ld3", ".16b", 0, false, 0 }, 00416 { AArch64::LD3Threev8h, "ld3", ".8h", 0, false, 0 }, 00417 { AArch64::LD3Threev4s, "ld3", ".4s", 0, false, 0 }, 00418 { AArch64::LD3Threev2d, "ld3", ".2d", 0, false, 0 }, 00419 { AArch64::LD3Threev8b, "ld3", ".8b", 0, false, 0 }, 00420 { AArch64::LD3Threev4h, "ld3", ".4h", 0, false, 0 }, 00421 { AArch64::LD3Threev2s, "ld3", ".2s", 0, false, 0 }, 00422 { AArch64::LD3Threev16b_POST, "ld3", ".16b", 1, false, 48 }, 00423 { AArch64::LD3Threev8h_POST, "ld3", ".8h", 1, false, 48 }, 00424 { AArch64::LD3Threev4s_POST, "ld3", ".4s", 1, false, 48 }, 00425 { AArch64::LD3Threev2d_POST, "ld3", ".2d", 1, false, 48 }, 00426 { AArch64::LD3Threev8b_POST, "ld3", ".8b", 1, false, 24 }, 00427 { AArch64::LD3Threev4h_POST, "ld3", ".4h", 1, false, 24 }, 00428 { AArch64::LD3Threev2s_POST, "ld3", ".2s", 1, false, 24 }, 00429 { AArch64::LD4i8, "ld4", ".b", 1, true, 0 }, 00430 { AArch64::LD4i16, "ld4", ".h", 1, true, 0 }, 00431 { AArch64::LD4i32, "ld4", ".s", 1, true, 0 }, 00432 { AArch64::LD4i64, "ld4", ".d", 1, true, 0 }, 00433 { AArch64::LD4i8_POST, "ld4", ".b", 2, true, 4 }, 00434 { AArch64::LD4i16_POST, "ld4", ".h", 2, true, 8 }, 00435 { AArch64::LD4i32_POST, "ld4", ".s", 2, true, 16 }, 00436 { AArch64::LD4i64_POST, "ld4", ".d", 2, true, 32 }, 00437 { AArch64::LD4Rv16b, "ld4r", ".16b", 0, false, 0 }, 00438 { AArch64::LD4Rv8h, "ld4r", ".8h", 0, false, 0 }, 00439 { AArch64::LD4Rv4s, "ld4r", ".4s", 0, false, 0 }, 00440 { AArch64::LD4Rv2d, "ld4r", ".2d", 0, false, 0 }, 00441 { AArch64::LD4Rv8b, "ld4r", ".8b", 0, false, 0 }, 00442 { AArch64::LD4Rv4h, "ld4r", ".4h", 0, false, 0 }, 00443 { AArch64::LD4Rv2s, "ld4r", ".2s", 0, false, 0 }, 00444 { AArch64::LD4Rv1d, "ld4r", ".1d", 0, false, 0 }, 00445 { AArch64::LD4Rv16b_POST, "ld4r", ".16b", 1, false, 4 }, 00446 { AArch64::LD4Rv8h_POST, "ld4r", ".8h", 1, false, 8 }, 00447 { AArch64::LD4Rv4s_POST, "ld4r", ".4s", 1, false, 16 }, 00448 { AArch64::LD4Rv2d_POST, "ld4r", ".2d", 1, false, 32 }, 00449 { AArch64::LD4Rv8b_POST, "ld4r", ".8b", 1, false, 4 }, 00450 { AArch64::LD4Rv4h_POST, "ld4r", ".4h", 1, false, 8 }, 00451 { AArch64::LD4Rv2s_POST, "ld4r", ".2s", 1, false, 16 }, 00452 { AArch64::LD4Rv1d_POST, "ld4r", ".1d", 1, false, 32 }, 00453 { AArch64::LD4Fourv16b, "ld4", ".16b", 0, false, 0 }, 00454 { AArch64::LD4Fourv8h, "ld4", ".8h", 0, false, 0 }, 00455 { AArch64::LD4Fourv4s, "ld4", ".4s", 0, false, 0 }, 00456 { AArch64::LD4Fourv2d, "ld4", ".2d", 0, false, 0 }, 00457 { AArch64::LD4Fourv8b, "ld4", ".8b", 0, false, 0 }, 00458 { AArch64::LD4Fourv4h, "ld4", ".4h", 0, false, 0 }, 00459 { AArch64::LD4Fourv2s, "ld4", ".2s", 0, false, 0 }, 00460 { AArch64::LD4Fourv16b_POST, "ld4", ".16b", 1, false, 64 }, 00461 { AArch64::LD4Fourv8h_POST, "ld4", ".8h", 1, false, 64 }, 00462 { AArch64::LD4Fourv4s_POST, "ld4", ".4s", 1, false, 64 }, 00463 { AArch64::LD4Fourv2d_POST, "ld4", ".2d", 1, false, 64 }, 00464 { AArch64::LD4Fourv8b_POST, "ld4", ".8b", 1, false, 32 }, 00465 { AArch64::LD4Fourv4h_POST, "ld4", ".4h", 1, false, 32 }, 00466 { AArch64::LD4Fourv2s_POST, "ld4", ".2s", 1, false, 32 }, 00467 { AArch64::ST1i8, "st1", ".b", 0, true, 0 }, 00468 { AArch64::ST1i16, "st1", ".h", 0, true, 0 }, 00469 { AArch64::ST1i32, "st1", ".s", 0, true, 0 }, 00470 { AArch64::ST1i64, "st1", ".d", 0, true, 0 }, 00471 { AArch64::ST1i8_POST, "st1", ".b", 1, true, 1 }, 00472 { AArch64::ST1i16_POST, "st1", ".h", 1, true, 2 }, 00473 { AArch64::ST1i32_POST, "st1", ".s", 1, true, 4 }, 00474 { AArch64::ST1i64_POST, "st1", ".d", 1, true, 8 }, 00475 { AArch64::ST1Onev16b, "st1", ".16b", 0, false, 0 }, 00476 { AArch64::ST1Onev8h, "st1", ".8h", 0, false, 0 }, 00477 { AArch64::ST1Onev4s, "st1", ".4s", 0, false, 0 }, 00478 { AArch64::ST1Onev2d, "st1", ".2d", 0, false, 0 }, 00479 { AArch64::ST1Onev8b, "st1", ".8b", 0, false, 0 }, 00480 { AArch64::ST1Onev4h, "st1", ".4h", 0, false, 0 }, 00481 { AArch64::ST1Onev2s, "st1", ".2s", 0, false, 0 }, 00482 { AArch64::ST1Onev1d, "st1", ".1d", 0, false, 0 }, 00483 { AArch64::ST1Onev16b_POST, "st1", ".16b", 1, false, 16 }, 00484 { AArch64::ST1Onev8h_POST, "st1", ".8h", 1, false, 16 }, 00485 { AArch64::ST1Onev4s_POST, "st1", ".4s", 1, false, 16 }, 00486 { AArch64::ST1Onev2d_POST, "st1", ".2d", 1, false, 16 }, 00487 { AArch64::ST1Onev8b_POST, "st1", ".8b", 1, false, 8 }, 00488 { AArch64::ST1Onev4h_POST, "st1", ".4h", 1, false, 8 }, 00489 { AArch64::ST1Onev2s_POST, "st1", ".2s", 1, false, 8 }, 00490 { AArch64::ST1Onev1d_POST, "st1", ".1d", 1, false, 8 }, 00491 { AArch64::ST1Twov16b, "st1", ".16b", 0, false, 0 }, 00492 { AArch64::ST1Twov8h, "st1", ".8h", 0, false, 0 }, 00493 { AArch64::ST1Twov4s, "st1", ".4s", 0, false, 0 }, 00494 { AArch64::ST1Twov2d, "st1", ".2d", 0, false, 0 }, 00495 { AArch64::ST1Twov8b, "st1", ".8b", 0, false, 0 }, 00496 { AArch64::ST1Twov4h, "st1", ".4h", 0, false, 0 }, 00497 { AArch64::ST1Twov2s, "st1", ".2s", 0, false, 0 }, 00498 { AArch64::ST1Twov1d, "st1", ".1d", 0, false, 0 }, 00499 { AArch64::ST1Twov16b_POST, "st1", ".16b", 1, false, 32 }, 00500 { AArch64::ST1Twov8h_POST, "st1", ".8h", 1, false, 32 }, 00501 { AArch64::ST1Twov4s_POST, "st1", ".4s", 1, false, 32 }, 00502 { AArch64::ST1Twov2d_POST, "st1", ".2d", 1, false, 32 }, 00503 { AArch64::ST1Twov8b_POST, "st1", ".8b", 1, false, 16 }, 00504 { AArch64::ST1Twov4h_POST, "st1", ".4h", 1, false, 16 }, 00505 { AArch64::ST1Twov2s_POST, "st1", ".2s", 1, false, 16 }, 00506 { AArch64::ST1Twov1d_POST, "st1", ".1d", 1, false, 16 }, 00507 { AArch64::ST1Threev16b, "st1", ".16b", 0, false, 0 }, 00508 { AArch64::ST1Threev8h, "st1", ".8h", 0, false, 0 }, 00509 { AArch64::ST1Threev4s, "st1", ".4s", 0, false, 0 }, 00510 { AArch64::ST1Threev2d, "st1", ".2d", 0, false, 0 }, 00511 { AArch64::ST1Threev8b, "st1", ".8b", 0, false, 0 }, 00512 { AArch64::ST1Threev4h, "st1", ".4h", 0, false, 0 }, 00513 { AArch64::ST1Threev2s, "st1", ".2s", 0, false, 0 }, 00514 { AArch64::ST1Threev1d, "st1", ".1d", 0, false, 0 }, 00515 { AArch64::ST1Threev16b_POST, "st1", ".16b", 1, false, 48 }, 00516 { AArch64::ST1Threev8h_POST, "st1", ".8h", 1, false, 48 }, 00517 { AArch64::ST1Threev4s_POST, "st1", ".4s", 1, false, 48 }, 00518 { AArch64::ST1Threev2d_POST, "st1", ".2d", 1, false, 48 }, 00519 { AArch64::ST1Threev8b_POST, "st1", ".8b", 1, false, 24 }, 00520 { AArch64::ST1Threev4h_POST, "st1", ".4h", 1, false, 24 }, 00521 { AArch64::ST1Threev2s_POST, "st1", ".2s", 1, false, 24 }, 00522 { AArch64::ST1Threev1d_POST, "st1", ".1d", 1, false, 24 }, 00523 { AArch64::ST1Fourv16b, "st1", ".16b", 0, false, 0 }, 00524 { AArch64::ST1Fourv8h, "st1", ".8h", 0, false, 0 }, 00525 { AArch64::ST1Fourv4s, "st1", ".4s", 0, false, 0 }, 00526 { AArch64::ST1Fourv2d, "st1", ".2d", 0, false, 0 }, 00527 { AArch64::ST1Fourv8b, "st1", ".8b", 0, false, 0 }, 00528 { AArch64::ST1Fourv4h, "st1", ".4h", 0, false, 0 }, 00529 { AArch64::ST1Fourv2s, "st1", ".2s", 0, false, 0 }, 00530 { AArch64::ST1Fourv1d, "st1", ".1d", 0, false, 0 }, 00531 { AArch64::ST1Fourv16b_POST, "st1", ".16b", 1, false, 64 }, 00532 { AArch64::ST1Fourv8h_POST, "st1", ".8h", 1, false, 64 }, 00533 { AArch64::ST1Fourv4s_POST, "st1", ".4s", 1, false, 64 }, 00534 { AArch64::ST1Fourv2d_POST, "st1", ".2d", 1, false, 64 }, 00535 { AArch64::ST1Fourv8b_POST, "st1", ".8b", 1, false, 32 }, 00536 { AArch64::ST1Fourv4h_POST, "st1", ".4h", 1, false, 32 }, 00537 { AArch64::ST1Fourv2s_POST, "st1", ".2s", 1, false, 32 }, 00538 { AArch64::ST1Fourv1d_POST, "st1", ".1d", 1, false, 32 }, 00539 { AArch64::ST2i8, "st2", ".b", 0, true, 0 }, 00540 { AArch64::ST2i16, "st2", ".h", 0, true, 0 }, 00541 { AArch64::ST2i32, "st2", ".s", 0, true, 0 }, 00542 { AArch64::ST2i64, "st2", ".d", 0, true, 0 }, 00543 { AArch64::ST2i8_POST, "st2", ".b", 1, true, 2 }, 00544 { AArch64::ST2i16_POST, "st2", ".h", 1, true, 4 }, 00545 { AArch64::ST2i32_POST, "st2", ".s", 1, true, 8 }, 00546 { AArch64::ST2i64_POST, "st2", ".d", 1, true, 16 }, 00547 { AArch64::ST2Twov16b, "st2", ".16b", 0, false, 0 }, 00548 { AArch64::ST2Twov8h, "st2", ".8h", 0, false, 0 }, 00549 { AArch64::ST2Twov4s, "st2", ".4s", 0, false, 0 }, 00550 { AArch64::ST2Twov2d, "st2", ".2d", 0, false, 0 }, 00551 { AArch64::ST2Twov8b, "st2", ".8b", 0, false, 0 }, 00552 { AArch64::ST2Twov4h, "st2", ".4h", 0, false, 0 }, 00553 { AArch64::ST2Twov2s, "st2", ".2s", 0, false, 0 }, 00554 { AArch64::ST2Twov16b_POST, "st2", ".16b", 1, false, 32 }, 00555 { AArch64::ST2Twov8h_POST, "st2", ".8h", 1, false, 32 }, 00556 { AArch64::ST2Twov4s_POST, "st2", ".4s", 1, false, 32 }, 00557 { AArch64::ST2Twov2d_POST, "st2", ".2d", 1, false, 32 }, 00558 { AArch64::ST2Twov8b_POST, "st2", ".8b", 1, false, 16 }, 00559 { AArch64::ST2Twov4h_POST, "st2", ".4h", 1, false, 16 }, 00560 { AArch64::ST2Twov2s_POST, "st2", ".2s", 1, false, 16 }, 00561 { AArch64::ST3i8, "st3", ".b", 0, true, 0 }, 00562 { AArch64::ST3i16, "st3", ".h", 0, true, 0 }, 00563 { AArch64::ST3i32, "st3", ".s", 0, true, 0 }, 00564 { AArch64::ST3i64, "st3", ".d", 0, true, 0 }, 00565 { AArch64::ST3i8_POST, "st3", ".b", 1, true, 3 }, 00566 { AArch64::ST3i16_POST, "st3", ".h", 1, true, 6 }, 00567 { AArch64::ST3i32_POST, "st3", ".s", 1, true, 12 }, 00568 { AArch64::ST3i64_POST, "st3", ".d", 1, true, 24 }, 00569 { AArch64::ST3Threev16b, "st3", ".16b", 0, false, 0 }, 00570 { AArch64::ST3Threev8h, "st3", ".8h", 0, false, 0 }, 00571 { AArch64::ST3Threev4s, "st3", ".4s", 0, false, 0 }, 00572 { AArch64::ST3Threev2d, "st3", ".2d", 0, false, 0 }, 00573 { AArch64::ST3Threev8b, "st3", ".8b", 0, false, 0 }, 00574 { AArch64::ST3Threev4h, "st3", ".4h", 0, false, 0 }, 00575 { AArch64::ST3Threev2s, "st3", ".2s", 0, false, 0 }, 00576 { AArch64::ST3Threev16b_POST, "st3", ".16b", 1, false, 48 }, 00577 { AArch64::ST3Threev8h_POST, "st3", ".8h", 1, false, 48 }, 00578 { AArch64::ST3Threev4s_POST, "st3", ".4s", 1, false, 48 }, 00579 { AArch64::ST3Threev2d_POST, "st3", ".2d", 1, false, 48 }, 00580 { AArch64::ST3Threev8b_POST, "st3", ".8b", 1, false, 24 }, 00581 { AArch64::ST3Threev4h_POST, "st3", ".4h", 1, false, 24 }, 00582 { AArch64::ST3Threev2s_POST, "st3", ".2s", 1, false, 24 }, 00583 { AArch64::ST4i8, "st4", ".b", 0, true, 0 }, 00584 { AArch64::ST4i16, "st4", ".h", 0, true, 0 }, 00585 { AArch64::ST4i32, "st4", ".s", 0, true, 0 }, 00586 { AArch64::ST4i64, "st4", ".d", 0, true, 0 }, 00587 { AArch64::ST4i8_POST, "st4", ".b", 1, true, 4 }, 00588 { AArch64::ST4i16_POST, "st4", ".h", 1, true, 8 }, 00589 { AArch64::ST4i32_POST, "st4", ".s", 1, true, 16 }, 00590 { AArch64::ST4i64_POST, "st4", ".d", 1, true, 32 }, 00591 { AArch64::ST4Fourv16b, "st4", ".16b", 0, false, 0 }, 00592 { AArch64::ST4Fourv8h, "st4", ".8h", 0, false, 0 }, 00593 { AArch64::ST4Fourv4s, "st4", ".4s", 0, false, 0 }, 00594 { AArch64::ST4Fourv2d, "st4", ".2d", 0, false, 0 }, 00595 { AArch64::ST4Fourv8b, "st4", ".8b", 0, false, 0 }, 00596 { AArch64::ST4Fourv4h, "st4", ".4h", 0, false, 0 }, 00597 { AArch64::ST4Fourv2s, "st4", ".2s", 0, false, 0 }, 00598 { AArch64::ST4Fourv16b_POST, "st4", ".16b", 1, false, 64 }, 00599 { AArch64::ST4Fourv8h_POST, "st4", ".8h", 1, false, 64 }, 00600 { AArch64::ST4Fourv4s_POST, "st4", ".4s", 1, false, 64 }, 00601 { AArch64::ST4Fourv2d_POST, "st4", ".2d", 1, false, 64 }, 00602 { AArch64::ST4Fourv8b_POST, "st4", ".8b", 1, false, 32 }, 00603 { AArch64::ST4Fourv4h_POST, "st4", ".4h", 1, false, 32 }, 00604 { AArch64::ST4Fourv2s_POST, "st4", ".2s", 1, false, 32 }, 00605 }; 00606 00607 static LdStNInstrDesc *getLdStNInstrDesc(unsigned Opcode) { 00608 unsigned Idx; 00609 for (Idx = 0; Idx != array_lengthof(LdStNInstInfo); ++Idx) 00610 if (LdStNInstInfo[Idx].Opcode == Opcode) 00611 return &LdStNInstInfo[Idx]; 00612 00613 return nullptr; 00614 } 00615 00616 void AArch64AppleInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 00617 StringRef Annot) { 00618 unsigned Opcode = MI->getOpcode(); 00619 StringRef Layout, Mnemonic; 00620 00621 bool IsTbx; 00622 if (isTblTbxInstruction(MI->getOpcode(), Layout, IsTbx)) { 00623 O << "\t" << (IsTbx ? "tbx" : "tbl") << Layout << '\t' 00624 << getRegisterName(MI->getOperand(0).getReg(), AArch64::vreg) << ", "; 00625 00626 unsigned ListOpNum = IsTbx ? 2 : 1; 00627 printVectorList(MI, ListOpNum, O, ""); 00628 00629 O << ", " 00630 << getRegisterName(MI->getOperand(ListOpNum + 1).getReg(), AArch64::vreg); 00631 printAnnotation(O, Annot); 00632 return; 00633 } 00634 00635 if (LdStNInstrDesc *LdStDesc = getLdStNInstrDesc(Opcode)) { 00636 O << "\t" << LdStDesc->Mnemonic << LdStDesc->Layout << '\t'; 00637 00638 // Now onto the operands: first a vector list with possible lane 00639 // specifier. E.g. { v0 }[2] 00640 int OpNum = LdStDesc->ListOperand; 00641 printVectorList(MI, OpNum++, O, ""); 00642 00643 if (LdStDesc->HasLane) 00644 O << '[' << MI->getOperand(OpNum++).getImm() << ']'; 00645 00646 // Next the address: [xN] 00647 unsigned AddrReg = MI->getOperand(OpNum++).getReg(); 00648 O << ", [" << getRegisterName(AddrReg) << ']'; 00649 00650 // Finally, there might be a post-indexed offset. 00651 if (LdStDesc->NaturalOffset != 0) { 00652 unsigned Reg = MI->getOperand(OpNum++).getReg(); 00653 if (Reg != AArch64::XZR) 00654 O << ", " << getRegisterName(Reg); 00655 else { 00656 assert(LdStDesc->NaturalOffset && "no offset on post-inc instruction?"); 00657 O << ", #" << LdStDesc->NaturalOffset; 00658 } 00659 } 00660 00661 printAnnotation(O, Annot); 00662 return; 00663 } 00664 00665 AArch64InstPrinter::printInst(MI, O, Annot); 00666 } 00667 00668 bool AArch64InstPrinter::printSysAlias(const MCInst *MI, raw_ostream &O) { 00669 #ifndef NDEBUG 00670 unsigned Opcode = MI->getOpcode(); 00671 assert(Opcode == AArch64::SYSxt && "Invalid opcode for SYS alias!"); 00672 #endif 00673 00674 const char *Asm = nullptr; 00675 const MCOperand &Op1 = MI->getOperand(0); 00676 const MCOperand &Cn = MI->getOperand(1); 00677 const MCOperand &Cm = MI->getOperand(2); 00678 const MCOperand &Op2 = MI->getOperand(3); 00679 00680 unsigned Op1Val = Op1.getImm(); 00681 unsigned CnVal = Cn.getImm(); 00682 unsigned CmVal = Cm.getImm(); 00683 unsigned Op2Val = Op2.getImm(); 00684 00685 if (CnVal == 7) { 00686 switch (CmVal) { 00687 default: 00688 break; 00689 00690 // IC aliases 00691 case 1: 00692 if (Op1Val == 0 && Op2Val == 0) 00693 Asm = "ic\tialluis"; 00694 break; 00695 case 5: 00696 if (Op1Val == 0 && Op2Val == 0) 00697 Asm = "ic\tiallu"; 00698 else if (Op1Val == 3 && Op2Val == 1) 00699 Asm = "ic\tivau"; 00700 break; 00701 00702 // DC aliases 00703 case 4: 00704 if (Op1Val == 3 && Op2Val == 1) 00705 Asm = "dc\tzva"; 00706 break; 00707 case 6: 00708 if (Op1Val == 0 && Op2Val == 1) 00709 Asm = "dc\tivac"; 00710 if (Op1Val == 0 && Op2Val == 2) 00711 Asm = "dc\tisw"; 00712 break; 00713 case 10: 00714 if (Op1Val == 3 && Op2Val == 1) 00715 Asm = "dc\tcvac"; 00716 else if (Op1Val == 0 && Op2Val == 2) 00717 Asm = "dc\tcsw"; 00718 break; 00719 case 11: 00720 if (Op1Val == 3 && Op2Val == 1) 00721 Asm = "dc\tcvau"; 00722 break; 00723 case 14: 00724 if (Op1Val == 3 && Op2Val == 1) 00725 Asm = "dc\tcivac"; 00726 else if (Op1Val == 0 && Op2Val == 2) 00727 Asm = "dc\tcisw"; 00728 break; 00729 00730 // AT aliases 00731 case 8: 00732 switch (Op1Val) { 00733 default: 00734 break; 00735 case 0: 00736 switch (Op2Val) { 00737 default: 00738 break; 00739 case 0: Asm = "at\ts1e1r"; break; 00740 case 1: Asm = "at\ts1e1w"; break; 00741 case 2: Asm = "at\ts1e0r"; break; 00742 case 3: Asm = "at\ts1e0w"; break; 00743 } 00744 break; 00745 case 4: 00746 switch (Op2Val) { 00747 default: 00748 break; 00749 case 0: Asm = "at\ts1e2r"; break; 00750 case 1: Asm = "at\ts1e2w"; break; 00751 case 4: Asm = "at\ts12e1r"; break; 00752 case 5: Asm = "at\ts12e1w"; break; 00753 case 6: Asm = "at\ts12e0r"; break; 00754 case 7: Asm = "at\ts12e0w"; break; 00755 } 00756 break; 00757 case 6: 00758 switch (Op2Val) { 00759 default: 00760 break; 00761 case 0: Asm = "at\ts1e3r"; break; 00762 case 1: Asm = "at\ts1e3w"; break; 00763 } 00764 break; 00765 } 00766 break; 00767 } 00768 } else if (CnVal == 8) { 00769 // TLBI aliases 00770 switch (CmVal) { 00771 default: 00772 break; 00773 case 3: 00774 switch (Op1Val) { 00775 default: 00776 break; 00777 case 0: 00778 switch (Op2Val) { 00779 default: 00780 break; 00781 case 0: Asm = "tlbi\tvmalle1is"; break; 00782 case 1: Asm = "tlbi\tvae1is"; break; 00783 case 2: Asm = "tlbi\taside1is"; break; 00784 case 3: Asm = "tlbi\tvaae1is"; break; 00785 case 5: Asm = "tlbi\tvale1is"; break; 00786 case 7: Asm = "tlbi\tvaale1is"; break; 00787 } 00788 break; 00789 case 4: 00790 switch (Op2Val) { 00791 default: 00792 break; 00793 case 0: Asm = "tlbi\talle2is"; break; 00794 case 1: Asm = "tlbi\tvae2is"; break; 00795 case 4: Asm = "tlbi\talle1is"; break; 00796 case 5: Asm = "tlbi\tvale2is"; break; 00797 case 6: Asm = "tlbi\tvmalls12e1is"; break; 00798 } 00799 break; 00800 case 6: 00801 switch (Op2Val) { 00802 default: 00803 break; 00804 case 0: Asm = "tlbi\talle3is"; break; 00805 case 1: Asm = "tlbi\tvae3is"; break; 00806 case 5: Asm = "tlbi\tvale3is"; break; 00807 } 00808 break; 00809 } 00810 break; 00811 case 0: 00812 switch (Op1Val) { 00813 default: 00814 break; 00815 case 4: 00816 switch (Op2Val) { 00817 default: 00818 break; 00819 case 1: Asm = "tlbi\tipas2e1is"; break; 00820 case 5: Asm = "tlbi\tipas2le1is"; break; 00821 } 00822 break; 00823 } 00824 break; 00825 case 4: 00826 switch (Op1Val) { 00827 default: 00828 break; 00829 case 4: 00830 switch (Op2Val) { 00831 default: 00832 break; 00833 case 1: Asm = "tlbi\tipas2e1"; break; 00834 case 5: Asm = "tlbi\tipas2le1"; break; 00835 } 00836 break; 00837 } 00838 break; 00839 case 7: 00840 switch (Op1Val) { 00841 default: 00842 break; 00843 case 0: 00844 switch (Op2Val) { 00845 default: 00846 break; 00847 case 0: Asm = "tlbi\tvmalle1"; break; 00848 case 1: Asm = "tlbi\tvae1"; break; 00849 case 2: Asm = "tlbi\taside1"; break; 00850 case 3: Asm = "tlbi\tvaae1"; break; 00851 case 5: Asm = "tlbi\tvale1"; break; 00852 case 7: Asm = "tlbi\tvaale1"; break; 00853 } 00854 break; 00855 case 4: 00856 switch (Op2Val) { 00857 default: 00858 break; 00859 case 0: Asm = "tlbi\talle2"; break; 00860 case 1: Asm = "tlbi\tvae2"; break; 00861 case 4: Asm = "tlbi\talle1"; break; 00862 case 5: Asm = "tlbi\tvale2"; break; 00863 case 6: Asm = "tlbi\tvmalls12e1"; break; 00864 } 00865 break; 00866 case 6: 00867 switch (Op2Val) { 00868 default: 00869 break; 00870 case 0: Asm = "tlbi\talle3"; break; 00871 case 1: Asm = "tlbi\tvae3"; break; 00872 case 5: Asm = "tlbi\tvale3"; break; 00873 } 00874 break; 00875 } 00876 break; 00877 } 00878 } 00879 00880 if (Asm) { 00881 unsigned Reg = MI->getOperand(4).getReg(); 00882 00883 O << '\t' << Asm; 00884 if (StringRef(Asm).lower().find("all") == StringRef::npos) 00885 O << ", " << getRegisterName(Reg); 00886 } 00887 00888 return Asm != nullptr; 00889 } 00890 00891 void AArch64InstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 00892 raw_ostream &O) { 00893 const MCOperand &Op = MI->getOperand(OpNo); 00894 if (Op.isReg()) { 00895 unsigned Reg = Op.getReg(); 00896 O << getRegisterName(Reg); 00897 } else if (Op.isImm()) { 00898 O << '#' << Op.getImm(); 00899 } else { 00900 assert(Op.isExpr() && "unknown operand kind in printOperand"); 00901 O << *Op.getExpr(); 00902 } 00903 } 00904 00905 void AArch64InstPrinter::printHexImm(const MCInst *MI, unsigned OpNo, 00906 raw_ostream &O) { 00907 const MCOperand &Op = MI->getOperand(OpNo); 00908 O << format("#%#llx", Op.getImm()); 00909 } 00910 00911 void AArch64InstPrinter::printPostIncOperand(const MCInst *MI, unsigned OpNo, 00912 unsigned Imm, raw_ostream &O) { 00913 const MCOperand &Op = MI->getOperand(OpNo); 00914 if (Op.isReg()) { 00915 unsigned Reg = Op.getReg(); 00916 if (Reg == AArch64::XZR) 00917 O << "#" << Imm; 00918 else 00919 O << getRegisterName(Reg); 00920 } else 00921 llvm_unreachable("unknown operand kind in printPostIncOperand64"); 00922 } 00923 00924 void AArch64InstPrinter::printVRegOperand(const MCInst *MI, unsigned OpNo, 00925 raw_ostream &O) { 00926 const MCOperand &Op = MI->getOperand(OpNo); 00927 assert(Op.isReg() && "Non-register vreg operand!"); 00928 unsigned Reg = Op.getReg(); 00929 O << getRegisterName(Reg, AArch64::vreg); 00930 } 00931 00932 void AArch64InstPrinter::printSysCROperand(const MCInst *MI, unsigned OpNo, 00933 raw_ostream &O) { 00934 const MCOperand &Op = MI->getOperand(OpNo); 00935 assert(Op.isImm() && "System instruction C[nm] operands must be immediates!"); 00936 O << "c" << Op.getImm(); 00937 } 00938 00939 void AArch64InstPrinter::printAddSubImm(const MCInst *MI, unsigned OpNum, 00940 raw_ostream &O) { 00941 const MCOperand &MO = MI->getOperand(OpNum); 00942 if (MO.isImm()) { 00943 unsigned Val = (MO.getImm() & 0xfff); 00944 assert(Val == MO.getImm() && "Add/sub immediate out of range!"); 00945 unsigned Shift = 00946 AArch64_AM::getShiftValue(MI->getOperand(OpNum + 1).getImm()); 00947 O << '#' << Val; 00948 if (Shift != 0) 00949 printShifter(MI, OpNum + 1, O); 00950 00951 if (CommentStream) 00952 *CommentStream << '=' << (Val << Shift) << '\n'; 00953 } else { 00954 assert(MO.isExpr() && "Unexpected operand type!"); 00955 O << *MO.getExpr(); 00956 printShifter(MI, OpNum + 1, O); 00957 } 00958 } 00959 00960 void AArch64InstPrinter::printLogicalImm32(const MCInst *MI, unsigned OpNum, 00961 raw_ostream &O) { 00962 uint64_t Val = MI->getOperand(OpNum).getImm(); 00963 O << "#0x"; 00964 O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 32)); 00965 } 00966 00967 void AArch64InstPrinter::printLogicalImm64(const MCInst *MI, unsigned OpNum, 00968 raw_ostream &O) { 00969 uint64_t Val = MI->getOperand(OpNum).getImm(); 00970 O << "#0x"; 00971 O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 64)); 00972 } 00973 00974 void AArch64InstPrinter::printShifter(const MCInst *MI, unsigned OpNum, 00975 raw_ostream &O) { 00976 unsigned Val = MI->getOperand(OpNum).getImm(); 00977 // LSL #0 should not be printed. 00978 if (AArch64_AM::getShiftType(Val) == AArch64_AM::LSL && 00979 AArch64_AM::getShiftValue(Val) == 0) 00980 return; 00981 O << ", " << AArch64_AM::getShiftExtendName(AArch64_AM::getShiftType(Val)) 00982 << " #" << AArch64_AM::getShiftValue(Val); 00983 } 00984 00985 void AArch64InstPrinter::printShiftedRegister(const MCInst *MI, unsigned OpNum, 00986 raw_ostream &O) { 00987 O << getRegisterName(MI->getOperand(OpNum).getReg()); 00988 printShifter(MI, OpNum + 1, O); 00989 } 00990 00991 void AArch64InstPrinter::printExtendedRegister(const MCInst *MI, unsigned OpNum, 00992 raw_ostream &O) { 00993 O << getRegisterName(MI->getOperand(OpNum).getReg()); 00994 printArithExtend(MI, OpNum + 1, O); 00995 } 00996 00997 void AArch64InstPrinter::printArithExtend(const MCInst *MI, unsigned OpNum, 00998 raw_ostream &O) { 00999 unsigned Val = MI->getOperand(OpNum).getImm(); 01000 AArch64_AM::ShiftExtendType ExtType = AArch64_AM::getArithExtendType(Val); 01001 unsigned ShiftVal = AArch64_AM::getArithShiftValue(Val); 01002 01003 // If the destination or first source register operand is [W]SP, print 01004 // UXTW/UXTX as LSL, and if the shift amount is also zero, print nothing at 01005 // all. 01006 if (ExtType == AArch64_AM::UXTW || ExtType == AArch64_AM::UXTX) { 01007 unsigned Dest = MI->getOperand(0).getReg(); 01008 unsigned Src1 = MI->getOperand(1).getReg(); 01009 if ( ((Dest == AArch64::SP || Src1 == AArch64::SP) && 01010 ExtType == AArch64_AM::UXTX) || 01011 ((Dest == AArch64::WSP || Src1 == AArch64::WSP) && 01012 ExtType == AArch64_AM::UXTW) ) { 01013 if (ShiftVal != 0) 01014 O << ", lsl #" << ShiftVal; 01015 return; 01016 } 01017 } 01018 O << ", " << AArch64_AM::getShiftExtendName(ExtType); 01019 if (ShiftVal != 0) 01020 O << " #" << ShiftVal; 01021 } 01022 01023 void AArch64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum, 01024 raw_ostream &O, char SrcRegKind, 01025 unsigned Width) { 01026 unsigned SignExtend = MI->getOperand(OpNum).getImm(); 01027 unsigned DoShift = MI->getOperand(OpNum + 1).getImm(); 01028 01029 // sxtw, sxtx, uxtw or lsl (== uxtx) 01030 bool IsLSL = !SignExtend && SrcRegKind == 'x'; 01031 if (IsLSL) 01032 O << "lsl"; 01033 else 01034 O << (SignExtend ? 's' : 'u') << "xt" << SrcRegKind; 01035 01036 if (DoShift || IsLSL) 01037 O << " #" << Log2_32(Width / 8); 01038 } 01039 01040 void AArch64InstPrinter::printCondCode(const MCInst *MI, unsigned OpNum, 01041 raw_ostream &O) { 01042 AArch64CC::CondCode CC = (AArch64CC::CondCode)MI->getOperand(OpNum).getImm(); 01043 O << AArch64CC::getCondCodeName(CC); 01044 } 01045 01046 void AArch64InstPrinter::printInverseCondCode(const MCInst *MI, unsigned OpNum, 01047 raw_ostream &O) { 01048 AArch64CC::CondCode CC = (AArch64CC::CondCode)MI->getOperand(OpNum).getImm(); 01049 O << AArch64CC::getCondCodeName(AArch64CC::getInvertedCondCode(CC)); 01050 } 01051 01052 void AArch64InstPrinter::printAMNoIndex(const MCInst *MI, unsigned OpNum, 01053 raw_ostream &O) { 01054 O << '[' << getRegisterName(MI->getOperand(OpNum).getReg()) << ']'; 01055 } 01056 01057 template<int Scale> 01058 void AArch64InstPrinter::printImmScale(const MCInst *MI, unsigned OpNum, 01059 raw_ostream &O) { 01060 O << '#' << Scale * MI->getOperand(OpNum).getImm(); 01061 } 01062 01063 void AArch64InstPrinter::printUImm12Offset(const MCInst *MI, unsigned OpNum, 01064 unsigned Scale, raw_ostream &O) { 01065 const MCOperand MO = MI->getOperand(OpNum); 01066 if (MO.isImm()) { 01067 O << "#" << (MO.getImm() * Scale); 01068 } else { 01069 assert(MO.isExpr() && "Unexpected operand type!"); 01070 O << *MO.getExpr(); 01071 } 01072 } 01073 01074 void AArch64InstPrinter::printAMIndexedWB(const MCInst *MI, unsigned OpNum, 01075 unsigned Scale, raw_ostream &O) { 01076 const MCOperand MO1 = MI->getOperand(OpNum + 1); 01077 O << '[' << getRegisterName(MI->getOperand(OpNum).getReg()); 01078 if (MO1.isImm()) { 01079 O << ", #" << (MO1.getImm() * Scale); 01080 } else { 01081 assert(MO1.isExpr() && "Unexpected operand type!"); 01082 O << ", " << *MO1.getExpr(); 01083 } 01084 O << ']'; 01085 } 01086 01087 void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum, 01088 raw_ostream &O) { 01089 unsigned prfop = MI->getOperand(OpNum).getImm(); 01090 bool Valid; 01091 StringRef Name = AArch64PRFM::PRFMMapper().toString(prfop, Valid); 01092 if (Valid) 01093 O << Name; 01094 else 01095 O << '#' << prfop; 01096 } 01097 01098 void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, 01099 raw_ostream &O) { 01100 const MCOperand &MO = MI->getOperand(OpNum); 01101 float FPImm = 01102 MO.isFPImm() ? MO.getFPImm() : AArch64_AM::getFPImmFloat(MO.getImm()); 01103 01104 // 8 decimal places are enough to perfectly represent permitted floats. 01105 O << format("#%.8f", FPImm); 01106 } 01107 01108 static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride = 1) { 01109 while (Stride--) { 01110 switch (Reg) { 01111 default: 01112 llvm_unreachable("Vector register expected!"); 01113 case AArch64::Q0: Reg = AArch64::Q1; break; 01114 case AArch64::Q1: Reg = AArch64::Q2; break; 01115 case AArch64::Q2: Reg = AArch64::Q3; break; 01116 case AArch64::Q3: Reg = AArch64::Q4; break; 01117 case AArch64::Q4: Reg = AArch64::Q5; break; 01118 case AArch64::Q5: Reg = AArch64::Q6; break; 01119 case AArch64::Q6: Reg = AArch64::Q7; break; 01120 case AArch64::Q7: Reg = AArch64::Q8; break; 01121 case AArch64::Q8: Reg = AArch64::Q9; break; 01122 case AArch64::Q9: Reg = AArch64::Q10; break; 01123 case AArch64::Q10: Reg = AArch64::Q11; break; 01124 case AArch64::Q11: Reg = AArch64::Q12; break; 01125 case AArch64::Q12: Reg = AArch64::Q13; break; 01126 case AArch64::Q13: Reg = AArch64::Q14; break; 01127 case AArch64::Q14: Reg = AArch64::Q15; break; 01128 case AArch64::Q15: Reg = AArch64::Q16; break; 01129 case AArch64::Q16: Reg = AArch64::Q17; break; 01130 case AArch64::Q17: Reg = AArch64::Q18; break; 01131 case AArch64::Q18: Reg = AArch64::Q19; break; 01132 case AArch64::Q19: Reg = AArch64::Q20; break; 01133 case AArch64::Q20: Reg = AArch64::Q21; break; 01134 case AArch64::Q21: Reg = AArch64::Q22; break; 01135 case AArch64::Q22: Reg = AArch64::Q23; break; 01136 case AArch64::Q23: Reg = AArch64::Q24; break; 01137 case AArch64::Q24: Reg = AArch64::Q25; break; 01138 case AArch64::Q25: Reg = AArch64::Q26; break; 01139 case AArch64::Q26: Reg = AArch64::Q27; break; 01140 case AArch64::Q27: Reg = AArch64::Q28; break; 01141 case AArch64::Q28: Reg = AArch64::Q29; break; 01142 case AArch64::Q29: Reg = AArch64::Q30; break; 01143 case AArch64::Q30: Reg = AArch64::Q31; break; 01144 // Vector lists can wrap around. 01145 case AArch64::Q31: 01146 Reg = AArch64::Q0; 01147 break; 01148 } 01149 } 01150 return Reg; 01151 } 01152 01153 void AArch64InstPrinter::printVectorList(const MCInst *MI, unsigned OpNum, 01154 raw_ostream &O, 01155 StringRef LayoutSuffix) { 01156 unsigned Reg = MI->getOperand(OpNum).getReg(); 01157 01158 O << "{ "; 01159 01160 // Work out how many registers there are in the list (if there is an actual 01161 // list). 01162 unsigned NumRegs = 1; 01163 if (MRI.getRegClass(AArch64::DDRegClassID).contains(Reg) || 01164 MRI.getRegClass(AArch64::QQRegClassID).contains(Reg)) 01165 NumRegs = 2; 01166 else if (MRI.getRegClass(AArch64::DDDRegClassID).contains(Reg) || 01167 MRI.getRegClass(AArch64::QQQRegClassID).contains(Reg)) 01168 NumRegs = 3; 01169 else if (MRI.getRegClass(AArch64::DDDDRegClassID).contains(Reg) || 01170 MRI.getRegClass(AArch64::QQQQRegClassID).contains(Reg)) 01171 NumRegs = 4; 01172 01173 // Now forget about the list and find out what the first register is. 01174 if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::dsub0)) 01175 Reg = FirstReg; 01176 else if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::qsub0)) 01177 Reg = FirstReg; 01178 01179 // If it's a D-reg, we need to promote it to the equivalent Q-reg before 01180 // printing (otherwise getRegisterName fails). 01181 if (MRI.getRegClass(AArch64::FPR64RegClassID).contains(Reg)) { 01182 const MCRegisterClass &FPR128RC = 01183 MRI.getRegClass(AArch64::FPR128RegClassID); 01184 Reg = MRI.getMatchingSuperReg(Reg, AArch64::dsub, &FPR128RC); 01185 } 01186 01187 for (unsigned i = 0; i < NumRegs; ++i, Reg = getNextVectorRegister(Reg)) { 01188 O << getRegisterName(Reg, AArch64::vreg) << LayoutSuffix; 01189 if (i + 1 != NumRegs) 01190 O << ", "; 01191 } 01192 01193 O << " }"; 01194 } 01195 01196 void AArch64InstPrinter::printImplicitlyTypedVectorList(const MCInst *MI, 01197 unsigned OpNum, 01198 raw_ostream &O) { 01199 printVectorList(MI, OpNum, O, ""); 01200 } 01201 01202 template <unsigned NumLanes, char LaneKind> 01203 void AArch64InstPrinter::printTypedVectorList(const MCInst *MI, unsigned OpNum, 01204 raw_ostream &O) { 01205 std::string Suffix("."); 01206 if (NumLanes) 01207 Suffix += itostr(NumLanes) + LaneKind; 01208 else 01209 Suffix += LaneKind; 01210 01211 printVectorList(MI, OpNum, O, Suffix); 01212 } 01213 01214 void AArch64InstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum, 01215 raw_ostream &O) { 01216 O << "[" << MI->getOperand(OpNum).getImm() << "]"; 01217 } 01218 01219 void AArch64InstPrinter::printAlignedLabel(const MCInst *MI, unsigned OpNum, 01220 raw_ostream &O) { 01221 const MCOperand &Op = MI->getOperand(OpNum); 01222 01223 // If the label has already been resolved to an immediate offset (say, when 01224 // we're running the disassembler), just print the immediate. 01225 if (Op.isImm()) { 01226 O << "#" << (Op.getImm() * 4); 01227 return; 01228 } 01229 01230 // If the branch target is simply an address then print it in hex. 01231 const MCConstantExpr *BranchTarget = 01232 dyn_cast<MCConstantExpr>(MI->getOperand(OpNum).getExpr()); 01233 int64_t Address; 01234 if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) { 01235 O << "0x"; 01236 O.write_hex(Address); 01237 } else { 01238 // Otherwise, just print the expression. 01239 O << *MI->getOperand(OpNum).getExpr(); 01240 } 01241 } 01242 01243 void AArch64InstPrinter::printAdrpLabel(const MCInst *MI, unsigned OpNum, 01244 raw_ostream &O) { 01245 const MCOperand &Op = MI->getOperand(OpNum); 01246 01247 // If the label has already been resolved to an immediate offset (say, when 01248 // we're running the disassembler), just print the immediate. 01249 if (Op.isImm()) { 01250 O << "#" << (Op.getImm() * (1 << 12)); 01251 return; 01252 } 01253 01254 // Otherwise, just print the expression. 01255 O << *MI->getOperand(OpNum).getExpr(); 01256 } 01257 01258 void AArch64InstPrinter::printBarrierOption(const MCInst *MI, unsigned OpNo, 01259 raw_ostream &O) { 01260 unsigned Val = MI->getOperand(OpNo).getImm(); 01261 unsigned Opcode = MI->getOpcode(); 01262 01263 bool Valid; 01264 StringRef Name; 01265 if (Opcode == AArch64::ISB) 01266 Name = AArch64ISB::ISBMapper().toString(Val, Valid); 01267 else 01268 Name = AArch64DB::DBarrierMapper().toString(Val, Valid); 01269 if (Valid) 01270 O << Name; 01271 else 01272 O << "#" << Val; 01273 } 01274 01275 void AArch64InstPrinter::printMRSSystemRegister(const MCInst *MI, unsigned OpNo, 01276 raw_ostream &O) { 01277 unsigned Val = MI->getOperand(OpNo).getImm(); 01278 01279 bool Valid; 01280 auto Mapper = AArch64SysReg::MRSMapper(getAvailableFeatures()); 01281 std::string Name = Mapper.toString(Val, Valid); 01282 01283 if (Valid) 01284 O << StringRef(Name).upper(); 01285 } 01286 01287 void AArch64InstPrinter::printMSRSystemRegister(const MCInst *MI, unsigned OpNo, 01288 raw_ostream &O) { 01289 unsigned Val = MI->getOperand(OpNo).getImm(); 01290 01291 bool Valid; 01292 auto Mapper = AArch64SysReg::MSRMapper(getAvailableFeatures()); 01293 std::string Name = Mapper.toString(Val, Valid); 01294 01295 if (Valid) 01296 O << StringRef(Name).upper(); 01297 } 01298 01299 void AArch64InstPrinter::printSystemPStateField(const MCInst *MI, unsigned OpNo, 01300 raw_ostream &O) { 01301 unsigned Val = MI->getOperand(OpNo).getImm(); 01302 01303 bool Valid; 01304 StringRef Name = AArch64PState::PStateMapper().toString(Val, Valid); 01305 if (Valid) 01306 O << StringRef(Name.str()).upper(); 01307 else 01308 O << "#" << Val; 01309 } 01310 01311 void AArch64InstPrinter::printSIMDType10Operand(const MCInst *MI, unsigned OpNo, 01312 raw_ostream &O) { 01313 unsigned RawVal = MI->getOperand(OpNo).getImm(); 01314 uint64_t Val = AArch64_AM::decodeAdvSIMDModImmType10(RawVal); 01315 O << format("#%#016llx", Val); 01316 }