AArch64AsmPrinter.cpp revision 0187e7a9ba5c50b4559e0c2e0afceb6d5cd32190
11bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma//===-- AArch64AsmPrinter.cpp - Print machine code to an AArch64 .s file --===// 21bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// 31bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// The LLVM Compiler Infrastructure 41bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// 51bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// This file is distributed under the University of Illinois Open Source 61bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// License. See LICENSE.TXT for details. 71bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// 81bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma//===----------------------------------------------------------------------===// 91bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// 101bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// This file contains a printer that converts from our internal representation 111bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// of machine-dependent LLVM code to GAS-format AArch64 assembly language. 121bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// 131bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma//===----------------------------------------------------------------------===// 143297e87c2ab798696b0fb3d06904dccea076b77aRob Landley 151bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#define DEBUG_TYPE "asm-printer" 161bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "AArch64AsmPrinter.h" 171bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "InstPrinter/AArch64InstPrinter.h" 181bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "llvm/DebugInfo.h" 191bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "llvm/ADT/SmallString.h" 201bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "llvm/CodeGen/MachineModuleInfoImpls.h" 211bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 221bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "llvm/MC/MCAsmInfo.h" 231bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "llvm/MC/MCInst.h" 241bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "llvm/MC/MCSymbol.h" 251bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "llvm/Support/TargetRegistry.h" 261bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "llvm/Target/Mangler.h" 271bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 281bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharmausing namespace llvm; 291bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 301bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma/// Try to print a floating-point register as if it belonged to a specified 311bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma/// register-class. For example the inline asm operand modifier "b" requires its 321bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma/// argument to be printed as "bN". 331bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharmastatic bool printModifiedFPRAsmOperand(const MachineOperand &MO, 341bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma const TargetRegisterInfo *TRI, 351bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma const TargetRegisterClass &RegClass, 361bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma raw_ostream &O) { 371bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (!MO.isReg()) 381bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return true; 391bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 401bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma for (MCRegAliasIterator AR(MO.getReg(), TRI, true); AR.isValid(); ++AR) { 411bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (RegClass.contains(*AR)) { 421bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << AArch64InstPrinter::getRegisterName(*AR); 431bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return false; 441bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 451bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 461bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return true; 471bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma} 481bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 491bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma/// Implements the 'w' and 'x' inline asm operand modifiers, which print a GPR 501bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma/// with the obvious type and an immediate 0 as either wzr or xzr. 511bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharmastatic bool printModifiedGPRAsmOperand(const MachineOperand &MO, 5282effc97f9f2d1c258ea50cb11b130753b8ba805Rob Landley const TargetRegisterInfo *TRI, 531bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma const TargetRegisterClass &RegClass, 541bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma raw_ostream &O) { 551bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma char Prefix = &RegClass == &AArch64::GPR32RegClass ? 'w' : 'x'; 561bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 571bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (MO.isImm() && MO.getImm() == 0) { 581bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << Prefix << "zr"; 591bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return false; 601bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } else if (MO.isReg()) { 611bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (MO.getReg() == AArch64::XSP || MO.getReg() == AArch64::WSP) { 621bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << (Prefix == 'x' ? "sp" : "wsp"); 631bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return false; 641bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 6582effc97f9f2d1c258ea50cb11b130753b8ba805Rob Landley 661bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma for (MCRegAliasIterator AR(MO.getReg(), TRI, true); AR.isValid(); ++AR) { 671bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (RegClass.contains(*AR)) { 681bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << AArch64InstPrinter::getRegisterName(*AR); 691bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return false; 701bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 711bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 721bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 731bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 741bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return true; 751bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma} 761bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 771bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharmabool AArch64AsmPrinter::printSymbolicAddress(const MachineOperand &MO, 781bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma bool PrintImmediatePrefix, 791bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma StringRef Suffix, raw_ostream &O) { 801bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma StringRef Name; 811bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma StringRef Modifier; 821bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma switch (MO.getType()) { 831bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma default: 841bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma llvm_unreachable("Unexpected operand for symbolic address constraint"); 851bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_GlobalAddress: 861bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Name = Mang->getSymbol(MO.getGlobal())->getName(); 871bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 881bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Global variables may be accessed either via a GOT or in various fun and 891bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // interesting TLS-model specific ways. Set the prefix modifier as 901bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // appropriate here. 911bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(MO.getGlobal())) { 921bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Reloc::Model RelocM = TM.getRelocationModel(); 931bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (GV->isThreadLocal()) { 941bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma switch (TM.getTLSModel(GV)) { 951bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case TLSModel::GeneralDynamic: 961bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Modifier = "tlsdesc"; 971bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma break; 981bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case TLSModel::LocalDynamic: 991bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Modifier = "dtprel"; 1001bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma break; 1011bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case TLSModel::InitialExec: 1021bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Modifier = "gottprel"; 1031bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma break; 1041bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case TLSModel::LocalExec: 1051bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Modifier = "tprel"; 1061bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma break; 1071bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 1081bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } else if (Subtarget->GVIsIndirectSymbol(GV, RelocM)) { 1091bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Modifier = "got"; 1101bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 1111bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 1121bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma break; 1131bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_BlockAddress: 1141bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Name = GetBlockAddressSymbol(MO.getBlockAddress())->getName(); 1151bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma break; 1161bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_ExternalSymbol: 1171bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Name = MO.getSymbolName(); 1181bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma break; 1191bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_ConstantPoolIndex: 1201bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Name = GetCPISymbol(MO.getIndex())->getName(); 12182effc97f9f2d1c258ea50cb11b130753b8ba805Rob Landley break; 1221bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 1231bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 1241bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Some instructions (notably ADRP) don't take the # prefix for 1251bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // immediates. Only print it if asked to. 1261bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (PrintImmediatePrefix) 1271bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << '#'; 1281bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 1291bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Only need the joining "_" if both the prefix and the suffix are 1301bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // non-null. This little block simply takes care of the four possibly 1311bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // combinations involved there. 1321bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (Modifier == "" && Suffix == "") 1331bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << Name; 13482effc97f9f2d1c258ea50cb11b130753b8ba805Rob Landley else if (Modifier == "" && Suffix != "") 1351bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << ":" << Suffix << ':' << Name; 1361bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma else if (Modifier != "" && Suffix == "") 1371bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << ":" << Modifier << ':' << Name; 1381bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma else 1391bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << ":" << Modifier << '_' << Suffix << ':' << Name; 1401bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 1411bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return false; 1421bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma} 1431bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 1441bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharmabool AArch64AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 1451bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma unsigned AsmVariant, 1461bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma const char *ExtraCode, raw_ostream &O) { 1471bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); 1481bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (!ExtraCode || !ExtraCode[0]) { 1491bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // There's actually no operand modifier, which leads to a slightly eclectic 1501bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // set of behaviour which we have to handle here. 15182effc97f9f2d1c258ea50cb11b130753b8ba805Rob Landley const MachineOperand &MO = MI->getOperand(OpNum); 1521bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma switch (MO.getType()) { 1531bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma default: 1541bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma llvm_unreachable("Unexpected operand for inline assembly"); 1551bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_Register: 1561bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // GCC prints the unmodified operand of a 'w' constraint as the vector 1571bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // register. Technically, we could allocate the argument as a VPR128, but 1581bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // that leads to extremely dodgy copies being generated to get the data 1591bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // there. 1601bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (printModifiedFPRAsmOperand(MO, TRI, AArch64::VPR128RegClass, O)) 1611bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << AArch64InstPrinter::getRegisterName(MO.getReg()); 1621bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma break; 1631bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_Immediate: 1641bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << '#' << MO.getImm(); 1651bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma break; 1661bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_FPImmediate: 1671bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma assert(MO.getFPImm()->isExactlyValue(0.0) && "Only FP 0.0 expected"); 1681bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << "#0.0"; 16982effc97f9f2d1c258ea50cb11b130753b8ba805Rob Landley break; 1701bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_BlockAddress: 1711bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_ConstantPoolIndex: 1721bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_GlobalAddress: 1731bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case MachineOperand::MO_ExternalSymbol: 1741bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return printSymbolicAddress(MO, false, "", O); 1751bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 1761bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return false; 1771bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 1781bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 1791bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // We have a real modifier to handle. 1801bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma switch(ExtraCode[0]) { 1811bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma default: 1821bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // See if this is a generic operand 1831bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O); 1841bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'c': // Don't print "#" before an immediate operand. 1851bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (!MI->getOperand(OpNum).isImm()) 1861bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return true; 1871bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << MI->getOperand(OpNum).getImm(); 1881bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return false; 1891bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'w': 1901bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output 32-bit general register operand, constant zero as wzr, or stack 1911bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // pointer as wsp. Ignored when used with other operand types. 1921bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return printModifiedGPRAsmOperand(MI->getOperand(OpNum), TRI, 1931bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma AArch64::GPR32RegClass, O); 1941bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'x': 1951bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output 64-bit general register operand, constant zero as xzr, or stack 1961bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // pointer as sp. Ignored when used with other operand types. 19782effc97f9f2d1c258ea50cb11b130753b8ba805Rob Landley return printModifiedGPRAsmOperand(MI->getOperand(OpNum), TRI, 1981bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma AArch64::GPR64RegClass, O); 1991bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'H': 2001bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output higher numbered of a 64-bit general register pair 2011bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'Q': 2021bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output least significant register of a 64-bit general register pair 2031bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'R': 2041bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output most significant register of a 64-bit general register pair 2051bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2061bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // FIXME note: these three operand modifiers will require, to some extent, 2071bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // adding a paired GPR64 register class. Initial investigation suggests that 2081bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // assertions are hit unless it has a type and is made legal for that type 2091bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // in ISelLowering. After that step is made, the number of modifications 2101bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // needed explodes (operation legality, calling conventions, stores, reg 2111bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // copies ...). 2121bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma llvm_unreachable("FIXME: Unimplemented register pairs"); 2131bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'b': 2141bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output 8-bit FP/SIMD scalar register operand, prefixed with b. 2151bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI, 2161bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma AArch64::FPR8RegClass, O); 2171bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'h': 2181bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output 16-bit FP/SIMD scalar register operand, prefixed with h. 2191bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI, 2201bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma AArch64::FPR16RegClass, O); 2211bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 's': 2221bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output 32-bit FP/SIMD scalar register operand, prefixed with s. 2231bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI, 2241bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma AArch64::FPR32RegClass, O); 2251bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'd': 2261bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output 64-bit FP/SIMD scalar register operand, prefixed with d. 2271bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI, 2281bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma AArch64::FPR64RegClass, O); 2291bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'q': 2301bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output 128-bit FP/SIMD scalar register operand, prefixed with q. 2311bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return printModifiedFPRAsmOperand(MI->getOperand(OpNum), TRI, 2321bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma AArch64::FPR128RegClass, O); 2331bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'A': 2341bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output symbolic address with appropriate relocation modifier (also 2351bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // suitable for ADRP). 2361bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return printSymbolicAddress(MI->getOperand(OpNum), false, "", O); 2371bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'L': 2381bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output bits 11:0 of symbolic address with appropriate :lo12: relocation 2391bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // modifier. 2401bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return printSymbolicAddress(MI->getOperand(OpNum), true, "lo12", O); 2411bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma case 'G': 2421bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output bits 23:12 of symbolic address with appropriate :hi12: relocation 2431bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // modifier (currently only for TLS local exec). 2441bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return printSymbolicAddress(MI->getOperand(OpNum), true, "hi12", O); 2451bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 2461bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2471bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2481bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma} 2491bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2501bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharmabool AArch64AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 2511bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma unsigned OpNum, 2521bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma unsigned AsmVariant, 2531bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma const char *ExtraCode, 2541bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma raw_ostream &O) { 2551bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Currently both the memory constraints (m and Q) behave the same and amount 2561bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // to the address as a single register. In future, we may allow "m" to provide 2571bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // both a base and an offset. 2581bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma const MachineOperand &MO = MI->getOperand(OpNum); 2591bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma assert(MO.isReg() && "unexpected inline assembly memory operand"); 2601bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma O << '[' << AArch64InstPrinter::getRegisterName(MO.getReg()) << ']'; 2611bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return false; 2621bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma} 2631bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2641bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma#include "AArch64GenMCPseudoLowering.inc" 2651bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2661bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharmavoid AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) { 2671bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Do any auto-generated pseudo lowerings. 2681bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (emitPseudoExpansionLowering(OutStreamer, MI)) 2691bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return; 2701bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2711bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma MCInst TmpInst; 2721bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma LowerAArch64MachineInstrToMCInst(MI, TmpInst, *this); 27382effc97f9f2d1c258ea50cb11b130753b8ba805Rob Landley OutStreamer.EmitInstruction(TmpInst); 2741bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma} 2751bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2761bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharmavoid AArch64AsmPrinter::EmitEndOfAsmFile(Module &M) { 2771bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (Subtarget->isTargetELF()) { 2781bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma const TargetLoweringObjectFileELF &TLOFELF = 2791bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); 2801bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2811bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); 2821bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2831bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma // Output stubs for external and common global variables. 2841bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 2851bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma if (!Stubs.empty()) { 2861bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); 2871bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma const DataLayout *TD = TM.getDataLayout(); 2881bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2891bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 2901bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma OutStreamer.EmitLabel(Stubs[i].first); 2911bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(), 2921bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma TD->getPointerSize(0), 0); 2931bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 2941bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma Stubs.clear(); 2951bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 2961bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma } 2971bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma} 2981bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 2991bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharmabool AArch64AsmPrinter::runOnMachineFunction(MachineFunction &MF) { 3001bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma return AsmPrinter::runOnMachineFunction(MF); 3011bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma} 3021bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 3031bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma// Force static initialization. 3041bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharmaextern "C" void LLVMInitializeAArch64AsmPrinter() { 3051bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma RegisterAsmPrinter<AArch64AsmPrinter> X(TheAArch64Target); 3061bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma} 3071bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma 3081bc21f0f98417bbad16db22ddb35eedae63765e6Ashwini Sharma