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