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" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 210b57cec5SDimitry Andric #include "llvm/IR/Mangler.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCInstBuilder.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 250b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h" 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric using namespace llvm; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the 300b57cec5SDimitry Andric // GR64 register operands turned into GR32s. 310b57cec5SDimitry Andric static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) { 320b57cec5SDimitry Andric if (MI->isCompare()) 330b57cec5SDimitry Andric return MCInstBuilder(Opcode) 340b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 350b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()); 360b57cec5SDimitry Andric else 370b57cec5SDimitry Andric return MCInstBuilder(Opcode) 380b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 390b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg())) 400b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the 440b57cec5SDimitry Andric // GR64 register operands turned into GRH32s. 450b57cec5SDimitry Andric static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) { 460b57cec5SDimitry Andric if (MI->isCompare()) 470b57cec5SDimitry Andric return MCInstBuilder(Opcode) 480b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 490b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()); 500b57cec5SDimitry Andric else 510b57cec5SDimitry Andric return MCInstBuilder(Opcode) 520b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 530b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg())) 540b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the 580b57cec5SDimitry Andric // R2 register turned into a GR64. 590b57cec5SDimitry Andric static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) { 600b57cec5SDimitry Andric return MCInstBuilder(Opcode) 610b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 620b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 630b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())) 640b57cec5SDimitry Andric .addImm(MI->getOperand(3).getImm()) 650b57cec5SDimitry Andric .addImm(MI->getOperand(4).getImm()) 660b57cec5SDimitry Andric .addImm(MI->getOperand(5).getImm()); 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) { 700b57cec5SDimitry Andric StringRef Name = "__tls_get_offset"; 710b57cec5SDimitry Andric return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), 720b57cec5SDimitry Andric MCSymbolRefExpr::VK_PLT, 730b57cec5SDimitry Andric Context); 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) { 770b57cec5SDimitry Andric StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 780b57cec5SDimitry Andric return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), 790b57cec5SDimitry Andric MCSymbolRefExpr::VK_None, 800b57cec5SDimitry Andric Context); 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric // MI is an instruction that accepts an optional alignment hint, 840b57cec5SDimitry Andric // and which was already lowered to LoweredMI. If the alignment 850b57cec5SDimitry Andric // of the original memory operand is known, update LoweredMI to 860b57cec5SDimitry Andric // an instruction with the corresponding hint set. 870b57cec5SDimitry Andric static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI, 880b57cec5SDimitry Andric unsigned Opcode) { 890b57cec5SDimitry Andric if (!MI->hasOneMemOperand()) 900b57cec5SDimitry Andric return; 910b57cec5SDimitry Andric const MachineMemOperand *MMO = *MI->memoperands_begin(); 920b57cec5SDimitry Andric unsigned AlignmentHint = 0; 930b57cec5SDimitry Andric if (MMO->getAlignment() >= 16) 940b57cec5SDimitry Andric AlignmentHint = 4; 950b57cec5SDimitry Andric else if (MMO->getAlignment() >= 8) 960b57cec5SDimitry Andric AlignmentHint = 3; 970b57cec5SDimitry Andric if (AlignmentHint == 0) 980b57cec5SDimitry Andric return; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric LoweredMI.setOpcode(Opcode); 1010b57cec5SDimitry Andric LoweredMI.addOperand(MCOperand::createImm(AlignmentHint)); 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric // MI loads the high part of a vector from memory. Return an instruction 1050b57cec5SDimitry Andric // that uses replicating vector load Opcode to do the same thing. 1060b57cec5SDimitry Andric static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) { 1070b57cec5SDimitry Andric return MCInstBuilder(Opcode) 1080b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 1090b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1100b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1110b57cec5SDimitry Andric .addReg(MI->getOperand(3).getReg()); 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric // MI stores the high part of a vector to memory. Return an instruction 1150b57cec5SDimitry Andric // that uses elemental vector store Opcode to do the same thing. 1160b57cec5SDimitry Andric static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) { 1170b57cec5SDimitry Andric return MCInstBuilder(Opcode) 1180b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 1190b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1200b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1210b57cec5SDimitry Andric .addReg(MI->getOperand(3).getReg()) 1220b57cec5SDimitry Andric .addImm(0); 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) { 1260b57cec5SDimitry Andric SystemZMCInstLower Lower(MF->getContext(), *this); 1270b57cec5SDimitry Andric MCInst LoweredMI; 1280b57cec5SDimitry Andric switch (MI->getOpcode()) { 1290b57cec5SDimitry Andric case SystemZ::Return: 1300b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D); 1310b57cec5SDimitry Andric break; 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric case SystemZ::CondReturn: 1340b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCR) 1350b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 1360b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 1370b57cec5SDimitry Andric .addReg(SystemZ::R14D); 1380b57cec5SDimitry Andric break; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric case SystemZ::CRBReturn: 1410b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CRB) 1420b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1430b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1440b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1450b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1460b57cec5SDimitry Andric .addImm(0); 1470b57cec5SDimitry Andric break; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric case SystemZ::CGRBReturn: 1500b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGRB) 1510b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1520b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1530b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1540b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1550b57cec5SDimitry Andric .addImm(0); 1560b57cec5SDimitry Andric break; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric case SystemZ::CIBReturn: 1590b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CIB) 1600b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1610b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 1620b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1630b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1640b57cec5SDimitry Andric .addImm(0); 1650b57cec5SDimitry Andric break; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric case SystemZ::CGIBReturn: 1680b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGIB) 1690b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1700b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 1710b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1720b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1730b57cec5SDimitry Andric .addImm(0); 1740b57cec5SDimitry Andric break; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric case SystemZ::CLRBReturn: 1770b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLRB) 1780b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1790b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1800b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1810b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1820b57cec5SDimitry Andric .addImm(0); 1830b57cec5SDimitry Andric break; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric case SystemZ::CLGRBReturn: 1860b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGRB) 1870b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1880b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 1890b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1900b57cec5SDimitry Andric .addReg(SystemZ::R14D) 1910b57cec5SDimitry Andric .addImm(0); 1920b57cec5SDimitry Andric break; 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric case SystemZ::CLIBReturn: 1950b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLIB) 1960b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 1970b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 1980b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 1990b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2000b57cec5SDimitry Andric .addImm(0); 2010b57cec5SDimitry Andric break; 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric case SystemZ::CLGIBReturn: 2040b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGIB) 2050b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2060b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2070b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2080b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2090b57cec5SDimitry Andric .addImm(0); 2100b57cec5SDimitry Andric break; 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric case SystemZ::CallBRASL: 2130b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 2140b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2150b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 2160b57cec5SDimitry Andric break; 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric case SystemZ::CallBASR: 2190b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BASR) 2200b57cec5SDimitry Andric .addReg(SystemZ::R14D) 2210b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()); 2220b57cec5SDimitry Andric break; 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric case SystemZ::CallJG: 2250b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::JG) 2260b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 2270b57cec5SDimitry Andric break; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric case SystemZ::CallBRCL: 2300b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRCL) 2310b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 2320b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2330b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT)); 2340b57cec5SDimitry Andric break; 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric case SystemZ::CallBR: 2370b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D); 2380b57cec5SDimitry Andric break; 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric case SystemZ::CallBCR: 2410b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCR) 2420b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 2430b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2440b57cec5SDimitry Andric .addReg(SystemZ::R1D); 2450b57cec5SDimitry Andric break; 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric case SystemZ::CRBCall: 2480b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CRB) 2490b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2500b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 2510b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2520b57cec5SDimitry Andric .addReg(SystemZ::R1D) 2530b57cec5SDimitry Andric .addImm(0); 2540b57cec5SDimitry Andric break; 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric case SystemZ::CGRBCall: 2570b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGRB) 2580b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2590b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 2600b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2610b57cec5SDimitry Andric .addReg(SystemZ::R1D) 2620b57cec5SDimitry Andric .addImm(0); 2630b57cec5SDimitry Andric break; 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric case SystemZ::CIBCall: 2660b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CIB) 2670b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2680b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2690b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2700b57cec5SDimitry Andric .addReg(SystemZ::R1D) 2710b57cec5SDimitry Andric .addImm(0); 2720b57cec5SDimitry Andric break; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric case SystemZ::CGIBCall: 2750b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGIB) 2760b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2770b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 2780b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2790b57cec5SDimitry Andric .addReg(SystemZ::R1D) 2800b57cec5SDimitry Andric .addImm(0); 2810b57cec5SDimitry Andric break; 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric case SystemZ::CLRBCall: 2840b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLRB) 2850b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2860b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 2870b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2880b57cec5SDimitry Andric .addReg(SystemZ::R1D) 2890b57cec5SDimitry Andric .addImm(0); 2900b57cec5SDimitry Andric break; 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric case SystemZ::CLGRBCall: 2930b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGRB) 2940b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 2950b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 2960b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 2970b57cec5SDimitry Andric .addReg(SystemZ::R1D) 2980b57cec5SDimitry Andric .addImm(0); 2990b57cec5SDimitry Andric break; 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric case SystemZ::CLIBCall: 3020b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLIB) 3030b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3040b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 3050b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 3060b57cec5SDimitry Andric .addReg(SystemZ::R1D) 3070b57cec5SDimitry Andric .addImm(0); 3080b57cec5SDimitry Andric break; 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric case SystemZ::CLGIBCall: 3110b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGIB) 3120b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3130b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 3140b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 3150b57cec5SDimitry Andric .addReg(SystemZ::R1D) 3160b57cec5SDimitry Andric .addImm(0); 3170b57cec5SDimitry Andric break; 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric case SystemZ::TLS_GDCALL: 3200b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 3210b57cec5SDimitry Andric .addReg(SystemZ::R14D) 3220b57cec5SDimitry Andric .addExpr(getTLSGetOffset(MF->getContext())) 3230b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD)); 3240b57cec5SDimitry Andric break; 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric case SystemZ::TLS_LDCALL: 3270b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 3280b57cec5SDimitry Andric .addReg(SystemZ::R14D) 3290b57cec5SDimitry Andric .addExpr(getTLSGetOffset(MF->getContext())) 3300b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM)); 3310b57cec5SDimitry Andric break; 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric case SystemZ::GOT: 3340b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::LARL) 3350b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3360b57cec5SDimitry Andric .addExpr(getGlobalOffsetTable(MF->getContext())); 3370b57cec5SDimitry Andric break; 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric case SystemZ::IILF64: 3400b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::IILF) 3410b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 3420b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 3430b57cec5SDimitry Andric break; 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric case SystemZ::IIHF64: 3460b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::IIHF) 3470b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 3480b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 3490b57cec5SDimitry Andric break; 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric case SystemZ::RISBHH: 3520b57cec5SDimitry Andric case SystemZ::RISBHL: 3530b57cec5SDimitry Andric LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG); 3540b57cec5SDimitry Andric break; 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric case SystemZ::RISBLH: 3570b57cec5SDimitry Andric case SystemZ::RISBLL: 3580b57cec5SDimitry Andric LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG); 3590b57cec5SDimitry Andric break; 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric case SystemZ::VLVGP32: 3620b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLVGP) 3630b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 3640b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg())) 3650b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())); 3660b57cec5SDimitry Andric break; 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric case SystemZ::VLR32: 3690b57cec5SDimitry Andric case SystemZ::VLR64: 3700b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLR) 3710b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 3720b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())); 3730b57cec5SDimitry Andric break; 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric case SystemZ::VL: 3760b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 3770b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign); 3780b57cec5SDimitry Andric break; 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric case SystemZ::VST: 3810b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 3820b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign); 3830b57cec5SDimitry Andric break; 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric case SystemZ::VLM: 3860b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 3870b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign); 3880b57cec5SDimitry Andric break; 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric case SystemZ::VSTM: 3910b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 3920b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign); 3930b57cec5SDimitry Andric break; 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric case SystemZ::VL32: 3960b57cec5SDimitry Andric LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF); 3970b57cec5SDimitry Andric break; 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric case SystemZ::VL64: 4000b57cec5SDimitry Andric LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG); 4010b57cec5SDimitry Andric break; 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric case SystemZ::VST32: 4040b57cec5SDimitry Andric LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF); 4050b57cec5SDimitry Andric break; 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric case SystemZ::VST64: 4080b57cec5SDimitry Andric LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG); 4090b57cec5SDimitry Andric break; 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric case SystemZ::LFER: 4120b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLGVF) 4130b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg())) 4140b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())) 4150b57cec5SDimitry Andric .addReg(0).addImm(0); 4160b57cec5SDimitry Andric break; 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric case SystemZ::LEFR: 4190b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLVGF) 4200b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 4210b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 4220b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 4230b57cec5SDimitry Andric .addReg(0).addImm(0); 4240b57cec5SDimitry Andric break; 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric #define LOWER_LOW(NAME) \ 4270b57cec5SDimitry Andric case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric LOWER_LOW(IILL); 4300b57cec5SDimitry Andric LOWER_LOW(IILH); 4310b57cec5SDimitry Andric LOWER_LOW(TMLL); 4320b57cec5SDimitry Andric LOWER_LOW(TMLH); 4330b57cec5SDimitry Andric LOWER_LOW(NILL); 4340b57cec5SDimitry Andric LOWER_LOW(NILH); 4350b57cec5SDimitry Andric LOWER_LOW(NILF); 4360b57cec5SDimitry Andric LOWER_LOW(OILL); 4370b57cec5SDimitry Andric LOWER_LOW(OILH); 4380b57cec5SDimitry Andric LOWER_LOW(OILF); 4390b57cec5SDimitry Andric LOWER_LOW(XILF); 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric #undef LOWER_LOW 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric #define LOWER_HIGH(NAME) \ 4440b57cec5SDimitry Andric case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric LOWER_HIGH(IIHL); 4470b57cec5SDimitry Andric LOWER_HIGH(IIHH); 4480b57cec5SDimitry Andric LOWER_HIGH(TMHL); 4490b57cec5SDimitry Andric LOWER_HIGH(TMHH); 4500b57cec5SDimitry Andric LOWER_HIGH(NIHL); 4510b57cec5SDimitry Andric LOWER_HIGH(NIHH); 4520b57cec5SDimitry Andric LOWER_HIGH(NIHF); 4530b57cec5SDimitry Andric LOWER_HIGH(OIHL); 4540b57cec5SDimitry Andric LOWER_HIGH(OIHH); 4550b57cec5SDimitry Andric LOWER_HIGH(OIHF); 4560b57cec5SDimitry Andric LOWER_HIGH(XIHF); 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric #undef LOWER_HIGH 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric case SystemZ::Serialize: 4610b57cec5SDimitry Andric if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization()) 4620b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 4630b57cec5SDimitry Andric .addImm(14).addReg(SystemZ::R0D); 4640b57cec5SDimitry Andric else 4650b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 4660b57cec5SDimitry Andric .addImm(15).addReg(SystemZ::R0D); 4670b57cec5SDimitry Andric break; 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric // Emit nothing here but a comment if we can. 4700b57cec5SDimitry Andric case SystemZ::MemBarrier: 4710b57cec5SDimitry Andric OutStreamer->emitRawComment("MEMBARRIER"); 4720b57cec5SDimitry Andric return; 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric // We want to emit "j .+2" for traps, jumping to the relative immediate field 4750b57cec5SDimitry Andric // of the jump instruction, which is an illegal instruction. We cannot emit a 4760b57cec5SDimitry Andric // "." symbol, so create and emit a temp label before the instruction and use 4770b57cec5SDimitry Andric // that instead. 4780b57cec5SDimitry Andric case SystemZ::Trap: { 4790b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 4800b57cec5SDimitry Andric OutStreamer->EmitLabel(DotSym); 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 4830b57cec5SDimitry Andric const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 4840b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::J) 4850b57cec5SDimitry Andric .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric break; 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric // Conditional traps will create a branch on condition instruction that jumps 4900b57cec5SDimitry Andric // to the relative immediate field of the jump instruction. (eg. "jo .+2") 4910b57cec5SDimitry Andric case SystemZ::CondTrap: { 4920b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 4930b57cec5SDimitry Andric OutStreamer->EmitLabel(DotSym); 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 4960b57cec5SDimitry Andric const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 4970b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRC) 4980b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 4990b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 5000b57cec5SDimitry Andric .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric break; 5030b57cec5SDimitry Andric 504*8bcb0991SDimitry Andric case TargetOpcode::FENTRY_CALL: 505*8bcb0991SDimitry Andric LowerFENTRY_CALL(*MI, Lower); 506*8bcb0991SDimitry Andric return; 507*8bcb0991SDimitry Andric 5080b57cec5SDimitry Andric case TargetOpcode::STACKMAP: 5090b57cec5SDimitry Andric LowerSTACKMAP(*MI); 5100b57cec5SDimitry Andric return; 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric case TargetOpcode::PATCHPOINT: 5130b57cec5SDimitry Andric LowerPATCHPOINT(*MI, Lower); 5140b57cec5SDimitry Andric return; 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric default: 5170b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 5180b57cec5SDimitry Andric break; 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, LoweredMI); 5210b57cec5SDimitry Andric } 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric // Emit the largest nop instruction smaller than or equal to NumBytes 5250b57cec5SDimitry Andric // bytes. Return the size of nop emitted. 5260b57cec5SDimitry Andric static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, 5270b57cec5SDimitry Andric unsigned NumBytes, const MCSubtargetInfo &STI) { 5280b57cec5SDimitry Andric if (NumBytes < 2) { 5290b57cec5SDimitry Andric llvm_unreachable("Zero nops?"); 5300b57cec5SDimitry Andric return 0; 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric else if (NumBytes < 4) { 5330b57cec5SDimitry Andric OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm) 5340b57cec5SDimitry Andric .addImm(0).addReg(SystemZ::R0D), STI); 5350b57cec5SDimitry Andric return 2; 5360b57cec5SDimitry Andric } 5370b57cec5SDimitry Andric else if (NumBytes < 6) { 5380b57cec5SDimitry Andric OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCAsm) 5390b57cec5SDimitry Andric .addImm(0).addReg(0).addImm(0).addReg(0), 5400b57cec5SDimitry Andric STI); 5410b57cec5SDimitry Andric return 4; 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric else { 5440b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 5450b57cec5SDimitry Andric const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext); 5460b57cec5SDimitry Andric OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm) 5470b57cec5SDimitry Andric .addImm(0).addExpr(Dot), STI); 5480b57cec5SDimitry Andric OutStreamer.EmitLabel(DotSym); 5490b57cec5SDimitry Andric return 6; 5500b57cec5SDimitry Andric } 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric 553*8bcb0991SDimitry Andric void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI, 554*8bcb0991SDimitry Andric SystemZMCInstLower &Lower) { 555*8bcb0991SDimitry Andric MCContext &Ctx = MF->getContext(); 556*8bcb0991SDimitry Andric if (MF->getFunction().getFnAttribute("mnop-mcount") 557*8bcb0991SDimitry Andric .getValueAsString() == "true") { 558*8bcb0991SDimitry Andric EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo()); 559*8bcb0991SDimitry Andric return; 560*8bcb0991SDimitry Andric } 561*8bcb0991SDimitry Andric 562*8bcb0991SDimitry Andric MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__"); 563*8bcb0991SDimitry Andric const MCSymbolRefExpr *Op = 564*8bcb0991SDimitry Andric MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_PLT, Ctx); 565*8bcb0991SDimitry Andric OutStreamer->EmitInstruction(MCInstBuilder(SystemZ::BRASL) 566*8bcb0991SDimitry Andric .addReg(SystemZ::R0D).addExpr(Op), getSubtargetInfo()); 567*8bcb0991SDimitry Andric } 568*8bcb0991SDimitry Andric 5690b57cec5SDimitry Andric void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) { 5700b57cec5SDimitry Andric const SystemZInstrInfo *TII = 5710b57cec5SDimitry Andric static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo()); 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric unsigned NumNOPBytes = MI.getOperand(1).getImm(); 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric SM.recordStackMap(MI); 5760b57cec5SDimitry Andric assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!"); 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric // Scan ahead to trim the shadow. 5790b57cec5SDimitry Andric unsigned ShadowBytes = 0; 5800b57cec5SDimitry Andric const MachineBasicBlock &MBB = *MI.getParent(); 5810b57cec5SDimitry Andric MachineBasicBlock::const_iterator MII(MI); 5820b57cec5SDimitry Andric ++MII; 5830b57cec5SDimitry Andric while (ShadowBytes < NumNOPBytes) { 5840b57cec5SDimitry Andric if (MII == MBB.end() || 5850b57cec5SDimitry Andric MII->getOpcode() == TargetOpcode::PATCHPOINT || 5860b57cec5SDimitry Andric MII->getOpcode() == TargetOpcode::STACKMAP) 5870b57cec5SDimitry Andric break; 5880b57cec5SDimitry Andric ShadowBytes += TII->getInstSizeInBytes(*MII); 5890b57cec5SDimitry Andric if (MII->isCall()) 5900b57cec5SDimitry Andric break; 5910b57cec5SDimitry Andric ++MII; 5920b57cec5SDimitry Andric } 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric // Emit nops. 5950b57cec5SDimitry Andric while (ShadowBytes < NumNOPBytes) 5960b57cec5SDimitry Andric ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes, 5970b57cec5SDimitry Andric getSubtargetInfo()); 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric // Lower a patchpoint of the form: 6010b57cec5SDimitry Andric // [<def>], <id>, <numBytes>, <target>, <numArgs> 6020b57cec5SDimitry Andric void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI, 6030b57cec5SDimitry Andric SystemZMCInstLower &Lower) { 6040b57cec5SDimitry Andric SM.recordPatchPoint(MI); 6050b57cec5SDimitry Andric PatchPointOpers Opers(&MI); 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric unsigned EncodedBytes = 0; 6080b57cec5SDimitry Andric const MachineOperand &CalleeMO = Opers.getCallTarget(); 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric if (CalleeMO.isImm()) { 6110b57cec5SDimitry Andric uint64_t CallTarget = CalleeMO.getImm(); 6120b57cec5SDimitry Andric if (CallTarget) { 6130b57cec5SDimitry Andric unsigned ScratchIdx = -1; 6140b57cec5SDimitry Andric unsigned ScratchReg = 0; 6150b57cec5SDimitry Andric do { 6160b57cec5SDimitry Andric ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1); 6170b57cec5SDimitry Andric ScratchReg = MI.getOperand(ScratchIdx).getReg(); 6180b57cec5SDimitry Andric } while (ScratchReg == SystemZ::R0D); 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric // Materialize the call target address 6210b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF) 6220b57cec5SDimitry Andric .addReg(ScratchReg) 6230b57cec5SDimitry Andric .addImm(CallTarget & 0xFFFFFFFF)); 6240b57cec5SDimitry Andric EncodedBytes += 6; 6250b57cec5SDimitry Andric if (CallTarget >> 32) { 6260b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF) 6270b57cec5SDimitry Andric .addReg(ScratchReg) 6280b57cec5SDimitry Andric .addImm(CallTarget >> 32)); 6290b57cec5SDimitry Andric EncodedBytes += 6; 6300b57cec5SDimitry Andric } 6310b57cec5SDimitry Andric 6320b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR) 6330b57cec5SDimitry Andric .addReg(SystemZ::R14D) 6340b57cec5SDimitry Andric .addReg(ScratchReg)); 6350b57cec5SDimitry Andric EncodedBytes += 2; 6360b57cec5SDimitry Andric } 6370b57cec5SDimitry Andric } else if (CalleeMO.isGlobal()) { 6380b57cec5SDimitry Andric const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT); 6390b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL) 6400b57cec5SDimitry Andric .addReg(SystemZ::R14D) 6410b57cec5SDimitry Andric .addExpr(Expr)); 6420b57cec5SDimitry Andric EncodedBytes += 6; 6430b57cec5SDimitry Andric } 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric // Emit padding. 6460b57cec5SDimitry Andric unsigned NumBytes = Opers.getNumPatchBytes(); 6470b57cec5SDimitry Andric assert(NumBytes >= EncodedBytes && 6480b57cec5SDimitry Andric "Patchpoint can't request size less than the length of a call."); 6490b57cec5SDimitry Andric assert((NumBytes - EncodedBytes) % 2 == 0 && 6500b57cec5SDimitry Andric "Invalid number of NOP bytes requested!"); 6510b57cec5SDimitry Andric while (EncodedBytes < NumBytes) 6520b57cec5SDimitry Andric EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes, 6530b57cec5SDimitry Andric getSubtargetInfo()); 6540b57cec5SDimitry Andric } 6550b57cec5SDimitry Andric 6560b57cec5SDimitry Andric // Convert a SystemZ-specific constant pool modifier into the associated 6570b57cec5SDimitry Andric // MCSymbolRefExpr variant kind. 6580b57cec5SDimitry Andric static MCSymbolRefExpr::VariantKind 6590b57cec5SDimitry Andric getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) { 6600b57cec5SDimitry Andric switch (Modifier) { 6610b57cec5SDimitry Andric case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; 6620b57cec5SDimitry Andric case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM; 6630b57cec5SDimitry Andric case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF; 6640b57cec5SDimitry Andric case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF; 6650b57cec5SDimitry Andric } 6660b57cec5SDimitry Andric llvm_unreachable("Invalid SystemCPModifier!"); 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric 6690b57cec5SDimitry Andric void SystemZAsmPrinter:: 6700b57cec5SDimitry Andric EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 6710b57cec5SDimitry Andric auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV); 6720b57cec5SDimitry Andric 6730b57cec5SDimitry Andric const MCExpr *Expr = 6740b57cec5SDimitry Andric MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()), 6750b57cec5SDimitry Andric getModifierVariantKind(ZCPV->getModifier()), 6760b57cec5SDimitry Andric OutContext); 6770b57cec5SDimitry Andric uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType()); 6780b57cec5SDimitry Andric 6790b57cec5SDimitry Andric OutStreamer->EmitValue(Expr, Size); 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 6830b57cec5SDimitry Andric const char *ExtraCode, 6840b57cec5SDimitry Andric raw_ostream &OS) { 6850b57cec5SDimitry Andric if (ExtraCode) 6860b57cec5SDimitry Andric return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); 6870b57cec5SDimitry Andric SystemZMCInstLower Lower(MF->getContext(), *this); 6880b57cec5SDimitry Andric MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo))); 6890b57cec5SDimitry Andric SystemZInstPrinter::printOperand(MO, MAI, OS); 6900b57cec5SDimitry Andric return false; 6910b57cec5SDimitry Andric } 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 6940b57cec5SDimitry Andric unsigned OpNo, 6950b57cec5SDimitry Andric const char *ExtraCode, 6960b57cec5SDimitry Andric raw_ostream &OS) { 6970b57cec5SDimitry Andric SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(), 6980b57cec5SDimitry Andric MI->getOperand(OpNo + 1).getImm(), 6990b57cec5SDimitry Andric MI->getOperand(OpNo + 2).getReg(), OS); 7000b57cec5SDimitry Andric return false; 7010b57cec5SDimitry Andric } 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) { 7040b57cec5SDimitry Andric emitStackMaps(SM); 7050b57cec5SDimitry Andric } 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric // Force static initialization. 7080b57cec5SDimitry Andric extern "C" void LLVMInitializeSystemZAsmPrinter() { 7090b57cec5SDimitry Andric RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget()); 7100b57cec5SDimitry Andric } 711