LLVM  9.0.0svn
SystemZInstPrinter.cpp
Go to the documentation of this file.
1 //===- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax -===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "SystemZInstPrinter.h"
10 #include "llvm/MC/MCExpr.h"
11 #include "llvm/MC/MCInst.h"
12 #include "llvm/MC/MCSymbol.h"
13 #include "llvm/Support/Casting.h"
17 #include <cassert>
18 #include <cstdint>
19 
20 using namespace llvm;
21 
22 #define DEBUG_TYPE "asm-printer"
23 
24 #include "SystemZGenAsmWriter.inc"
25 
26 void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp,
27  unsigned Index, raw_ostream &O) {
28  O << Disp;
29  if (Base || Index) {
30  O << '(';
31  if (Index) {
32  O << '%' << getRegisterName(Index);
33  if (Base)
34  O << ',';
35  }
36  if (Base)
37  O << '%' << getRegisterName(Base);
38  O << ')';
39  }
40 }
41 
43  raw_ostream &O) {
44  if (MO.isReg())
45  O << '%' << getRegisterName(MO.getReg());
46  else if (MO.isImm())
47  O << MO.getImm();
48  else if (MO.isExpr())
49  MO.getExpr()->print(O, MAI);
50  else
51  llvm_unreachable("Invalid operand");
52 }
53 
55  StringRef Annot,
56  const MCSubtargetInfo &STI) {
57  printInstruction(MI, O);
58  printAnnotation(O, Annot);
59 }
60 
61 void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
62  O << '%' << getRegisterName(RegNo);
63 }
64 
65 template <unsigned N>
66 static void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
67  int64_t Value = MI->getOperand(OpNum).getImm();
68  assert(isUInt<N>(Value) && "Invalid uimm argument");
69  O << Value;
70 }
71 
72 template <unsigned N>
73 static void printSImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
74  int64_t Value = MI->getOperand(OpNum).getImm();
75  assert(isInt<N>(Value) && "Invalid simm argument");
76  O << Value;
77 }
78 
79 void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
80  raw_ostream &O) {
81  printUImmOperand<1>(MI, OpNum, O);
82 }
83 
84 void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
85  raw_ostream &O) {
86  printUImmOperand<2>(MI, OpNum, O);
87 }
88 
89 void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
90  raw_ostream &O) {
91  printUImmOperand<3>(MI, OpNum, O);
92 }
93 
94 void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
95  raw_ostream &O) {
96  printUImmOperand<4>(MI, OpNum, O);
97 }
98 
99 void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
100  raw_ostream &O) {
101  printUImmOperand<6>(MI, OpNum, O);
102 }
103 
104 void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
105  raw_ostream &O) {
106  printSImmOperand<8>(MI, OpNum, O);
107 }
108 
109 void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
110  raw_ostream &O) {
111  printUImmOperand<8>(MI, OpNum, O);
112 }
113 
114 void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
115  raw_ostream &O) {
116  printUImmOperand<12>(MI, OpNum, O);
117 }
118 
119 void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
120  raw_ostream &O) {
121  printSImmOperand<16>(MI, OpNum, O);
122 }
123 
124 void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
125  raw_ostream &O) {
126  printUImmOperand<16>(MI, OpNum, O);
127 }
128 
129 void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
130  raw_ostream &O) {
131  printSImmOperand<32>(MI, OpNum, O);
132 }
133 
134 void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
135  raw_ostream &O) {
136  printUImmOperand<32>(MI, OpNum, O);
137 }
138 
139 void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum,
140  raw_ostream &O) {
141  printUImmOperand<48>(MI, OpNum, O);
142 }
143 
144 void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
145  raw_ostream &O) {
146  const MCOperand &MO = MI->getOperand(OpNum);
147  if (MO.isImm()) {
148  O << "0x";
149  O.write_hex(MO.getImm());
150  } else
151  MO.getExpr()->print(O, &MAI);
152 }
153 
154 void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum,
155  raw_ostream &O) {
156  // Output the PC-relative operand.
157  printPCRelOperand(MI, OpNum, O);
158 
159  // Output the TLS marker if present.
160  if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
161  const MCOperand &MO = MI->getOperand(OpNum + 1);
162  const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());
163  switch (refExp.getKind()) {
165  O << ":tls_gdcall:";
166  break;
168  O << ":tls_ldcall:";
169  break;
170  default:
171  llvm_unreachable("Unexpected symbol kind");
172  }
173  O << refExp.getSymbol().getName();
174  }
175 }
176 
177 void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
178  raw_ostream &O) {
179  printOperand(MI->getOperand(OpNum), &MAI, O);
180 }
181 
182 void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
183  raw_ostream &O) {
184  printAddress(MI->getOperand(OpNum).getReg(),
185  MI->getOperand(OpNum + 1).getImm(), 0, O);
186 }
187 
188 void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
189  raw_ostream &O) {
190  printAddress(MI->getOperand(OpNum).getReg(),
191  MI->getOperand(OpNum + 1).getImm(),
192  MI->getOperand(OpNum + 2).getReg(), O);
193 }
194 
195 void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
196  raw_ostream &O) {
197  unsigned Base = MI->getOperand(OpNum).getReg();
198  uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
199  uint64_t Length = MI->getOperand(OpNum + 2).getImm();
200  O << Disp << '(' << Length;
201  if (Base)
202  O << ",%" << getRegisterName(Base);
203  O << ')';
204 }
205 
206 void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
207  raw_ostream &O) {
208  unsigned Base = MI->getOperand(OpNum).getReg();
209  uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
210  unsigned Length = MI->getOperand(OpNum + 2).getReg();
211  O << Disp << "(%" << getRegisterName(Length);
212  if (Base)
213  O << ",%" << getRegisterName(Base);
214  O << ')';
215 }
216 
217 void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
218  raw_ostream &O) {
219  printAddress(MI->getOperand(OpNum).getReg(),
220  MI->getOperand(OpNum + 1).getImm(),
221  MI->getOperand(OpNum + 2).getReg(), O);
222 }
223 
224 void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
225  raw_ostream &O) {
226  static const char *const CondNames[] = {
227  "o", "h", "nle", "l", "nhe", "lh", "ne",
228  "e", "nlh", "he", "nl", "le", "nh", "no"
229  };
230  uint64_t Imm = MI->getOperand(OpNum).getImm();
231  assert(Imm > 0 && Imm < 15 && "Invalid condition");
232  O << CondNames[Imm - 1];
233 }
bool isImm() const
Definition: MCInst.h:58
void printInstruction(const MCInst *MI, raw_ostream &O)
static void printAddress(unsigned Base, int64_t Disp, unsigned Index, raw_ostream &O)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
VariantKind getKind() const
Definition: MCExpr.h:338
bool isReg() const
Definition: MCInst.h:57
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:165
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:64
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
const MCExpr * getExpr() const
Definition: MCInst.h:95
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
int64_t getImm() const
Definition: MCInst.h:75
static const char * getRegisterName(unsigned RegNo)
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
bool isExpr() const
Definition: MCInst.h:60
static void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
unsigned getNumOperands() const
Definition: MCInst.h:181
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCSymbol & getSymbol() const
Definition: MCExpr.h:336
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:179
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:45
static void printSImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
Generic base class for all target subtargets.
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) override
Print the specified MCInst to the specified raw_ostream.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:203
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void printOperand(const MCOperand &MO, const MCAsmInfo *MAI, raw_ostream &O)
LLVM Value Representation.
Definition: Value.h:72
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
void printRegName(raw_ostream &O, unsigned RegNo) const override
Print the assembler register name.
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34