1*0b57cec5SDimitry Andric //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // Streams SystemZ assembly language and associated data, in the form of 10*0b57cec5SDimitry Andric // MCInsts and MCExprs respectively. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "SystemZAsmPrinter.h" 15*0b57cec5SDimitry Andric #include "MCTargetDesc/SystemZInstPrinter.h" 16*0b57cec5SDimitry Andric #include "SystemZConstantPoolValue.h" 17*0b57cec5SDimitry Andric #include "SystemZMCInstLower.h" 18*0b57cec5SDimitry Andric #include "TargetInfo/SystemZTargetInfo.h" 19*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h" 20*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 21*0b57cec5SDimitry Andric #include "llvm/IR/Mangler.h" 22*0b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 23*0b57cec5SDimitry Andric #include "llvm/MC/MCInstBuilder.h" 24*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 25*0b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h" 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric using namespace llvm; 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the 30*0b57cec5SDimitry Andric // GR64 register operands turned into GR32s. 31*0b57cec5SDimitry Andric static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) { 32*0b57cec5SDimitry Andric if (MI->isCompare()) 33*0b57cec5SDimitry Andric return MCInstBuilder(Opcode) 34*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 35*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()); 36*0b57cec5SDimitry Andric else 37*0b57cec5SDimitry Andric return MCInstBuilder(Opcode) 38*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 39*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg())) 40*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 41*0b57cec5SDimitry Andric } 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the 44*0b57cec5SDimitry Andric // GR64 register operands turned into GRH32s. 45*0b57cec5SDimitry Andric static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) { 46*0b57cec5SDimitry Andric if (MI->isCompare()) 47*0b57cec5SDimitry Andric return MCInstBuilder(Opcode) 48*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 49*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()); 50*0b57cec5SDimitry Andric else 51*0b57cec5SDimitry Andric return MCInstBuilder(Opcode) 52*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 53*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg())) 54*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 55*0b57cec5SDimitry Andric } 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the 58*0b57cec5SDimitry Andric // R2 register turned into a GR64. 59*0b57cec5SDimitry Andric static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) { 60*0b57cec5SDimitry Andric return MCInstBuilder(Opcode) 61*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 62*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 63*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())) 64*0b57cec5SDimitry Andric .addImm(MI->getOperand(3).getImm()) 65*0b57cec5SDimitry Andric .addImm(MI->getOperand(4).getImm()) 66*0b57cec5SDimitry Andric .addImm(MI->getOperand(5).getImm()); 67*0b57cec5SDimitry Andric } 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) { 70*0b57cec5SDimitry Andric StringRef Name = "__tls_get_offset"; 71*0b57cec5SDimitry Andric return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), 72*0b57cec5SDimitry Andric MCSymbolRefExpr::VK_PLT, 73*0b57cec5SDimitry Andric Context); 74*0b57cec5SDimitry Andric } 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andric static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) { 77*0b57cec5SDimitry Andric StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 78*0b57cec5SDimitry Andric return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name), 79*0b57cec5SDimitry Andric MCSymbolRefExpr::VK_None, 80*0b57cec5SDimitry Andric Context); 81*0b57cec5SDimitry Andric } 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric // MI is an instruction that accepts an optional alignment hint, 84*0b57cec5SDimitry Andric // and which was already lowered to LoweredMI. If the alignment 85*0b57cec5SDimitry Andric // of the original memory operand is known, update LoweredMI to 86*0b57cec5SDimitry Andric // an instruction with the corresponding hint set. 87*0b57cec5SDimitry Andric static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI, 88*0b57cec5SDimitry Andric unsigned Opcode) { 89*0b57cec5SDimitry Andric if (!MI->hasOneMemOperand()) 90*0b57cec5SDimitry Andric return; 91*0b57cec5SDimitry Andric const MachineMemOperand *MMO = *MI->memoperands_begin(); 92*0b57cec5SDimitry Andric unsigned AlignmentHint = 0; 93*0b57cec5SDimitry Andric if (MMO->getAlignment() >= 16) 94*0b57cec5SDimitry Andric AlignmentHint = 4; 95*0b57cec5SDimitry Andric else if (MMO->getAlignment() >= 8) 96*0b57cec5SDimitry Andric AlignmentHint = 3; 97*0b57cec5SDimitry Andric if (AlignmentHint == 0) 98*0b57cec5SDimitry Andric return; 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric LoweredMI.setOpcode(Opcode); 101*0b57cec5SDimitry Andric LoweredMI.addOperand(MCOperand::createImm(AlignmentHint)); 102*0b57cec5SDimitry Andric } 103*0b57cec5SDimitry Andric 104*0b57cec5SDimitry Andric // MI loads the high part of a vector from memory. Return an instruction 105*0b57cec5SDimitry Andric // that uses replicating vector load Opcode to do the same thing. 106*0b57cec5SDimitry Andric static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) { 107*0b57cec5SDimitry Andric return MCInstBuilder(Opcode) 108*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 109*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 110*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 111*0b57cec5SDimitry Andric .addReg(MI->getOperand(3).getReg()); 112*0b57cec5SDimitry Andric } 113*0b57cec5SDimitry Andric 114*0b57cec5SDimitry Andric // MI stores the high part of a vector to memory. Return an instruction 115*0b57cec5SDimitry Andric // that uses elemental vector store Opcode to do the same thing. 116*0b57cec5SDimitry Andric static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) { 117*0b57cec5SDimitry Andric return MCInstBuilder(Opcode) 118*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 119*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 120*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 121*0b57cec5SDimitry Andric .addReg(MI->getOperand(3).getReg()) 122*0b57cec5SDimitry Andric .addImm(0); 123*0b57cec5SDimitry Andric } 124*0b57cec5SDimitry Andric 125*0b57cec5SDimitry Andric void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) { 126*0b57cec5SDimitry Andric SystemZMCInstLower Lower(MF->getContext(), *this); 127*0b57cec5SDimitry Andric MCInst LoweredMI; 128*0b57cec5SDimitry Andric switch (MI->getOpcode()) { 129*0b57cec5SDimitry Andric case SystemZ::Return: 130*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D); 131*0b57cec5SDimitry Andric break; 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric case SystemZ::CondReturn: 134*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCR) 135*0b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 136*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 137*0b57cec5SDimitry Andric .addReg(SystemZ::R14D); 138*0b57cec5SDimitry Andric break; 139*0b57cec5SDimitry Andric 140*0b57cec5SDimitry Andric case SystemZ::CRBReturn: 141*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CRB) 142*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 143*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 144*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 145*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 146*0b57cec5SDimitry Andric .addImm(0); 147*0b57cec5SDimitry Andric break; 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andric case SystemZ::CGRBReturn: 150*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGRB) 151*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 152*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 153*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 154*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 155*0b57cec5SDimitry Andric .addImm(0); 156*0b57cec5SDimitry Andric break; 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric case SystemZ::CIBReturn: 159*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CIB) 160*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 161*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 162*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 163*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 164*0b57cec5SDimitry Andric .addImm(0); 165*0b57cec5SDimitry Andric break; 166*0b57cec5SDimitry Andric 167*0b57cec5SDimitry Andric case SystemZ::CGIBReturn: 168*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGIB) 169*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 170*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 171*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 172*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 173*0b57cec5SDimitry Andric .addImm(0); 174*0b57cec5SDimitry Andric break; 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric case SystemZ::CLRBReturn: 177*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLRB) 178*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 179*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 180*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 181*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 182*0b57cec5SDimitry Andric .addImm(0); 183*0b57cec5SDimitry Andric break; 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric case SystemZ::CLGRBReturn: 186*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGRB) 187*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 188*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 189*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 190*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 191*0b57cec5SDimitry Andric .addImm(0); 192*0b57cec5SDimitry Andric break; 193*0b57cec5SDimitry Andric 194*0b57cec5SDimitry Andric case SystemZ::CLIBReturn: 195*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLIB) 196*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 197*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 198*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 199*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 200*0b57cec5SDimitry Andric .addImm(0); 201*0b57cec5SDimitry Andric break; 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric case SystemZ::CLGIBReturn: 204*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGIB) 205*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 206*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 207*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 208*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 209*0b57cec5SDimitry Andric .addImm(0); 210*0b57cec5SDimitry Andric break; 211*0b57cec5SDimitry Andric 212*0b57cec5SDimitry Andric case SystemZ::CallBRASL: 213*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 214*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 215*0b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 216*0b57cec5SDimitry Andric break; 217*0b57cec5SDimitry Andric 218*0b57cec5SDimitry Andric case SystemZ::CallBASR: 219*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BASR) 220*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 221*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()); 222*0b57cec5SDimitry Andric break; 223*0b57cec5SDimitry Andric 224*0b57cec5SDimitry Andric case SystemZ::CallJG: 225*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::JG) 226*0b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 227*0b57cec5SDimitry Andric break; 228*0b57cec5SDimitry Andric 229*0b57cec5SDimitry Andric case SystemZ::CallBRCL: 230*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRCL) 231*0b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 232*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 233*0b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT)); 234*0b57cec5SDimitry Andric break; 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric case SystemZ::CallBR: 237*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D); 238*0b57cec5SDimitry Andric break; 239*0b57cec5SDimitry Andric 240*0b57cec5SDimitry Andric case SystemZ::CallBCR: 241*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCR) 242*0b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 243*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 244*0b57cec5SDimitry Andric .addReg(SystemZ::R1D); 245*0b57cec5SDimitry Andric break; 246*0b57cec5SDimitry Andric 247*0b57cec5SDimitry Andric case SystemZ::CRBCall: 248*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CRB) 249*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 250*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 251*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 252*0b57cec5SDimitry Andric .addReg(SystemZ::R1D) 253*0b57cec5SDimitry Andric .addImm(0); 254*0b57cec5SDimitry Andric break; 255*0b57cec5SDimitry Andric 256*0b57cec5SDimitry Andric case SystemZ::CGRBCall: 257*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGRB) 258*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 259*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 260*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 261*0b57cec5SDimitry Andric .addReg(SystemZ::R1D) 262*0b57cec5SDimitry Andric .addImm(0); 263*0b57cec5SDimitry Andric break; 264*0b57cec5SDimitry Andric 265*0b57cec5SDimitry Andric case SystemZ::CIBCall: 266*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CIB) 267*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 268*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 269*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 270*0b57cec5SDimitry Andric .addReg(SystemZ::R1D) 271*0b57cec5SDimitry Andric .addImm(0); 272*0b57cec5SDimitry Andric break; 273*0b57cec5SDimitry Andric 274*0b57cec5SDimitry Andric case SystemZ::CGIBCall: 275*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGIB) 276*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 277*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 278*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 279*0b57cec5SDimitry Andric .addReg(SystemZ::R1D) 280*0b57cec5SDimitry Andric .addImm(0); 281*0b57cec5SDimitry Andric break; 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric case SystemZ::CLRBCall: 284*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLRB) 285*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 286*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 287*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 288*0b57cec5SDimitry Andric .addReg(SystemZ::R1D) 289*0b57cec5SDimitry Andric .addImm(0); 290*0b57cec5SDimitry Andric break; 291*0b57cec5SDimitry Andric 292*0b57cec5SDimitry Andric case SystemZ::CLGRBCall: 293*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGRB) 294*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 295*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 296*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 297*0b57cec5SDimitry Andric .addReg(SystemZ::R1D) 298*0b57cec5SDimitry Andric .addImm(0); 299*0b57cec5SDimitry Andric break; 300*0b57cec5SDimitry Andric 301*0b57cec5SDimitry Andric case SystemZ::CLIBCall: 302*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLIB) 303*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 304*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 305*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 306*0b57cec5SDimitry Andric .addReg(SystemZ::R1D) 307*0b57cec5SDimitry Andric .addImm(0); 308*0b57cec5SDimitry Andric break; 309*0b57cec5SDimitry Andric 310*0b57cec5SDimitry Andric case SystemZ::CLGIBCall: 311*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGIB) 312*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 313*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 314*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()) 315*0b57cec5SDimitry Andric .addReg(SystemZ::R1D) 316*0b57cec5SDimitry Andric .addImm(0); 317*0b57cec5SDimitry Andric break; 318*0b57cec5SDimitry Andric 319*0b57cec5SDimitry Andric case SystemZ::TLS_GDCALL: 320*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 321*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 322*0b57cec5SDimitry Andric .addExpr(getTLSGetOffset(MF->getContext())) 323*0b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD)); 324*0b57cec5SDimitry Andric break; 325*0b57cec5SDimitry Andric 326*0b57cec5SDimitry Andric case SystemZ::TLS_LDCALL: 327*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL) 328*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 329*0b57cec5SDimitry Andric .addExpr(getTLSGetOffset(MF->getContext())) 330*0b57cec5SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM)); 331*0b57cec5SDimitry Andric break; 332*0b57cec5SDimitry Andric 333*0b57cec5SDimitry Andric case SystemZ::GOT: 334*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::LARL) 335*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 336*0b57cec5SDimitry Andric .addExpr(getGlobalOffsetTable(MF->getContext())); 337*0b57cec5SDimitry Andric break; 338*0b57cec5SDimitry Andric 339*0b57cec5SDimitry Andric case SystemZ::IILF64: 340*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::IILF) 341*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 342*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 343*0b57cec5SDimitry Andric break; 344*0b57cec5SDimitry Andric 345*0b57cec5SDimitry Andric case SystemZ::IIHF64: 346*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::IIHF) 347*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 348*0b57cec5SDimitry Andric .addImm(MI->getOperand(2).getImm()); 349*0b57cec5SDimitry Andric break; 350*0b57cec5SDimitry Andric 351*0b57cec5SDimitry Andric case SystemZ::RISBHH: 352*0b57cec5SDimitry Andric case SystemZ::RISBHL: 353*0b57cec5SDimitry Andric LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG); 354*0b57cec5SDimitry Andric break; 355*0b57cec5SDimitry Andric 356*0b57cec5SDimitry Andric case SystemZ::RISBLH: 357*0b57cec5SDimitry Andric case SystemZ::RISBLL: 358*0b57cec5SDimitry Andric LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG); 359*0b57cec5SDimitry Andric break; 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andric case SystemZ::VLVGP32: 362*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLVGP) 363*0b57cec5SDimitry Andric .addReg(MI->getOperand(0).getReg()) 364*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg())) 365*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())); 366*0b57cec5SDimitry Andric break; 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric case SystemZ::VLR32: 369*0b57cec5SDimitry Andric case SystemZ::VLR64: 370*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLR) 371*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 372*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())); 373*0b57cec5SDimitry Andric break; 374*0b57cec5SDimitry Andric 375*0b57cec5SDimitry Andric case SystemZ::VL: 376*0b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 377*0b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign); 378*0b57cec5SDimitry Andric break; 379*0b57cec5SDimitry Andric 380*0b57cec5SDimitry Andric case SystemZ::VST: 381*0b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 382*0b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign); 383*0b57cec5SDimitry Andric break; 384*0b57cec5SDimitry Andric 385*0b57cec5SDimitry Andric case SystemZ::VLM: 386*0b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 387*0b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign); 388*0b57cec5SDimitry Andric break; 389*0b57cec5SDimitry Andric 390*0b57cec5SDimitry Andric case SystemZ::VSTM: 391*0b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 392*0b57cec5SDimitry Andric lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign); 393*0b57cec5SDimitry Andric break; 394*0b57cec5SDimitry Andric 395*0b57cec5SDimitry Andric case SystemZ::VL32: 396*0b57cec5SDimitry Andric LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF); 397*0b57cec5SDimitry Andric break; 398*0b57cec5SDimitry Andric 399*0b57cec5SDimitry Andric case SystemZ::VL64: 400*0b57cec5SDimitry Andric LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG); 401*0b57cec5SDimitry Andric break; 402*0b57cec5SDimitry Andric 403*0b57cec5SDimitry Andric case SystemZ::VST32: 404*0b57cec5SDimitry Andric LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF); 405*0b57cec5SDimitry Andric break; 406*0b57cec5SDimitry Andric 407*0b57cec5SDimitry Andric case SystemZ::VST64: 408*0b57cec5SDimitry Andric LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG); 409*0b57cec5SDimitry Andric break; 410*0b57cec5SDimitry Andric 411*0b57cec5SDimitry Andric case SystemZ::LFER: 412*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLGVF) 413*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg())) 414*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg())) 415*0b57cec5SDimitry Andric .addReg(0).addImm(0); 416*0b57cec5SDimitry Andric break; 417*0b57cec5SDimitry Andric 418*0b57cec5SDimitry Andric case SystemZ::LEFR: 419*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLVGF) 420*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 421*0b57cec5SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg())) 422*0b57cec5SDimitry Andric .addReg(MI->getOperand(1).getReg()) 423*0b57cec5SDimitry Andric .addReg(0).addImm(0); 424*0b57cec5SDimitry Andric break; 425*0b57cec5SDimitry Andric 426*0b57cec5SDimitry Andric #define LOWER_LOW(NAME) \ 427*0b57cec5SDimitry Andric case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break 428*0b57cec5SDimitry Andric 429*0b57cec5SDimitry Andric LOWER_LOW(IILL); 430*0b57cec5SDimitry Andric LOWER_LOW(IILH); 431*0b57cec5SDimitry Andric LOWER_LOW(TMLL); 432*0b57cec5SDimitry Andric LOWER_LOW(TMLH); 433*0b57cec5SDimitry Andric LOWER_LOW(NILL); 434*0b57cec5SDimitry Andric LOWER_LOW(NILH); 435*0b57cec5SDimitry Andric LOWER_LOW(NILF); 436*0b57cec5SDimitry Andric LOWER_LOW(OILL); 437*0b57cec5SDimitry Andric LOWER_LOW(OILH); 438*0b57cec5SDimitry Andric LOWER_LOW(OILF); 439*0b57cec5SDimitry Andric LOWER_LOW(XILF); 440*0b57cec5SDimitry Andric 441*0b57cec5SDimitry Andric #undef LOWER_LOW 442*0b57cec5SDimitry Andric 443*0b57cec5SDimitry Andric #define LOWER_HIGH(NAME) \ 444*0b57cec5SDimitry Andric case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break 445*0b57cec5SDimitry Andric 446*0b57cec5SDimitry Andric LOWER_HIGH(IIHL); 447*0b57cec5SDimitry Andric LOWER_HIGH(IIHH); 448*0b57cec5SDimitry Andric LOWER_HIGH(TMHL); 449*0b57cec5SDimitry Andric LOWER_HIGH(TMHH); 450*0b57cec5SDimitry Andric LOWER_HIGH(NIHL); 451*0b57cec5SDimitry Andric LOWER_HIGH(NIHH); 452*0b57cec5SDimitry Andric LOWER_HIGH(NIHF); 453*0b57cec5SDimitry Andric LOWER_HIGH(OIHL); 454*0b57cec5SDimitry Andric LOWER_HIGH(OIHH); 455*0b57cec5SDimitry Andric LOWER_HIGH(OIHF); 456*0b57cec5SDimitry Andric LOWER_HIGH(XIHF); 457*0b57cec5SDimitry Andric 458*0b57cec5SDimitry Andric #undef LOWER_HIGH 459*0b57cec5SDimitry Andric 460*0b57cec5SDimitry Andric case SystemZ::Serialize: 461*0b57cec5SDimitry Andric if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization()) 462*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 463*0b57cec5SDimitry Andric .addImm(14).addReg(SystemZ::R0D); 464*0b57cec5SDimitry Andric else 465*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCRAsm) 466*0b57cec5SDimitry Andric .addImm(15).addReg(SystemZ::R0D); 467*0b57cec5SDimitry Andric break; 468*0b57cec5SDimitry Andric 469*0b57cec5SDimitry Andric // Emit nothing here but a comment if we can. 470*0b57cec5SDimitry Andric case SystemZ::MemBarrier: 471*0b57cec5SDimitry Andric OutStreamer->emitRawComment("MEMBARRIER"); 472*0b57cec5SDimitry Andric return; 473*0b57cec5SDimitry Andric 474*0b57cec5SDimitry Andric // We want to emit "j .+2" for traps, jumping to the relative immediate field 475*0b57cec5SDimitry Andric // of the jump instruction, which is an illegal instruction. We cannot emit a 476*0b57cec5SDimitry Andric // "." symbol, so create and emit a temp label before the instruction and use 477*0b57cec5SDimitry Andric // that instead. 478*0b57cec5SDimitry Andric case SystemZ::Trap: { 479*0b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 480*0b57cec5SDimitry Andric OutStreamer->EmitLabel(DotSym); 481*0b57cec5SDimitry Andric 482*0b57cec5SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 483*0b57cec5SDimitry Andric const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 484*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::J) 485*0b57cec5SDimitry Andric .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 486*0b57cec5SDimitry Andric } 487*0b57cec5SDimitry Andric break; 488*0b57cec5SDimitry Andric 489*0b57cec5SDimitry Andric // Conditional traps will create a branch on condition instruction that jumps 490*0b57cec5SDimitry Andric // to the relative immediate field of the jump instruction. (eg. "jo .+2") 491*0b57cec5SDimitry Andric case SystemZ::CondTrap: { 492*0b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 493*0b57cec5SDimitry Andric OutStreamer->EmitLabel(DotSym); 494*0b57cec5SDimitry Andric 495*0b57cec5SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext); 496*0b57cec5SDimitry Andric const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext); 497*0b57cec5SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRC) 498*0b57cec5SDimitry Andric .addImm(MI->getOperand(0).getImm()) 499*0b57cec5SDimitry Andric .addImm(MI->getOperand(1).getImm()) 500*0b57cec5SDimitry Andric .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext)); 501*0b57cec5SDimitry Andric } 502*0b57cec5SDimitry Andric break; 503*0b57cec5SDimitry Andric 504*0b57cec5SDimitry Andric case TargetOpcode::STACKMAP: 505*0b57cec5SDimitry Andric LowerSTACKMAP(*MI); 506*0b57cec5SDimitry Andric return; 507*0b57cec5SDimitry Andric 508*0b57cec5SDimitry Andric case TargetOpcode::PATCHPOINT: 509*0b57cec5SDimitry Andric LowerPATCHPOINT(*MI, Lower); 510*0b57cec5SDimitry Andric return; 511*0b57cec5SDimitry Andric 512*0b57cec5SDimitry Andric default: 513*0b57cec5SDimitry Andric Lower.lower(MI, LoweredMI); 514*0b57cec5SDimitry Andric break; 515*0b57cec5SDimitry Andric } 516*0b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, LoweredMI); 517*0b57cec5SDimitry Andric } 518*0b57cec5SDimitry Andric 519*0b57cec5SDimitry Andric 520*0b57cec5SDimitry Andric // Emit the largest nop instruction smaller than or equal to NumBytes 521*0b57cec5SDimitry Andric // bytes. Return the size of nop emitted. 522*0b57cec5SDimitry Andric static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer, 523*0b57cec5SDimitry Andric unsigned NumBytes, const MCSubtargetInfo &STI) { 524*0b57cec5SDimitry Andric if (NumBytes < 2) { 525*0b57cec5SDimitry Andric llvm_unreachable("Zero nops?"); 526*0b57cec5SDimitry Andric return 0; 527*0b57cec5SDimitry Andric } 528*0b57cec5SDimitry Andric else if (NumBytes < 4) { 529*0b57cec5SDimitry Andric OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm) 530*0b57cec5SDimitry Andric .addImm(0).addReg(SystemZ::R0D), STI); 531*0b57cec5SDimitry Andric return 2; 532*0b57cec5SDimitry Andric } 533*0b57cec5SDimitry Andric else if (NumBytes < 6) { 534*0b57cec5SDimitry Andric OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCAsm) 535*0b57cec5SDimitry Andric .addImm(0).addReg(0).addImm(0).addReg(0), 536*0b57cec5SDimitry Andric STI); 537*0b57cec5SDimitry Andric return 4; 538*0b57cec5SDimitry Andric } 539*0b57cec5SDimitry Andric else { 540*0b57cec5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol(); 541*0b57cec5SDimitry Andric const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext); 542*0b57cec5SDimitry Andric OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm) 543*0b57cec5SDimitry Andric .addImm(0).addExpr(Dot), STI); 544*0b57cec5SDimitry Andric OutStreamer.EmitLabel(DotSym); 545*0b57cec5SDimitry Andric return 6; 546*0b57cec5SDimitry Andric } 547*0b57cec5SDimitry Andric } 548*0b57cec5SDimitry Andric 549*0b57cec5SDimitry Andric void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) { 550*0b57cec5SDimitry Andric const SystemZInstrInfo *TII = 551*0b57cec5SDimitry Andric static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo()); 552*0b57cec5SDimitry Andric 553*0b57cec5SDimitry Andric unsigned NumNOPBytes = MI.getOperand(1).getImm(); 554*0b57cec5SDimitry Andric 555*0b57cec5SDimitry Andric SM.recordStackMap(MI); 556*0b57cec5SDimitry Andric assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!"); 557*0b57cec5SDimitry Andric 558*0b57cec5SDimitry Andric // Scan ahead to trim the shadow. 559*0b57cec5SDimitry Andric unsigned ShadowBytes = 0; 560*0b57cec5SDimitry Andric const MachineBasicBlock &MBB = *MI.getParent(); 561*0b57cec5SDimitry Andric MachineBasicBlock::const_iterator MII(MI); 562*0b57cec5SDimitry Andric ++MII; 563*0b57cec5SDimitry Andric while (ShadowBytes < NumNOPBytes) { 564*0b57cec5SDimitry Andric if (MII == MBB.end() || 565*0b57cec5SDimitry Andric MII->getOpcode() == TargetOpcode::PATCHPOINT || 566*0b57cec5SDimitry Andric MII->getOpcode() == TargetOpcode::STACKMAP) 567*0b57cec5SDimitry Andric break; 568*0b57cec5SDimitry Andric ShadowBytes += TII->getInstSizeInBytes(*MII); 569*0b57cec5SDimitry Andric if (MII->isCall()) 570*0b57cec5SDimitry Andric break; 571*0b57cec5SDimitry Andric ++MII; 572*0b57cec5SDimitry Andric } 573*0b57cec5SDimitry Andric 574*0b57cec5SDimitry Andric // Emit nops. 575*0b57cec5SDimitry Andric while (ShadowBytes < NumNOPBytes) 576*0b57cec5SDimitry Andric ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes, 577*0b57cec5SDimitry Andric getSubtargetInfo()); 578*0b57cec5SDimitry Andric } 579*0b57cec5SDimitry Andric 580*0b57cec5SDimitry Andric // Lower a patchpoint of the form: 581*0b57cec5SDimitry Andric // [<def>], <id>, <numBytes>, <target>, <numArgs> 582*0b57cec5SDimitry Andric void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI, 583*0b57cec5SDimitry Andric SystemZMCInstLower &Lower) { 584*0b57cec5SDimitry Andric SM.recordPatchPoint(MI); 585*0b57cec5SDimitry Andric PatchPointOpers Opers(&MI); 586*0b57cec5SDimitry Andric 587*0b57cec5SDimitry Andric unsigned EncodedBytes = 0; 588*0b57cec5SDimitry Andric const MachineOperand &CalleeMO = Opers.getCallTarget(); 589*0b57cec5SDimitry Andric 590*0b57cec5SDimitry Andric if (CalleeMO.isImm()) { 591*0b57cec5SDimitry Andric uint64_t CallTarget = CalleeMO.getImm(); 592*0b57cec5SDimitry Andric if (CallTarget) { 593*0b57cec5SDimitry Andric unsigned ScratchIdx = -1; 594*0b57cec5SDimitry Andric unsigned ScratchReg = 0; 595*0b57cec5SDimitry Andric do { 596*0b57cec5SDimitry Andric ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1); 597*0b57cec5SDimitry Andric ScratchReg = MI.getOperand(ScratchIdx).getReg(); 598*0b57cec5SDimitry Andric } while (ScratchReg == SystemZ::R0D); 599*0b57cec5SDimitry Andric 600*0b57cec5SDimitry Andric // Materialize the call target address 601*0b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF) 602*0b57cec5SDimitry Andric .addReg(ScratchReg) 603*0b57cec5SDimitry Andric .addImm(CallTarget & 0xFFFFFFFF)); 604*0b57cec5SDimitry Andric EncodedBytes += 6; 605*0b57cec5SDimitry Andric if (CallTarget >> 32) { 606*0b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF) 607*0b57cec5SDimitry Andric .addReg(ScratchReg) 608*0b57cec5SDimitry Andric .addImm(CallTarget >> 32)); 609*0b57cec5SDimitry Andric EncodedBytes += 6; 610*0b57cec5SDimitry Andric } 611*0b57cec5SDimitry Andric 612*0b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR) 613*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 614*0b57cec5SDimitry Andric .addReg(ScratchReg)); 615*0b57cec5SDimitry Andric EncodedBytes += 2; 616*0b57cec5SDimitry Andric } 617*0b57cec5SDimitry Andric } else if (CalleeMO.isGlobal()) { 618*0b57cec5SDimitry Andric const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT); 619*0b57cec5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL) 620*0b57cec5SDimitry Andric .addReg(SystemZ::R14D) 621*0b57cec5SDimitry Andric .addExpr(Expr)); 622*0b57cec5SDimitry Andric EncodedBytes += 6; 623*0b57cec5SDimitry Andric } 624*0b57cec5SDimitry Andric 625*0b57cec5SDimitry Andric // Emit padding. 626*0b57cec5SDimitry Andric unsigned NumBytes = Opers.getNumPatchBytes(); 627*0b57cec5SDimitry Andric assert(NumBytes >= EncodedBytes && 628*0b57cec5SDimitry Andric "Patchpoint can't request size less than the length of a call."); 629*0b57cec5SDimitry Andric assert((NumBytes - EncodedBytes) % 2 == 0 && 630*0b57cec5SDimitry Andric "Invalid number of NOP bytes requested!"); 631*0b57cec5SDimitry Andric while (EncodedBytes < NumBytes) 632*0b57cec5SDimitry Andric EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes, 633*0b57cec5SDimitry Andric getSubtargetInfo()); 634*0b57cec5SDimitry Andric } 635*0b57cec5SDimitry Andric 636*0b57cec5SDimitry Andric // Convert a SystemZ-specific constant pool modifier into the associated 637*0b57cec5SDimitry Andric // MCSymbolRefExpr variant kind. 638*0b57cec5SDimitry Andric static MCSymbolRefExpr::VariantKind 639*0b57cec5SDimitry Andric getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) { 640*0b57cec5SDimitry Andric switch (Modifier) { 641*0b57cec5SDimitry Andric case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; 642*0b57cec5SDimitry Andric case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM; 643*0b57cec5SDimitry Andric case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF; 644*0b57cec5SDimitry Andric case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF; 645*0b57cec5SDimitry Andric } 646*0b57cec5SDimitry Andric llvm_unreachable("Invalid SystemCPModifier!"); 647*0b57cec5SDimitry Andric } 648*0b57cec5SDimitry Andric 649*0b57cec5SDimitry Andric void SystemZAsmPrinter:: 650*0b57cec5SDimitry Andric EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 651*0b57cec5SDimitry Andric auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV); 652*0b57cec5SDimitry Andric 653*0b57cec5SDimitry Andric const MCExpr *Expr = 654*0b57cec5SDimitry Andric MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()), 655*0b57cec5SDimitry Andric getModifierVariantKind(ZCPV->getModifier()), 656*0b57cec5SDimitry Andric OutContext); 657*0b57cec5SDimitry Andric uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType()); 658*0b57cec5SDimitry Andric 659*0b57cec5SDimitry Andric OutStreamer->EmitValue(Expr, Size); 660*0b57cec5SDimitry Andric } 661*0b57cec5SDimitry Andric 662*0b57cec5SDimitry Andric bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 663*0b57cec5SDimitry Andric const char *ExtraCode, 664*0b57cec5SDimitry Andric raw_ostream &OS) { 665*0b57cec5SDimitry Andric if (ExtraCode) 666*0b57cec5SDimitry Andric return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); 667*0b57cec5SDimitry Andric SystemZMCInstLower Lower(MF->getContext(), *this); 668*0b57cec5SDimitry Andric MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo))); 669*0b57cec5SDimitry Andric SystemZInstPrinter::printOperand(MO, MAI, OS); 670*0b57cec5SDimitry Andric return false; 671*0b57cec5SDimitry Andric } 672*0b57cec5SDimitry Andric 673*0b57cec5SDimitry Andric bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 674*0b57cec5SDimitry Andric unsigned OpNo, 675*0b57cec5SDimitry Andric const char *ExtraCode, 676*0b57cec5SDimitry Andric raw_ostream &OS) { 677*0b57cec5SDimitry Andric SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(), 678*0b57cec5SDimitry Andric MI->getOperand(OpNo + 1).getImm(), 679*0b57cec5SDimitry Andric MI->getOperand(OpNo + 2).getReg(), OS); 680*0b57cec5SDimitry Andric return false; 681*0b57cec5SDimitry Andric } 682*0b57cec5SDimitry Andric 683*0b57cec5SDimitry Andric void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) { 684*0b57cec5SDimitry Andric emitStackMaps(SM); 685*0b57cec5SDimitry Andric } 686*0b57cec5SDimitry Andric 687*0b57cec5SDimitry Andric // Force static initialization. 688*0b57cec5SDimitry Andric extern "C" void LLVMInitializeSystemZAsmPrinter() { 689*0b57cec5SDimitry Andric RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget()); 690*0b57cec5SDimitry Andric } 691