blob: 026a75f21403eb2c0914c14ec0bfea06beda4e52 [file] [log] [blame]
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001//===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Streams SystemZ assembly language and associated data, in the form of
11// MCInsts and MCExprs respectively.
12//
13//===----------------------------------------------------------------------===//
14
15#include "SystemZAsmPrinter.h"
16#include "InstPrinter/SystemZInstPrinter.h"
17#include "SystemZConstantPoolValue.h"
18#include "SystemZMCInstLower.h"
19#include "llvm/CodeGen/MachineModuleInfoImpls.h"
20#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
Rafael Espindola894843c2014-01-07 21:19:40 +000021#include "llvm/IR/Mangler.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000022#include "llvm/MC/MCExpr.h"
Richard Sandiford9ab97cd2013-09-25 10:20:08 +000023#include "llvm/MC/MCInstBuilder.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000024#include "llvm/MC/MCStreamer.h"
25#include "llvm/Support/TargetRegistry.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000026
27using namespace llvm;
28
Richard Sandiford652784e2013-09-25 11:11:53 +000029// Return an RI instruction like MI with opcode Opcode, but with the
30// GR64 register operands turned into GR32s.
31static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
Richard Sandifordf03789c2013-11-22 17:28:28 +000032 if (MI->isCompare())
33 return MCInstBuilder(Opcode)
34 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
35 .addImm(MI->getOperand(1).getImm());
36 else
37 return MCInstBuilder(Opcode)
38 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
39 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
40 .addImm(MI->getOperand(2).getImm());
Richard Sandiford652784e2013-09-25 11:11:53 +000041}
42
Richard Sandiford0755c932013-10-01 11:26:28 +000043// Return an RI instruction like MI with opcode Opcode, but with the
Richard Sandiford1a569312013-10-01 13:18:56 +000044// GR64 register operands turned into GRH32s.
45static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
Richard Sandifordf03789c2013-11-22 17:28:28 +000046 if (MI->isCompare())
47 return MCInstBuilder(Opcode)
48 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
49 .addImm(MI->getOperand(1).getImm());
50 else
51 return MCInstBuilder(Opcode)
52 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
53 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
54 .addImm(MI->getOperand(2).getImm());
Richard Sandiford1a569312013-10-01 13:18:56 +000055}
56
57// Return an RI instruction like MI with opcode Opcode, but with the
Richard Sandiford0755c932013-10-01 11:26:28 +000058// R2 register turned into a GR64.
59static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
60 return MCInstBuilder(Opcode)
61 .addReg(MI->getOperand(0).getReg())
62 .addReg(MI->getOperand(1).getReg())
63 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
64 .addImm(MI->getOperand(3).getImm())
65 .addImm(MI->getOperand(4).getImm())
66 .addImm(MI->getOperand(5).getImm());
67}
68
Ulrich Weigand7db69182015-02-18 09:13:27 +000069static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
70 StringRef Name = "__tls_get_offset";
71 return MCSymbolRefExpr::Create(Context.GetOrCreateSymbol(Name),
72 MCSymbolRefExpr::VK_PLT,
73 Context);
74}
75
76static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
77 StringRef Name = "_GLOBAL_OFFSET_TABLE_";
78 return MCSymbolRefExpr::Create(Context.GetOrCreateSymbol(Name),
79 MCSymbolRefExpr::VK_None,
80 Context);
81}
82
Ulrich Weigand5f613df2013-05-06 16:15:19 +000083void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
Rafael Espindola69c1d632013-10-29 16:18:15 +000084 SystemZMCInstLower Lower(MF->getContext(), *this);
Ulrich Weigand5f613df2013-05-06 16:15:19 +000085 MCInst LoweredMI;
Richard Sandiford9ab97cd2013-09-25 10:20:08 +000086 switch (MI->getOpcode()) {
87 case SystemZ::Return:
88 LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
89 break;
90
Richard Sandifordf348f832013-09-25 10:37:17 +000091 case SystemZ::CallBRASL:
92 LoweredMI = MCInstBuilder(SystemZ::BRASL)
93 .addReg(SystemZ::R14D)
94 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
95 break;
96
97 case SystemZ::CallBASR:
98 LoweredMI = MCInstBuilder(SystemZ::BASR)
99 .addReg(SystemZ::R14D)
100 .addReg(MI->getOperand(0).getReg());
101 break;
102
103 case SystemZ::CallJG:
104 LoweredMI = MCInstBuilder(SystemZ::JG)
105 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
106 break;
107
108 case SystemZ::CallBR:
109 LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
110 break;
111
Ulrich Weigand7db69182015-02-18 09:13:27 +0000112 case SystemZ::TLS_GDCALL:
113 LoweredMI = MCInstBuilder(SystemZ::BRASL)
114 .addReg(SystemZ::R14D)
115 .addExpr(getTLSGetOffset(MF->getContext()))
116 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
117 break;
118
119 case SystemZ::TLS_LDCALL:
120 LoweredMI = MCInstBuilder(SystemZ::BRASL)
121 .addReg(SystemZ::R14D)
122 .addExpr(getTLSGetOffset(MF->getContext()))
123 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
124 break;
125
126 case SystemZ::GOT:
127 LoweredMI = MCInstBuilder(SystemZ::LARL)
128 .addReg(MI->getOperand(0).getReg())
129 .addExpr(getGlobalOffsetTable(MF->getContext()));
130 break;
131
Richard Sandiford652784e2013-09-25 11:11:53 +0000132 case SystemZ::IILF64:
133 LoweredMI = MCInstBuilder(SystemZ::IILF)
134 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
135 .addImm(MI->getOperand(2).getImm());
136 break;
137
Richard Sandiford01240232013-10-01 13:02:28 +0000138 case SystemZ::IIHF64:
139 LoweredMI = MCInstBuilder(SystemZ::IIHF)
140 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
141 .addImm(MI->getOperand(2).getImm());
142 break;
143
Richard Sandiford0755c932013-10-01 11:26:28 +0000144 case SystemZ::RISBHH:
145 case SystemZ::RISBHL:
146 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
147 break;
148
149 case SystemZ::RISBLH:
150 case SystemZ::RISBLL:
151 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
152 break;
153
Ulrich Weigandce4c1092015-05-05 19:25:42 +0000154 case SystemZ::VLVGP32:
155 LoweredMI = MCInstBuilder(SystemZ::VLVGP)
156 .addReg(MI->getOperand(0).getReg())
157 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
158 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
159 break;
160
Ulrich Weigand80b3af72015-05-05 19:27:45 +0000161 case SystemZ::LFER:
162 LoweredMI = MCInstBuilder(SystemZ::VLGVF)
163 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
164 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
165 .addReg(0).addImm(0);
166 break;
167
168 case SystemZ::LEFR:
169 LoweredMI = MCInstBuilder(SystemZ::VLVGF)
170 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
171 .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
172 .addReg(MI->getOperand(1).getReg())
173 .addReg(0).addImm(0);
174 break;
175
Richard Sandiford652784e2013-09-25 11:11:53 +0000176#define LOWER_LOW(NAME) \
177 case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
178
179 LOWER_LOW(IILL);
180 LOWER_LOW(IILH);
Richard Sandifordf03789c2013-11-22 17:28:28 +0000181 LOWER_LOW(TMLL);
182 LOWER_LOW(TMLH);
Richard Sandiford652784e2013-09-25 11:11:53 +0000183 LOWER_LOW(NILL);
184 LOWER_LOW(NILH);
185 LOWER_LOW(NILF);
186 LOWER_LOW(OILL);
187 LOWER_LOW(OILH);
188 LOWER_LOW(OILF);
189 LOWER_LOW(XILF);
190
191#undef LOWER_LOW
192
Richard Sandiford1a569312013-10-01 13:18:56 +0000193#define LOWER_HIGH(NAME) \
194 case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
195
196 LOWER_HIGH(IIHL);
197 LOWER_HIGH(IIHH);
Richard Sandifordf03789c2013-11-22 17:28:28 +0000198 LOWER_HIGH(TMHL);
199 LOWER_HIGH(TMHH);
Richard Sandiford70284282013-10-01 14:20:41 +0000200 LOWER_HIGH(NIHL);
201 LOWER_HIGH(NIHH);
202 LOWER_HIGH(NIHF);
Richard Sandiford6e96ac62013-10-01 13:22:41 +0000203 LOWER_HIGH(OIHL);
204 LOWER_HIGH(OIHH);
205 LOWER_HIGH(OIHF);
Richard Sandiford5718dac2013-10-01 14:08:44 +0000206 LOWER_HIGH(XIHF);
Richard Sandiford1a569312013-10-01 13:18:56 +0000207
208#undef LOWER_HIGH
209
Richard Sandiford9afe6132013-12-10 10:36:34 +0000210 case SystemZ::Serialize:
Eric Christopherd84f5d32015-02-19 01:26:28 +0000211 if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
Richard Sandiford9afe6132013-12-10 10:36:34 +0000212 LoweredMI = MCInstBuilder(SystemZ::AsmBCR)
213 .addImm(14).addReg(SystemZ::R0D);
214 else
215 LoweredMI = MCInstBuilder(SystemZ::AsmBCR)
216 .addImm(15).addReg(SystemZ::R0D);
217 break;
218
Richard Sandiford9ab97cd2013-09-25 10:20:08 +0000219 default:
Richard Sandifordf348f832013-09-25 10:37:17 +0000220 Lower.lower(MI, LoweredMI);
Richard Sandiford9ab97cd2013-09-25 10:20:08 +0000221 break;
222 }
Lang Hames9ff69c82015-04-24 19:11:51 +0000223 EmitToStreamer(*OutStreamer, LoweredMI);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000224}
225
226// Convert a SystemZ-specific constant pool modifier into the associated
227// MCSymbolRefExpr variant kind.
228static MCSymbolRefExpr::VariantKind
229getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
230 switch (Modifier) {
Ulrich Weigand7db69182015-02-18 09:13:27 +0000231 case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD;
232 case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM;
233 case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000234 case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
235 }
236 llvm_unreachable("Invalid SystemCPModifier!");
237}
238
239void SystemZAsmPrinter::
240EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
Richard Sandiford21f5d682014-03-06 11:22:58 +0000241 auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000242
243 const MCExpr *Expr =
Rafael Espindola79858aa2013-10-29 17:07:16 +0000244 MCSymbolRefExpr::Create(getSymbol(ZCPV->getGlobalValue()),
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000245 getModifierVariantKind(ZCPV->getModifier()),
246 OutContext);
Eric Christopher8b770652015-01-26 19:03:15 +0000247 uint64_t Size = TM.getDataLayout()->getTypeAllocSize(ZCPV->getType());
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000248
Lang Hames9ff69c82015-04-24 19:11:51 +0000249 OutStreamer->EmitValue(Expr, Size);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000250}
251
252bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
253 unsigned OpNo,
254 unsigned AsmVariant,
255 const char *ExtraCode,
256 raw_ostream &OS) {
257 if (ExtraCode && *ExtraCode == 'n') {
258 if (!MI->getOperand(OpNo).isImm())
259 return true;
260 OS << -int64_t(MI->getOperand(OpNo).getImm());
261 } else {
Rafael Espindola69c1d632013-10-29 16:18:15 +0000262 SystemZMCInstLower Lower(MF->getContext(), *this);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000263 MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
264 SystemZInstPrinter::printOperand(MO, OS);
265 }
266 return false;
267}
268
269bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
270 unsigned OpNo,
271 unsigned AsmVariant,
272 const char *ExtraCode,
273 raw_ostream &OS) {
274 SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
275 MI->getOperand(OpNo + 1).getImm(),
276 MI->getOperand(OpNo + 2).getReg(), OS);
277 return false;
278}
279
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000280// Force static initialization.
281extern "C" void LLVMInitializeSystemZAsmPrinter() {
282 RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
283}