LLVM  3.7.0
HexagonInstPrinter.cpp
Go to the documentation of this file.
1 //===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===//
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 // This class prints an Hexagon MCInst to a .s file.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "HexagonAsmPrinter.h"
15 #include "Hexagon.h"
16 #include "HexagonInstPrinter.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "asm-printer"
27 
28 #define GET_INSTRUCTION_NAME
29 #include "HexagonGenAsmWriter.inc"
30 
32  : MCInstPrinter(*RawPrinter), RawPrinter(RawPrinter) {}
33 
35  StringRef Annot,
36  MCSubtargetInfo const &STI) {
37  assert(HexagonMCInstrInfo::isBundle(*MI));
39  std::string Buffer;
40  {
41  raw_string_ostream TempStream(Buffer);
42  RawPrinter->printInst(MI, TempStream, "", STI);
43  }
44  StringRef Contents(Buffer);
45  auto PacketBundle = Contents.rsplit('\n');
46  auto HeadTail = PacketBundle.first.split('\n');
47  auto Preamble = "\t{\n\t\t";
48  auto Separator = "";
49  while(!HeadTail.first.empty()) {
50  O << Separator;
51  StringRef Inst;
52  auto Duplex = HeadTail.first.split('\v');
53  if(!Duplex.second.empty()){
54  O << Duplex.first << "\n";
55  Inst = Duplex.second;
56  }
57  else
58  Inst = Duplex.first;
59  O << Preamble;
60  O << Inst;
61  HeadTail = HeadTail.second.split('\n');
62  Preamble = "";
63  Separator = "\n\t\t";
64  }
65  O << "\n\t}" << PacketBundle.second;
66 }
67 
68 void HexagonAsmInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
69  RawPrinter->printRegName(O, RegNo);
70 }
71 
72 // Return the minimum value that a constant extendable operand can have
73 // without being extended.
74 static int getMinValue(uint64_t TSFlags) {
75  unsigned isSigned =
77  unsigned bits =
79 
80  if (isSigned)
81  return -1U << (bits - 1);
82 
83  return 0;
84 }
85 
86 // Return the maximum value that a constant extendable operand can have
87 // without being extended.
88 static int getMaxValue(uint64_t TSFlags) {
89  unsigned isSigned =
91  unsigned bits =
93 
94  if (isSigned)
95  return ~(-1U << (bits - 1));
96 
97  return ~(-1U << bits);
98 }
99 
100 // Return true if the instruction must be extended.
101 static bool isExtended(uint64_t TSFlags) {
102  return (TSFlags >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
103 }
104 
105 // Currently just used in an assert statement
106 static bool isExtendable(uint64_t TSFlags) LLVM_ATTRIBUTE_UNUSED;
107 // Return true if the instruction may be extended based on the operand value.
108 static bool isExtendable(uint64_t TSFlags) {
110 }
111 
113  return MII.getName(Opcode);
114 }
115 
116 void HexagonInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
117  OS << getRegisterName(RegNo);
118 }
119 
120 void HexagonInstPrinter::setExtender(MCInst const &MCI) {
121  HasExtender = HexagonMCInstrInfo::isImmext(MCI);
122 }
123 
125  StringRef Annot,
126  MCSubtargetInfo const &STI) {
127  assert(HexagonMCInstrInfo::isBundle(*MI));
129  HasExtender = false;
130  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) {
131  MCInst const &MCI = *I.getInst();
132  if (HexagonMCInstrInfo::isDuplex(MII, MCI)) {
133  printInstruction(MCI.getOperand(1).getInst(), OS);
134  OS << '\v';
135  HasExtender = false;
136  printInstruction(MCI.getOperand(0).getInst(), OS);
137  } else
138  printInstruction(&MCI, OS);
139  setExtender(MCI);
140  OS << "\n";
141  }
142 
143  auto Separator = "";
145  OS << Separator;
146  Separator = " ";
147  MCInst ME;
148  ME.setOpcode(Hexagon::ENDLOOP0);
149  printInstruction(&ME, OS);
150  }
152  OS << Separator;
153  Separator = " ";
154  MCInst ME;
155  ME.setOpcode(Hexagon::ENDLOOP1);
156  printInstruction(&ME, OS);
157  }
158 }
159 
160 void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
161  raw_ostream &O) const {
162  const MCOperand& MO = MI->getOperand(OpNo);
163 
164  if (MO.isReg()) {
165  printRegName(O, MO.getReg());
166  } else if(MO.isExpr()) {
167  MO.getExpr()->print(O, &MAI);
168  } else if(MO.isImm()) {
169  printImmOperand(MI, OpNo, O);
170  } else {
171  llvm_unreachable("Unknown operand");
172  }
173 }
174 
175 void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
176  raw_ostream &O) const {
177  const MCOperand& MO = MI->getOperand(OpNo);
178 
179  if(MO.isExpr()) {
180  MO.getExpr()->print(O, &MAI);
181  } else if(MO.isImm()) {
182  O << MI->getOperand(OpNo).getImm();
183  } else {
184  llvm_unreachable("Unknown operand");
185  }
186 }
187 
188 void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
189  raw_ostream &O) const {
190  const MCOperand &MO = MI->getOperand(OpNo);
191  const MCInstrDesc &MII = getMII().get(MI->getOpcode());
192 
193  assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
194  "Expecting an extendable operand");
195 
196  if (MO.isExpr() || isExtended(MII.TSFlags)) {
197  O << "#";
198  } else if (MO.isImm()) {
199  int ImmValue = MO.getImm();
200  if (ImmValue < getMinValue(MII.TSFlags) ||
201  ImmValue > getMaxValue(MII.TSFlags))
202  O << "#";
203  }
204  printOperand(MI, OpNo, O);
205 }
206 
208  unsigned OpNo, raw_ostream &O) const {
209  O << MI->getOperand(OpNo).getImm();
210 }
211 
213  raw_ostream &O) const {
214  O << -MI->getOperand(OpNo).getImm();
215 }
216 
218  raw_ostream &O) const {
219  O << -1;
220 }
221 
223  raw_ostream &O) const {
224  const MCOperand& MO0 = MI->getOperand(OpNo);
225  const MCOperand& MO1 = MI->getOperand(OpNo + 1);
226 
227  printRegName(O, MO0.getReg());
228  O << " + #" << MO1.getImm();
229 }
230 
232  raw_ostream &O) const {
233  const MCOperand& MO0 = MI->getOperand(OpNo);
234  const MCOperand& MO1 = MI->getOperand(OpNo + 1);
235 
236  printRegName(O, MO0.getReg());
237  O << ", #" << MO1.getImm();
238 }
239 
241  raw_ostream &O) const {
242  assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
243 
244  printOperand(MI, OpNo, O);
245 }
246 
247 void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo,
248  raw_ostream &O) const {
249  assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
250 
251  printOperand(MI, OpNo, O);
252 }
253 
255  raw_ostream &O) const {
256  assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
257 
258  printOperand(MI, OpNo, O);
259 }
260 
262  raw_ostream &O) const {
263  // Branches can take an immediate operand. This is used by the branch
264  // selection pass to print $+8, an eight byte displacement from the PC.
265  llvm_unreachable("Unknown branch operand.");
266 }
267 
268 void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo,
269  raw_ostream &O) const {
270 }
271 
273  raw_ostream &O) const {
274 }
275 
277  raw_ostream &O) const {
278 }
279 
280 void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo,
281  raw_ostream &O, bool hi) const {
282  assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand");
283 
284  O << '#' << (hi ? "HI" : "LO") << "(#";
285  printOperand(MI, OpNo, O);
286  O << ')';
287 }
288 
289 void HexagonInstPrinter::printExtBrtarget(const MCInst *MI, unsigned OpNo,
290  raw_ostream &O) const {
291  const MCOperand &MO = MI->getOperand(OpNo);
292  const MCInstrDesc &MII = getMII().get(MI->getOpcode());
293 
294  assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
295  "Expecting an extendable operand");
296 
297  if (MO.isExpr() || isExtended(MII.TSFlags)) {
298  O << "##";
299  }
300  printOperand(MI, OpNo, O);
301 }
void printFrameIndexOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
bool isDuplex(MCInstrInfo const &MCII, MCInst const &MCI)
void printUnsignedImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
void printSymbol(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool hi) const
const MCInstrInfo & getMII() const
bool isReg() const
Definition: MCInst.h:56
void printJumpTable(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
std::unique_ptr< MCInstPrinter > RawPrinter
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:138
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:450
static bool isExtendable(uint64_t TSFlags) LLVM_ATTRIBUTE_UNUSED
bool isBundle(MCInst const &MCI)
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
static int getMaxValue(uint64_t TSFlags)
void printNOneImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
bool isOuterLoop(MCInst const &MCI)
static bool isExtended(uint64_t TSFlags)
std::pair< StringRef, StringRef > rsplit(char Separator) const
Split into two substrings around the last occurrence of a separator character.
Definition: StringRef.h:502
void printInst(MCInst const *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) override
Print the specified MCInst to the specified raw_ostream.
bool isImmext(MCInst const &MCI)
void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
#define HEXAGON_PACKET_SIZE
Definition: Hexagon.h:33
void printConstantPool(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:63
void printMEMriOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
void printInst(MCInst const *MI, raw_ostream &O, StringRef Annot, MCSubtargetInfo const &STI) override
Print the specified MCInst to the specified raw_ostream.
void printExtOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
static const char * getRegisterName(unsigned RegNo)
bool isImm() const
Definition: MCInst.h:57
const MCExpr * getExpr() const
Definition: MCInst.h:93
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
Definition: MCExpr.cpp:33
HexagonAsmInstPrinter(MCInstPrinter *RawPrinter)
void printNegImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
const char * getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Definition: MCInstrInfo.h:51
void printRegName(raw_ostream &O, unsigned RegNo) const override
Print the assembler register name.
bool isExpr() const
Definition: MCInst.h:59
void printAbsAddrOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:142
iterator_range< MCInst::const_iterator > bundleInstructions(MCInst const &MCI)
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
static int getMinValue(uint64_t TSFlags)
void printImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
void setOpcode(unsigned Op)
Definition: MCInst.h:158
unsigned getOpcode() const
Definition: MCInst.h:159
int64_t getImm() const
Definition: MCInst.h:74
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:44
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:38
#define I(x, y, z)
Definition: MD5.cpp:54
MCSubtargetInfo - Generic base class for all target subtargets.
const MCInst * getInst() const
Definition: MCInst.h:102
size_t bundleSize(MCInst const &MCI)
void printCallOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
virtual StringRef getOpcodeName(unsigned Opcode) const
bool isInnerLoop(MCInst const &MCI)
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:465
void printInstruction(const MCInst *MI, raw_ostream &O)
void printExtBrtarget(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
void printPredicateOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
void printRegName(raw_ostream &OS, unsigned RegNo) const override
Print the assembler register name.
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
void printGlobalOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164