LLVM  3.7.0
SystemZAsmPrinter.cpp
Go to the documentation of this file.
1 //===-- 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"
18 #include "SystemZMCInstLower.h"
21 #include "llvm/IR/Mangler.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInstBuilder.h"
24 #include "llvm/MC/MCStreamer.h"
26 
27 using namespace llvm;
28 
29 // Return an RI instruction like MI with opcode Opcode, but with the
30 // GR64 register operands turned into GR32s.
31 static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
32  if (MI->isCompare())
33  return MCInstBuilder(Opcode)
35  .addImm(MI->getOperand(1).getImm());
36  else
37  return MCInstBuilder(Opcode)
40  .addImm(MI->getOperand(2).getImm());
41 }
42 
43 // Return an RI instruction like MI with opcode Opcode, but with the
44 // GR64 register operands turned into GRH32s.
45 static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
46  if (MI->isCompare())
47  return MCInstBuilder(Opcode)
49  .addImm(MI->getOperand(1).getImm());
50  else
51  return MCInstBuilder(Opcode)
54  .addImm(MI->getOperand(2).getImm());
55 }
56 
57 // Return an RI instruction like MI with opcode Opcode, but with the
58 // R2 register turned into a GR64.
59 static 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 
69 static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
70  StringRef Name = "__tls_get_offset";
71  return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
73  Context);
74 }
75 
77  StringRef Name = "_GLOBAL_OFFSET_TABLE_";
78  return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
80  Context);
81 }
82 
83 // MI loads the high part of a vector from memory. Return an instruction
84 // that uses replicating vector load Opcode to do the same thing.
85 static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
86  return MCInstBuilder(Opcode)
88  .addReg(MI->getOperand(1).getReg())
89  .addImm(MI->getOperand(2).getImm())
90  .addReg(MI->getOperand(3).getReg());
91 }
92 
93 // MI stores the high part of a vector to memory. Return an instruction
94 // that uses elemental vector store Opcode to do the same thing.
95 static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
96  return MCInstBuilder(Opcode)
98  .addReg(MI->getOperand(1).getReg())
99  .addImm(MI->getOperand(2).getImm())
100  .addReg(MI->getOperand(3).getReg())
101  .addImm(0);
102 }
103 
105  SystemZMCInstLower Lower(MF->getContext(), *this);
106  MCInst LoweredMI;
107  switch (MI->getOpcode()) {
108  case SystemZ::Return:
109  LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
110  break;
111 
112  case SystemZ::CallBRASL:
113  LoweredMI = MCInstBuilder(SystemZ::BRASL)
114  .addReg(SystemZ::R14D)
115  .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
116  break;
117 
118  case SystemZ::CallBASR:
119  LoweredMI = MCInstBuilder(SystemZ::BASR)
120  .addReg(SystemZ::R14D)
121  .addReg(MI->getOperand(0).getReg());
122  break;
123 
124  case SystemZ::CallJG:
125  LoweredMI = MCInstBuilder(SystemZ::JG)
126  .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
127  break;
128 
129  case SystemZ::CallBR:
130  LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
131  break;
132 
133  case SystemZ::TLS_GDCALL:
134  LoweredMI = MCInstBuilder(SystemZ::BRASL)
135  .addReg(SystemZ::R14D)
137  .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
138  break;
139 
140  case SystemZ::TLS_LDCALL:
141  LoweredMI = MCInstBuilder(SystemZ::BRASL)
142  .addReg(SystemZ::R14D)
144  .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
145  break;
146 
147  case SystemZ::GOT:
148  LoweredMI = MCInstBuilder(SystemZ::LARL)
149  .addReg(MI->getOperand(0).getReg())
150  .addExpr(getGlobalOffsetTable(MF->getContext()));
151  break;
152 
153  case SystemZ::IILF64:
154  LoweredMI = MCInstBuilder(SystemZ::IILF)
156  .addImm(MI->getOperand(2).getImm());
157  break;
158 
159  case SystemZ::IIHF64:
160  LoweredMI = MCInstBuilder(SystemZ::IIHF)
162  .addImm(MI->getOperand(2).getImm());
163  break;
164 
165  case SystemZ::RISBHH:
166  case SystemZ::RISBHL:
167  LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
168  break;
169 
170  case SystemZ::RISBLH:
171  case SystemZ::RISBLL:
172  LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
173  break;
174 
175  case SystemZ::VLVGP32:
176  LoweredMI = MCInstBuilder(SystemZ::VLVGP)
177  .addReg(MI->getOperand(0).getReg())
178  .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
180  break;
181 
182  case SystemZ::VLR32:
183  case SystemZ::VLR64:
184  LoweredMI = MCInstBuilder(SystemZ::VLR)
187  break;
188 
189  case SystemZ::VL32:
190  LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
191  break;
192 
193  case SystemZ::VL64:
194  LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
195  break;
196 
197  case SystemZ::VST32:
198  LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
199  break;
200 
201  case SystemZ::VST64:
202  LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
203  break;
204 
205  case SystemZ::LFER:
206  LoweredMI = MCInstBuilder(SystemZ::VLGVF)
209  .addReg(0).addImm(0);
210  break;
211 
212  case SystemZ::LEFR:
213  LoweredMI = MCInstBuilder(SystemZ::VLVGF)
216  .addReg(MI->getOperand(1).getReg())
217  .addReg(0).addImm(0);
218  break;
219 
220 #define LOWER_LOW(NAME) \
221  case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
222 
223  LOWER_LOW(IILL);
224  LOWER_LOW(IILH);
225  LOWER_LOW(TMLL);
226  LOWER_LOW(TMLH);
227  LOWER_LOW(NILL);
228  LOWER_LOW(NILH);
229  LOWER_LOW(NILF);
230  LOWER_LOW(OILL);
231  LOWER_LOW(OILH);
232  LOWER_LOW(OILF);
233  LOWER_LOW(XILF);
234 
235 #undef LOWER_LOW
236 
237 #define LOWER_HIGH(NAME) \
238  case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
239 
240  LOWER_HIGH(IIHL);
241  LOWER_HIGH(IIHH);
242  LOWER_HIGH(TMHL);
243  LOWER_HIGH(TMHH);
244  LOWER_HIGH(NIHL);
245  LOWER_HIGH(NIHH);
246  LOWER_HIGH(NIHF);
247  LOWER_HIGH(OIHL);
248  LOWER_HIGH(OIHH);
249  LOWER_HIGH(OIHF);
250  LOWER_HIGH(XIHF);
251 
252 #undef LOWER_HIGH
253 
254  case SystemZ::Serialize:
256  LoweredMI = MCInstBuilder(SystemZ::AsmBCR)
257  .addImm(14).addReg(SystemZ::R0D);
258  else
259  LoweredMI = MCInstBuilder(SystemZ::AsmBCR)
260  .addImm(15).addReg(SystemZ::R0D);
261  break;
262 
263  default:
264  Lower.lower(MI, LoweredMI);
265  break;
266  }
267  EmitToStreamer(*OutStreamer, LoweredMI);
268 }
269 
270 // Convert a SystemZ-specific constant pool modifier into the associated
271 // MCSymbolRefExpr variant kind.
274  switch (Modifier) {
279  }
280  llvm_unreachable("Invalid SystemCPModifier!");
281 }
282 
285  auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
286 
287  const MCExpr *Expr =
288  MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
289  getModifierVariantKind(ZCPV->getModifier()),
290  OutContext);
291  uint64_t Size = TM.getDataLayout()->getTypeAllocSize(ZCPV->getType());
292 
293  OutStreamer->EmitValue(Expr, Size);
294 }
295 
297  unsigned OpNo,
298  unsigned AsmVariant,
299  const char *ExtraCode,
300  raw_ostream &OS) {
301  if (ExtraCode && *ExtraCode == 'n') {
302  if (!MI->getOperand(OpNo).isImm())
303  return true;
304  OS << -int64_t(MI->getOperand(OpNo).getImm());
305  } else {
306  SystemZMCInstLower Lower(MF->getContext(), *this);
307  MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
309  }
310  return false;
311 }
312 
314  unsigned OpNo,
315  unsigned AsmVariant,
316  const char *ExtraCode,
317  raw_ostream &OS) {
319  MI->getOperand(OpNo + 1).getImm(),
320  MI->getOperand(OpNo + 2).getReg(), OS);
321  return false;
322 }
323 
324 // Force static initialization.
327 }
#define LOWER_LOW(NAME)
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:83
static void printAddress(unsigned Base, int64_t Disp, unsigned Index, raw_ostream &O)
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:339
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:315
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:78
void LLVMInitializeSystemZAsmPrinter()
const MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:86
bool hasFastSerialization() const
Target TheSystemZTarget
static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
unsigned getRegAsGRH32(unsigned Reg)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
unsigned getRegAsGR32(unsigned Reg)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:33
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:159
void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override
Context object for machine code objects.
Definition: MCContext.h:48
int64_t getImm() const
MCContext & getContext() const
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Definition: MCInstBuilder.h:50
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:267
static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode)
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
Definition: MCInstBuilder.h:32
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:533
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:74
static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:70
static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:38
Abstract base class for all machine specific constantpool value subclasses.
static const MCSymbolRefExpr * getTLSGetOffset(MCContext &Context)
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant...
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:388
const DataLayout * getDataLayout() const
Deprecated in 3.7, will be removed in 3.8.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:148
static MCSymbolRefExpr::VariantKind getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier)
unsigned getRegAsGR64(unsigned Reg)
unsigned getRegAsVR128(unsigned Reg)
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
Definition: MachineInstr.h:464
static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode)
Representation of each machine instruction.
Definition: MachineInstr.h:51
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:111
void EmitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
static const MCSymbolRefExpr * getGlobalOffsetTable(MCContext &Context)
unsigned getReg() const
getReg - Returns the register number.
static void printOperand(const MCOperand &MO, const MCAsmInfo *MAI, raw_ostream &O)
#define LOWER_HIGH(NAME)
RegisterAsmPrinter - Helper template for registering a target specific assembly printer, for use in the target machine initialization function.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
A SystemZ-specific constant pool value.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33