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" 270b57cec5SDimitry Andric #include "llvm/Support/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); 1290b57cec5SDimitry Andric MCInst LoweredMI; 1300b57cec5SDimitry Andric switch (MI->getOpcode()) { 1310b57cec5SDimitry Andric case SystemZ::Return: 1320b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D); 1330b57cec5SDimitry Andric break; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric case SystemZ::CondReturn: 1360b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCR) 1370b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 1380b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 1390b57cec5SDimitry Andric .addReg(SystemZ::R14D); 1400b57cec5SDimitry Andric break; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric case SystemZ::CRBReturn: 1430b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CRB) 1440b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1450b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1460b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1470b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1480b57cec5SDimitry Andric .addImm(0); 1490b57cec5SDimitry Andric break; 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric case SystemZ::CGRBReturn: 1520b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGRB) 1530b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1540b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1550b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1560b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1570b57cec5SDimitry Andric .addImm(0); 1580b57cec5SDimitry Andric break; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric case SystemZ::CIBReturn: 1610b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CIB) 1620b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1630b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 1640b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1650b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1660b57cec5SDimitry Andric .addImm(0); 1670b57cec5SDimitry Andric break; 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric case SystemZ::CGIBReturn: 1700b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGIB) 1710b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1720b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 1730b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1740b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1750b57cec5SDimitry Andric .addImm(0); 1760b57cec5SDimitry Andric break; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric case SystemZ::CLRBReturn: 1790b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLRB) 1800b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1810b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1820b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1830b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1840b57cec5SDimitry Andric .addImm(0); 1850b57cec5SDimitry Andric break; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric case SystemZ::CLGRBReturn: 1880b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGRB) 1890b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1900b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1910b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1920b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1930b57cec5SDimitry Andric .addImm(0); 1940b57cec5SDimitry Andric break; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric case SystemZ::CLIBReturn: 1970b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLIB) 1980b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1990b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2000b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2010b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2020b57cec5SDimitry Andric .addImm(0); 2030b57cec5SDimitry Andric break; 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric case SystemZ::CLGIBReturn: 2060b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGIB) 2070b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2080b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2090b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2100b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2110b57cec5SDimitry Andric .addImm(0); 2120b57cec5SDimitry Andric break; 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric case SystemZ::CallBRASL: 2150b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 2160b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2170b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 2180b57cec5SDimitry Andric break; 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric case SystemZ::CallBASR: 2210b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BASR) 2220b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2230b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()); 2240b57cec5SDimitry Andric break; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric case SystemZ::CallJG: 2270b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::JG) 2280b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 2290b57cec5SDimitry Andric break; 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric case SystemZ::CallBRCL: 2320b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRCL) 2330b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 2340b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2350b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT)); 2360b57cec5SDimitry Andric break; 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric case SystemZ::CallBR: 239*e8d8bef9SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BR) 240*e8d8bef9SDimitry Andric .addReg(MI->getOperand(0).getReg()); 2410b57cec5SDimitry Andric break; 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric case SystemZ::CallBCR: 2440b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCR) 2450b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 2460b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 247*e8d8bef9SDimitry Andric .addReg(MI->getOperand(2).getReg()); 2480b57cec5SDimitry Andric break; 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric case SystemZ::CRBCall: 2510b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CRB) 2520b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2530b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 2540b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 255*e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 2560b57cec5SDimitry Andric .addImm(0); 2570b57cec5SDimitry Andric break; 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric case SystemZ::CGRBCall: 2600b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGRB) 2610b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2620b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 2630b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 264*e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 2650b57cec5SDimitry Andric .addImm(0); 2660b57cec5SDimitry Andric break; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric case SystemZ::CIBCall: 2690b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CIB) 2700b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2710b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2720b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 273*e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 2740b57cec5SDimitry Andric .addImm(0); 2750b57cec5SDimitry Andric break; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric case SystemZ::CGIBCall: 2780b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGIB) 2790b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2800b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2810b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 282*e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 2830b57cec5SDimitry Andric .addImm(0); 2840b57cec5SDimitry Andric break; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric case SystemZ::CLRBCall: 2870b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLRB) 2880b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2890b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 2900b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 291*e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 2920b57cec5SDimitry Andric .addImm(0); 2930b57cec5SDimitry Andric break; 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric case SystemZ::CLGRBCall: 2960b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGRB) 2970b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2980b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 2990b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 300*e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 3010b57cec5SDimitry Andric .addImm(0); 3020b57cec5SDimitry Andric break; 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric case SystemZ::CLIBCall: 3050b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLIB) 3060b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3070b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 3080b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 309*e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 3100b57cec5SDimitry Andric .addImm(0); 3110b57cec5SDimitry Andric break; 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric case SystemZ::CLGIBCall: 3140b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGIB) 3150b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3160b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 3170b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 318*e8d8bef9SDimitry Andric .addReg(MI->getOperand(3).getReg()) 3190b57cec5SDimitry Andric .addImm(0); 3200b57cec5SDimitry Andric break; 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric case SystemZ::TLS_GDCALL: 3230b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 3240b57cec5SDimitry Andric .addReg(SystemZ::R14D) 3250b57cec5SDimitry Andric .addExpr(getTLSGetOffset(MF->getContext())) 3260b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD)); 3270b57cec5SDimitry Andric break; 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric case SystemZ::TLS_LDCALL: 3300b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 3310b57cec5SDimitry Andric .addReg(SystemZ::R14D) 3320b57cec5SDimitry Andric .addExpr(getTLSGetOffset(MF->getContext())) 3330b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM)); 3340b57cec5SDimitry Andric break; 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric case SystemZ::GOT: 3370b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::LARL) 3380b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3390b57cec5SDimitry Andric .addExpr(getGlobalOffsetTable(MF->getContext())); 3400b57cec5SDimitry Andric break; 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric case SystemZ::IILF64: 3430b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::IILF) 3440b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 3450b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 3460b57cec5SDimitry Andric break; 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric case SystemZ::IIHF64: 3490b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::IIHF) 3500b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 3510b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 3520b57cec5SDimitry Andric break; 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric case SystemZ::RISBHH: 3550b57cec5SDimitry Andric case SystemZ::RISBHL: 3560b57cec5SDimitry Andric LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG); 3570b57cec5SDimitry Andric break; 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric case SystemZ::RISBLH: 3600b57cec5SDimitry Andric case SystemZ::RISBLL: 3610b57cec5SDimitry Andric LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG); 3620b57cec5SDimitry Andric break; 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric case SystemZ::VLVGP32: 3650b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLVGP) 3660b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3670b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg())) 3680b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())); 3690b57cec5SDimitry Andric break; 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric case SystemZ::VLR32: 3720b57cec5SDimitry Andric case SystemZ::VLR64: 3730b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLR) 3740b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 3750b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())); 3760b57cec5SDimitry Andric break; 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric case SystemZ::VL: 3790b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 3800b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign); 3810b57cec5SDimitry Andric break; 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric case SystemZ::VST: 3840b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 3850b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign); 3860b57cec5SDimitry Andric break; 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric case SystemZ::VLM: 3890b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 3900b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign); 3910b57cec5SDimitry Andric break; 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric case SystemZ::VSTM: 3940b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 3950b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign); 3960b57cec5SDimitry Andric break; 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric case SystemZ::VL32: 3990b57cec5SDimitry Andric LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF); 4000b57cec5SDimitry Andric break; 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric case SystemZ::VL64: 4030b57cec5SDimitry Andric LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG); 4040b57cec5SDimitry Andric break; 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric case SystemZ::VST32: 4070b57cec5SDimitry Andric LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF); 4080b57cec5SDimitry Andric break; 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric case SystemZ::VST64: 4110b57cec5SDimitry Andric LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG); 4120b57cec5SDimitry Andric break; 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric case SystemZ::LFER: 4150b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLGVF) 4160b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg())) 4170b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())) 4180b57cec5SDimitry Andric .addReg(0).addImm(0); 4190b57cec5SDimitry Andric break; 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric case SystemZ::LEFR: 4220b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLVGF) 4230b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 4240b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 4250b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 4260b57cec5SDimitry Andric .addReg(0).addImm(0); 4270b57cec5SDimitry Andric break; 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric #define LOWER_LOW(NAME) \ 4300b57cec5SDimitry Andric case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric LOWER_LOW(IILL); 4330b57cec5SDimitry Andric LOWER_LOW(IILH); 4340b57cec5SDimitry Andric LOWER_LOW(TMLL); 4350b57cec5SDimitry Andric LOWER_LOW(TMLH); 4360b57cec5SDimitry Andric LOWER_LOW(NILL); 4370b57cec5SDimitry Andric LOWER_LOW(NILH); 4380b57cec5SDimitry Andric LOWER_LOW(NILF); 4390b57cec5SDimitry Andric LOWER_LOW(OILL); 4400b57cec5SDimitry Andric LOWER_LOW(OILH); 4410b57cec5SDimitry Andric LOWER_LOW(OILF); 4420b57cec5SDimitry Andric LOWER_LOW(XILF); 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric #undef LOWER_LOW 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric #define LOWER_HIGH(NAME) \ 4470b57cec5SDimitry Andric case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric LOWER_HIGH(IIHL); 4500b57cec5SDimitry Andric LOWER_HIGH(IIHH); 4510b57cec5SDimitry Andric LOWER_HIGH(TMHL); 4520b57cec5SDimitry Andric LOWER_HIGH(TMHH); 4530b57cec5SDimitry Andric LOWER_HIGH(NIHL); 4540b57cec5SDimitry Andric LOWER_HIGH(NIHH); 4550b57cec5SDimitry Andric LOWER_HIGH(NIHF); 4560b57cec5SDimitry Andric LOWER_HIGH(OIHL); 4570b57cec5SDimitry Andric LOWER_HIGH(OIHH); 4580b57cec5SDimitry Andric LOWER_HIGH(OIHF); 4590b57cec5SDimitry Andric LOWER_HIGH(XIHF); 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric #undef LOWER_HIGH 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric case SystemZ::Serialize: 4640b57cec5SDimitry Andric if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization()) 4650b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 4660b57cec5SDimitry Andric .addImm(14).addReg(SystemZ::R0D); 4670b57cec5SDimitry Andric else 4680b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 4690b57cec5SDimitry Andric .addImm(15).addReg(SystemZ::R0D); 4700b57cec5SDimitry Andric break; 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric // Emit nothing here but a comment if we can. 4730b57cec5SDimitry Andric case SystemZ::MemBarrier: 4740b57cec5SDimitry Andric OutStreamer->emitRawComment("MEMBARRIER"); 4750b57cec5SDimitry Andric return; 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric // We want to emit "j .+2" for traps, jumping to the relative immediate field 4780b57cec5SDimitry Andric // of the jump instruction, which is an illegal instruction. We cannot emit a 4790b57cec5SDimitry Andric // "." symbol, so create and emit a temp label before the instruction and use 4800b57cec5SDimitry Andric // that instead. 4810b57cec5SDimitry Andric case SystemZ::Trap: { 4820b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 4835ffd83dbSDimitry Andric OutStreamer->emitLabel(DotSym); 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 4860b57cec5SDimitry Andric const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 4870b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::J) 4880b57cec5SDimitry Andric .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 4890b57cec5SDimitry Andric } 4900b57cec5SDimitry Andric break; 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric // Conditional traps will create a branch on condition instruction that jumps 4930b57cec5SDimitry Andric // to the relative immediate field of the jump instruction. (eg. "jo .+2") 4940b57cec5SDimitry Andric case SystemZ::CondTrap: { 4950b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 4965ffd83dbSDimitry Andric OutStreamer->emitLabel(DotSym); 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 4990b57cec5SDimitry Andric const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 5000b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRC) 5010b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 5020b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 5030b57cec5SDimitry Andric .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric break; 5060b57cec5SDimitry Andric 5078bcb0991SDimitry Andric case TargetOpcode::FENTRY_CALL: 5088bcb0991SDimitry Andric LowerFENTRY_CALL(*MI, Lower); 5098bcb0991SDimitry Andric return; 5108bcb0991SDimitry Andric 5110b57cec5SDimitry Andric case TargetOpcode::STACKMAP: 5120b57cec5SDimitry Andric LowerSTACKMAP(*MI); 5130b57cec5SDimitry Andric return; 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric case TargetOpcode::PATCHPOINT: 5160b57cec5SDimitry Andric LowerPATCHPOINT(*MI, Lower); 5170b57cec5SDimitry Andric return; 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric default: 5200b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 5210b57cec5SDimitry Andric break; 5220b57cec5SDimitry Andric } 5230b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, LoweredMI); 5240b57cec5SDimitry Andric } 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric // Emit the largest nop instruction smaller than or equal to NumBytes 5270b57cec5SDimitry Andric // bytes. Return the size of nop emitted. 5280b57cec5SDimitry Andric static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, 5290b57cec5SDimitry Andric unsigned NumBytes, const MCSubtargetInfo &STI) { 5300b57cec5SDimitry Andric if (NumBytes < 2) { 5310b57cec5SDimitry Andric llvm_unreachable("Zero nops?"); 5320b57cec5SDimitry Andric return 0; 5330b57cec5SDimitry Andric } 5340b57cec5SDimitry Andric else if (NumBytes < 4) { 5355ffd83dbSDimitry Andric OutStreamer.emitInstruction( 5365ffd83dbSDimitry Andric MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D), STI); 5370b57cec5SDimitry Andric return 2; 5380b57cec5SDimitry Andric } 5390b57cec5SDimitry Andric else if (NumBytes < 6) { 5405ffd83dbSDimitry Andric OutStreamer.emitInstruction( 5415ffd83dbSDimitry Andric MCInstBuilder(SystemZ::BCAsm).addImm(0).addReg(0).addImm(0).addReg(0), 5420b57cec5SDimitry Andric STI); 5430b57cec5SDimitry Andric return 4; 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric else { 5460b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 5470b57cec5SDimitry Andric const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext); 5485ffd83dbSDimitry Andric OutStreamer.emitLabel(DotSym); 5495ffd83dbSDimitry Andric OutStreamer.emitInstruction( 5505ffd83dbSDimitry Andric MCInstBuilder(SystemZ::BRCLAsm).addImm(0).addExpr(Dot), STI); 5510b57cec5SDimitry Andric return 6; 5520b57cec5SDimitry Andric } 5530b57cec5SDimitry Andric } 5540b57cec5SDimitry Andric 5558bcb0991SDimitry Andric void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI, 5568bcb0991SDimitry Andric SystemZMCInstLower &Lower) { 5578bcb0991SDimitry Andric MCContext &Ctx = MF->getContext(); 558480093f4SDimitry Andric if (MF->getFunction().hasFnAttribute("mrecord-mcount")) { 559480093f4SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 560480093f4SDimitry Andric OutStreamer->PushSection(); 561480093f4SDimitry Andric OutStreamer->SwitchSection( 562480093f4SDimitry Andric Ctx.getELFSection("__mcount_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC)); 5635ffd83dbSDimitry Andric OutStreamer->emitSymbolValue(DotSym, 8); 564480093f4SDimitry Andric OutStreamer->PopSection(); 5655ffd83dbSDimitry Andric OutStreamer->emitLabel(DotSym); 566480093f4SDimitry Andric } 567480093f4SDimitry Andric 568480093f4SDimitry Andric if (MF->getFunction().hasFnAttribute("mnop-mcount")) { 5698bcb0991SDimitry Andric EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo()); 5708bcb0991SDimitry Andric return; 5718bcb0991SDimitry Andric } 5728bcb0991SDimitry Andric 5738bcb0991SDimitry Andric MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__"); 5748bcb0991SDimitry Andric const MCSymbolRefExpr *Op = 5758bcb0991SDimitry Andric MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_PLT, Ctx); 5765ffd83dbSDimitry Andric OutStreamer->emitInstruction( 5775ffd83dbSDimitry Andric MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R0D).addExpr(Op), 5785ffd83dbSDimitry Andric getSubtargetInfo()); 5798bcb0991SDimitry Andric } 5808bcb0991SDimitry Andric 5810b57cec5SDimitry Andric void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) { 5820b57cec5SDimitry Andric const SystemZInstrInfo *TII = 5830b57cec5SDimitry Andric static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo()); 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric unsigned NumNOPBytes = MI.getOperand(1).getImm(); 5860b57cec5SDimitry Andric 587480093f4SDimitry Andric auto &Ctx = OutStreamer->getContext(); 588480093f4SDimitry Andric MCSymbol *MILabel = Ctx.createTempSymbol(); 5895ffd83dbSDimitry Andric OutStreamer->emitLabel(MILabel); 590480093f4SDimitry Andric 591480093f4SDimitry Andric SM.recordStackMap(*MILabel, MI); 5920b57cec5SDimitry Andric assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!"); 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric // Scan ahead to trim the shadow. 5950b57cec5SDimitry Andric unsigned ShadowBytes = 0; 5960b57cec5SDimitry Andric const MachineBasicBlock &MBB = *MI.getParent(); 5970b57cec5SDimitry Andric MachineBasicBlock::const_iterator MII(MI); 5980b57cec5SDimitry Andric ++MII; 5990b57cec5SDimitry Andric while (ShadowBytes < NumNOPBytes) { 6000b57cec5SDimitry Andric if (MII == MBB.end() || 6010b57cec5SDimitry Andric MII->getOpcode() == TargetOpcode::PATCHPOINT || 6020b57cec5SDimitry Andric MII->getOpcode() == TargetOpcode::STACKMAP) 6030b57cec5SDimitry Andric break; 6040b57cec5SDimitry Andric ShadowBytes += TII->getInstSizeInBytes(*MII); 6050b57cec5SDimitry Andric if (MII->isCall()) 6060b57cec5SDimitry Andric break; 6070b57cec5SDimitry Andric ++MII; 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric // Emit nops. 6110b57cec5SDimitry Andric while (ShadowBytes < NumNOPBytes) 6120b57cec5SDimitry Andric ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes, 6130b57cec5SDimitry Andric getSubtargetInfo()); 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric // Lower a patchpoint of the form: 6170b57cec5SDimitry Andric // [<def>], <id>, <numBytes>, <target>, <numArgs> 6180b57cec5SDimitry Andric void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI, 6190b57cec5SDimitry Andric SystemZMCInstLower &Lower) { 620480093f4SDimitry Andric auto &Ctx = OutStreamer->getContext(); 621480093f4SDimitry Andric MCSymbol *MILabel = Ctx.createTempSymbol(); 6225ffd83dbSDimitry Andric OutStreamer->emitLabel(MILabel); 623480093f4SDimitry Andric 624480093f4SDimitry Andric SM.recordPatchPoint(*MILabel, MI); 6250b57cec5SDimitry Andric PatchPointOpers Opers(&MI); 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric unsigned EncodedBytes = 0; 6280b57cec5SDimitry Andric const MachineOperand &CalleeMO = Opers.getCallTarget(); 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric if (CalleeMO.isImm()) { 6310b57cec5SDimitry Andric uint64_t CallTarget = CalleeMO.getImm(); 6320b57cec5SDimitry Andric if (CallTarget) { 6330b57cec5SDimitry Andric unsigned ScratchIdx = -1; 6340b57cec5SDimitry Andric unsigned ScratchReg = 0; 6350b57cec5SDimitry Andric do { 6360b57cec5SDimitry Andric ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1); 6370b57cec5SDimitry Andric ScratchReg = MI.getOperand(ScratchIdx).getReg(); 6380b57cec5SDimitry Andric } while (ScratchReg == SystemZ::R0D); 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andric // Materialize the call target address 6410b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF) 6420b57cec5SDimitry Andric .addReg(ScratchReg) 6430b57cec5SDimitry Andric .addImm(CallTarget & 0xFFFFFFFF)); 6440b57cec5SDimitry Andric EncodedBytes += 6; 6450b57cec5SDimitry Andric if (CallTarget >> 32) { 6460b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF) 6470b57cec5SDimitry Andric .addReg(ScratchReg) 6480b57cec5SDimitry Andric .addImm(CallTarget >> 32)); 6490b57cec5SDimitry Andric EncodedBytes += 6; 6500b57cec5SDimitry Andric } 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR) 6530b57cec5SDimitry Andric .addReg(SystemZ::R14D) 6540b57cec5SDimitry Andric .addReg(ScratchReg)); 6550b57cec5SDimitry Andric EncodedBytes += 2; 6560b57cec5SDimitry Andric } 6570b57cec5SDimitry Andric } else if (CalleeMO.isGlobal()) { 6580b57cec5SDimitry Andric const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT); 6590b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL) 6600b57cec5SDimitry Andric .addReg(SystemZ::R14D) 6610b57cec5SDimitry Andric .addExpr(Expr)); 6620b57cec5SDimitry Andric EncodedBytes += 6; 6630b57cec5SDimitry Andric } 6640b57cec5SDimitry Andric 6650b57cec5SDimitry Andric // Emit padding. 6660b57cec5SDimitry Andric unsigned NumBytes = Opers.getNumPatchBytes(); 6670b57cec5SDimitry Andric assert(NumBytes >= EncodedBytes && 6680b57cec5SDimitry Andric "Patchpoint can't request size less than the length of a call."); 6690b57cec5SDimitry Andric assert((NumBytes - EncodedBytes) % 2 == 0 && 6700b57cec5SDimitry Andric "Invalid number of NOP bytes requested!"); 6710b57cec5SDimitry Andric while (EncodedBytes < NumBytes) 6720b57cec5SDimitry Andric EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes, 6730b57cec5SDimitry Andric getSubtargetInfo()); 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric // Convert a SystemZ-specific constant pool modifier into the associated 6770b57cec5SDimitry Andric // MCSymbolRefExpr variant kind. 6780b57cec5SDimitry Andric static MCSymbolRefExpr::VariantKind 6790b57cec5SDimitry Andric getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) { 6800b57cec5SDimitry Andric switch (Modifier) { 6810b57cec5SDimitry Andric case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; 6820b57cec5SDimitry Andric case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM; 6830b57cec5SDimitry Andric case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF; 6840b57cec5SDimitry Andric case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF; 6850b57cec5SDimitry Andric } 6860b57cec5SDimitry Andric llvm_unreachable("Invalid SystemCPModifier!"); 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric 6895ffd83dbSDimitry Andric void SystemZAsmPrinter::emitMachineConstantPoolValue( 6905ffd83dbSDimitry Andric MachineConstantPoolValue *MCPV) { 6910b57cec5SDimitry Andric auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV); 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric const MCExpr *Expr = 6940b57cec5SDimitry Andric MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()), 6950b57cec5SDimitry Andric getModifierVariantKind(ZCPV->getModifier()), 6960b57cec5SDimitry Andric OutContext); 6970b57cec5SDimitry Andric uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType()); 6980b57cec5SDimitry Andric 6995ffd83dbSDimitry Andric OutStreamer->emitValue(Expr, Size); 7000b57cec5SDimitry Andric } 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 7030b57cec5SDimitry Andric const char *ExtraCode, 7040b57cec5SDimitry Andric raw_ostream &OS) { 7050b57cec5SDimitry Andric if (ExtraCode) 7060b57cec5SDimitry Andric return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); 7070b57cec5SDimitry Andric SystemZMCInstLower Lower(MF->getContext(), *this); 7080b57cec5SDimitry Andric MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo))); 7090b57cec5SDimitry Andric SystemZInstPrinter::printOperand(MO, MAI, OS); 7100b57cec5SDimitry Andric return false; 7110b57cec5SDimitry Andric } 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 7140b57cec5SDimitry Andric unsigned OpNo, 7150b57cec5SDimitry Andric const char *ExtraCode, 7160b57cec5SDimitry Andric raw_ostream &OS) { 7170b57cec5SDimitry Andric SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(), 7180b57cec5SDimitry Andric MI->getOperand(OpNo + 1).getImm(), 7190b57cec5SDimitry Andric MI->getOperand(OpNo + 2).getReg(), OS); 7200b57cec5SDimitry Andric return false; 7210b57cec5SDimitry Andric } 7220b57cec5SDimitry Andric 7235ffd83dbSDimitry Andric void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) { 7240b57cec5SDimitry Andric emitStackMaps(SM); 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric // Force static initialization. 728480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmPrinter() { 7290b57cec5SDimitry Andric RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget()); 7300b57cec5SDimitry Andric } 731