15f613dfdSUlrich Weigand //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
25f613dfdSUlrich Weigand //
35f613dfdSUlrich Weigand //                     The LLVM Compiler Infrastructure
45f613dfdSUlrich Weigand //
55f613dfdSUlrich Weigand // This file is distributed under the University of Illinois Open Source
65f613dfdSUlrich Weigand // License. See LICENSE.TXT for details.
75f613dfdSUlrich Weigand //
85f613dfdSUlrich Weigand //===----------------------------------------------------------------------===//
95f613dfdSUlrich Weigand //
105f613dfdSUlrich Weigand // Streams SystemZ assembly language and associated data, in the form of
115f613dfdSUlrich Weigand // MCInsts and MCExprs respectively.
125f613dfdSUlrich Weigand //
135f613dfdSUlrich Weigand //===----------------------------------------------------------------------===//
145f613dfdSUlrich Weigand 
155f613dfdSUlrich Weigand #include "SystemZAsmPrinter.h"
165f613dfdSUlrich Weigand #include "InstPrinter/SystemZInstPrinter.h"
175f613dfdSUlrich Weigand #include "SystemZConstantPoolValue.h"
185f613dfdSUlrich Weigand #include "SystemZMCInstLower.h"
195f613dfdSUlrich Weigand #include "llvm/CodeGen/MachineModuleInfoImpls.h"
205f613dfdSUlrich Weigand #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
21894843cbSRafael Espindola #include "llvm/IR/Mangler.h"
225f613dfdSUlrich Weigand #include "llvm/MC/MCExpr.h"
239ab97cd1SRichard Sandiford #include "llvm/MC/MCInstBuilder.h"
245f613dfdSUlrich Weigand #include "llvm/MC/MCStreamer.h"
255f613dfdSUlrich Weigand #include "llvm/Support/TargetRegistry.h"
265f613dfdSUlrich Weigand 
275f613dfdSUlrich Weigand using namespace llvm;
285f613dfdSUlrich Weigand 
29652784e2SRichard Sandiford // Return an RI instruction like MI with opcode Opcode, but with the
30652784e2SRichard Sandiford // GR64 register operands turned into GR32s.
31652784e2SRichard Sandiford static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
32f03789caSRichard Sandiford   if (MI->isCompare())
33f03789caSRichard Sandiford     return MCInstBuilder(Opcode)
34f03789caSRichard Sandiford       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
35f03789caSRichard Sandiford       .addImm(MI->getOperand(1).getImm());
36f03789caSRichard Sandiford   else
37652784e2SRichard Sandiford     return MCInstBuilder(Opcode)
38652784e2SRichard Sandiford       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
39652784e2SRichard Sandiford       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
40652784e2SRichard Sandiford       .addImm(MI->getOperand(2).getImm());
41652784e2SRichard Sandiford }
42652784e2SRichard Sandiford 
430755c93bSRichard Sandiford // Return an RI instruction like MI with opcode Opcode, but with the
441a56931bSRichard Sandiford // GR64 register operands turned into GRH32s.
451a56931bSRichard Sandiford static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
46f03789caSRichard Sandiford   if (MI->isCompare())
47f03789caSRichard Sandiford     return MCInstBuilder(Opcode)
48f03789caSRichard Sandiford       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
49f03789caSRichard Sandiford       .addImm(MI->getOperand(1).getImm());
50f03789caSRichard Sandiford   else
511a56931bSRichard Sandiford     return MCInstBuilder(Opcode)
521a56931bSRichard Sandiford       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
531a56931bSRichard Sandiford       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
541a56931bSRichard Sandiford       .addImm(MI->getOperand(2).getImm());
551a56931bSRichard Sandiford }
561a56931bSRichard Sandiford 
571a56931bSRichard Sandiford // Return an RI instruction like MI with opcode Opcode, but with the
580755c93bSRichard Sandiford // R2 register turned into a GR64.
590755c93bSRichard Sandiford static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
600755c93bSRichard Sandiford   return MCInstBuilder(Opcode)
610755c93bSRichard Sandiford     .addReg(MI->getOperand(0).getReg())
620755c93bSRichard Sandiford     .addReg(MI->getOperand(1).getReg())
630755c93bSRichard Sandiford     .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
640755c93bSRichard Sandiford     .addImm(MI->getOperand(3).getImm())
650755c93bSRichard Sandiford     .addImm(MI->getOperand(4).getImm())
660755c93bSRichard Sandiford     .addImm(MI->getOperand(5).getImm());
670755c93bSRichard Sandiford }
680755c93bSRichard Sandiford 
697db6918eSUlrich Weigand static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
707db6918eSUlrich Weigand   StringRef Name = "__tls_get_offset";
7113760bd1SJim Grosbach   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
727db6918eSUlrich Weigand                                  MCSymbolRefExpr::VK_PLT,
737db6918eSUlrich Weigand                                  Context);
747db6918eSUlrich Weigand }
757db6918eSUlrich Weigand 
767db6918eSUlrich Weigand static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
777db6918eSUlrich Weigand   StringRef Name = "_GLOBAL_OFFSET_TABLE_";
7813760bd1SJim Grosbach   return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
797db6918eSUlrich Weigand                                  MCSymbolRefExpr::VK_None,
807db6918eSUlrich Weigand                                  Context);
817db6918eSUlrich Weigand }
827db6918eSUlrich Weigand 
8349506d78SUlrich Weigand // MI loads the high part of a vector from memory.  Return an instruction
8449506d78SUlrich Weigand // that uses replicating vector load Opcode to do the same thing.
8549506d78SUlrich Weigand static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
8649506d78SUlrich Weigand   return MCInstBuilder(Opcode)
8749506d78SUlrich Weigand     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
8849506d78SUlrich Weigand     .addReg(MI->getOperand(1).getReg())
8949506d78SUlrich Weigand     .addImm(MI->getOperand(2).getImm())
9049506d78SUlrich Weigand     .addReg(MI->getOperand(3).getReg());
9149506d78SUlrich Weigand }
9249506d78SUlrich Weigand 
9349506d78SUlrich Weigand // MI stores the high part of a vector to memory.  Return an instruction
9449506d78SUlrich Weigand // that uses elemental vector store Opcode to do the same thing.
9549506d78SUlrich Weigand static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
9649506d78SUlrich Weigand   return MCInstBuilder(Opcode)
9749506d78SUlrich Weigand     .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
9849506d78SUlrich Weigand     .addReg(MI->getOperand(1).getReg())
9949506d78SUlrich Weigand     .addImm(MI->getOperand(2).getImm())
10049506d78SUlrich Weigand     .addReg(MI->getOperand(3).getReg())
10149506d78SUlrich Weigand     .addImm(0);
10249506d78SUlrich Weigand }
10349506d78SUlrich Weigand 
1045f613dfdSUlrich Weigand void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
10569c1d631SRafael Espindola   SystemZMCInstLower Lower(MF->getContext(), *this);
1065f613dfdSUlrich Weigand   MCInst LoweredMI;
1079ab97cd1SRichard Sandiford   switch (MI->getOpcode()) {
1089ab97cd1SRichard Sandiford   case SystemZ::Return:
1099ab97cd1SRichard Sandiford     LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
1109ab97cd1SRichard Sandiford     break;
1119ab97cd1SRichard Sandiford 
1122eb027d2SUlrich Weigand   case SystemZ::CondReturn:
1132eb027d2SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::BCR)
1142eb027d2SUlrich Weigand       .addImm(MI->getOperand(0).getImm())
1152eb027d2SUlrich Weigand       .addImm(MI->getOperand(1).getImm())
1162eb027d2SUlrich Weigand       .addReg(SystemZ::R14D);
1172eb027d2SUlrich Weigand     break;
1182eb027d2SUlrich Weigand 
1192eb027d2SUlrich Weigand   case SystemZ::CRBReturn:
1202eb027d2SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::CRB)
1212eb027d2SUlrich Weigand       .addReg(MI->getOperand(0).getReg())
1222eb027d2SUlrich Weigand       .addReg(MI->getOperand(1).getReg())
1232eb027d2SUlrich Weigand       .addImm(MI->getOperand(2).getImm())
1242eb027d2SUlrich Weigand       .addReg(SystemZ::R14D)
1252eb027d2SUlrich Weigand       .addImm(0);
1262eb027d2SUlrich Weigand     break;
1272eb027d2SUlrich Weigand 
1282eb027d2SUlrich Weigand   case SystemZ::CGRBReturn:
1292eb027d2SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::CGRB)
1302eb027d2SUlrich Weigand       .addReg(MI->getOperand(0).getReg())
1312eb027d2SUlrich Weigand       .addReg(MI->getOperand(1).getReg())
1322eb027d2SUlrich Weigand       .addImm(MI->getOperand(2).getImm())
1332eb027d2SUlrich Weigand       .addReg(SystemZ::R14D)
1342eb027d2SUlrich Weigand       .addImm(0);
1352eb027d2SUlrich Weigand     break;
1362eb027d2SUlrich Weigand 
1372eb027d2SUlrich Weigand   case SystemZ::CIBReturn:
1382eb027d2SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::CIB)
1392eb027d2SUlrich Weigand       .addReg(MI->getOperand(0).getReg())
1402eb027d2SUlrich Weigand       .addImm(MI->getOperand(1).getImm())
1412eb027d2SUlrich Weigand       .addImm(MI->getOperand(2).getImm())
1422eb027d2SUlrich Weigand       .addReg(SystemZ::R14D)
1432eb027d2SUlrich Weigand       .addImm(0);
1442eb027d2SUlrich Weigand     break;
1452eb027d2SUlrich Weigand 
1462eb027d2SUlrich Weigand   case SystemZ::CGIBReturn:
1472eb027d2SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::CGIB)
1482eb027d2SUlrich Weigand       .addReg(MI->getOperand(0).getReg())
1492eb027d2SUlrich Weigand       .addImm(MI->getOperand(1).getImm())
1502eb027d2SUlrich Weigand       .addImm(MI->getOperand(2).getImm())
1512eb027d2SUlrich Weigand       .addReg(SystemZ::R14D)
1522eb027d2SUlrich Weigand       .addImm(0);
1532eb027d2SUlrich Weigand     break;
1542eb027d2SUlrich Weigand 
1552eb027d2SUlrich Weigand   case SystemZ::CLRBReturn:
1562eb027d2SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::CLRB)
1572eb027d2SUlrich Weigand       .addReg(MI->getOperand(0).getReg())
1582eb027d2SUlrich Weigand       .addReg(MI->getOperand(1).getReg())
1592eb027d2SUlrich Weigand       .addImm(MI->getOperand(2).getImm())
1602eb027d2SUlrich Weigand       .addReg(SystemZ::R14D)
1612eb027d2SUlrich Weigand       .addImm(0);
1622eb027d2SUlrich Weigand     break;
1632eb027d2SUlrich Weigand 
1642eb027d2SUlrich Weigand   case SystemZ::CLGRBReturn:
1652eb027d2SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::CLGRB)
1662eb027d2SUlrich Weigand       .addReg(MI->getOperand(0).getReg())
1672eb027d2SUlrich Weigand       .addReg(MI->getOperand(1).getReg())
1682eb027d2SUlrich Weigand       .addImm(MI->getOperand(2).getImm())
1692eb027d2SUlrich Weigand       .addReg(SystemZ::R14D)
1702eb027d2SUlrich Weigand       .addImm(0);
1712eb027d2SUlrich Weigand     break;
1722eb027d2SUlrich Weigand 
1732eb027d2SUlrich Weigand   case SystemZ::CLIBReturn:
1742eb027d2SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::CLIB)
1752eb027d2SUlrich Weigand       .addReg(MI->getOperand(0).getReg())
1762eb027d2SUlrich Weigand       .addImm(MI->getOperand(1).getImm())
1772eb027d2SUlrich Weigand       .addImm(MI->getOperand(2).getImm())
1782eb027d2SUlrich Weigand       .addReg(SystemZ::R14D)
1792eb027d2SUlrich Weigand       .addImm(0);
1802eb027d2SUlrich Weigand     break;
1812eb027d2SUlrich Weigand 
1822eb027d2SUlrich Weigand   case SystemZ::CLGIBReturn:
1832eb027d2SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::CLGIB)
1842eb027d2SUlrich Weigand       .addReg(MI->getOperand(0).getReg())
1852eb027d2SUlrich Weigand       .addImm(MI->getOperand(1).getImm())
1862eb027d2SUlrich Weigand       .addImm(MI->getOperand(2).getImm())
1872eb027d2SUlrich Weigand       .addReg(SystemZ::R14D)
1882eb027d2SUlrich Weigand       .addImm(0);
1892eb027d2SUlrich Weigand     break;
1902eb027d2SUlrich Weigand 
191f348f831SRichard Sandiford   case SystemZ::CallBRASL:
192f348f831SRichard Sandiford     LoweredMI = MCInstBuilder(SystemZ::BRASL)
193f348f831SRichard Sandiford       .addReg(SystemZ::R14D)
194f348f831SRichard Sandiford       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
195f348f831SRichard Sandiford     break;
196f348f831SRichard Sandiford 
197f348f831SRichard Sandiford   case SystemZ::CallBASR:
198f348f831SRichard Sandiford     LoweredMI = MCInstBuilder(SystemZ::BASR)
199f348f831SRichard Sandiford       .addReg(SystemZ::R14D)
200f348f831SRichard Sandiford       .addReg(MI->getOperand(0).getReg());
201f348f831SRichard Sandiford     break;
202f348f831SRichard Sandiford 
203f348f831SRichard Sandiford   case SystemZ::CallJG:
204f348f831SRichard Sandiford     LoweredMI = MCInstBuilder(SystemZ::JG)
205f348f831SRichard Sandiford       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
206f348f831SRichard Sandiford     break;
207f348f831SRichard Sandiford 
208*fa2dffbcSUlrich Weigand   case SystemZ::CallBRCL:
209*fa2dffbcSUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::BRCL)
210*fa2dffbcSUlrich Weigand       .addImm(MI->getOperand(0).getImm())
211*fa2dffbcSUlrich Weigand       .addImm(MI->getOperand(1).getImm())
212*fa2dffbcSUlrich Weigand       .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
213*fa2dffbcSUlrich Weigand     break;
214*fa2dffbcSUlrich Weigand 
215f348f831SRichard Sandiford   case SystemZ::CallBR:
216f348f831SRichard Sandiford     LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
217f348f831SRichard Sandiford     break;
218f348f831SRichard Sandiford 
2197db6918eSUlrich Weigand   case SystemZ::TLS_GDCALL:
2207db6918eSUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::BRASL)
2217db6918eSUlrich Weigand       .addReg(SystemZ::R14D)
2227db6918eSUlrich Weigand       .addExpr(getTLSGetOffset(MF->getContext()))
2237db6918eSUlrich Weigand       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
2247db6918eSUlrich Weigand     break;
2257db6918eSUlrich Weigand 
2267db6918eSUlrich Weigand   case SystemZ::TLS_LDCALL:
2277db6918eSUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::BRASL)
2287db6918eSUlrich Weigand       .addReg(SystemZ::R14D)
2297db6918eSUlrich Weigand       .addExpr(getTLSGetOffset(MF->getContext()))
2307db6918eSUlrich Weigand       .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
2317db6918eSUlrich Weigand     break;
2327db6918eSUlrich Weigand 
2337db6918eSUlrich Weigand   case SystemZ::GOT:
2347db6918eSUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::LARL)
2357db6918eSUlrich Weigand       .addReg(MI->getOperand(0).getReg())
2367db6918eSUlrich Weigand       .addExpr(getGlobalOffsetTable(MF->getContext()));
2377db6918eSUlrich Weigand     break;
2387db6918eSUlrich Weigand 
239652784e2SRichard Sandiford   case SystemZ::IILF64:
240652784e2SRichard Sandiford     LoweredMI = MCInstBuilder(SystemZ::IILF)
241652784e2SRichard Sandiford       .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
242652784e2SRichard Sandiford       .addImm(MI->getOperand(2).getImm());
243652784e2SRichard Sandiford     break;
244652784e2SRichard Sandiford 
24501240234SRichard Sandiford   case SystemZ::IIHF64:
24601240234SRichard Sandiford     LoweredMI = MCInstBuilder(SystemZ::IIHF)
24701240234SRichard Sandiford       .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
24801240234SRichard Sandiford       .addImm(MI->getOperand(2).getImm());
24901240234SRichard Sandiford     break;
25001240234SRichard Sandiford 
2510755c93bSRichard Sandiford   case SystemZ::RISBHH:
2520755c93bSRichard Sandiford   case SystemZ::RISBHL:
2530755c93bSRichard Sandiford     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
2540755c93bSRichard Sandiford     break;
2550755c93bSRichard Sandiford 
2560755c93bSRichard Sandiford   case SystemZ::RISBLH:
2570755c93bSRichard Sandiford   case SystemZ::RISBLL:
2580755c93bSRichard Sandiford     LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
2590755c93bSRichard Sandiford     break;
2600755c93bSRichard Sandiford 
261ce4c1095SUlrich Weigand   case SystemZ::VLVGP32:
262ce4c1095SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::VLVGP)
263ce4c1095SUlrich Weigand       .addReg(MI->getOperand(0).getReg())
264ce4c1095SUlrich Weigand       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
265ce4c1095SUlrich Weigand       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
266ce4c1095SUlrich Weigand     break;
267ce4c1095SUlrich Weigand 
26849506d78SUlrich Weigand   case SystemZ::VLR32:
26949506d78SUlrich Weigand   case SystemZ::VLR64:
27049506d78SUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::VLR)
27149506d78SUlrich Weigand       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
27249506d78SUlrich Weigand       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
27349506d78SUlrich Weigand     break;
27449506d78SUlrich Weigand 
27549506d78SUlrich Weigand   case SystemZ::VL32:
27649506d78SUlrich Weigand     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
27749506d78SUlrich Weigand     break;
27849506d78SUlrich Weigand 
27949506d78SUlrich Weigand   case SystemZ::VL64:
28049506d78SUlrich Weigand     LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
28149506d78SUlrich Weigand     break;
28249506d78SUlrich Weigand 
28349506d78SUlrich Weigand   case SystemZ::VST32:
28449506d78SUlrich Weigand     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
28549506d78SUlrich Weigand     break;
28649506d78SUlrich Weigand 
28749506d78SUlrich Weigand   case SystemZ::VST64:
28849506d78SUlrich Weigand     LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
28949506d78SUlrich Weigand     break;
29049506d78SUlrich Weigand 
29180b3af7aSUlrich Weigand   case SystemZ::LFER:
29280b3af7aSUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::VLGVF)
29380b3af7aSUlrich Weigand       .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
29480b3af7aSUlrich Weigand       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
29580b3af7aSUlrich Weigand       .addReg(0).addImm(0);
29680b3af7aSUlrich Weigand     break;
29780b3af7aSUlrich Weigand 
29880b3af7aSUlrich Weigand   case SystemZ::LEFR:
29980b3af7aSUlrich Weigand     LoweredMI = MCInstBuilder(SystemZ::VLVGF)
30080b3af7aSUlrich Weigand       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
30180b3af7aSUlrich Weigand       .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
30280b3af7aSUlrich Weigand       .addReg(MI->getOperand(1).getReg())
30380b3af7aSUlrich Weigand       .addReg(0).addImm(0);
30480b3af7aSUlrich Weigand     break;
30580b3af7aSUlrich Weigand 
306652784e2SRichard Sandiford #define LOWER_LOW(NAME)                                                 \
307652784e2SRichard Sandiford   case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
308652784e2SRichard Sandiford 
309652784e2SRichard Sandiford   LOWER_LOW(IILL);
310652784e2SRichard Sandiford   LOWER_LOW(IILH);
311f03789caSRichard Sandiford   LOWER_LOW(TMLL);
312f03789caSRichard Sandiford   LOWER_LOW(TMLH);
313652784e2SRichard Sandiford   LOWER_LOW(NILL);
314652784e2SRichard Sandiford   LOWER_LOW(NILH);
315652784e2SRichard Sandiford   LOWER_LOW(NILF);
316652784e2SRichard Sandiford   LOWER_LOW(OILL);
317652784e2SRichard Sandiford   LOWER_LOW(OILH);
318652784e2SRichard Sandiford   LOWER_LOW(OILF);
319652784e2SRichard Sandiford   LOWER_LOW(XILF);
320652784e2SRichard Sandiford 
321652784e2SRichard Sandiford #undef LOWER_LOW
322652784e2SRichard Sandiford 
3231a56931bSRichard Sandiford #define LOWER_HIGH(NAME) \
3241a56931bSRichard Sandiford   case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
3251a56931bSRichard Sandiford 
3261a56931bSRichard Sandiford   LOWER_HIGH(IIHL);
3271a56931bSRichard Sandiford   LOWER_HIGH(IIHH);
328f03789caSRichard Sandiford   LOWER_HIGH(TMHL);
329f03789caSRichard Sandiford   LOWER_HIGH(TMHH);
3307028428cSRichard Sandiford   LOWER_HIGH(NIHL);
3317028428cSRichard Sandiford   LOWER_HIGH(NIHH);
3327028428cSRichard Sandiford   LOWER_HIGH(NIHF);
3336e96ac60SRichard Sandiford   LOWER_HIGH(OIHL);
3346e96ac60SRichard Sandiford   LOWER_HIGH(OIHH);
3356e96ac60SRichard Sandiford   LOWER_HIGH(OIHF);
3365718dacbSRichard Sandiford   LOWER_HIGH(XIHF);
3371a56931bSRichard Sandiford 
3381a56931bSRichard Sandiford #undef LOWER_HIGH
3391a56931bSRichard Sandiford 
3409afe613dSRichard Sandiford   case SystemZ::Serialize:
341d84f5d30SEric Christopher     if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
3429afe613dSRichard Sandiford       LoweredMI = MCInstBuilder(SystemZ::AsmBCR)
3439afe613dSRichard Sandiford         .addImm(14).addReg(SystemZ::R0D);
3449afe613dSRichard Sandiford     else
3459afe613dSRichard Sandiford       LoweredMI = MCInstBuilder(SystemZ::AsmBCR)
3469afe613dSRichard Sandiford         .addImm(15).addReg(SystemZ::R0D);
3479afe613dSRichard Sandiford     break;
3489afe613dSRichard Sandiford 
349a9ac6d6cSUlrich Weigand   // Emit nothing here but a comment if we can.
350a9ac6d6cSUlrich Weigand   case SystemZ::MemBarrier:
351a9ac6d6cSUlrich Weigand     OutStreamer->emitRawComment("MEMBARRIER");
352a9ac6d6cSUlrich Weigand     return;
353a9ac6d6cSUlrich Weigand 
3549ab97cd1SRichard Sandiford   default:
355f348f831SRichard Sandiford     Lower.lower(MI, LoweredMI);
3569ab97cd1SRichard Sandiford     break;
3579ab97cd1SRichard Sandiford   }
3589ff69c8fSLang Hames   EmitToStreamer(*OutStreamer, LoweredMI);
3595f613dfdSUlrich Weigand }
3605f613dfdSUlrich Weigand 
3615f613dfdSUlrich Weigand // Convert a SystemZ-specific constant pool modifier into the associated
3625f613dfdSUlrich Weigand // MCSymbolRefExpr variant kind.
3635f613dfdSUlrich Weigand static MCSymbolRefExpr::VariantKind
3645f613dfdSUlrich Weigand getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
3655f613dfdSUlrich Weigand   switch (Modifier) {
3667db6918eSUlrich Weigand   case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
3677db6918eSUlrich Weigand   case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
3687db6918eSUlrich Weigand   case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
3695f613dfdSUlrich Weigand   case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
3705f613dfdSUlrich Weigand   }
3715f613dfdSUlrich Weigand   llvm_unreachable("Invalid SystemCPModifier!");
3725f613dfdSUlrich Weigand }
3735f613dfdSUlrich Weigand 
3745f613dfdSUlrich Weigand void SystemZAsmPrinter::
3755f613dfdSUlrich Weigand EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
37621f5d68aSRichard Sandiford   auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
3775f613dfdSUlrich Weigand 
3785f613dfdSUlrich Weigand   const MCExpr *Expr =
37913760bd1SJim Grosbach     MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
3805f613dfdSUlrich Weigand                             getModifierVariantKind(ZCPV->getModifier()),
3815f613dfdSUlrich Weigand                             OutContext);
382bd7287ebSMehdi Amini   uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
3835f613dfdSUlrich Weigand 
3849ff69c8fSLang Hames   OutStreamer->EmitValue(Expr, Size);
3855f613dfdSUlrich Weigand }
3865f613dfdSUlrich Weigand 
3875f613dfdSUlrich Weigand bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
3885f613dfdSUlrich Weigand                                         unsigned OpNo,
3895f613dfdSUlrich Weigand                                         unsigned AsmVariant,
3905f613dfdSUlrich Weigand                                         const char *ExtraCode,
3915f613dfdSUlrich Weigand                                         raw_ostream &OS) {
3925f613dfdSUlrich Weigand   if (ExtraCode && *ExtraCode == 'n') {
3935f613dfdSUlrich Weigand     if (!MI->getOperand(OpNo).isImm())
3945f613dfdSUlrich Weigand       return true;
3955f613dfdSUlrich Weigand     OS << -int64_t(MI->getOperand(OpNo).getImm());
3965f613dfdSUlrich Weigand   } else {
39769c1d631SRafael Espindola     SystemZMCInstLower Lower(MF->getContext(), *this);
3985f613dfdSUlrich Weigand     MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
3998b643559SMatt Arsenault     SystemZInstPrinter::printOperand(MO, MAI, OS);
4005f613dfdSUlrich Weigand   }
4015f613dfdSUlrich Weigand   return false;
4025f613dfdSUlrich Weigand }
4035f613dfdSUlrich Weigand 
4045f613dfdSUlrich Weigand bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
4055f613dfdSUlrich Weigand                                               unsigned OpNo,
4065f613dfdSUlrich Weigand                                               unsigned AsmVariant,
4075f613dfdSUlrich Weigand                                               const char *ExtraCode,
4085f613dfdSUlrich Weigand                                               raw_ostream &OS) {
4095f613dfdSUlrich Weigand   SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
4105f613dfdSUlrich Weigand                                    MI->getOperand(OpNo + 1).getImm(),
4115f613dfdSUlrich Weigand                                    MI->getOperand(OpNo + 2).getReg(), OS);
4125f613dfdSUlrich Weigand   return false;
4135f613dfdSUlrich Weigand }
4145f613dfdSUlrich Weigand 
4155f613dfdSUlrich Weigand // Force static initialization.
4165f613dfdSUlrich Weigand extern "C" void LLVMInitializeSystemZAsmPrinter() {
4175f613dfdSUlrich Weigand   RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
4185f613dfdSUlrich Weigand }
419