1284c1978SDimitry Andric //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
2284c1978SDimitry Andric //
3284c1978SDimitry Andric // The LLVM Compiler Infrastructure
4284c1978SDimitry Andric //
5284c1978SDimitry Andric // This file is distributed under the University of Illinois Open Source
6284c1978SDimitry Andric // License. See LICENSE.TXT for details.
7284c1978SDimitry Andric //
8284c1978SDimitry Andric //===----------------------------------------------------------------------===//
9284c1978SDimitry Andric //
10284c1978SDimitry Andric // Streams SystemZ assembly language and associated data, in the form of
11284c1978SDimitry Andric // MCInsts and MCExprs respectively.
12284c1978SDimitry Andric //
13284c1978SDimitry Andric //===----------------------------------------------------------------------===//
14284c1978SDimitry Andric
15284c1978SDimitry Andric #include "SystemZAsmPrinter.h"
16284c1978SDimitry Andric #include "InstPrinter/SystemZInstPrinter.h"
17284c1978SDimitry Andric #include "SystemZConstantPoolValue.h"
18284c1978SDimitry Andric #include "SystemZMCInstLower.h"
19284c1978SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h"
20284c1978SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
2191bc56edSDimitry Andric #include "llvm/IR/Mangler.h"
22284c1978SDimitry Andric #include "llvm/MC/MCExpr.h"
23f785676fSDimitry Andric #include "llvm/MC/MCInstBuilder.h"
24284c1978SDimitry Andric #include "llvm/MC/MCStreamer.h"
25284c1978SDimitry Andric #include "llvm/Support/TargetRegistry.h"
26284c1978SDimitry Andric
27284c1978SDimitry Andric using namespace llvm;
28284c1978SDimitry Andric
29f785676fSDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the
30f785676fSDimitry Andric // GR64 register operands turned into GR32s.
lowerRILow(const MachineInstr * MI,unsigned Opcode)31f785676fSDimitry Andric static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
32f785676fSDimitry Andric if (MI->isCompare())
33f785676fSDimitry Andric return MCInstBuilder(Opcode)
34f785676fSDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
35f785676fSDimitry Andric .addImm(MI->getOperand(1).getImm());
36f785676fSDimitry Andric else
37f785676fSDimitry Andric return MCInstBuilder(Opcode)
38f785676fSDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
39f785676fSDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
40f785676fSDimitry Andric .addImm(MI->getOperand(2).getImm());
41f785676fSDimitry Andric }
42f785676fSDimitry Andric
43f785676fSDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the
44f785676fSDimitry Andric // GR64 register operands turned into GRH32s.
lowerRIHigh(const MachineInstr * MI,unsigned Opcode)45f785676fSDimitry Andric static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
46f785676fSDimitry Andric if (MI->isCompare())
47f785676fSDimitry Andric return MCInstBuilder(Opcode)
48f785676fSDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
49f785676fSDimitry Andric .addImm(MI->getOperand(1).getImm());
50f785676fSDimitry Andric else
51f785676fSDimitry Andric return MCInstBuilder(Opcode)
52f785676fSDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
53f785676fSDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
54f785676fSDimitry Andric .addImm(MI->getOperand(2).getImm());
55f785676fSDimitry Andric }
56f785676fSDimitry Andric
57f785676fSDimitry Andric // Return an RI instruction like MI with opcode Opcode, but with the
58f785676fSDimitry Andric // R2 register turned into a GR64.
lowerRIEfLow(const MachineInstr * MI,unsigned Opcode)59f785676fSDimitry Andric static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
60f785676fSDimitry Andric return MCInstBuilder(Opcode)
61f785676fSDimitry Andric .addReg(MI->getOperand(0).getReg())
62f785676fSDimitry Andric .addReg(MI->getOperand(1).getReg())
63f785676fSDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
64f785676fSDimitry Andric .addImm(MI->getOperand(3).getImm())
65f785676fSDimitry Andric .addImm(MI->getOperand(4).getImm())
66f785676fSDimitry Andric .addImm(MI->getOperand(5).getImm());
67f785676fSDimitry Andric }
68f785676fSDimitry Andric
getTLSGetOffset(MCContext & Context)69ff0cc061SDimitry Andric static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
70ff0cc061SDimitry Andric StringRef Name = "__tls_get_offset";
7197bc6c73SDimitry Andric return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
72ff0cc061SDimitry Andric MCSymbolRefExpr::VK_PLT,
73ff0cc061SDimitry Andric Context);
74ff0cc061SDimitry Andric }
75ff0cc061SDimitry Andric
getGlobalOffsetTable(MCContext & Context)76ff0cc061SDimitry Andric static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
77ff0cc061SDimitry Andric StringRef Name = "_GLOBAL_OFFSET_TABLE_";
7897bc6c73SDimitry Andric return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
79ff0cc061SDimitry Andric MCSymbolRefExpr::VK_None,
80ff0cc061SDimitry Andric Context);
81ff0cc061SDimitry Andric }
82ff0cc061SDimitry Andric
83ff0cc061SDimitry Andric // MI loads the high part of a vector from memory. Return an instruction
84ff0cc061SDimitry Andric // that uses replicating vector load Opcode to do the same thing.
lowerSubvectorLoad(const MachineInstr * MI,unsigned Opcode)85ff0cc061SDimitry Andric static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
86ff0cc061SDimitry Andric return MCInstBuilder(Opcode)
87ff0cc061SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
88ff0cc061SDimitry Andric .addReg(MI->getOperand(1).getReg())
89ff0cc061SDimitry Andric .addImm(MI->getOperand(2).getImm())
90ff0cc061SDimitry Andric .addReg(MI->getOperand(3).getReg());
91ff0cc061SDimitry Andric }
92ff0cc061SDimitry Andric
93ff0cc061SDimitry Andric // MI stores the high part of a vector to memory. Return an instruction
94ff0cc061SDimitry Andric // that uses elemental vector store Opcode to do the same thing.
lowerSubvectorStore(const MachineInstr * MI,unsigned Opcode)95ff0cc061SDimitry Andric static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
96ff0cc061SDimitry Andric return MCInstBuilder(Opcode)
97ff0cc061SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
98ff0cc061SDimitry Andric .addReg(MI->getOperand(1).getReg())
99ff0cc061SDimitry Andric .addImm(MI->getOperand(2).getImm())
100ff0cc061SDimitry Andric .addReg(MI->getOperand(3).getReg())
101ff0cc061SDimitry Andric .addImm(0);
102ff0cc061SDimitry Andric }
103ff0cc061SDimitry Andric
EmitInstruction(const MachineInstr * MI)104284c1978SDimitry Andric void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
105f785676fSDimitry Andric SystemZMCInstLower Lower(MF->getContext(), *this);
106284c1978SDimitry Andric MCInst LoweredMI;
107f785676fSDimitry Andric switch (MI->getOpcode()) {
108f785676fSDimitry Andric case SystemZ::Return:
109f785676fSDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
110f785676fSDimitry Andric break;
111f785676fSDimitry Andric
1123ca95b02SDimitry Andric case SystemZ::CondReturn:
1133ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCR)
1143ca95b02SDimitry Andric .addImm(MI->getOperand(0).getImm())
1153ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
1163ca95b02SDimitry Andric .addReg(SystemZ::R14D);
1173ca95b02SDimitry Andric break;
1183ca95b02SDimitry Andric
1193ca95b02SDimitry Andric case SystemZ::CRBReturn:
1203ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CRB)
1213ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
1223ca95b02SDimitry Andric .addReg(MI->getOperand(1).getReg())
1233ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
1243ca95b02SDimitry Andric .addReg(SystemZ::R14D)
1253ca95b02SDimitry Andric .addImm(0);
1263ca95b02SDimitry Andric break;
1273ca95b02SDimitry Andric
1283ca95b02SDimitry Andric case SystemZ::CGRBReturn:
1293ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGRB)
1303ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
1313ca95b02SDimitry Andric .addReg(MI->getOperand(1).getReg())
1323ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
1333ca95b02SDimitry Andric .addReg(SystemZ::R14D)
1343ca95b02SDimitry Andric .addImm(0);
1353ca95b02SDimitry Andric break;
1363ca95b02SDimitry Andric
1373ca95b02SDimitry Andric case SystemZ::CIBReturn:
1383ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CIB)
1393ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
1403ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
1413ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
1423ca95b02SDimitry Andric .addReg(SystemZ::R14D)
1433ca95b02SDimitry Andric .addImm(0);
1443ca95b02SDimitry Andric break;
1453ca95b02SDimitry Andric
1463ca95b02SDimitry Andric case SystemZ::CGIBReturn:
1473ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGIB)
1483ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
1493ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
1503ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
1513ca95b02SDimitry Andric .addReg(SystemZ::R14D)
1523ca95b02SDimitry Andric .addImm(0);
1533ca95b02SDimitry Andric break;
1543ca95b02SDimitry Andric
1553ca95b02SDimitry Andric case SystemZ::CLRBReturn:
1563ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLRB)
1573ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
1583ca95b02SDimitry Andric .addReg(MI->getOperand(1).getReg())
1593ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
1603ca95b02SDimitry Andric .addReg(SystemZ::R14D)
1613ca95b02SDimitry Andric .addImm(0);
1623ca95b02SDimitry Andric break;
1633ca95b02SDimitry Andric
1643ca95b02SDimitry Andric case SystemZ::CLGRBReturn:
1653ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGRB)
1663ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
1673ca95b02SDimitry Andric .addReg(MI->getOperand(1).getReg())
1683ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
1693ca95b02SDimitry Andric .addReg(SystemZ::R14D)
1703ca95b02SDimitry Andric .addImm(0);
1713ca95b02SDimitry Andric break;
1723ca95b02SDimitry Andric
1733ca95b02SDimitry Andric case SystemZ::CLIBReturn:
1743ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLIB)
1753ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
1763ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
1773ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
1783ca95b02SDimitry Andric .addReg(SystemZ::R14D)
1793ca95b02SDimitry Andric .addImm(0);
1803ca95b02SDimitry Andric break;
1813ca95b02SDimitry Andric
1823ca95b02SDimitry Andric case SystemZ::CLGIBReturn:
1833ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGIB)
1843ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
1853ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
1863ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
1873ca95b02SDimitry Andric .addReg(SystemZ::R14D)
1883ca95b02SDimitry Andric .addImm(0);
1893ca95b02SDimitry Andric break;
1903ca95b02SDimitry Andric
191f785676fSDimitry Andric case SystemZ::CallBRASL:
192f785676fSDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL)
193f785676fSDimitry Andric .addReg(SystemZ::R14D)
194f785676fSDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
195f785676fSDimitry Andric break;
196f785676fSDimitry Andric
197f785676fSDimitry Andric case SystemZ::CallBASR:
198f785676fSDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BASR)
199f785676fSDimitry Andric .addReg(SystemZ::R14D)
200f785676fSDimitry Andric .addReg(MI->getOperand(0).getReg());
201f785676fSDimitry Andric break;
202f785676fSDimitry Andric
203f785676fSDimitry Andric case SystemZ::CallJG:
204f785676fSDimitry Andric LoweredMI = MCInstBuilder(SystemZ::JG)
205f785676fSDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
206f785676fSDimitry Andric break;
207f785676fSDimitry Andric
2083ca95b02SDimitry Andric case SystemZ::CallBRCL:
2093ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRCL)
2103ca95b02SDimitry Andric .addImm(MI->getOperand(0).getImm())
2113ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
2123ca95b02SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
2133ca95b02SDimitry Andric break;
2143ca95b02SDimitry Andric
215f785676fSDimitry Andric case SystemZ::CallBR:
216f785676fSDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
217f785676fSDimitry Andric break;
218f785676fSDimitry Andric
2193ca95b02SDimitry Andric case SystemZ::CallBCR:
2203ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCR)
2213ca95b02SDimitry Andric .addImm(MI->getOperand(0).getImm())
2223ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
2233ca95b02SDimitry Andric .addReg(SystemZ::R1D);
2243ca95b02SDimitry Andric break;
2253ca95b02SDimitry Andric
2263ca95b02SDimitry Andric case SystemZ::CRBCall:
2273ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CRB)
2283ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
2293ca95b02SDimitry Andric .addReg(MI->getOperand(1).getReg())
2303ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
2313ca95b02SDimitry Andric .addReg(SystemZ::R1D)
2323ca95b02SDimitry Andric .addImm(0);
2333ca95b02SDimitry Andric break;
2343ca95b02SDimitry Andric
2353ca95b02SDimitry Andric case SystemZ::CGRBCall:
2363ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGRB)
2373ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
2383ca95b02SDimitry Andric .addReg(MI->getOperand(1).getReg())
2393ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
2403ca95b02SDimitry Andric .addReg(SystemZ::R1D)
2413ca95b02SDimitry Andric .addImm(0);
2423ca95b02SDimitry Andric break;
2433ca95b02SDimitry Andric
2443ca95b02SDimitry Andric case SystemZ::CIBCall:
2453ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CIB)
2463ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
2473ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
2483ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
2493ca95b02SDimitry Andric .addReg(SystemZ::R1D)
2503ca95b02SDimitry Andric .addImm(0);
2513ca95b02SDimitry Andric break;
2523ca95b02SDimitry Andric
2533ca95b02SDimitry Andric case SystemZ::CGIBCall:
2543ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CGIB)
2553ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
2563ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
2573ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
2583ca95b02SDimitry Andric .addReg(SystemZ::R1D)
2593ca95b02SDimitry Andric .addImm(0);
2603ca95b02SDimitry Andric break;
2613ca95b02SDimitry Andric
2623ca95b02SDimitry Andric case SystemZ::CLRBCall:
2633ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLRB)
2643ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
2653ca95b02SDimitry Andric .addReg(MI->getOperand(1).getReg())
2663ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
2673ca95b02SDimitry Andric .addReg(SystemZ::R1D)
2683ca95b02SDimitry Andric .addImm(0);
2693ca95b02SDimitry Andric break;
2703ca95b02SDimitry Andric
2713ca95b02SDimitry Andric case SystemZ::CLGRBCall:
2723ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGRB)
2733ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
2743ca95b02SDimitry Andric .addReg(MI->getOperand(1).getReg())
2753ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
2763ca95b02SDimitry Andric .addReg(SystemZ::R1D)
2773ca95b02SDimitry Andric .addImm(0);
2783ca95b02SDimitry Andric break;
2793ca95b02SDimitry Andric
2803ca95b02SDimitry Andric case SystemZ::CLIBCall:
2813ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLIB)
2823ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
2833ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
2843ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
2853ca95b02SDimitry Andric .addReg(SystemZ::R1D)
2863ca95b02SDimitry Andric .addImm(0);
2873ca95b02SDimitry Andric break;
2883ca95b02SDimitry Andric
2893ca95b02SDimitry Andric case SystemZ::CLGIBCall:
2903ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::CLGIB)
2913ca95b02SDimitry Andric .addReg(MI->getOperand(0).getReg())
2923ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
2933ca95b02SDimitry Andric .addImm(MI->getOperand(2).getImm())
2943ca95b02SDimitry Andric .addReg(SystemZ::R1D)
2953ca95b02SDimitry Andric .addImm(0);
2963ca95b02SDimitry Andric break;
2973ca95b02SDimitry Andric
298ff0cc061SDimitry Andric case SystemZ::TLS_GDCALL:
299ff0cc061SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL)
300ff0cc061SDimitry Andric .addReg(SystemZ::R14D)
301ff0cc061SDimitry Andric .addExpr(getTLSGetOffset(MF->getContext()))
302ff0cc061SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
303ff0cc061SDimitry Andric break;
304ff0cc061SDimitry Andric
305ff0cc061SDimitry Andric case SystemZ::TLS_LDCALL:
306ff0cc061SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRASL)
307ff0cc061SDimitry Andric .addReg(SystemZ::R14D)
308ff0cc061SDimitry Andric .addExpr(getTLSGetOffset(MF->getContext()))
309ff0cc061SDimitry Andric .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
310ff0cc061SDimitry Andric break;
311ff0cc061SDimitry Andric
312ff0cc061SDimitry Andric case SystemZ::GOT:
313ff0cc061SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::LARL)
314ff0cc061SDimitry Andric .addReg(MI->getOperand(0).getReg())
315ff0cc061SDimitry Andric .addExpr(getGlobalOffsetTable(MF->getContext()));
316ff0cc061SDimitry Andric break;
317ff0cc061SDimitry Andric
318f785676fSDimitry Andric case SystemZ::IILF64:
319f785676fSDimitry Andric LoweredMI = MCInstBuilder(SystemZ::IILF)
320f785676fSDimitry Andric .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
321f785676fSDimitry Andric .addImm(MI->getOperand(2).getImm());
322f785676fSDimitry Andric break;
323f785676fSDimitry Andric
324f785676fSDimitry Andric case SystemZ::IIHF64:
325f785676fSDimitry Andric LoweredMI = MCInstBuilder(SystemZ::IIHF)
326f785676fSDimitry Andric .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
327f785676fSDimitry Andric .addImm(MI->getOperand(2).getImm());
328f785676fSDimitry Andric break;
329f785676fSDimitry Andric
330f785676fSDimitry Andric case SystemZ::RISBHH:
331f785676fSDimitry Andric case SystemZ::RISBHL:
332f785676fSDimitry Andric LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
333f785676fSDimitry Andric break;
334f785676fSDimitry Andric
335f785676fSDimitry Andric case SystemZ::RISBLH:
336f785676fSDimitry Andric case SystemZ::RISBLL:
337f785676fSDimitry Andric LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
338f785676fSDimitry Andric break;
339f785676fSDimitry Andric
340ff0cc061SDimitry Andric case SystemZ::VLVGP32:
341ff0cc061SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLVGP)
342ff0cc061SDimitry Andric .addReg(MI->getOperand(0).getReg())
343ff0cc061SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
344ff0cc061SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
345ff0cc061SDimitry Andric break;
346ff0cc061SDimitry Andric
347ff0cc061SDimitry Andric case SystemZ::VLR32:
348ff0cc061SDimitry Andric case SystemZ::VLR64:
349ff0cc061SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLR)
350ff0cc061SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
351ff0cc061SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
352ff0cc061SDimitry Andric break;
353ff0cc061SDimitry Andric
354ff0cc061SDimitry Andric case SystemZ::VL32:
355ff0cc061SDimitry Andric LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
356ff0cc061SDimitry Andric break;
357ff0cc061SDimitry Andric
358ff0cc061SDimitry Andric case SystemZ::VL64:
359ff0cc061SDimitry Andric LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
360ff0cc061SDimitry Andric break;
361ff0cc061SDimitry Andric
362ff0cc061SDimitry Andric case SystemZ::VST32:
363ff0cc061SDimitry Andric LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
364ff0cc061SDimitry Andric break;
365ff0cc061SDimitry Andric
366ff0cc061SDimitry Andric case SystemZ::VST64:
367ff0cc061SDimitry Andric LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
368ff0cc061SDimitry Andric break;
369ff0cc061SDimitry Andric
370ff0cc061SDimitry Andric case SystemZ::LFER:
371ff0cc061SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLGVF)
372ff0cc061SDimitry Andric .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
373ff0cc061SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
374ff0cc061SDimitry Andric .addReg(0).addImm(0);
375ff0cc061SDimitry Andric break;
376ff0cc061SDimitry Andric
377ff0cc061SDimitry Andric case SystemZ::LEFR:
378ff0cc061SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::VLVGF)
379ff0cc061SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
380ff0cc061SDimitry Andric .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
381ff0cc061SDimitry Andric .addReg(MI->getOperand(1).getReg())
382ff0cc061SDimitry Andric .addReg(0).addImm(0);
383ff0cc061SDimitry Andric break;
384ff0cc061SDimitry Andric
385f785676fSDimitry Andric #define LOWER_LOW(NAME) \
386f785676fSDimitry Andric case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
387f785676fSDimitry Andric
388f785676fSDimitry Andric LOWER_LOW(IILL);
389f785676fSDimitry Andric LOWER_LOW(IILH);
390f785676fSDimitry Andric LOWER_LOW(TMLL);
391f785676fSDimitry Andric LOWER_LOW(TMLH);
392f785676fSDimitry Andric LOWER_LOW(NILL);
393f785676fSDimitry Andric LOWER_LOW(NILH);
394f785676fSDimitry Andric LOWER_LOW(NILF);
395f785676fSDimitry Andric LOWER_LOW(OILL);
396f785676fSDimitry Andric LOWER_LOW(OILH);
397f785676fSDimitry Andric LOWER_LOW(OILF);
398f785676fSDimitry Andric LOWER_LOW(XILF);
399f785676fSDimitry Andric
400f785676fSDimitry Andric #undef LOWER_LOW
401f785676fSDimitry Andric
402f785676fSDimitry Andric #define LOWER_HIGH(NAME) \
403f785676fSDimitry Andric case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
404f785676fSDimitry Andric
405f785676fSDimitry Andric LOWER_HIGH(IIHL);
406f785676fSDimitry Andric LOWER_HIGH(IIHH);
407f785676fSDimitry Andric LOWER_HIGH(TMHL);
408f785676fSDimitry Andric LOWER_HIGH(TMHH);
409f785676fSDimitry Andric LOWER_HIGH(NIHL);
410f785676fSDimitry Andric LOWER_HIGH(NIHH);
411f785676fSDimitry Andric LOWER_HIGH(NIHF);
412f785676fSDimitry Andric LOWER_HIGH(OIHL);
413f785676fSDimitry Andric LOWER_HIGH(OIHH);
414f785676fSDimitry Andric LOWER_HIGH(OIHF);
415f785676fSDimitry Andric LOWER_HIGH(XIHF);
416f785676fSDimitry Andric
417f785676fSDimitry Andric #undef LOWER_HIGH
418f785676fSDimitry Andric
41991bc56edSDimitry Andric case SystemZ::Serialize:
420ff0cc061SDimitry Andric if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
421d88c1a5aSDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
42291bc56edSDimitry Andric .addImm(14).addReg(SystemZ::R0D);
42391bc56edSDimitry Andric else
424d88c1a5aSDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
42591bc56edSDimitry Andric .addImm(15).addReg(SystemZ::R0D);
42691bc56edSDimitry Andric break;
42791bc56edSDimitry Andric
4283ca95b02SDimitry Andric // Emit nothing here but a comment if we can.
4293ca95b02SDimitry Andric case SystemZ::MemBarrier:
4303ca95b02SDimitry Andric OutStreamer->emitRawComment("MEMBARRIER");
4313ca95b02SDimitry Andric return;
4323ca95b02SDimitry Andric
4333ca95b02SDimitry Andric // We want to emit "j .+2" for traps, jumping to the relative immediate field
4343ca95b02SDimitry Andric // of the jump instruction, which is an illegal instruction. We cannot emit a
4353ca95b02SDimitry Andric // "." symbol, so create and emit a temp label before the instruction and use
4363ca95b02SDimitry Andric // that instead.
4373ca95b02SDimitry Andric case SystemZ::Trap: {
4383ca95b02SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol();
4393ca95b02SDimitry Andric OutStreamer->EmitLabel(DotSym);
4403ca95b02SDimitry Andric
4413ca95b02SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
4423ca95b02SDimitry Andric const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
4433ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::J)
4443ca95b02SDimitry Andric .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
4453ca95b02SDimitry Andric }
4463ca95b02SDimitry Andric break;
4473ca95b02SDimitry Andric
4483ca95b02SDimitry Andric // Conditional traps will create a branch on condition instruction that jumps
4493ca95b02SDimitry Andric // to the relative immediate field of the jump instruction. (eg. "jo .+2")
4503ca95b02SDimitry Andric case SystemZ::CondTrap: {
4513ca95b02SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol();
4523ca95b02SDimitry Andric OutStreamer->EmitLabel(DotSym);
4533ca95b02SDimitry Andric
4543ca95b02SDimitry Andric const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
4553ca95b02SDimitry Andric const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
4563ca95b02SDimitry Andric LoweredMI = MCInstBuilder(SystemZ::BRC)
4573ca95b02SDimitry Andric .addImm(MI->getOperand(0).getImm())
4583ca95b02SDimitry Andric .addImm(MI->getOperand(1).getImm())
4593ca95b02SDimitry Andric .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
4603ca95b02SDimitry Andric }
4613ca95b02SDimitry Andric break;
4623ca95b02SDimitry Andric
4634ba319b5SDimitry Andric case TargetOpcode::STACKMAP:
4644ba319b5SDimitry Andric LowerSTACKMAP(*MI);
4654ba319b5SDimitry Andric return;
4664ba319b5SDimitry Andric
4674ba319b5SDimitry Andric case TargetOpcode::PATCHPOINT:
4684ba319b5SDimitry Andric LowerPATCHPOINT(*MI, Lower);
4694ba319b5SDimitry Andric return;
4704ba319b5SDimitry Andric
471f785676fSDimitry Andric default:
472284c1978SDimitry Andric Lower.lower(MI, LoweredMI);
473f785676fSDimitry Andric break;
474f785676fSDimitry Andric }
475ff0cc061SDimitry Andric EmitToStreamer(*OutStreamer, LoweredMI);
476284c1978SDimitry Andric }
477284c1978SDimitry Andric
4784ba319b5SDimitry Andric
4794ba319b5SDimitry Andric // Emit the largest nop instruction smaller than or equal to NumBytes
4804ba319b5SDimitry Andric // bytes. Return the size of nop emitted.
EmitNop(MCContext & OutContext,MCStreamer & OutStreamer,unsigned NumBytes,const MCSubtargetInfo & STI)4814ba319b5SDimitry Andric static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
4824ba319b5SDimitry Andric unsigned NumBytes, const MCSubtargetInfo &STI) {
4834ba319b5SDimitry Andric if (NumBytes < 2) {
4844ba319b5SDimitry Andric llvm_unreachable("Zero nops?");
4854ba319b5SDimitry Andric return 0;
4864ba319b5SDimitry Andric }
4874ba319b5SDimitry Andric else if (NumBytes < 4) {
4884ba319b5SDimitry Andric OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm)
4894ba319b5SDimitry Andric .addImm(0).addReg(SystemZ::R0D), STI);
4904ba319b5SDimitry Andric return 2;
4914ba319b5SDimitry Andric }
4924ba319b5SDimitry Andric else if (NumBytes < 6) {
4934ba319b5SDimitry Andric OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCAsm)
4944ba319b5SDimitry Andric .addImm(0).addReg(0).addImm(0).addReg(0),
4954ba319b5SDimitry Andric STI);
4964ba319b5SDimitry Andric return 4;
4974ba319b5SDimitry Andric }
4984ba319b5SDimitry Andric else {
4994ba319b5SDimitry Andric MCSymbol *DotSym = OutContext.createTempSymbol();
5004ba319b5SDimitry Andric const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
5014ba319b5SDimitry Andric OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm)
5024ba319b5SDimitry Andric .addImm(0).addExpr(Dot), STI);
5034ba319b5SDimitry Andric OutStreamer.EmitLabel(DotSym);
5044ba319b5SDimitry Andric return 6;
5054ba319b5SDimitry Andric }
5064ba319b5SDimitry Andric }
5074ba319b5SDimitry Andric
LowerSTACKMAP(const MachineInstr & MI)5084ba319b5SDimitry Andric void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
5094ba319b5SDimitry Andric const SystemZInstrInfo *TII =
5104ba319b5SDimitry Andric static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo());
5114ba319b5SDimitry Andric
5124ba319b5SDimitry Andric unsigned NumNOPBytes = MI.getOperand(1).getImm();
5134ba319b5SDimitry Andric
5144ba319b5SDimitry Andric SM.recordStackMap(MI);
5154ba319b5SDimitry Andric assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
5164ba319b5SDimitry Andric
5174ba319b5SDimitry Andric // Scan ahead to trim the shadow.
5184ba319b5SDimitry Andric unsigned ShadowBytes = 0;
5194ba319b5SDimitry Andric const MachineBasicBlock &MBB = *MI.getParent();
5204ba319b5SDimitry Andric MachineBasicBlock::const_iterator MII(MI);
5214ba319b5SDimitry Andric ++MII;
5224ba319b5SDimitry Andric while (ShadowBytes < NumNOPBytes) {
5234ba319b5SDimitry Andric if (MII == MBB.end() ||
5244ba319b5SDimitry Andric MII->getOpcode() == TargetOpcode::PATCHPOINT ||
5254ba319b5SDimitry Andric MII->getOpcode() == TargetOpcode::STACKMAP)
5264ba319b5SDimitry Andric break;
5274ba319b5SDimitry Andric ShadowBytes += TII->getInstSizeInBytes(*MII);
5284ba319b5SDimitry Andric if (MII->isCall())
5294ba319b5SDimitry Andric break;
5304ba319b5SDimitry Andric ++MII;
5314ba319b5SDimitry Andric }
5324ba319b5SDimitry Andric
5334ba319b5SDimitry Andric // Emit nops.
5344ba319b5SDimitry Andric while (ShadowBytes < NumNOPBytes)
5354ba319b5SDimitry Andric ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
5364ba319b5SDimitry Andric getSubtargetInfo());
5374ba319b5SDimitry Andric }
5384ba319b5SDimitry Andric
5394ba319b5SDimitry Andric // Lower a patchpoint of the form:
5404ba319b5SDimitry Andric // [<def>], <id>, <numBytes>, <target>, <numArgs>
LowerPATCHPOINT(const MachineInstr & MI,SystemZMCInstLower & Lower)5414ba319b5SDimitry Andric void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
5424ba319b5SDimitry Andric SystemZMCInstLower &Lower) {
5434ba319b5SDimitry Andric SM.recordPatchPoint(MI);
5444ba319b5SDimitry Andric PatchPointOpers Opers(&MI);
5454ba319b5SDimitry Andric
5464ba319b5SDimitry Andric unsigned EncodedBytes = 0;
5474ba319b5SDimitry Andric const MachineOperand &CalleeMO = Opers.getCallTarget();
5484ba319b5SDimitry Andric
5494ba319b5SDimitry Andric if (CalleeMO.isImm()) {
5504ba319b5SDimitry Andric uint64_t CallTarget = CalleeMO.getImm();
5514ba319b5SDimitry Andric if (CallTarget) {
5524ba319b5SDimitry Andric unsigned ScratchIdx = -1;
5534ba319b5SDimitry Andric unsigned ScratchReg = 0;
5544ba319b5SDimitry Andric do {
5554ba319b5SDimitry Andric ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
5564ba319b5SDimitry Andric ScratchReg = MI.getOperand(ScratchIdx).getReg();
5574ba319b5SDimitry Andric } while (ScratchReg == SystemZ::R0D);
5584ba319b5SDimitry Andric
5594ba319b5SDimitry Andric // Materialize the call target address
5604ba319b5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF)
5614ba319b5SDimitry Andric .addReg(ScratchReg)
5624ba319b5SDimitry Andric .addImm(CallTarget & 0xFFFFFFFF));
5634ba319b5SDimitry Andric EncodedBytes += 6;
5644ba319b5SDimitry Andric if (CallTarget >> 32) {
5654ba319b5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF)
5664ba319b5SDimitry Andric .addReg(ScratchReg)
5674ba319b5SDimitry Andric .addImm(CallTarget >> 32));
5684ba319b5SDimitry Andric EncodedBytes += 6;
5694ba319b5SDimitry Andric }
5704ba319b5SDimitry Andric
5714ba319b5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
5724ba319b5SDimitry Andric .addReg(SystemZ::R14D)
5734ba319b5SDimitry Andric .addReg(ScratchReg));
5744ba319b5SDimitry Andric EncodedBytes += 2;
5754ba319b5SDimitry Andric }
5764ba319b5SDimitry Andric } else if (CalleeMO.isGlobal()) {
5774ba319b5SDimitry Andric const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
5784ba319b5SDimitry Andric EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
5794ba319b5SDimitry Andric .addReg(SystemZ::R14D)
5804ba319b5SDimitry Andric .addExpr(Expr));
5814ba319b5SDimitry Andric EncodedBytes += 6;
5824ba319b5SDimitry Andric }
5834ba319b5SDimitry Andric
5844ba319b5SDimitry Andric // Emit padding.
5854ba319b5SDimitry Andric unsigned NumBytes = Opers.getNumPatchBytes();
5864ba319b5SDimitry Andric assert(NumBytes >= EncodedBytes &&
5874ba319b5SDimitry Andric "Patchpoint can't request size less than the length of a call.");
5884ba319b5SDimitry Andric assert((NumBytes - EncodedBytes) % 2 == 0 &&
5894ba319b5SDimitry Andric "Invalid number of NOP bytes requested!");
5904ba319b5SDimitry Andric while (EncodedBytes < NumBytes)
5914ba319b5SDimitry Andric EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
5924ba319b5SDimitry Andric getSubtargetInfo());
5934ba319b5SDimitry Andric }
5944ba319b5SDimitry Andric
595284c1978SDimitry Andric // Convert a SystemZ-specific constant pool modifier into the associated
596284c1978SDimitry Andric // MCSymbolRefExpr variant kind.
597284c1978SDimitry Andric static MCSymbolRefExpr::VariantKind
getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier)598284c1978SDimitry Andric getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
599284c1978SDimitry Andric switch (Modifier) {
600ff0cc061SDimitry Andric case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
601ff0cc061SDimitry Andric case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
602ff0cc061SDimitry Andric case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
603284c1978SDimitry Andric case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
604284c1978SDimitry Andric }
605284c1978SDimitry Andric llvm_unreachable("Invalid SystemCPModifier!");
606284c1978SDimitry Andric }
607284c1978SDimitry Andric
608284c1978SDimitry Andric void SystemZAsmPrinter::
EmitMachineConstantPoolValue(MachineConstantPoolValue * MCPV)609284c1978SDimitry Andric EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
61091bc56edSDimitry Andric auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
611284c1978SDimitry Andric
612284c1978SDimitry Andric const MCExpr *Expr =
61397bc6c73SDimitry Andric MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
614284c1978SDimitry Andric getModifierVariantKind(ZCPV->getModifier()),
615284c1978SDimitry Andric OutContext);
6167d523365SDimitry Andric uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
617284c1978SDimitry Andric
618ff0cc061SDimitry Andric OutStreamer->EmitValue(Expr, Size);
619284c1978SDimitry Andric }
620284c1978SDimitry Andric
PrintAsmOperand(const MachineInstr * MI,unsigned OpNo,unsigned AsmVariant,const char * ExtraCode,raw_ostream & OS)621284c1978SDimitry Andric bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
622284c1978SDimitry Andric unsigned OpNo,
623284c1978SDimitry Andric unsigned AsmVariant,
624284c1978SDimitry Andric const char *ExtraCode,
625284c1978SDimitry Andric raw_ostream &OS) {
626284c1978SDimitry Andric if (ExtraCode && *ExtraCode == 'n') {
627284c1978SDimitry Andric if (!MI->getOperand(OpNo).isImm())
628284c1978SDimitry Andric return true;
629284c1978SDimitry Andric OS << -int64_t(MI->getOperand(OpNo).getImm());
630284c1978SDimitry Andric } else {
631f785676fSDimitry Andric SystemZMCInstLower Lower(MF->getContext(), *this);
632284c1978SDimitry Andric MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
63397bc6c73SDimitry Andric SystemZInstPrinter::printOperand(MO, MAI, OS);
634284c1978SDimitry Andric }
635284c1978SDimitry Andric return false;
636284c1978SDimitry Andric }
637284c1978SDimitry Andric
PrintAsmMemoryOperand(const MachineInstr * MI,unsigned OpNo,unsigned AsmVariant,const char * ExtraCode,raw_ostream & OS)638284c1978SDimitry Andric bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
639284c1978SDimitry Andric unsigned OpNo,
640284c1978SDimitry Andric unsigned AsmVariant,
641284c1978SDimitry Andric const char *ExtraCode,
642284c1978SDimitry Andric raw_ostream &OS) {
643284c1978SDimitry Andric SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
644284c1978SDimitry Andric MI->getOperand(OpNo + 1).getImm(),
645284c1978SDimitry Andric MI->getOperand(OpNo + 2).getReg(), OS);
646284c1978SDimitry Andric return false;
647284c1978SDimitry Andric }
648284c1978SDimitry Andric
EmitEndOfAsmFile(Module & M)6494ba319b5SDimitry Andric void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
650*b5893f02SDimitry Andric emitStackMaps(SM);
6514ba319b5SDimitry Andric }
6524ba319b5SDimitry Andric
653284c1978SDimitry Andric // Force static initialization.
LLVMInitializeSystemZAsmPrinter()654284c1978SDimitry Andric extern "C" void LLVMInitializeSystemZAsmPrinter() {
655d88c1a5aSDimitry Andric RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget());
656284c1978SDimitry Andric }
657