10b57cec5SDimitry Andric //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Streams SystemZ assembly language and associated data, in the form of 100b57cec5SDimitry Andric // MCInsts and MCExprs respectively. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "SystemZAsmPrinter.h" 150b57cec5SDimitry Andric #include "MCTargetDesc/SystemZInstPrinter.h" 160b57cec5SDimitry Andric #include "SystemZConstantPoolValue.h" 170b57cec5SDimitry Andric #include "SystemZMCInstLower.h" 180b57cec5SDimitry Andric #include "TargetInfo/SystemZTargetInfo.h" 19480093f4SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 220b57cec5SDimitry Andric #include "llvm/IR/Mangler.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCInstBuilder.h" 25480093f4SDimitry Andric #include "llvm/MC/MCSectionELF.h" 260b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 27*349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric using namespace llvm; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the 320b57cec5SDimitry Andric // GR64 register operands turned into GR32s. 330b57cec5SDimitry Andric static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) { 340b57cec5SDimitry Andric if (MI->isCompare()) 350b57cec5SDimitry Andric return MCInstBuilder(Opcode) 360b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 370b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()); 380b57cec5SDimitry Andric else 390b57cec5SDimitry Andric return MCInstBuilder(Opcode) 400b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 410b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg())) 420b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the 460b57cec5SDimitry Andric // GR64 register operands turned into GRH32s. 470b57cec5SDimitry Andric static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) { 480b57cec5SDimitry Andric if (MI->isCompare()) 490b57cec5SDimitry Andric return MCInstBuilder(Opcode) 500b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 510b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()); 520b57cec5SDimitry Andric else 530b57cec5SDimitry Andric return MCInstBuilder(Opcode) 540b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 550b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg())) 560b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the 600b57cec5SDimitry Andric // R2 register turned into a GR64. 610b57cec5SDimitry Andric static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) { 620b57cec5SDimitry Andric return MCInstBuilder(Opcode) 630b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 640b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 650b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())) 660b57cec5SDimitry Andric .addImm(MI->getOperand(3).getImm()) 670b57cec5SDimitry Andric .addImm(MI->getOperand(4).getImm()) 680b57cec5SDimitry Andric .addImm(MI->getOperand(5).getImm()); 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) { 720b57cec5SDimitry Andric StringRef Name = "__tls_get_offset"; 730b57cec5SDimitry Andric return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), 740b57cec5SDimitry Andric MCSymbolRefExpr::VK_PLT, 750b57cec5SDimitry Andric Context); 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) { 790b57cec5SDimitry Andric StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 800b57cec5SDimitry Andric return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), 810b57cec5SDimitry Andric MCSymbolRefExpr::VK_None, 820b57cec5SDimitry Andric Context); 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric // MI is an instruction that accepts an optional alignment hint, 860b57cec5SDimitry Andric // and which was already lowered to LoweredMI. If the alignment 870b57cec5SDimitry Andric // of the original memory operand is known, update LoweredMI to 880b57cec5SDimitry Andric // an instruction with the corresponding hint set. 890b57cec5SDimitry Andric static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI, 900b57cec5SDimitry Andric unsigned Opcode) { 910b57cec5SDimitry Andric if (!MI->hasOneMemOperand()) 920b57cec5SDimitry Andric return; 930b57cec5SDimitry Andric const MachineMemOperand *MMO = *MI->memoperands_begin(); 940b57cec5SDimitry Andric unsigned AlignmentHint = 0; 955ffd83dbSDimitry Andric if (MMO->getAlign() >= Align(16)) 960b57cec5SDimitry Andric AlignmentHint = 4; 975ffd83dbSDimitry Andric else if (MMO->getAlign() >= Align(8)) 980b57cec5SDimitry Andric AlignmentHint = 3; 990b57cec5SDimitry Andric if (AlignmentHint == 0) 1000b57cec5SDimitry Andric return; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric LoweredMI.setOpcode(Opcode); 1030b57cec5SDimitry Andric LoweredMI.addOperand(MCOperand::createImm(AlignmentHint)); 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric // MI loads the high part of a vector from memory. Return an instruction 1070b57cec5SDimitry Andric // that uses replicating vector load Opcode to do the same thing. 1080b57cec5SDimitry Andric static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) { 1090b57cec5SDimitry Andric return MCInstBuilder(Opcode) 1100b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 1110b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1120b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1130b57cec5SDimitry Andric .addReg(MI->getOperand(3).getReg()); 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric // MI stores the high part of a vector to memory. Return an instruction 1170b57cec5SDimitry Andric // that uses elemental vector store Opcode to do the same thing. 1180b57cec5SDimitry Andric static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) { 1190b57cec5SDimitry Andric return MCInstBuilder(Opcode) 1200b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 1210b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1220b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1230b57cec5SDimitry Andric .addReg(MI->getOperand(3).getReg()) 1240b57cec5SDimitry Andric .addImm(0); 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1275ffd83dbSDimitry Andric void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) { 1280b57cec5SDimitry Andric SystemZMCInstLower Lower(MF->getContext(), *this); 129fe6060f1SDimitry Andric const SystemZSubtarget *Subtarget = &MF->getSubtarget<SystemZSubtarget>(); 1300b57cec5SDimitry Andric MCInst LoweredMI; 1310b57cec5SDimitry Andric switch (MI->getOpcode()) { 1320b57cec5SDimitry Andric case SystemZ::Return: 133fe6060f1SDimitry Andric if (Subtarget->isTargetXPLINK64()) 134fe6060f1SDimitry Andric LoweredMI = 135fe6060f1SDimitry Andric MCInstBuilder(SystemZ::B).addReg(SystemZ::R7D).addImm(2).addReg(0); 136fe6060f1SDimitry Andric else 1370b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D); 1380b57cec5SDimitry Andric break; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric case SystemZ::CondReturn: 1410b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCR) 1420b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 1430b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 1440b57cec5SDimitry Andric .addReg(SystemZ::R14D); 1450b57cec5SDimitry Andric break; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric case SystemZ::CRBReturn: 1480b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CRB) 1490b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1500b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1510b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1520b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1530b57cec5SDimitry Andric .addImm(0); 1540b57cec5SDimitry Andric break; 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric case SystemZ::CGRBReturn: 1570b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGRB) 1580b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1590b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1600b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1610b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1620b57cec5SDimitry Andric .addImm(0); 1630b57cec5SDimitry Andric break; 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric case SystemZ::CIBReturn: 1660b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CIB) 1670b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1680b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 1690b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1700b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1710b57cec5SDimitry Andric .addImm(0); 1720b57cec5SDimitry Andric break; 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric case SystemZ::CGIBReturn: 1750b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGIB) 1760b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1770b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 1780b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1790b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1800b57cec5SDimitry Andric .addImm(0); 1810b57cec5SDimitry Andric break; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric case SystemZ::CLRBReturn: 1840b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLRB) 1850b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1860b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1870b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1880b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1890b57cec5SDimitry Andric .addImm(0); 1900b57cec5SDimitry Andric break; 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric case SystemZ::CLGRBReturn: 1930b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGRB) 1940b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1950b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1960b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1970b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1980b57cec5SDimitry Andric .addImm(0); 1990b57cec5SDimitry Andric break; 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric case SystemZ::CLIBReturn: 2020b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLIB) 2030b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2040b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2050b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2060b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2070b57cec5SDimitry Andric .addImm(0); 2080b57cec5SDimitry Andric break; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric case SystemZ::CLGIBReturn: 2110b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGIB) 2120b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2130b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2140b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2150b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2160b57cec5SDimitry Andric .addImm(0); 2170b57cec5SDimitry Andric break; 2180b57cec5SDimitry Andric 219fe6060f1SDimitry Andric case SystemZ::CallBRASL_XPLINK64: 220fe6060f1SDimitry Andric EmitToStreamer(*OutStreamer, 221fe6060f1SDimitry Andric MCInstBuilder(SystemZ::BRASL) 222fe6060f1SDimitry Andric .addReg(SystemZ::R7D) 223fe6060f1SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), 224fe6060f1SDimitry Andric MCSymbolRefExpr::VK_PLT))); 225fe6060f1SDimitry Andric EmitToStreamer( 226fe6060f1SDimitry Andric *OutStreamer, 227fe6060f1SDimitry Andric MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R3D)); 228fe6060f1SDimitry Andric return; 229fe6060f1SDimitry Andric 230fe6060f1SDimitry Andric case SystemZ::CallBASR_XPLINK64: 231fe6060f1SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR) 232fe6060f1SDimitry Andric .addReg(SystemZ::R7D) 233fe6060f1SDimitry Andric .addReg(MI->getOperand(0).getReg())); 234fe6060f1SDimitry Andric EmitToStreamer( 235fe6060f1SDimitry Andric *OutStreamer, 236fe6060f1SDimitry Andric MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D)); 237fe6060f1SDimitry Andric return; 238fe6060f1SDimitry Andric 2390b57cec5SDimitry Andric case SystemZ::CallBRASL: 2400b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 2410b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2420b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 2430b57cec5SDimitry Andric break; 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric case SystemZ::CallBASR: 2460b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BASR) 2470b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2480b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()); 2490b57cec5SDimitry Andric break; 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric case SystemZ::CallJG: 2520b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::JG) 2530b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 2540b57cec5SDimitry Andric break; 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric case SystemZ::CallBRCL: 2570b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRCL) 2580b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 2590b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2600b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT)); 2610b57cec5SDimitry Andric break; 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric case SystemZ::CallBR: 264e8d8bef9SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BR) 265e8d8bef9SDimitry Andric .addReg(MI->getOperand(0).getReg()); 2660b57cec5SDimitry Andric break; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric case SystemZ::CallBCR: 2690b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCR) 2700b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 2710b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 272e8d8bef9SDimitry Andric .addReg(MI->getOperand(2).getReg()); 2730b57cec5SDimitry Andric break; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric case SystemZ::CRBCall: 2760b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CRB) 2770b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2780b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 2790b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 280e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 2810b57cec5SDimitry Andric .addImm(0); 2820b57cec5SDimitry Andric break; 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric case SystemZ::CGRBCall: 2850b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGRB) 2860b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2870b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 2880b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 289e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 2900b57cec5SDimitry Andric .addImm(0); 2910b57cec5SDimitry Andric break; 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric case SystemZ::CIBCall: 2940b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CIB) 2950b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2960b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2970b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 298e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 2990b57cec5SDimitry Andric .addImm(0); 3000b57cec5SDimitry Andric break; 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric case SystemZ::CGIBCall: 3030b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGIB) 3040b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3050b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 3060b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 307e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 3080b57cec5SDimitry Andric .addImm(0); 3090b57cec5SDimitry Andric break; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric case SystemZ::CLRBCall: 3120b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLRB) 3130b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3140b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 3150b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 316e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 3170b57cec5SDimitry Andric .addImm(0); 3180b57cec5SDimitry Andric break; 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric case SystemZ::CLGRBCall: 3210b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGRB) 3220b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3230b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 3240b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 325e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 3260b57cec5SDimitry Andric .addImm(0); 3270b57cec5SDimitry Andric break; 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric case SystemZ::CLIBCall: 3300b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLIB) 3310b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3320b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 3330b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 334e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 3350b57cec5SDimitry Andric .addImm(0); 3360b57cec5SDimitry Andric break; 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric case SystemZ::CLGIBCall: 3390b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGIB) 3400b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3410b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 3420b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 343e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 3440b57cec5SDimitry Andric .addImm(0); 3450b57cec5SDimitry Andric break; 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric case SystemZ::TLS_GDCALL: 3480b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 3490b57cec5SDimitry Andric .addReg(SystemZ::R14D) 3500b57cec5SDimitry Andric .addExpr(getTLSGetOffset(MF->getContext())) 3510b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD)); 3520b57cec5SDimitry Andric break; 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric case SystemZ::TLS_LDCALL: 3550b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 3560b57cec5SDimitry Andric .addReg(SystemZ::R14D) 3570b57cec5SDimitry Andric .addExpr(getTLSGetOffset(MF->getContext())) 3580b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM)); 3590b57cec5SDimitry Andric break; 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric case SystemZ::GOT: 3620b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::LARL) 3630b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3640b57cec5SDimitry Andric .addExpr(getGlobalOffsetTable(MF->getContext())); 3650b57cec5SDimitry Andric break; 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric case SystemZ::IILF64: 3680b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::IILF) 3690b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 3700b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 3710b57cec5SDimitry Andric break; 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric case SystemZ::IIHF64: 3740b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::IIHF) 3750b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 3760b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 3770b57cec5SDimitry Andric break; 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric case SystemZ::RISBHH: 3800b57cec5SDimitry Andric case SystemZ::RISBHL: 3810b57cec5SDimitry Andric LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG); 3820b57cec5SDimitry Andric break; 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric case SystemZ::RISBLH: 3850b57cec5SDimitry Andric case SystemZ::RISBLL: 3860b57cec5SDimitry Andric LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG); 3870b57cec5SDimitry Andric break; 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric case SystemZ::VLVGP32: 3900b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLVGP) 3910b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3920b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg())) 3930b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())); 3940b57cec5SDimitry Andric break; 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric case SystemZ::VLR32: 3970b57cec5SDimitry Andric case SystemZ::VLR64: 3980b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLR) 3990b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 4000b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())); 4010b57cec5SDimitry Andric break; 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric case SystemZ::VL: 4040b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 4050b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign); 4060b57cec5SDimitry Andric break; 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric case SystemZ::VST: 4090b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 4100b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign); 4110b57cec5SDimitry Andric break; 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric case SystemZ::VLM: 4140b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 4150b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign); 4160b57cec5SDimitry Andric break; 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric case SystemZ::VSTM: 4190b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 4200b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign); 4210b57cec5SDimitry Andric break; 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric case SystemZ::VL32: 4240b57cec5SDimitry Andric LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF); 4250b57cec5SDimitry Andric break; 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric case SystemZ::VL64: 4280b57cec5SDimitry Andric LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG); 4290b57cec5SDimitry Andric break; 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric case SystemZ::VST32: 4320b57cec5SDimitry Andric LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF); 4330b57cec5SDimitry Andric break; 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric case SystemZ::VST64: 4360b57cec5SDimitry Andric LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG); 4370b57cec5SDimitry Andric break; 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric case SystemZ::LFER: 4400b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLGVF) 4410b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg())) 4420b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())) 4430b57cec5SDimitry Andric .addReg(0).addImm(0); 4440b57cec5SDimitry Andric break; 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric case SystemZ::LEFR: 4470b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLVGF) 4480b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 4490b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 4500b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 4510b57cec5SDimitry Andric .addReg(0).addImm(0); 4520b57cec5SDimitry Andric break; 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric #define LOWER_LOW(NAME) \ 4550b57cec5SDimitry Andric case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric LOWER_LOW(IILL); 4580b57cec5SDimitry Andric LOWER_LOW(IILH); 4590b57cec5SDimitry Andric LOWER_LOW(TMLL); 4600b57cec5SDimitry Andric LOWER_LOW(TMLH); 4610b57cec5SDimitry Andric LOWER_LOW(NILL); 4620b57cec5SDimitry Andric LOWER_LOW(NILH); 4630b57cec5SDimitry Andric LOWER_LOW(NILF); 4640b57cec5SDimitry Andric LOWER_LOW(OILL); 4650b57cec5SDimitry Andric LOWER_LOW(OILH); 4660b57cec5SDimitry Andric LOWER_LOW(OILF); 4670b57cec5SDimitry Andric LOWER_LOW(XILF); 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric #undef LOWER_LOW 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric #define LOWER_HIGH(NAME) \ 4720b57cec5SDimitry Andric case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric LOWER_HIGH(IIHL); 4750b57cec5SDimitry Andric LOWER_HIGH(IIHH); 4760b57cec5SDimitry Andric LOWER_HIGH(TMHL); 4770b57cec5SDimitry Andric LOWER_HIGH(TMHH); 4780b57cec5SDimitry Andric LOWER_HIGH(NIHL); 4790b57cec5SDimitry Andric LOWER_HIGH(NIHH); 4800b57cec5SDimitry Andric LOWER_HIGH(NIHF); 4810b57cec5SDimitry Andric LOWER_HIGH(OIHL); 4820b57cec5SDimitry Andric LOWER_HIGH(OIHH); 4830b57cec5SDimitry Andric LOWER_HIGH(OIHF); 4840b57cec5SDimitry Andric LOWER_HIGH(XIHF); 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric #undef LOWER_HIGH 4870b57cec5SDimitry Andric 4880b57cec5SDimitry Andric case SystemZ::Serialize: 4890b57cec5SDimitry Andric if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization()) 4900b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 4910b57cec5SDimitry Andric .addImm(14).addReg(SystemZ::R0D); 4920b57cec5SDimitry Andric else 4930b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 4940b57cec5SDimitry Andric .addImm(15).addReg(SystemZ::R0D); 4950b57cec5SDimitry Andric break; 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric // Emit nothing here but a comment if we can. 4980b57cec5SDimitry Andric case SystemZ::MemBarrier: 4990b57cec5SDimitry Andric OutStreamer->emitRawComment("MEMBARRIER"); 5000b57cec5SDimitry Andric return; 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric // We want to emit "j .+2" for traps, jumping to the relative immediate field 5030b57cec5SDimitry Andric // of the jump instruction, which is an illegal instruction. We cannot emit a 5040b57cec5SDimitry Andric // "." symbol, so create and emit a temp label before the instruction and use 5050b57cec5SDimitry Andric // that instead. 5060b57cec5SDimitry Andric case SystemZ::Trap: { 5070b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 5085ffd83dbSDimitry Andric OutStreamer->emitLabel(DotSym); 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 5110b57cec5SDimitry Andric const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 5120b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::J) 5130b57cec5SDimitry Andric .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric break; 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric // Conditional traps will create a branch on condition instruction that jumps 5180b57cec5SDimitry Andric // to the relative immediate field of the jump instruction. (eg. "jo .+2") 5190b57cec5SDimitry Andric case SystemZ::CondTrap: { 5200b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 5215ffd83dbSDimitry Andric OutStreamer->emitLabel(DotSym); 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 5240b57cec5SDimitry Andric const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 5250b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRC) 5260b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 5270b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 5280b57cec5SDimitry Andric .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 5290b57cec5SDimitry Andric } 5300b57cec5SDimitry Andric break; 5310b57cec5SDimitry Andric 5328bcb0991SDimitry Andric case TargetOpcode::FENTRY_CALL: 5338bcb0991SDimitry Andric LowerFENTRY_CALL(*MI, Lower); 5348bcb0991SDimitry Andric return; 5358bcb0991SDimitry Andric 5360b57cec5SDimitry Andric case TargetOpcode::STACKMAP: 5370b57cec5SDimitry Andric LowerSTACKMAP(*MI); 5380b57cec5SDimitry Andric return; 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric case TargetOpcode::PATCHPOINT: 5410b57cec5SDimitry Andric LowerPATCHPOINT(*MI, Lower); 5420b57cec5SDimitry Andric return; 5430b57cec5SDimitry Andric 544fe6060f1SDimitry Andric case SystemZ::EXRL_Pseudo: { 545fe6060f1SDimitry Andric unsigned TargetInsOpc = MI->getOperand(0).getImm(); 546fe6060f1SDimitry Andric Register LenMinus1Reg = MI->getOperand(1).getReg(); 547fe6060f1SDimitry Andric Register DestReg = MI->getOperand(2).getReg(); 548fe6060f1SDimitry Andric int64_t DestDisp = MI->getOperand(3).getImm(); 549fe6060f1SDimitry Andric Register SrcReg = MI->getOperand(4).getReg(); 550fe6060f1SDimitry Andric int64_t SrcDisp = MI->getOperand(5).getImm(); 551fe6060f1SDimitry Andric 552*349cc55cSDimitry Andric SystemZTargetStreamer *TS = getTargetStreamer(); 553fe6060f1SDimitry Andric MCSymbol *DotSym = nullptr; 554fe6060f1SDimitry Andric MCInst ET = MCInstBuilder(TargetInsOpc).addReg(DestReg) 555fe6060f1SDimitry Andric .addImm(DestDisp).addImm(1).addReg(SrcReg).addImm(SrcDisp); 556*349cc55cSDimitry Andric SystemZTargetStreamer::MCInstSTIPair ET_STI(ET, &MF->getSubtarget()); 557*349cc55cSDimitry Andric SystemZTargetStreamer::EXRLT2SymMap::iterator I = 558*349cc55cSDimitry Andric TS->EXRLTargets2Sym.find(ET_STI); 559*349cc55cSDimitry Andric if (I != TS->EXRLTargets2Sym.end()) 560fe6060f1SDimitry Andric DotSym = I->second; 561fe6060f1SDimitry Andric else 562*349cc55cSDimitry Andric TS->EXRLTargets2Sym[ET_STI] = DotSym = OutContext.createTempSymbol(); 563fe6060f1SDimitry Andric const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext); 564fe6060f1SDimitry Andric EmitToStreamer( 565fe6060f1SDimitry Andric *OutStreamer, 566fe6060f1SDimitry Andric MCInstBuilder(SystemZ::EXRL).addReg(LenMinus1Reg).addExpr(Dot)); 567fe6060f1SDimitry Andric return; 568fe6060f1SDimitry Andric } 569fe6060f1SDimitry Andric 5700b57cec5SDimitry Andric default: 5710b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 5720b57cec5SDimitry Andric break; 5730b57cec5SDimitry Andric } 5740b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, LoweredMI); 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric // Emit the largest nop instruction smaller than or equal to NumBytes 5780b57cec5SDimitry Andric // bytes. Return the size of nop emitted. 5790b57cec5SDimitry Andric static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, 5800b57cec5SDimitry Andric unsigned NumBytes, const MCSubtargetInfo &STI) { 5810b57cec5SDimitry Andric if (NumBytes < 2) { 5820b57cec5SDimitry Andric llvm_unreachable("Zero nops?"); 5830b57cec5SDimitry Andric return 0; 5840b57cec5SDimitry Andric } 5850b57cec5SDimitry Andric else if (NumBytes < 4) { 5865ffd83dbSDimitry Andric OutStreamer.emitInstruction( 5875ffd83dbSDimitry Andric MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D), STI); 5880b57cec5SDimitry Andric return 2; 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric else if (NumBytes < 6) { 5915ffd83dbSDimitry Andric OutStreamer.emitInstruction( 5925ffd83dbSDimitry Andric MCInstBuilder(SystemZ::BCAsm).addImm(0).addReg(0).addImm(0).addReg(0), 5930b57cec5SDimitry Andric STI); 5940b57cec5SDimitry Andric return 4; 5950b57cec5SDimitry Andric } 5960b57cec5SDimitry Andric else { 5970b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 5980b57cec5SDimitry Andric const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext); 5995ffd83dbSDimitry Andric OutStreamer.emitLabel(DotSym); 6005ffd83dbSDimitry Andric OutStreamer.emitInstruction( 6015ffd83dbSDimitry Andric MCInstBuilder(SystemZ::BRCLAsm).addImm(0).addExpr(Dot), STI); 6020b57cec5SDimitry Andric return 6; 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 6068bcb0991SDimitry Andric void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI, 6078bcb0991SDimitry Andric SystemZMCInstLower &Lower) { 6088bcb0991SDimitry Andric MCContext &Ctx = MF->getContext(); 609480093f4SDimitry Andric if (MF->getFunction().hasFnAttribute("mrecord-mcount")) { 610480093f4SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 611480093f4SDimitry Andric OutStreamer->PushSection(); 612480093f4SDimitry Andric OutStreamer->SwitchSection( 613480093f4SDimitry Andric Ctx.getELFSection("__mcount_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC)); 6145ffd83dbSDimitry Andric OutStreamer->emitSymbolValue(DotSym, 8); 615480093f4SDimitry Andric OutStreamer->PopSection(); 6165ffd83dbSDimitry Andric OutStreamer->emitLabel(DotSym); 617480093f4SDimitry Andric } 618480093f4SDimitry Andric 619480093f4SDimitry Andric if (MF->getFunction().hasFnAttribute("mnop-mcount")) { 6208bcb0991SDimitry Andric EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo()); 6218bcb0991SDimitry Andric return; 6228bcb0991SDimitry Andric } 6238bcb0991SDimitry Andric 6248bcb0991SDimitry Andric MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__"); 6258bcb0991SDimitry Andric const MCSymbolRefExpr *Op = 6268bcb0991SDimitry Andric MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_PLT, Ctx); 6275ffd83dbSDimitry Andric OutStreamer->emitInstruction( 6285ffd83dbSDimitry Andric MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R0D).addExpr(Op), 6295ffd83dbSDimitry Andric getSubtargetInfo()); 6308bcb0991SDimitry Andric } 6318bcb0991SDimitry Andric 6320b57cec5SDimitry Andric void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) { 6330b57cec5SDimitry Andric const SystemZInstrInfo *TII = 6340b57cec5SDimitry Andric static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo()); 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric unsigned NumNOPBytes = MI.getOperand(1).getImm(); 6370b57cec5SDimitry Andric 638480093f4SDimitry Andric auto &Ctx = OutStreamer->getContext(); 639480093f4SDimitry Andric MCSymbol *MILabel = Ctx.createTempSymbol(); 6405ffd83dbSDimitry Andric OutStreamer->emitLabel(MILabel); 641480093f4SDimitry Andric 642480093f4SDimitry Andric SM.recordStackMap(*MILabel, MI); 6430b57cec5SDimitry Andric assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!"); 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric // Scan ahead to trim the shadow. 6460b57cec5SDimitry Andric unsigned ShadowBytes = 0; 6470b57cec5SDimitry Andric const MachineBasicBlock &MBB = *MI.getParent(); 6480b57cec5SDimitry Andric MachineBasicBlock::const_iterator MII(MI); 6490b57cec5SDimitry Andric ++MII; 6500b57cec5SDimitry Andric while (ShadowBytes < NumNOPBytes) { 6510b57cec5SDimitry Andric if (MII == MBB.end() || 6520b57cec5SDimitry Andric MII->getOpcode() == TargetOpcode::PATCHPOINT || 6530b57cec5SDimitry Andric MII->getOpcode() == TargetOpcode::STACKMAP) 6540b57cec5SDimitry Andric break; 6550b57cec5SDimitry Andric ShadowBytes += TII->getInstSizeInBytes(*MII); 6560b57cec5SDimitry Andric if (MII->isCall()) 6570b57cec5SDimitry Andric break; 6580b57cec5SDimitry Andric ++MII; 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric // Emit nops. 6620b57cec5SDimitry Andric while (ShadowBytes < NumNOPBytes) 6630b57cec5SDimitry Andric ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes, 6640b57cec5SDimitry Andric getSubtargetInfo()); 6650b57cec5SDimitry Andric } 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric // Lower a patchpoint of the form: 6680b57cec5SDimitry Andric // [<def>], <id>, <numBytes>, <target>, <numArgs> 6690b57cec5SDimitry Andric void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI, 6700b57cec5SDimitry Andric SystemZMCInstLower &Lower) { 671480093f4SDimitry Andric auto &Ctx = OutStreamer->getContext(); 672480093f4SDimitry Andric MCSymbol *MILabel = Ctx.createTempSymbol(); 6735ffd83dbSDimitry Andric OutStreamer->emitLabel(MILabel); 674480093f4SDimitry Andric 675480093f4SDimitry Andric SM.recordPatchPoint(*MILabel, MI); 6760b57cec5SDimitry Andric PatchPointOpers Opers(&MI); 6770b57cec5SDimitry Andric 6780b57cec5SDimitry Andric unsigned EncodedBytes = 0; 6790b57cec5SDimitry Andric const MachineOperand &CalleeMO = Opers.getCallTarget(); 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andric if (CalleeMO.isImm()) { 6820b57cec5SDimitry Andric uint64_t CallTarget = CalleeMO.getImm(); 6830b57cec5SDimitry Andric if (CallTarget) { 6840b57cec5SDimitry Andric unsigned ScratchIdx = -1; 6850b57cec5SDimitry Andric unsigned ScratchReg = 0; 6860b57cec5SDimitry Andric do { 6870b57cec5SDimitry Andric ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1); 6880b57cec5SDimitry Andric ScratchReg = MI.getOperand(ScratchIdx).getReg(); 6890b57cec5SDimitry Andric } while (ScratchReg == SystemZ::R0D); 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric // Materialize the call target address 6920b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF) 6930b57cec5SDimitry Andric .addReg(ScratchReg) 6940b57cec5SDimitry Andric .addImm(CallTarget & 0xFFFFFFFF)); 6950b57cec5SDimitry Andric EncodedBytes += 6; 6960b57cec5SDimitry Andric if (CallTarget >> 32) { 6970b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF) 6980b57cec5SDimitry Andric .addReg(ScratchReg) 6990b57cec5SDimitry Andric .addImm(CallTarget >> 32)); 7000b57cec5SDimitry Andric EncodedBytes += 6; 7010b57cec5SDimitry Andric } 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR) 7040b57cec5SDimitry Andric .addReg(SystemZ::R14D) 7050b57cec5SDimitry Andric .addReg(ScratchReg)); 7060b57cec5SDimitry Andric EncodedBytes += 2; 7070b57cec5SDimitry Andric } 7080b57cec5SDimitry Andric } else if (CalleeMO.isGlobal()) { 7090b57cec5SDimitry Andric const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT); 7100b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL) 7110b57cec5SDimitry Andric .addReg(SystemZ::R14D) 7120b57cec5SDimitry Andric .addExpr(Expr)); 7130b57cec5SDimitry Andric EncodedBytes += 6; 7140b57cec5SDimitry Andric } 7150b57cec5SDimitry Andric 7160b57cec5SDimitry Andric // Emit padding. 7170b57cec5SDimitry Andric unsigned NumBytes = Opers.getNumPatchBytes(); 7180b57cec5SDimitry Andric assert(NumBytes >= EncodedBytes && 7190b57cec5SDimitry Andric "Patchpoint can't request size less than the length of a call."); 7200b57cec5SDimitry Andric assert((NumBytes - EncodedBytes) % 2 == 0 && 7210b57cec5SDimitry Andric "Invalid number of NOP bytes requested!"); 7220b57cec5SDimitry Andric while (EncodedBytes < NumBytes) 7230b57cec5SDimitry Andric EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes, 7240b57cec5SDimitry Andric getSubtargetInfo()); 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric // Convert a SystemZ-specific constant pool modifier into the associated 7280b57cec5SDimitry Andric // MCSymbolRefExpr variant kind. 7290b57cec5SDimitry Andric static MCSymbolRefExpr::VariantKind 7300b57cec5SDimitry Andric getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) { 7310b57cec5SDimitry Andric switch (Modifier) { 7320b57cec5SDimitry Andric case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; 7330b57cec5SDimitry Andric case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM; 7340b57cec5SDimitry Andric case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF; 7350b57cec5SDimitry Andric case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF; 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric llvm_unreachable("Invalid SystemCPModifier!"); 7380b57cec5SDimitry Andric } 7390b57cec5SDimitry Andric 7405ffd83dbSDimitry Andric void SystemZAsmPrinter::emitMachineConstantPoolValue( 7415ffd83dbSDimitry Andric MachineConstantPoolValue *MCPV) { 7420b57cec5SDimitry Andric auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV); 7430b57cec5SDimitry Andric 7440b57cec5SDimitry Andric const MCExpr *Expr = 7450b57cec5SDimitry Andric MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()), 7460b57cec5SDimitry Andric getModifierVariantKind(ZCPV->getModifier()), 7470b57cec5SDimitry Andric OutContext); 7480b57cec5SDimitry Andric uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType()); 7490b57cec5SDimitry Andric 7505ffd83dbSDimitry Andric OutStreamer->emitValue(Expr, Size); 7510b57cec5SDimitry Andric } 7520b57cec5SDimitry Andric 7530b57cec5SDimitry Andric bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 7540b57cec5SDimitry Andric const char *ExtraCode, 7550b57cec5SDimitry Andric raw_ostream &OS) { 756fe6060f1SDimitry Andric const MCRegisterInfo &MRI = *TM.getMCRegisterInfo(); 757fe6060f1SDimitry Andric const MachineOperand &MO = MI->getOperand(OpNo); 758fe6060f1SDimitry Andric MCOperand MCOp; 759fe6060f1SDimitry Andric if (ExtraCode) { 760fe6060f1SDimitry Andric if (ExtraCode[0] == 'N' && !ExtraCode[1] && MO.isReg() && 761fe6060f1SDimitry Andric SystemZ::GR128BitRegClass.contains(MO.getReg())) 762fe6060f1SDimitry Andric MCOp = 763fe6060f1SDimitry Andric MCOperand::createReg(MRI.getSubReg(MO.getReg(), SystemZ::subreg_l64)); 764fe6060f1SDimitry Andric else 7650b57cec5SDimitry Andric return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); 766fe6060f1SDimitry Andric } else { 7670b57cec5SDimitry Andric SystemZMCInstLower Lower(MF->getContext(), *this); 768fe6060f1SDimitry Andric MCOp = Lower.lowerOperand(MO); 769fe6060f1SDimitry Andric } 770fe6060f1SDimitry Andric SystemZInstPrinter::printOperand(MCOp, MAI, OS); 7710b57cec5SDimitry Andric return false; 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric 7740b57cec5SDimitry Andric bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 7750b57cec5SDimitry Andric unsigned OpNo, 7760b57cec5SDimitry Andric const char *ExtraCode, 7770b57cec5SDimitry Andric raw_ostream &OS) { 778*349cc55cSDimitry Andric SystemZInstPrinter:: 779*349cc55cSDimitry Andric printAddress(MAI, MI->getOperand(OpNo).getReg(), 780*349cc55cSDimitry Andric MCOperand::createImm(MI->getOperand(OpNo + 1).getImm()), 7810b57cec5SDimitry Andric MI->getOperand(OpNo + 2).getReg(), OS); 7820b57cec5SDimitry Andric return false; 7830b57cec5SDimitry Andric } 7840b57cec5SDimitry Andric 7855ffd83dbSDimitry Andric void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) { 7860b57cec5SDimitry Andric emitStackMaps(SM); 7870b57cec5SDimitry Andric } 7880b57cec5SDimitry Andric 7890b57cec5SDimitry Andric // Force static initialization. 790480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmPrinter() { 7910b57cec5SDimitry Andric RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget()); 7920b57cec5SDimitry Andric } 793