15f613dfdSUlrich Weigand //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
25f613dfdSUlrich Weigand //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f613dfdSUlrich Weigand //
75f613dfdSUlrich Weigand //===----------------------------------------------------------------------===//
85f613dfdSUlrich Weigand //
95f613dfdSUlrich Weigand // Streams SystemZ assembly language and associated data, in the form of
105f613dfdSUlrich Weigand // MCInsts and MCExprs respectively.
115f613dfdSUlrich Weigand //
125f613dfdSUlrich Weigand //===----------------------------------------------------------------------===//
135f613dfdSUlrich Weigand
145f613dfdSUlrich Weigand #include "SystemZAsmPrinter.h"
15d0124bd7SRichard Trieu #include "MCTargetDesc/SystemZInstPrinter.h"
165f613dfdSUlrich Weigand #include "SystemZConstantPoolValue.h"
175f613dfdSUlrich Weigand #include "SystemZMCInstLower.h"
181e6f98b8SRichard Trieu #include "TargetInfo/SystemZTargetInfo.h"
196be15788SJonas Paulsson #include "llvm/BinaryFormat/ELF.h"
205f613dfdSUlrich Weigand #include "llvm/CodeGen/MachineModuleInfoImpls.h"
215f613dfdSUlrich Weigand #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
22894843cbSRafael Espindola #include "llvm/IR/Mangler.h"
235f613dfdSUlrich Weigand #include "llvm/MC/MCExpr.h"
249ab97cd1SRichard Sandiford #include "llvm/MC/MCInstBuilder.h"
256be15788SJonas Paulsson #include "llvm/MC/MCSectionELF.h"
265f613dfdSUlrich Weigand #include "llvm/MC/MCStreamer.h"
2789b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
285f613dfdSUlrich Weigand
295f613dfdSUlrich Weigand using namespace llvm;
305f613dfdSUlrich Weigand
31652784e2SRichard Sandiford // Return an RI instruction like MI with opcode Opcode, but with the
32652784e2SRichard Sandiford // GR64 register operands turned into GR32s.
lowerRILow(const MachineInstr * MI,unsigned Opcode)33652784e2SRichard Sandiford static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
34f03789caSRichard Sandiford if (MI->isCompare())
35f03789caSRichard Sandiford return MCInstBuilder(Opcode)
36f03789caSRichard Sandiford .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
37f03789caSRichard Sandiford .addImm(MI->getOperand(1).getImm());
38f03789caSRichard Sandiford else
39652784e2SRichard Sandiford return MCInstBuilder(Opcode)
40652784e2SRichard Sandiford .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
41652784e2SRichard Sandiford .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
42652784e2SRichard Sandiford .addImm(MI->getOperand(2).getImm());
43652784e2SRichard Sandiford }
44652784e2SRichard Sandiford
450755c93bSRichard Sandiford // Return an RI instruction like MI with opcode Opcode, but with the
461a56931bSRichard Sandiford // GR64 register operands turned into GRH32s.
lowerRIHigh(const MachineInstr * MI,unsigned Opcode)471a56931bSRichard Sandiford static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
48f03789caSRichard Sandiford if (MI->isCompare())
49f03789caSRichard Sandiford return MCInstBuilder(Opcode)
50f03789caSRichard Sandiford .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
51f03789caSRichard Sandiford .addImm(MI->getOperand(1).getImm());
52f03789caSRichard Sandiford else
531a56931bSRichard Sandiford return MCInstBuilder(Opcode)
541a56931bSRichard Sandiford .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
551a56931bSRichard Sandiford .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
561a56931bSRichard Sandiford .addImm(MI->getOperand(2).getImm());
571a56931bSRichard Sandiford }
581a56931bSRichard Sandiford
591a56931bSRichard Sandiford // Return an RI instruction like MI with opcode Opcode, but with the
600755c93bSRichard Sandiford // R2 register turned into a GR64.
lowerRIEfLow(const MachineInstr * MI,unsigned Opcode)610755c93bSRichard Sandiford static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
620755c93bSRichard Sandiford return MCInstBuilder(Opcode)
630755c93bSRichard Sandiford .addReg(MI->getOperand(0).getReg())
640755c93bSRichard Sandiford .addReg(MI->getOperand(1).getReg())
650755c93bSRichard Sandiford .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
660755c93bSRichard Sandiford .addImm(MI->getOperand(3).getImm())
670755c93bSRichard Sandiford .addImm(MI->getOperand(4).getImm())
680755c93bSRichard Sandiford .addImm(MI->getOperand(5).getImm());
690755c93bSRichard Sandiford }
700755c93bSRichard Sandiford
getTLSGetOffset(MCContext & Context)717db6918eSUlrich Weigand static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
727db6918eSUlrich Weigand StringRef Name = "__tls_get_offset";
7313760bd1SJim Grosbach return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
747db6918eSUlrich Weigand MCSymbolRefExpr::VK_PLT,
757db6918eSUlrich Weigand Context);
767db6918eSUlrich Weigand }
777db6918eSUlrich Weigand
getGlobalOffsetTable(MCContext & Context)787db6918eSUlrich Weigand static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
797db6918eSUlrich Weigand StringRef Name = "_GLOBAL_OFFSET_TABLE_";
8013760bd1SJim Grosbach return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
817db6918eSUlrich Weigand MCSymbolRefExpr::VK_None,
827db6918eSUlrich Weigand Context);
837db6918eSUlrich Weigand }
847db6918eSUlrich Weigand
853641b10fSUlrich Weigand // MI is an instruction that accepts an optional alignment hint,
863641b10fSUlrich Weigand // and which was already lowered to LoweredMI. If the alignment
873641b10fSUlrich Weigand // of the original memory operand is known, update LoweredMI to
883641b10fSUlrich Weigand // an instruction with the corresponding hint set.
lowerAlignmentHint(const MachineInstr * MI,MCInst & LoweredMI,unsigned Opcode)893641b10fSUlrich Weigand static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI,
903641b10fSUlrich Weigand unsigned Opcode) {
91cf426100SJonas Paulsson if (MI->memoperands_empty())
923641b10fSUlrich Weigand return;
93cf426100SJonas Paulsson
94cf426100SJonas Paulsson Align Alignment = Align(16);
95cf426100SJonas Paulsson for (MachineInstr::mmo_iterator MMOI = MI->memoperands_begin(),
96cf426100SJonas Paulsson EE = MI->memoperands_end(); MMOI != EE; ++MMOI)
97cf426100SJonas Paulsson if ((*MMOI)->getAlign() < Alignment)
98cf426100SJonas Paulsson Alignment = (*MMOI)->getAlign();
99cf426100SJonas Paulsson
1003641b10fSUlrich Weigand unsigned AlignmentHint = 0;
101cf426100SJonas Paulsson if (Alignment >= Align(16))
1023641b10fSUlrich Weigand AlignmentHint = 4;
103cf426100SJonas Paulsson else if (Alignment >= Align(8))
1043641b10fSUlrich Weigand AlignmentHint = 3;
1053641b10fSUlrich Weigand if (AlignmentHint == 0)
1063641b10fSUlrich Weigand return;
1073641b10fSUlrich Weigand
1083641b10fSUlrich Weigand LoweredMI.setOpcode(Opcode);
1093641b10fSUlrich Weigand LoweredMI.addOperand(MCOperand::createImm(AlignmentHint));
1103641b10fSUlrich Weigand }
1113641b10fSUlrich Weigand
11249506d78SUlrich Weigand // MI loads the high part of a vector from memory. Return an instruction
11349506d78SUlrich Weigand // that uses replicating vector load Opcode to do the same thing.
lowerSubvectorLoad(const MachineInstr * MI,unsigned Opcode)11449506d78SUlrich Weigand static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
11549506d78SUlrich Weigand return MCInstBuilder(Opcode)
11649506d78SUlrich Weigand .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
11749506d78SUlrich Weigand .addReg(MI->getOperand(1).getReg())
11849506d78SUlrich Weigand .addImm(MI->getOperand(2).getImm())
11949506d78SUlrich Weigand .addReg(MI->getOperand(3).getReg());
12049506d78SUlrich Weigand }
12149506d78SUlrich Weigand
12249506d78SUlrich Weigand // MI stores the high part of a vector to memory. Return an instruction
12349506d78SUlrich Weigand // that uses elemental vector store Opcode to do the same thing.
lowerSubvectorStore(const MachineInstr * MI,unsigned Opcode)12449506d78SUlrich Weigand static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
12549506d78SUlrich Weigand return MCInstBuilder(Opcode)
12649506d78SUlrich Weigand .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
12749506d78SUlrich Weigand .addReg(MI->getOperand(1).getReg())
12849506d78SUlrich Weigand .addImm(MI->getOperand(2).getImm())
12949506d78SUlrich Weigand .addReg(MI->getOperand(3).getReg())
13049506d78SUlrich Weigand .addImm(0);
13149506d78SUlrich Weigand }
13249506d78SUlrich Weigand
13362ba528aSKai Nacke // The XPLINK ABI requires that a no-op encoding the call type is emitted after
13462ba528aSKai Nacke // each call to a subroutine. This information can be used by the called
13562ba528aSKai Nacke // function to determine its entry point, e.g. for generating a backtrace. The
13662ba528aSKai Nacke // call type is encoded as a register number in the bcr instruction. See
13762ba528aSKai Nacke // enumeration CallType for the possible values.
emitCallInformation(CallType CT)13862ba528aSKai Nacke void SystemZAsmPrinter::emitCallInformation(CallType CT) {
13962ba528aSKai Nacke EmitToStreamer(*OutStreamer,
14062ba528aSKai Nacke MCInstBuilder(SystemZ::BCRAsm)
14162ba528aSKai Nacke .addImm(0)
14262ba528aSKai Nacke .addReg(SystemZMC::GR64Regs[static_cast<unsigned>(CT)]));
14362ba528aSKai Nacke }
14462ba528aSKai Nacke
emitInstruction(const MachineInstr * MI)145bcd24b2dSFangrui Song void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
146*3e0bf1c7SDavid Green SystemZ_MC::verifyInstructionPredicates(MI->getOpcode(),
147*3e0bf1c7SDavid Green getSubtargetInfo().getFeatureBits());
148*3e0bf1c7SDavid Green
14969c1d631SRafael Espindola SystemZMCInstLower Lower(MF->getContext(), *this);
1505f613dfdSUlrich Weigand MCInst LoweredMI;
1519ab97cd1SRichard Sandiford switch (MI->getOpcode()) {
1529ab97cd1SRichard Sandiford case SystemZ::Return:
153ff99f3a5SKai Nacke LoweredMI = MCInstBuilder(SystemZ::BR)
154ff99f3a5SKai Nacke .addReg(SystemZ::R14D);
155ff99f3a5SKai Nacke break;
156ff99f3a5SKai Nacke
157ff99f3a5SKai Nacke case SystemZ::Return_XPLINK:
158ff99f3a5SKai Nacke LoweredMI = MCInstBuilder(SystemZ::B)
159ff99f3a5SKai Nacke .addReg(SystemZ::R7D)
160ff99f3a5SKai Nacke .addImm(2)
161ff99f3a5SKai Nacke .addReg(0);
1629ab97cd1SRichard Sandiford break;
1639ab97cd1SRichard Sandiford
1642eb027d2SUlrich Weigand case SystemZ::CondReturn:
1652eb027d2SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::BCR)
1662eb027d2SUlrich Weigand .addImm(MI->getOperand(0).getImm())
1672eb027d2SUlrich Weigand .addImm(MI->getOperand(1).getImm())
1682eb027d2SUlrich Weigand .addReg(SystemZ::R14D);
1692eb027d2SUlrich Weigand break;
1702eb027d2SUlrich Weigand
171ff99f3a5SKai Nacke case SystemZ::CondReturn_XPLINK:
172ff99f3a5SKai Nacke LoweredMI = MCInstBuilder(SystemZ::BC)
173ff99f3a5SKai Nacke .addImm(MI->getOperand(0).getImm())
174ff99f3a5SKai Nacke .addImm(MI->getOperand(1).getImm())
175ff99f3a5SKai Nacke .addReg(SystemZ::R7D)
176ff99f3a5SKai Nacke .addImm(2)
177ff99f3a5SKai Nacke .addReg(0);
178ff99f3a5SKai Nacke break;
179ff99f3a5SKai Nacke
1802eb027d2SUlrich Weigand case SystemZ::CRBReturn:
1812eb027d2SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CRB)
1822eb027d2SUlrich Weigand .addReg(MI->getOperand(0).getReg())
1832eb027d2SUlrich Weigand .addReg(MI->getOperand(1).getReg())
1842eb027d2SUlrich Weigand .addImm(MI->getOperand(2).getImm())
1852eb027d2SUlrich Weigand .addReg(SystemZ::R14D)
1862eb027d2SUlrich Weigand .addImm(0);
1872eb027d2SUlrich Weigand break;
1882eb027d2SUlrich Weigand
1892eb027d2SUlrich Weigand case SystemZ::CGRBReturn:
1902eb027d2SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CGRB)
1912eb027d2SUlrich Weigand .addReg(MI->getOperand(0).getReg())
1922eb027d2SUlrich Weigand .addReg(MI->getOperand(1).getReg())
1932eb027d2SUlrich Weigand .addImm(MI->getOperand(2).getImm())
1942eb027d2SUlrich Weigand .addReg(SystemZ::R14D)
1952eb027d2SUlrich Weigand .addImm(0);
1962eb027d2SUlrich Weigand break;
1972eb027d2SUlrich Weigand
1982eb027d2SUlrich Weigand case SystemZ::CIBReturn:
1992eb027d2SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CIB)
2002eb027d2SUlrich Weigand .addReg(MI->getOperand(0).getReg())
2012eb027d2SUlrich Weigand .addImm(MI->getOperand(1).getImm())
2022eb027d2SUlrich Weigand .addImm(MI->getOperand(2).getImm())
2032eb027d2SUlrich Weigand .addReg(SystemZ::R14D)
2042eb027d2SUlrich Weigand .addImm(0);
2052eb027d2SUlrich Weigand break;
2062eb027d2SUlrich Weigand
2072eb027d2SUlrich Weigand case SystemZ::CGIBReturn:
2082eb027d2SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CGIB)
2092eb027d2SUlrich Weigand .addReg(MI->getOperand(0).getReg())
2102eb027d2SUlrich Weigand .addImm(MI->getOperand(1).getImm())
2112eb027d2SUlrich Weigand .addImm(MI->getOperand(2).getImm())
2122eb027d2SUlrich Weigand .addReg(SystemZ::R14D)
2132eb027d2SUlrich Weigand .addImm(0);
2142eb027d2SUlrich Weigand break;
2152eb027d2SUlrich Weigand
2162eb027d2SUlrich Weigand case SystemZ::CLRBReturn:
2172eb027d2SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CLRB)
2182eb027d2SUlrich Weigand .addReg(MI->getOperand(0).getReg())
2192eb027d2SUlrich Weigand .addReg(MI->getOperand(1).getReg())
2202eb027d2SUlrich Weigand .addImm(MI->getOperand(2).getImm())
2212eb027d2SUlrich Weigand .addReg(SystemZ::R14D)
2222eb027d2SUlrich Weigand .addImm(0);
2232eb027d2SUlrich Weigand break;
2242eb027d2SUlrich Weigand
2252eb027d2SUlrich Weigand case SystemZ::CLGRBReturn:
2262eb027d2SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CLGRB)
2272eb027d2SUlrich Weigand .addReg(MI->getOperand(0).getReg())
2282eb027d2SUlrich Weigand .addReg(MI->getOperand(1).getReg())
2292eb027d2SUlrich Weigand .addImm(MI->getOperand(2).getImm())
2302eb027d2SUlrich Weigand .addReg(SystemZ::R14D)
2312eb027d2SUlrich Weigand .addImm(0);
2322eb027d2SUlrich Weigand break;
2332eb027d2SUlrich Weigand
2342eb027d2SUlrich Weigand case SystemZ::CLIBReturn:
2352eb027d2SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CLIB)
2362eb027d2SUlrich Weigand .addReg(MI->getOperand(0).getReg())
2372eb027d2SUlrich Weigand .addImm(MI->getOperand(1).getImm())
2382eb027d2SUlrich Weigand .addImm(MI->getOperand(2).getImm())
2392eb027d2SUlrich Weigand .addReg(SystemZ::R14D)
2402eb027d2SUlrich Weigand .addImm(0);
2412eb027d2SUlrich Weigand break;
2422eb027d2SUlrich Weigand
2432eb027d2SUlrich Weigand case SystemZ::CLGIBReturn:
2442eb027d2SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CLGIB)
2452eb027d2SUlrich Weigand .addReg(MI->getOperand(0).getReg())
2462eb027d2SUlrich Weigand .addImm(MI->getOperand(1).getImm())
2472eb027d2SUlrich Weigand .addImm(MI->getOperand(2).getImm())
2482eb027d2SUlrich Weigand .addReg(SystemZ::R14D)
2492eb027d2SUlrich Weigand .addImm(0);
2502eb027d2SUlrich Weigand break;
2512eb027d2SUlrich Weigand
252b006f555SYusra Syeda case SystemZ::CallBRASL_XPLINK64:
253b006f555SYusra Syeda EmitToStreamer(*OutStreamer,
254b006f555SYusra Syeda MCInstBuilder(SystemZ::BRASL)
255b006f555SYusra Syeda .addReg(SystemZ::R7D)
256b006f555SYusra Syeda .addExpr(Lower.getExpr(MI->getOperand(0),
257b006f555SYusra Syeda MCSymbolRefExpr::VK_PLT)));
25862ba528aSKai Nacke emitCallInformation(CallType::BRASL7);
259b006f555SYusra Syeda return;
260b006f555SYusra Syeda
261b006f555SYusra Syeda case SystemZ::CallBASR_XPLINK64:
262b006f555SYusra Syeda EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
263b006f555SYusra Syeda .addReg(SystemZ::R7D)
264b006f555SYusra Syeda .addReg(MI->getOperand(0).getReg()));
26562ba528aSKai Nacke emitCallInformation(CallType::BASR76);
266b006f555SYusra Syeda return;
267b006f555SYusra Syeda
268eb3e09c9SNeumann Hon case SystemZ::CallBASR_STACKEXT:
269eb3e09c9SNeumann Hon EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
270eb3e09c9SNeumann Hon .addReg(SystemZ::R3D)
271eb3e09c9SNeumann Hon .addReg(MI->getOperand(0).getReg()));
272eb3e09c9SNeumann Hon emitCallInformation(CallType::BASR33);
273eb3e09c9SNeumann Hon return;
274eb3e09c9SNeumann Hon
275f348f831SRichard Sandiford case SystemZ::CallBRASL:
276f348f831SRichard Sandiford LoweredMI = MCInstBuilder(SystemZ::BRASL)
277f348f831SRichard Sandiford .addReg(SystemZ::R14D)
278f348f831SRichard Sandiford .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
279f348f831SRichard Sandiford break;
280f348f831SRichard Sandiford
281f348f831SRichard Sandiford case SystemZ::CallBASR:
282f348f831SRichard Sandiford LoweredMI = MCInstBuilder(SystemZ::BASR)
283f348f831SRichard Sandiford .addReg(SystemZ::R14D)
284f348f831SRichard Sandiford .addReg(MI->getOperand(0).getReg());
285f348f831SRichard Sandiford break;
286f348f831SRichard Sandiford
287f348f831SRichard Sandiford case SystemZ::CallJG:
288f348f831SRichard Sandiford LoweredMI = MCInstBuilder(SystemZ::JG)
289f348f831SRichard Sandiford .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
290f348f831SRichard Sandiford break;
291f348f831SRichard Sandiford
292fa2dffbcSUlrich Weigand case SystemZ::CallBRCL:
293fa2dffbcSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::BRCL)
294fa2dffbcSUlrich Weigand .addImm(MI->getOperand(0).getImm())
295fa2dffbcSUlrich Weigand .addImm(MI->getOperand(1).getImm())
296fa2dffbcSUlrich Weigand .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
297fa2dffbcSUlrich Weigand break;
298fa2dffbcSUlrich Weigand
299f348f831SRichard Sandiford case SystemZ::CallBR:
300ebef9216SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::BR)
301ebef9216SUlrich Weigand .addReg(MI->getOperand(0).getReg());
302f348f831SRichard Sandiford break;
303f348f831SRichard Sandiford
304848a513dSUlrich Weigand case SystemZ::CallBCR:
305848a513dSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::BCR)
306848a513dSUlrich Weigand .addImm(MI->getOperand(0).getImm())
307848a513dSUlrich Weigand .addImm(MI->getOperand(1).getImm())
308ebef9216SUlrich Weigand .addReg(MI->getOperand(2).getReg());
309848a513dSUlrich Weigand break;
310848a513dSUlrich Weigand
311848a513dSUlrich Weigand case SystemZ::CRBCall:
312848a513dSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CRB)
313848a513dSUlrich Weigand .addReg(MI->getOperand(0).getReg())
314848a513dSUlrich Weigand .addReg(MI->getOperand(1).getReg())
315848a513dSUlrich Weigand .addImm(MI->getOperand(2).getImm())
316ebef9216SUlrich Weigand .addReg(MI->getOperand(3).getReg())
317848a513dSUlrich Weigand .addImm(0);
318848a513dSUlrich Weigand break;
319848a513dSUlrich Weigand
320848a513dSUlrich Weigand case SystemZ::CGRBCall:
321848a513dSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CGRB)
322848a513dSUlrich Weigand .addReg(MI->getOperand(0).getReg())
323848a513dSUlrich Weigand .addReg(MI->getOperand(1).getReg())
324848a513dSUlrich Weigand .addImm(MI->getOperand(2).getImm())
325ebef9216SUlrich Weigand .addReg(MI->getOperand(3).getReg())
326848a513dSUlrich Weigand .addImm(0);
327848a513dSUlrich Weigand break;
328848a513dSUlrich Weigand
329848a513dSUlrich Weigand case SystemZ::CIBCall:
330848a513dSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CIB)
331848a513dSUlrich Weigand .addReg(MI->getOperand(0).getReg())
332848a513dSUlrich Weigand .addImm(MI->getOperand(1).getImm())
333848a513dSUlrich Weigand .addImm(MI->getOperand(2).getImm())
334ebef9216SUlrich Weigand .addReg(MI->getOperand(3).getReg())
335848a513dSUlrich Weigand .addImm(0);
336848a513dSUlrich Weigand break;
337848a513dSUlrich Weigand
338848a513dSUlrich Weigand case SystemZ::CGIBCall:
339848a513dSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CGIB)
340848a513dSUlrich Weigand .addReg(MI->getOperand(0).getReg())
341848a513dSUlrich Weigand .addImm(MI->getOperand(1).getImm())
342848a513dSUlrich Weigand .addImm(MI->getOperand(2).getImm())
343ebef9216SUlrich Weigand .addReg(MI->getOperand(3).getReg())
344848a513dSUlrich Weigand .addImm(0);
345848a513dSUlrich Weigand break;
346848a513dSUlrich Weigand
347848a513dSUlrich Weigand case SystemZ::CLRBCall:
348848a513dSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CLRB)
349848a513dSUlrich Weigand .addReg(MI->getOperand(0).getReg())
350848a513dSUlrich Weigand .addReg(MI->getOperand(1).getReg())
351848a513dSUlrich Weigand .addImm(MI->getOperand(2).getImm())
352ebef9216SUlrich Weigand .addReg(MI->getOperand(3).getReg())
353848a513dSUlrich Weigand .addImm(0);
354848a513dSUlrich Weigand break;
355848a513dSUlrich Weigand
356848a513dSUlrich Weigand case SystemZ::CLGRBCall:
357848a513dSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CLGRB)
358848a513dSUlrich Weigand .addReg(MI->getOperand(0).getReg())
359848a513dSUlrich Weigand .addReg(MI->getOperand(1).getReg())
360848a513dSUlrich Weigand .addImm(MI->getOperand(2).getImm())
361ebef9216SUlrich Weigand .addReg(MI->getOperand(3).getReg())
362848a513dSUlrich Weigand .addImm(0);
363848a513dSUlrich Weigand break;
364848a513dSUlrich Weigand
365848a513dSUlrich Weigand case SystemZ::CLIBCall:
366848a513dSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CLIB)
367848a513dSUlrich Weigand .addReg(MI->getOperand(0).getReg())
368848a513dSUlrich Weigand .addImm(MI->getOperand(1).getImm())
369848a513dSUlrich Weigand .addImm(MI->getOperand(2).getImm())
370ebef9216SUlrich Weigand .addReg(MI->getOperand(3).getReg())
371848a513dSUlrich Weigand .addImm(0);
372848a513dSUlrich Weigand break;
373848a513dSUlrich Weigand
374848a513dSUlrich Weigand case SystemZ::CLGIBCall:
375848a513dSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::CLGIB)
376848a513dSUlrich Weigand .addReg(MI->getOperand(0).getReg())
377848a513dSUlrich Weigand .addImm(MI->getOperand(1).getImm())
378848a513dSUlrich Weigand .addImm(MI->getOperand(2).getImm())
379ebef9216SUlrich Weigand .addReg(MI->getOperand(3).getReg())
380848a513dSUlrich Weigand .addImm(0);
381848a513dSUlrich Weigand break;
382848a513dSUlrich Weigand
3837db6918eSUlrich Weigand case SystemZ::TLS_GDCALL:
3847db6918eSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::BRASL)
3857db6918eSUlrich Weigand .addReg(SystemZ::R14D)
3867db6918eSUlrich Weigand .addExpr(getTLSGetOffset(MF->getContext()))
3877db6918eSUlrich Weigand .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
3887db6918eSUlrich Weigand break;
3897db6918eSUlrich Weigand
3907db6918eSUlrich Weigand case SystemZ::TLS_LDCALL:
3917db6918eSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::BRASL)
3927db6918eSUlrich Weigand .addReg(SystemZ::R14D)
3937db6918eSUlrich Weigand .addExpr(getTLSGetOffset(MF->getContext()))
3947db6918eSUlrich Weigand .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
3957db6918eSUlrich Weigand break;
3967db6918eSUlrich Weigand
3977db6918eSUlrich Weigand case SystemZ::GOT:
3987db6918eSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::LARL)
3997db6918eSUlrich Weigand .addReg(MI->getOperand(0).getReg())
4007db6918eSUlrich Weigand .addExpr(getGlobalOffsetTable(MF->getContext()));
4017db6918eSUlrich Weigand break;
4027db6918eSUlrich Weigand
403652784e2SRichard Sandiford case SystemZ::IILF64:
404652784e2SRichard Sandiford LoweredMI = MCInstBuilder(SystemZ::IILF)
405652784e2SRichard Sandiford .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
406652784e2SRichard Sandiford .addImm(MI->getOperand(2).getImm());
407652784e2SRichard Sandiford break;
408652784e2SRichard Sandiford
40901240234SRichard Sandiford case SystemZ::IIHF64:
41001240234SRichard Sandiford LoweredMI = MCInstBuilder(SystemZ::IIHF)
41101240234SRichard Sandiford .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
41201240234SRichard Sandiford .addImm(MI->getOperand(2).getImm());
41301240234SRichard Sandiford break;
41401240234SRichard Sandiford
4150755c93bSRichard Sandiford case SystemZ::RISBHH:
4160755c93bSRichard Sandiford case SystemZ::RISBHL:
4170755c93bSRichard Sandiford LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
4180755c93bSRichard Sandiford break;
4190755c93bSRichard Sandiford
4200755c93bSRichard Sandiford case SystemZ::RISBLH:
4210755c93bSRichard Sandiford case SystemZ::RISBLL:
4220755c93bSRichard Sandiford LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
4230755c93bSRichard Sandiford break;
4240755c93bSRichard Sandiford
425ce4c1095SUlrich Weigand case SystemZ::VLVGP32:
426ce4c1095SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::VLVGP)
427ce4c1095SUlrich Weigand .addReg(MI->getOperand(0).getReg())
428ce4c1095SUlrich Weigand .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
429ce4c1095SUlrich Weigand .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
430ce4c1095SUlrich Weigand break;
431ce4c1095SUlrich Weigand
43249506d78SUlrich Weigand case SystemZ::VLR32:
43349506d78SUlrich Weigand case SystemZ::VLR64:
43449506d78SUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::VLR)
43549506d78SUlrich Weigand .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
43649506d78SUlrich Weigand .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
43749506d78SUlrich Weigand break;
43849506d78SUlrich Weigand
4393641b10fSUlrich Weigand case SystemZ::VL:
4403641b10fSUlrich Weigand Lower.lower(MI, LoweredMI);
4413641b10fSUlrich Weigand lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign);
4423641b10fSUlrich Weigand break;
4433641b10fSUlrich Weigand
4443641b10fSUlrich Weigand case SystemZ::VST:
4453641b10fSUlrich Weigand Lower.lower(MI, LoweredMI);
4463641b10fSUlrich Weigand lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign);
4473641b10fSUlrich Weigand break;
4483641b10fSUlrich Weigand
4493641b10fSUlrich Weigand case SystemZ::VLM:
4503641b10fSUlrich Weigand Lower.lower(MI, LoweredMI);
4513641b10fSUlrich Weigand lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign);
4523641b10fSUlrich Weigand break;
4533641b10fSUlrich Weigand
4543641b10fSUlrich Weigand case SystemZ::VSTM:
4553641b10fSUlrich Weigand Lower.lower(MI, LoweredMI);
4563641b10fSUlrich Weigand lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign);
4573641b10fSUlrich Weigand break;
4583641b10fSUlrich Weigand
45949506d78SUlrich Weigand case SystemZ::VL32:
46049506d78SUlrich Weigand LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
46149506d78SUlrich Weigand break;
46249506d78SUlrich Weigand
46349506d78SUlrich Weigand case SystemZ::VL64:
46449506d78SUlrich Weigand LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
46549506d78SUlrich Weigand break;
46649506d78SUlrich Weigand
46749506d78SUlrich Weigand case SystemZ::VST32:
46849506d78SUlrich Weigand LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
46949506d78SUlrich Weigand break;
47049506d78SUlrich Weigand
47149506d78SUlrich Weigand case SystemZ::VST64:
47249506d78SUlrich Weigand LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
47349506d78SUlrich Weigand break;
47449506d78SUlrich Weigand
47580b3af7aSUlrich Weigand case SystemZ::LFER:
47680b3af7aSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::VLGVF)
47780b3af7aSUlrich Weigand .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
47880b3af7aSUlrich Weigand .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
47980b3af7aSUlrich Weigand .addReg(0).addImm(0);
48080b3af7aSUlrich Weigand break;
48180b3af7aSUlrich Weigand
48280b3af7aSUlrich Weigand case SystemZ::LEFR:
48380b3af7aSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::VLVGF)
48480b3af7aSUlrich Weigand .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
48580b3af7aSUlrich Weigand .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
48680b3af7aSUlrich Weigand .addReg(MI->getOperand(1).getReg())
48780b3af7aSUlrich Weigand .addReg(0).addImm(0);
48880b3af7aSUlrich Weigand break;
48980b3af7aSUlrich Weigand
490652784e2SRichard Sandiford #define LOWER_LOW(NAME) \
491652784e2SRichard Sandiford case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
492652784e2SRichard Sandiford
493652784e2SRichard Sandiford LOWER_LOW(IILL);
494652784e2SRichard Sandiford LOWER_LOW(IILH);
495f03789caSRichard Sandiford LOWER_LOW(TMLL);
496f03789caSRichard Sandiford LOWER_LOW(TMLH);
497652784e2SRichard Sandiford LOWER_LOW(NILL);
498652784e2SRichard Sandiford LOWER_LOW(NILH);
499652784e2SRichard Sandiford LOWER_LOW(NILF);
500652784e2SRichard Sandiford LOWER_LOW(OILL);
501652784e2SRichard Sandiford LOWER_LOW(OILH);
502652784e2SRichard Sandiford LOWER_LOW(OILF);
503652784e2SRichard Sandiford LOWER_LOW(XILF);
504652784e2SRichard Sandiford
505652784e2SRichard Sandiford #undef LOWER_LOW
506652784e2SRichard Sandiford
5071a56931bSRichard Sandiford #define LOWER_HIGH(NAME) \
5081a56931bSRichard Sandiford case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
5091a56931bSRichard Sandiford
5101a56931bSRichard Sandiford LOWER_HIGH(IIHL);
5111a56931bSRichard Sandiford LOWER_HIGH(IIHH);
512f03789caSRichard Sandiford LOWER_HIGH(TMHL);
513f03789caSRichard Sandiford LOWER_HIGH(TMHH);
5147028428cSRichard Sandiford LOWER_HIGH(NIHL);
5157028428cSRichard Sandiford LOWER_HIGH(NIHH);
5167028428cSRichard Sandiford LOWER_HIGH(NIHF);
5176e96ac60SRichard Sandiford LOWER_HIGH(OIHL);
5186e96ac60SRichard Sandiford LOWER_HIGH(OIHH);
5196e96ac60SRichard Sandiford LOWER_HIGH(OIHF);
5205718dacbSRichard Sandiford LOWER_HIGH(XIHF);
5211a56931bSRichard Sandiford
5221a56931bSRichard Sandiford #undef LOWER_HIGH
5231a56931bSRichard Sandiford
5249afe613dSRichard Sandiford case SystemZ::Serialize:
525d84f5d30SEric Christopher if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
526d2148cafSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
5279afe613dSRichard Sandiford .addImm(14).addReg(SystemZ::R0D);
5289afe613dSRichard Sandiford else
529d2148cafSUlrich Weigand LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
5309afe613dSRichard Sandiford .addImm(15).addReg(SystemZ::R0D);
5319afe613dSRichard Sandiford break;
5329afe613dSRichard Sandiford
533a9ac6d6cSUlrich Weigand // Emit nothing here but a comment if we can.
534a9ac6d6cSUlrich Weigand case SystemZ::MemBarrier:
535a9ac6d6cSUlrich Weigand OutStreamer->emitRawComment("MEMBARRIER");
536a9ac6d6cSUlrich Weigand return;
537a9ac6d6cSUlrich Weigand
538ab42cbceSZhan Jun Liau // We want to emit "j .+2" for traps, jumping to the relative immediate field
539ab42cbceSZhan Jun Liau // of the jump instruction, which is an illegal instruction. We cannot emit a
540ab42cbceSZhan Jun Liau // "." symbol, so create and emit a temp label before the instruction and use
541ab42cbceSZhan Jun Liau // that instead.
542ab42cbceSZhan Jun Liau case SystemZ::Trap: {
543ab42cbceSZhan Jun Liau MCSymbol *DotSym = OutContext.createTempSymbol();
5446d2d589bSFangrui Song OutStreamer->emitLabel(DotSym);
545ab42cbceSZhan Jun Liau
546ab42cbceSZhan Jun Liau const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
547ab42cbceSZhan Jun Liau const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
548ab42cbceSZhan Jun Liau LoweredMI = MCInstBuilder(SystemZ::J)
549ab42cbceSZhan Jun Liau .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
550ab42cbceSZhan Jun Liau }
551ab42cbceSZhan Jun Liau break;
552ab42cbceSZhan Jun Liau
553ab42cbceSZhan Jun Liau // Conditional traps will create a branch on condition instruction that jumps
554ab42cbceSZhan Jun Liau // to the relative immediate field of the jump instruction. (eg. "jo .+2")
555ab42cbceSZhan Jun Liau case SystemZ::CondTrap: {
556ab42cbceSZhan Jun Liau MCSymbol *DotSym = OutContext.createTempSymbol();
5576d2d589bSFangrui Song OutStreamer->emitLabel(DotSym);
558ab42cbceSZhan Jun Liau
559ab42cbceSZhan Jun Liau const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
560ab42cbceSZhan Jun Liau const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
561ab42cbceSZhan Jun Liau LoweredMI = MCInstBuilder(SystemZ::BRC)
562ab42cbceSZhan Jun Liau .addImm(MI->getOperand(0).getImm())
563ab42cbceSZhan Jun Liau .addImm(MI->getOperand(1).getImm())
564ab42cbceSZhan Jun Liau .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
565ab42cbceSZhan Jun Liau }
566ab42cbceSZhan Jun Liau break;
567ab42cbceSZhan Jun Liau
568f1241581SJonas Paulsson case TargetOpcode::FENTRY_CALL:
569f1241581SJonas Paulsson LowerFENTRY_CALL(*MI, Lower);
570f1241581SJonas Paulsson return;
571f1241581SJonas Paulsson
5725eb64110SUlrich Weigand case TargetOpcode::STACKMAP:
5735eb64110SUlrich Weigand LowerSTACKMAP(*MI);
5745eb64110SUlrich Weigand return;
5755eb64110SUlrich Weigand
5765eb64110SUlrich Weigand case TargetOpcode::PATCHPOINT:
5775eb64110SUlrich Weigand LowerPATCHPOINT(*MI, Lower);
5785eb64110SUlrich Weigand return;
5795eb64110SUlrich Weigand
58037a92f3bSJonas Paulsson case SystemZ::EXRL_Pseudo: {
58137a92f3bSJonas Paulsson unsigned TargetInsOpc = MI->getOperand(0).getImm();
58237a92f3bSJonas Paulsson Register LenMinus1Reg = MI->getOperand(1).getReg();
58337a92f3bSJonas Paulsson Register DestReg = MI->getOperand(2).getReg();
58437a92f3bSJonas Paulsson int64_t DestDisp = MI->getOperand(3).getImm();
58537a92f3bSJonas Paulsson Register SrcReg = MI->getOperand(4).getReg();
58637a92f3bSJonas Paulsson int64_t SrcDisp = MI->getOperand(5).getImm();
58737a92f3bSJonas Paulsson
588a48b43f9SJonas Paulsson SystemZTargetStreamer *TS = getTargetStreamer();
58937a92f3bSJonas Paulsson MCSymbol *DotSym = nullptr;
59037a92f3bSJonas Paulsson MCInst ET = MCInstBuilder(TargetInsOpc).addReg(DestReg)
59137a92f3bSJonas Paulsson .addImm(DestDisp).addImm(1).addReg(SrcReg).addImm(SrcDisp);
592a48b43f9SJonas Paulsson SystemZTargetStreamer::MCInstSTIPair ET_STI(ET, &MF->getSubtarget());
593a48b43f9SJonas Paulsson SystemZTargetStreamer::EXRLT2SymMap::iterator I =
594a48b43f9SJonas Paulsson TS->EXRLTargets2Sym.find(ET_STI);
595a48b43f9SJonas Paulsson if (I != TS->EXRLTargets2Sym.end())
59637a92f3bSJonas Paulsson DotSym = I->second;
59737a92f3bSJonas Paulsson else
598a48b43f9SJonas Paulsson TS->EXRLTargets2Sym[ET_STI] = DotSym = OutContext.createTempSymbol();
59937a92f3bSJonas Paulsson const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
60037a92f3bSJonas Paulsson EmitToStreamer(
60137a92f3bSJonas Paulsson *OutStreamer,
60237a92f3bSJonas Paulsson MCInstBuilder(SystemZ::EXRL).addReg(LenMinus1Reg).addExpr(Dot));
60337a92f3bSJonas Paulsson return;
60437a92f3bSJonas Paulsson }
60537a92f3bSJonas Paulsson
6069ab97cd1SRichard Sandiford default:
607f348f831SRichard Sandiford Lower.lower(MI, LoweredMI);
6089ab97cd1SRichard Sandiford break;
6099ab97cd1SRichard Sandiford }
6109ff69c8fSLang Hames EmitToStreamer(*OutStreamer, LoweredMI);
6115f613dfdSUlrich Weigand }
6125f613dfdSUlrich Weigand
6135eb64110SUlrich Weigand // Emit the largest nop instruction smaller than or equal to NumBytes
6145eb64110SUlrich Weigand // bytes. Return the size of nop emitted.
EmitNop(MCContext & OutContext,MCStreamer & OutStreamer,unsigned NumBytes,const MCSubtargetInfo & STI)6155eb64110SUlrich Weigand static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
6165eb64110SUlrich Weigand unsigned NumBytes, const MCSubtargetInfo &STI) {
6175eb64110SUlrich Weigand if (NumBytes < 2) {
6185eb64110SUlrich Weigand llvm_unreachable("Zero nops?");
6195eb64110SUlrich Weigand return 0;
6205eb64110SUlrich Weigand }
6215eb64110SUlrich Weigand else if (NumBytes < 4) {
622bcd24b2dSFangrui Song OutStreamer.emitInstruction(
623bcd24b2dSFangrui Song MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D), STI);
6245eb64110SUlrich Weigand return 2;
6255eb64110SUlrich Weigand }
6265eb64110SUlrich Weigand else if (NumBytes < 6) {
627bcd24b2dSFangrui Song OutStreamer.emitInstruction(
628bcd24b2dSFangrui Song MCInstBuilder(SystemZ::BCAsm).addImm(0).addReg(0).addImm(0).addReg(0),
6295eb64110SUlrich Weigand STI);
6305eb64110SUlrich Weigand return 4;
6315eb64110SUlrich Weigand }
6325eb64110SUlrich Weigand else {
6335eb64110SUlrich Weigand MCSymbol *DotSym = OutContext.createTempSymbol();
6345eb64110SUlrich Weigand const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
6356d2d589bSFangrui Song OutStreamer.emitLabel(DotSym);
636bcd24b2dSFangrui Song OutStreamer.emitInstruction(
637bcd24b2dSFangrui Song MCInstBuilder(SystemZ::BRCLAsm).addImm(0).addExpr(Dot), STI);
6385eb64110SUlrich Weigand return 6;
6395eb64110SUlrich Weigand }
6405eb64110SUlrich Weigand }
6415eb64110SUlrich Weigand
LowerFENTRY_CALL(const MachineInstr & MI,SystemZMCInstLower & Lower)642f1241581SJonas Paulsson void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI,
643f1241581SJonas Paulsson SystemZMCInstLower &Lower) {
644f1241581SJonas Paulsson MCContext &Ctx = MF->getContext();
6456be15788SJonas Paulsson if (MF->getFunction().hasFnAttribute("mrecord-mcount")) {
6466be15788SJonas Paulsson MCSymbol *DotSym = OutContext.createTempSymbol();
64715d82c62SFangrui Song OutStreamer->pushSection();
648adf4142fSFangrui Song OutStreamer->switchSection(
6496be15788SJonas Paulsson Ctx.getELFSection("__mcount_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC));
6506d2d589bSFangrui Song OutStreamer->emitSymbolValue(DotSym, 8);
65115d82c62SFangrui Song OutStreamer->popSection();
6526d2d589bSFangrui Song OutStreamer->emitLabel(DotSym);
6536be15788SJonas Paulsson }
6546be15788SJonas Paulsson
655ca520592SJonas Paulsson if (MF->getFunction().hasFnAttribute("mnop-mcount")) {
6566e504d77SJonas Paulsson EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo());
6576e504d77SJonas Paulsson return;
6586e504d77SJonas Paulsson }
6596e504d77SJonas Paulsson
660f1241581SJonas Paulsson MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__");
661f1241581SJonas Paulsson const MCSymbolRefExpr *Op =
662f1241581SJonas Paulsson MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_PLT, Ctx);
663bcd24b2dSFangrui Song OutStreamer->emitInstruction(
664bcd24b2dSFangrui Song MCInstBuilder(SystemZ::BRASL).addReg(SystemZ::R0D).addExpr(Op),
665bcd24b2dSFangrui Song getSubtargetInfo());
666f1241581SJonas Paulsson }
667f1241581SJonas Paulsson
LowerSTACKMAP(const MachineInstr & MI)6685eb64110SUlrich Weigand void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
6693432d40cSJonas Paulsson auto *TII = MF->getSubtarget<SystemZSubtarget>().getInstrInfo();
6705eb64110SUlrich Weigand
6715eb64110SUlrich Weigand unsigned NumNOPBytes = MI.getOperand(1).getImm();
6725eb64110SUlrich Weigand
6738277c91cSPhilip Reames auto &Ctx = OutStreamer->getContext();
6748277c91cSPhilip Reames MCSymbol *MILabel = Ctx.createTempSymbol();
6756d2d589bSFangrui Song OutStreamer->emitLabel(MILabel);
6768277c91cSPhilip Reames
6778277c91cSPhilip Reames SM.recordStackMap(*MILabel, MI);
6785eb64110SUlrich Weigand assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
6795eb64110SUlrich Weigand
6805eb64110SUlrich Weigand // Scan ahead to trim the shadow.
6815eb64110SUlrich Weigand unsigned ShadowBytes = 0;
6825eb64110SUlrich Weigand const MachineBasicBlock &MBB = *MI.getParent();
6835eb64110SUlrich Weigand MachineBasicBlock::const_iterator MII(MI);
6845eb64110SUlrich Weigand ++MII;
6855eb64110SUlrich Weigand while (ShadowBytes < NumNOPBytes) {
6865eb64110SUlrich Weigand if (MII == MBB.end() ||
6875eb64110SUlrich Weigand MII->getOpcode() == TargetOpcode::PATCHPOINT ||
6885eb64110SUlrich Weigand MII->getOpcode() == TargetOpcode::STACKMAP)
6895eb64110SUlrich Weigand break;
6905eb64110SUlrich Weigand ShadowBytes += TII->getInstSizeInBytes(*MII);
6915eb64110SUlrich Weigand if (MII->isCall())
6925eb64110SUlrich Weigand break;
6935eb64110SUlrich Weigand ++MII;
6945eb64110SUlrich Weigand }
6955eb64110SUlrich Weigand
6965eb64110SUlrich Weigand // Emit nops.
6975eb64110SUlrich Weigand while (ShadowBytes < NumNOPBytes)
6985eb64110SUlrich Weigand ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
6995eb64110SUlrich Weigand getSubtargetInfo());
7005eb64110SUlrich Weigand }
7015eb64110SUlrich Weigand
7025eb64110SUlrich Weigand // Lower a patchpoint of the form:
7035eb64110SUlrich Weigand // [<def>], <id>, <numBytes>, <target>, <numArgs>
LowerPATCHPOINT(const MachineInstr & MI,SystemZMCInstLower & Lower)7045eb64110SUlrich Weigand void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
7055eb64110SUlrich Weigand SystemZMCInstLower &Lower) {
7068277c91cSPhilip Reames auto &Ctx = OutStreamer->getContext();
7078277c91cSPhilip Reames MCSymbol *MILabel = Ctx.createTempSymbol();
7086d2d589bSFangrui Song OutStreamer->emitLabel(MILabel);
7098277c91cSPhilip Reames
7108277c91cSPhilip Reames SM.recordPatchPoint(*MILabel, MI);
7115eb64110SUlrich Weigand PatchPointOpers Opers(&MI);
7125eb64110SUlrich Weigand
7135eb64110SUlrich Weigand unsigned EncodedBytes = 0;
7145eb64110SUlrich Weigand const MachineOperand &CalleeMO = Opers.getCallTarget();
7155eb64110SUlrich Weigand
7165eb64110SUlrich Weigand if (CalleeMO.isImm()) {
7175eb64110SUlrich Weigand uint64_t CallTarget = CalleeMO.getImm();
7185eb64110SUlrich Weigand if (CallTarget) {
7195eb64110SUlrich Weigand unsigned ScratchIdx = -1;
7205eb64110SUlrich Weigand unsigned ScratchReg = 0;
7215eb64110SUlrich Weigand do {
7225eb64110SUlrich Weigand ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
7235eb64110SUlrich Weigand ScratchReg = MI.getOperand(ScratchIdx).getReg();
7245eb64110SUlrich Weigand } while (ScratchReg == SystemZ::R0D);
7255eb64110SUlrich Weigand
7265eb64110SUlrich Weigand // Materialize the call target address
7275eb64110SUlrich Weigand EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF)
7285eb64110SUlrich Weigand .addReg(ScratchReg)
7295eb64110SUlrich Weigand .addImm(CallTarget & 0xFFFFFFFF));
7305eb64110SUlrich Weigand EncodedBytes += 6;
7315eb64110SUlrich Weigand if (CallTarget >> 32) {
7325eb64110SUlrich Weigand EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF)
7335eb64110SUlrich Weigand .addReg(ScratchReg)
7345eb64110SUlrich Weigand .addImm(CallTarget >> 32));
7355eb64110SUlrich Weigand EncodedBytes += 6;
7365eb64110SUlrich Weigand }
7375eb64110SUlrich Weigand
7385eb64110SUlrich Weigand EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
7395eb64110SUlrich Weigand .addReg(SystemZ::R14D)
7405eb64110SUlrich Weigand .addReg(ScratchReg));
7415eb64110SUlrich Weigand EncodedBytes += 2;
7425eb64110SUlrich Weigand }
7435eb64110SUlrich Weigand } else if (CalleeMO.isGlobal()) {
7445eb64110SUlrich Weigand const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
7455eb64110SUlrich Weigand EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
7465eb64110SUlrich Weigand .addReg(SystemZ::R14D)
7475eb64110SUlrich Weigand .addExpr(Expr));
7485eb64110SUlrich Weigand EncodedBytes += 6;
7495eb64110SUlrich Weigand }
7505eb64110SUlrich Weigand
7515eb64110SUlrich Weigand // Emit padding.
7525eb64110SUlrich Weigand unsigned NumBytes = Opers.getNumPatchBytes();
7535eb64110SUlrich Weigand assert(NumBytes >= EncodedBytes &&
7545eb64110SUlrich Weigand "Patchpoint can't request size less than the length of a call.");
7555eb64110SUlrich Weigand assert((NumBytes - EncodedBytes) % 2 == 0 &&
7565eb64110SUlrich Weigand "Invalid number of NOP bytes requested!");
7575eb64110SUlrich Weigand while (EncodedBytes < NumBytes)
7585eb64110SUlrich Weigand EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
7595eb64110SUlrich Weigand getSubtargetInfo());
7605eb64110SUlrich Weigand }
7615eb64110SUlrich Weigand
7625f613dfdSUlrich Weigand // Convert a SystemZ-specific constant pool modifier into the associated
7635f613dfdSUlrich Weigand // MCSymbolRefExpr variant kind.
7645f613dfdSUlrich Weigand static MCSymbolRefExpr::VariantKind
getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier)7655f613dfdSUlrich Weigand getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
7665f613dfdSUlrich Weigand switch (Modifier) {
7677db6918eSUlrich Weigand case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
7687db6918eSUlrich Weigand case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
7697db6918eSUlrich Weigand case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
7705f613dfdSUlrich Weigand case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
7715f613dfdSUlrich Weigand }
7725f613dfdSUlrich Weigand llvm_unreachable("Invalid SystemCPModifier!");
7735f613dfdSUlrich Weigand }
7745f613dfdSUlrich Weigand
emitMachineConstantPoolValue(MachineConstantPoolValue * MCPV)7751d49eb00SFangrui Song void SystemZAsmPrinter::emitMachineConstantPoolValue(
7761d49eb00SFangrui Song MachineConstantPoolValue *MCPV) {
77721f5d68aSRichard Sandiford auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
7785f613dfdSUlrich Weigand
7795f613dfdSUlrich Weigand const MCExpr *Expr =
78013760bd1SJim Grosbach MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
7815f613dfdSUlrich Weigand getModifierVariantKind(ZCPV->getModifier()),
7825f613dfdSUlrich Weigand OutContext);
783bd7287ebSMehdi Amini uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
7845f613dfdSUlrich Weigand
78577497103SFangrui Song OutStreamer->emitValue(Expr, Size);
7865f613dfdSUlrich Weigand }
7875f613dfdSUlrich Weigand
PrintAsmOperand(const MachineInstr * MI,unsigned OpNo,const char * ExtraCode,raw_ostream & OS)7885277b3ffSNick Desaulniers bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
7895f613dfdSUlrich Weigand const char *ExtraCode,
7905f613dfdSUlrich Weigand raw_ostream &OS) {
791458eac25SJonas Paulsson const MCRegisterInfo &MRI = *TM.getMCRegisterInfo();
79296421af5SJonas Paulsson const MachineOperand &MO = MI->getOperand(OpNo);
79396421af5SJonas Paulsson MCOperand MCOp;
794458eac25SJonas Paulsson if (ExtraCode) {
795458eac25SJonas Paulsson if (ExtraCode[0] == 'N' && !ExtraCode[1] && MO.isReg() &&
796458eac25SJonas Paulsson SystemZ::GR128BitRegClass.contains(MO.getReg()))
79796421af5SJonas Paulsson MCOp =
79896421af5SJonas Paulsson MCOperand::createReg(MRI.getSubReg(MO.getReg(), SystemZ::subreg_l64));
799458eac25SJonas Paulsson else
8007ab164c4SNick Desaulniers return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
80196421af5SJonas Paulsson } else {
80269c1d631SRafael Espindola SystemZMCInstLower Lower(MF->getContext(), *this);
80396421af5SJonas Paulsson MCOp = Lower.lowerOperand(MO);
80496421af5SJonas Paulsson }
805458eac25SJonas Paulsson SystemZInstPrinter::printOperand(MCOp, MAI, OS);
8065f613dfdSUlrich Weigand return false;
8075f613dfdSUlrich Weigand }
8085f613dfdSUlrich Weigand
PrintAsmMemoryOperand(const MachineInstr * MI,unsigned OpNo,const char * ExtraCode,raw_ostream & OS)8095f613dfdSUlrich Weigand bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
8105f613dfdSUlrich Weigand unsigned OpNo,
8115f613dfdSUlrich Weigand const char *ExtraCode,
8125f613dfdSUlrich Weigand raw_ostream &OS) {
8131c3ef9efSJonas Paulsson SystemZInstPrinter::
8141c3ef9efSJonas Paulsson printAddress(MAI, MI->getOperand(OpNo).getReg(),
8151c3ef9efSJonas Paulsson MCOperand::createImm(MI->getOperand(OpNo + 1).getImm()),
8165f613dfdSUlrich Weigand MI->getOperand(OpNo + 2).getReg(), OS);
8175f613dfdSUlrich Weigand return false;
8185f613dfdSUlrich Weigand }
8195f613dfdSUlrich Weigand
emitEndOfAsmFile(Module & M)8200dce409cSFangrui Song void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
82130c804bbSThan McIntosh emitStackMaps(SM);
8225eb64110SUlrich Weigand }
8235eb64110SUlrich Weigand
emitFunctionBodyEnd()8245ac411aeSYusra Syeda void SystemZAsmPrinter::emitFunctionBodyEnd() {
8255ac411aeSYusra Syeda if (TM.getTargetTriple().isOSzOS()) {
8265ac411aeSYusra Syeda // Emit symbol for the end of function if the z/OS target streamer
8275ac411aeSYusra Syeda // is used. This is needed to calculate the size of the function.
8285ac411aeSYusra Syeda MCSymbol *FnEndSym = createTempSymbol("func_end");
8295ac411aeSYusra Syeda OutStreamer->emitLabel(FnEndSym);
8305ac411aeSYusra Syeda
83115d82c62SFangrui Song OutStreamer->pushSection();
832adf4142fSFangrui Song OutStreamer->switchSection(getObjFileLowering().getPPA1Section());
8335ac411aeSYusra Syeda emitPPA1(FnEndSym);
83415d82c62SFangrui Song OutStreamer->popSection();
8355ac411aeSYusra Syeda
8365ac411aeSYusra Syeda CurrentFnPPA1Sym = nullptr;
8375ac411aeSYusra Syeda CurrentFnEPMarkerSym = nullptr;
8385ac411aeSYusra Syeda }
8395ac411aeSYusra Syeda }
8405ac411aeSYusra Syeda
emitPPA1Flags(std::unique_ptr<MCStreamer> & OutStreamer,bool VarArg,bool StackProtector,bool FPRMask,bool VRMask)8415ac411aeSYusra Syeda static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer, bool VarArg,
8425ac411aeSYusra Syeda bool StackProtector, bool FPRMask, bool VRMask) {
8435ac411aeSYusra Syeda enum class PPA1Flag1 : uint8_t {
8445ac411aeSYusra Syeda DSA64Bit = (0x80 >> 0),
8455ac411aeSYusra Syeda VarArg = (0x80 >> 7),
8465ac411aeSYusra Syeda LLVM_MARK_AS_BITMASK_ENUM(DSA64Bit)
8475ac411aeSYusra Syeda };
8485ac411aeSYusra Syeda enum class PPA1Flag2 : uint8_t {
8495ac411aeSYusra Syeda ExternalProcedure = (0x80 >> 0),
8505ac411aeSYusra Syeda STACKPROTECTOR = (0x80 >> 3),
8515ac411aeSYusra Syeda LLVM_MARK_AS_BITMASK_ENUM(ExternalProcedure)
8525ac411aeSYusra Syeda };
8535ac411aeSYusra Syeda enum class PPA1Flag3 : uint8_t {
8545ac411aeSYusra Syeda FPRMask = (0x80 >> 2),
8555ac411aeSYusra Syeda LLVM_MARK_AS_BITMASK_ENUM(FPRMask)
8565ac411aeSYusra Syeda };
8575ac411aeSYusra Syeda enum class PPA1Flag4 : uint8_t {
8585ac411aeSYusra Syeda EPMOffsetPresent = (0x80 >> 0),
8595ac411aeSYusra Syeda VRMask = (0x80 >> 2),
8605ac411aeSYusra Syeda ProcedureNamePresent = (0x80 >> 7),
8615ac411aeSYusra Syeda LLVM_MARK_AS_BITMASK_ENUM(EPMOffsetPresent)
8625ac411aeSYusra Syeda };
8635ac411aeSYusra Syeda
8645ac411aeSYusra Syeda // Declare optional section flags that can be modified.
8655ac411aeSYusra Syeda auto Flags1 = PPA1Flag1(0);
8665ac411aeSYusra Syeda auto Flags2 = PPA1Flag2::ExternalProcedure;
8675ac411aeSYusra Syeda auto Flags3 = PPA1Flag3(0);
8685ac411aeSYusra Syeda auto Flags4 = PPA1Flag4::EPMOffsetPresent | PPA1Flag4::ProcedureNamePresent;
8695ac411aeSYusra Syeda
8705ac411aeSYusra Syeda Flags1 |= PPA1Flag1::DSA64Bit;
8715ac411aeSYusra Syeda
8725ac411aeSYusra Syeda if (VarArg)
8735ac411aeSYusra Syeda Flags1 |= PPA1Flag1::VarArg;
8745ac411aeSYusra Syeda
8755ac411aeSYusra Syeda if (StackProtector)
8765ac411aeSYusra Syeda Flags2 |= PPA1Flag2::STACKPROTECTOR;
8775ac411aeSYusra Syeda
8785ac411aeSYusra Syeda // SavedGPRMask, SavedFPRMask, and SavedVRMask are precomputed in.
8795ac411aeSYusra Syeda if (FPRMask)
8805ac411aeSYusra Syeda Flags3 |= PPA1Flag3::FPRMask; // Add emit FPR mask flag.
8815ac411aeSYusra Syeda
8825ac411aeSYusra Syeda if (VRMask)
8835ac411aeSYusra Syeda Flags4 |= PPA1Flag4::VRMask; // Add emit VR mask flag.
8845ac411aeSYusra Syeda
8855ac411aeSYusra Syeda OutStreamer->AddComment("PPA1 Flags 1");
8865ac411aeSYusra Syeda if ((Flags1 & PPA1Flag1::DSA64Bit) == PPA1Flag1::DSA64Bit)
8875ac411aeSYusra Syeda OutStreamer->AddComment(" Bit 0: 1 = 64-bit DSA");
8885ac411aeSYusra Syeda else
8895ac411aeSYusra Syeda OutStreamer->AddComment(" Bit 0: 0 = 32-bit DSA");
8905ac411aeSYusra Syeda if ((Flags1 & PPA1Flag1::VarArg) == PPA1Flag1::VarArg)
8915ac411aeSYusra Syeda OutStreamer->AddComment(" Bit 7: 1 = Vararg function");
8925ac411aeSYusra Syeda OutStreamer->emitInt8(static_cast<uint8_t>(Flags1)); // Flags 1.
8935ac411aeSYusra Syeda
8945ac411aeSYusra Syeda OutStreamer->AddComment("PPA1 Flags 2");
8955ac411aeSYusra Syeda if ((Flags2 & PPA1Flag2::ExternalProcedure) == PPA1Flag2::ExternalProcedure)
8965ac411aeSYusra Syeda OutStreamer->AddComment(" Bit 0: 1 = External procedure");
8975ac411aeSYusra Syeda if ((Flags2 & PPA1Flag2::STACKPROTECTOR) == PPA1Flag2::STACKPROTECTOR)
8985ac411aeSYusra Syeda OutStreamer->AddComment(" Bit 3: 1 = STACKPROTECT is enabled");
8995ac411aeSYusra Syeda else
9005ac411aeSYusra Syeda OutStreamer->AddComment(" Bit 3: 0 = STACKPROTECT is not enabled");
9015ac411aeSYusra Syeda OutStreamer->emitInt8(static_cast<uint8_t>(Flags2)); // Flags 2.
9025ac411aeSYusra Syeda
9035ac411aeSYusra Syeda OutStreamer->AddComment("PPA1 Flags 3");
9045ac411aeSYusra Syeda if ((Flags3 & PPA1Flag3::FPRMask) == PPA1Flag3::FPRMask)
9055ac411aeSYusra Syeda OutStreamer->AddComment(" Bit 2: 1 = FP Reg Mask is in optional area");
9065ac411aeSYusra Syeda OutStreamer->emitInt8(
9075ac411aeSYusra Syeda static_cast<uint8_t>(Flags3)); // Flags 3 (optional sections).
9085ac411aeSYusra Syeda
9095ac411aeSYusra Syeda OutStreamer->AddComment("PPA1 Flags 4");
9105ac411aeSYusra Syeda if ((Flags4 & PPA1Flag4::VRMask) == PPA1Flag4::VRMask)
9115ac411aeSYusra Syeda OutStreamer->AddComment(" Bit 2: 1 = Vector Reg Mask is in optional area");
9125ac411aeSYusra Syeda OutStreamer->emitInt8(static_cast<uint8_t>(
9135ac411aeSYusra Syeda Flags4)); // Flags 4 (optional sections, always emit these).
9145ac411aeSYusra Syeda }
9155ac411aeSYusra Syeda
emitPPA1(MCSymbol * FnEndSym)9165ac411aeSYusra Syeda void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) {
9175ac411aeSYusra Syeda const TargetRegisterInfo *TRI = MF->getRegInfo().getTargetRegisterInfo();
9185ac411aeSYusra Syeda const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
9195ac411aeSYusra Syeda const auto TargetHasVector = Subtarget.hasVector();
9205ac411aeSYusra Syeda
9215ac411aeSYusra Syeda const SystemZMachineFunctionInfo *ZFI =
9225ac411aeSYusra Syeda MF->getInfo<SystemZMachineFunctionInfo>();
9235ac411aeSYusra Syeda const auto *ZFL = static_cast<const SystemZXPLINKFrameLowering *>(
9245ac411aeSYusra Syeda Subtarget.getFrameLowering());
9255ac411aeSYusra Syeda const MachineFrameInfo &MFFrame = MF->getFrameInfo();
9265ac411aeSYusra Syeda
9275ac411aeSYusra Syeda // Get saved GPR/FPR/VPR masks.
9285ac411aeSYusra Syeda const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
9295ac411aeSYusra Syeda uint16_t SavedGPRMask = 0;
9305ac411aeSYusra Syeda uint16_t SavedFPRMask = 0;
9315ac411aeSYusra Syeda uint8_t SavedVRMask = 0;
9325ac411aeSYusra Syeda int64_t OffsetFPR = 0;
9335ac411aeSYusra Syeda int64_t OffsetVR = 0;
9345ac411aeSYusra Syeda const int64_t TopOfStack =
9355ac411aeSYusra Syeda MFFrame.getOffsetAdjustment() + MFFrame.getStackSize();
9365ac411aeSYusra Syeda
9375ac411aeSYusra Syeda // Loop over the spilled registers. The CalleeSavedInfo can't be used because
9385ac411aeSYusra Syeda // it does not contain all spilled registers.
9395ac411aeSYusra Syeda for (unsigned I = ZFI->getSpillGPRRegs().LowGPR,
9405ac411aeSYusra Syeda E = ZFI->getSpillGPRRegs().HighGPR;
9415ac411aeSYusra Syeda I && E && I <= E; ++I) {
9425ac411aeSYusra Syeda unsigned V = TRI->getEncodingValue((Register)I);
9435ac411aeSYusra Syeda assert(V < 16 && "GPR index out of range");
9445ac411aeSYusra Syeda SavedGPRMask |= 1 << (15 - V);
9455ac411aeSYusra Syeda }
9465ac411aeSYusra Syeda
9475ac411aeSYusra Syeda for (auto &CS : CSI) {
9485ac411aeSYusra Syeda unsigned Reg = CS.getReg();
9495ac411aeSYusra Syeda unsigned I = TRI->getEncodingValue(Reg);
9505ac411aeSYusra Syeda
9515ac411aeSYusra Syeda if (SystemZ::FP64BitRegClass.contains(Reg)) {
9525ac411aeSYusra Syeda assert(I < 16 && "FPR index out of range");
9535ac411aeSYusra Syeda SavedFPRMask |= 1 << (15 - I);
9545ac411aeSYusra Syeda int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
9555ac411aeSYusra Syeda if (Temp < OffsetFPR)
9565ac411aeSYusra Syeda OffsetFPR = Temp;
9575ac411aeSYusra Syeda } else if (SystemZ::VR128BitRegClass.contains(Reg)) {
9585ac411aeSYusra Syeda assert(I >= 16 && I <= 23 && "VPR index out of range");
9595ac411aeSYusra Syeda unsigned BitNum = I - 16;
9605ac411aeSYusra Syeda SavedVRMask |= 1 << (7 - BitNum);
9615ac411aeSYusra Syeda int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
9625ac411aeSYusra Syeda if (Temp < OffsetVR)
9635ac411aeSYusra Syeda OffsetVR = Temp;
9645ac411aeSYusra Syeda }
9655ac411aeSYusra Syeda }
9665ac411aeSYusra Syeda
9675ac411aeSYusra Syeda // Adjust the offset.
9685ac411aeSYusra Syeda OffsetFPR += (OffsetFPR < 0) ? TopOfStack : 0;
9695ac411aeSYusra Syeda OffsetVR += (OffsetVR < 0) ? TopOfStack : 0;
9705ac411aeSYusra Syeda
9715ac411aeSYusra Syeda // Get alloca register.
9725ac411aeSYusra Syeda uint8_t FrameReg = TRI->getEncodingValue(TRI->getFrameRegister(*MF));
9735ac411aeSYusra Syeda uint8_t AllocaReg = ZFL->hasFP(*MF) ? FrameReg : 0;
9745ac411aeSYusra Syeda assert(AllocaReg < 16 && "Can't have alloca register larger than 15");
9758801a5d1SNAKAMURA Takumi (void)AllocaReg;
9765ac411aeSYusra Syeda
9775ac411aeSYusra Syeda // Build FPR save area offset.
9785ac411aeSYusra Syeda uint32_t FrameAndFPROffset = 0;
9795ac411aeSYusra Syeda if (SavedFPRMask) {
9805ac411aeSYusra Syeda uint64_t FPRSaveAreaOffset = OffsetFPR;
9815ac411aeSYusra Syeda assert(FPRSaveAreaOffset < 0x10000000 && "Offset out of range");
9825ac411aeSYusra Syeda
9835ac411aeSYusra Syeda FrameAndFPROffset = FPRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits.
9845ac411aeSYusra Syeda FrameAndFPROffset |= FrameReg << 28; // Put into top 4 bits.
9855ac411aeSYusra Syeda }
9865ac411aeSYusra Syeda
9875ac411aeSYusra Syeda // Build VR save area offset.
9885ac411aeSYusra Syeda uint32_t FrameAndVROffset = 0;
9895ac411aeSYusra Syeda if (TargetHasVector && SavedVRMask) {
9905ac411aeSYusra Syeda uint64_t VRSaveAreaOffset = OffsetVR;
9915ac411aeSYusra Syeda assert(VRSaveAreaOffset < 0x10000000 && "Offset out of range");
9925ac411aeSYusra Syeda
9935ac411aeSYusra Syeda FrameAndVROffset = VRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits.
9945ac411aeSYusra Syeda FrameAndVROffset |= FrameReg << 28; // Put into top 4 bits.
9955ac411aeSYusra Syeda }
9965ac411aeSYusra Syeda
9975ac411aeSYusra Syeda // Emit PPA1 section.
9985ac411aeSYusra Syeda OutStreamer->AddComment("PPA1");
9995ac411aeSYusra Syeda OutStreamer->emitLabel(CurrentFnPPA1Sym);
10005ac411aeSYusra Syeda OutStreamer->AddComment("Version");
10015ac411aeSYusra Syeda OutStreamer->emitInt8(0x02); // Version.
10025ac411aeSYusra Syeda OutStreamer->AddComment("LE Signature X'CE'");
10035ac411aeSYusra Syeda OutStreamer->emitInt8(0xCE); // CEL signature.
10045ac411aeSYusra Syeda OutStreamer->AddComment("Saved GPR Mask");
10055ac411aeSYusra Syeda OutStreamer->emitInt16(SavedGPRMask);
10065ac411aeSYusra Syeda
10075ac411aeSYusra Syeda emitPPA1Flags(OutStreamer, MF->getFunction().isVarArg(),
10085ac411aeSYusra Syeda MFFrame.hasStackProtectorIndex(), SavedFPRMask != 0,
10095ac411aeSYusra Syeda TargetHasVector && SavedVRMask != 0);
10105ac411aeSYusra Syeda
10115ac411aeSYusra Syeda OutStreamer->AddComment("Length/4 of Parms");
10125ac411aeSYusra Syeda OutStreamer->emitInt16(
10135ac411aeSYusra Syeda static_cast<uint16_t>(MFFrame.getMaxCallFrameSize() / 4)); // Parms/4.
10145ac411aeSYusra Syeda OutStreamer->AddComment("Length of Code");
10155ac411aeSYusra Syeda OutStreamer->emitAbsoluteSymbolDiff(FnEndSym, CurrentFnEPMarkerSym, 4);
10165ac411aeSYusra Syeda
10175ac411aeSYusra Syeda // Emit saved FPR mask and offset to FPR save area (0x20 of flags 3).
10185ac411aeSYusra Syeda if (SavedFPRMask) {
10195ac411aeSYusra Syeda OutStreamer->AddComment("FPR mask");
10205ac411aeSYusra Syeda OutStreamer->emitInt16(SavedFPRMask);
10215ac411aeSYusra Syeda OutStreamer->AddComment("AR mask");
10225ac411aeSYusra Syeda OutStreamer->emitInt16(0); // AR Mask, unused currently.
10235ac411aeSYusra Syeda OutStreamer->AddComment("FPR Save Area Locator");
10245ac411aeSYusra Syeda OutStreamer->AddComment(Twine(" Bit 0-3: Register R")
10255ac411aeSYusra Syeda .concat(utostr(FrameAndFPROffset >> 28))
10265ac411aeSYusra Syeda .str());
10275ac411aeSYusra Syeda OutStreamer->AddComment(Twine(" Bit 4-31: Offset ")
10285ac411aeSYusra Syeda .concat(utostr(FrameAndFPROffset & 0x0FFFFFFF))
10295ac411aeSYusra Syeda .str());
10305ac411aeSYusra Syeda OutStreamer->emitInt32(FrameAndFPROffset); // Offset to FPR save area with
10315ac411aeSYusra Syeda // register to add value to
10325ac411aeSYusra Syeda // (alloca reg).
10335ac411aeSYusra Syeda }
10345ac411aeSYusra Syeda
10355ac411aeSYusra Syeda // Emit saved VR mask to VR save area.
10365ac411aeSYusra Syeda if (TargetHasVector && SavedVRMask) {
10375ac411aeSYusra Syeda OutStreamer->AddComment("VR mask");
10385ac411aeSYusra Syeda OutStreamer->emitInt8(SavedVRMask);
10395ac411aeSYusra Syeda OutStreamer->emitInt8(0); // Reserved.
10405ac411aeSYusra Syeda OutStreamer->emitInt16(0); // Also reserved.
10415ac411aeSYusra Syeda OutStreamer->AddComment("VR Save Area Locator");
10425ac411aeSYusra Syeda OutStreamer->AddComment(Twine(" Bit 0-3: Register R")
10435ac411aeSYusra Syeda .concat(utostr(FrameAndVROffset >> 28))
10445ac411aeSYusra Syeda .str());
10455ac411aeSYusra Syeda OutStreamer->AddComment(Twine(" Bit 4-31: Offset ")
10465ac411aeSYusra Syeda .concat(utostr(FrameAndVROffset & 0x0FFFFFFF))
10475ac411aeSYusra Syeda .str());
10485ac411aeSYusra Syeda OutStreamer->emitInt32(FrameAndVROffset);
10495ac411aeSYusra Syeda }
10505ac411aeSYusra Syeda
10515ac411aeSYusra Syeda // Emit offset to entry point optional section (0x80 of flags 4).
10525ac411aeSYusra Syeda OutStreamer->emitAbsoluteSymbolDiff(CurrentFnEPMarkerSym, CurrentFnPPA1Sym,
10535ac411aeSYusra Syeda 4);
10545ac411aeSYusra Syeda }
10555ac411aeSYusra Syeda
emitFunctionEntryLabel()1056fc8a0876SYusra Syeda void SystemZAsmPrinter::emitFunctionEntryLabel() {
1057ad73ce31SZongwei Lan const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
1058fc8a0876SYusra Syeda
1059fc8a0876SYusra Syeda if (Subtarget.getTargetTriple().isOSzOS()) {
1060fc8a0876SYusra Syeda MCContext &OutContext = OutStreamer->getContext();
10615ac411aeSYusra Syeda
10625ac411aeSYusra Syeda // Save information for later use.
10635ac411aeSYusra Syeda std::string N(MF->getFunction().hasName()
10645ac411aeSYusra Syeda ? Twine(MF->getFunction().getName()).concat("_").str()
10655ac411aeSYusra Syeda : "");
10665ac411aeSYusra Syeda
10675ac411aeSYusra Syeda CurrentFnEPMarkerSym =
10685ac411aeSYusra Syeda OutContext.createTempSymbol(Twine("EPM_").concat(N).str(), true);
10695ac411aeSYusra Syeda CurrentFnPPA1Sym =
10705ac411aeSYusra Syeda OutContext.createTempSymbol(Twine("PPA1_").concat(N).str(), true);
1071fc8a0876SYusra Syeda
1072fc8a0876SYusra Syeda // EntryPoint Marker
1073fc8a0876SYusra Syeda const MachineFrameInfo &MFFrame = MF->getFrameInfo();
1074fc8a0876SYusra Syeda bool IsUsingAlloca = MFFrame.hasVarSizedObjects();
1075fc8a0876SYusra Syeda
1076fc8a0876SYusra Syeda // Set Flags
1077fc8a0876SYusra Syeda uint8_t Flags = 0;
1078fc8a0876SYusra Syeda if (IsUsingAlloca)
1079fc8a0876SYusra Syeda Flags |= 0x04;
1080fc8a0876SYusra Syeda
1081fc8a0876SYusra Syeda uint32_t DSASize = MFFrame.getStackSize();
1082fc8a0876SYusra Syeda
1083fc8a0876SYusra Syeda // Combine into top 27 bits of DSASize and bottom 5 bits of Flags.
1084fc8a0876SYusra Syeda uint32_t DSAAndFlags = DSASize & 0xFFFFFFE0; // (x/32) << 5
1085fc8a0876SYusra Syeda DSAAndFlags |= Flags;
1086fc8a0876SYusra Syeda
1087fc8a0876SYusra Syeda // Emit entry point marker section.
1088fc8a0876SYusra Syeda OutStreamer->AddComment("XPLINK Routine Layout Entry");
10895ac411aeSYusra Syeda OutStreamer->emitLabel(CurrentFnEPMarkerSym);
1090fc8a0876SYusra Syeda OutStreamer->AddComment("Eyecatcher 0x00C300C500C500");
1091fc8a0876SYusra Syeda OutStreamer->emitIntValueInHex(0x00C300C500C500, 7); // Eyecatcher.
1092fc8a0876SYusra Syeda OutStreamer->AddComment("Mark Type C'1'");
1093fc8a0876SYusra Syeda OutStreamer->emitInt8(0xF1); // Mark Type.
10945ac411aeSYusra Syeda OutStreamer->AddComment("Offset to PPA1");
10955ac411aeSYusra Syeda OutStreamer->emitAbsoluteSymbolDiff(CurrentFnPPA1Sym, CurrentFnEPMarkerSym,
10965ac411aeSYusra Syeda 4);
1097fc8a0876SYusra Syeda if (OutStreamer->isVerboseAsm()) {
1098fc8a0876SYusra Syeda OutStreamer->AddComment("DSA Size 0x" + Twine::utohexstr(DSASize));
1099fc8a0876SYusra Syeda OutStreamer->AddComment("Entry Flags");
1100fc8a0876SYusra Syeda if (Flags & 0x04)
1101fc8a0876SYusra Syeda OutStreamer->AddComment(" Bit 2: 1 = Uses alloca");
1102fc8a0876SYusra Syeda else
1103fc8a0876SYusra Syeda OutStreamer->AddComment(" Bit 2: 0 = Does not use alloca");
1104fc8a0876SYusra Syeda }
1105fc8a0876SYusra Syeda OutStreamer->emitInt32(DSAAndFlags);
1106fc8a0876SYusra Syeda }
1107fc8a0876SYusra Syeda
1108fc8a0876SYusra Syeda AsmPrinter::emitFunctionEntryLabel();
1109fc8a0876SYusra Syeda }
1110fc8a0876SYusra Syeda
11115f613dfdSUlrich Weigand // Force static initialization.
LLVMInitializeSystemZAsmPrinter()11120dbcb363STom Stellard extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmPrinter() {
1113f42454b9SMehdi Amini RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget());
11145f613dfdSUlrich Weigand }
1115