LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HexagonAsmPrinter.cpp
Go to the documentation of this file.
1 //===-- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly --===//
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 file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to Hexagon assembly language. This printer is
12 // the output mechanism used by `llc'.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #define DEBUG_TYPE "asm-printer"
17 #include "Hexagon.h"
18 #include "HexagonAsmPrinter.h"
20 #include "HexagonTargetMachine.h"
21 #include "HexagonSubtarget.h"
24 #include "llvm/ADT/SmallString.h"
25 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/ADT/StringExtras.h"
28 #include "llvm/Assembly/Writer.h"
34 #include "llvm/IR/Constants.h"
35 #include "llvm/IR/DataLayout.h"
36 #include "llvm/IR/DerivedTypes.h"
37 #include "llvm/IR/Module.h"
38 #include "llvm/MC/MCAsmInfo.h"
39 #include "llvm/MC/MCContext.h"
40 #include "llvm/MC/MCExpr.h"
41 #include "llvm/MC/MCInst.h"
42 #include "llvm/MC/MCSection.h"
43 #include "llvm/MC/MCStreamer.h"
44 #include "llvm/MC/MCSymbol.h"
46 #include "llvm/Support/Compiler.h"
47 #include "llvm/Support/Debug.h"
48 #include "llvm/Support/Format.h"
52 #include "llvm/Target/Mangler.h"
57 
58 using namespace llvm;
59 
61  "hexagon-align-calls", cl::Hidden, cl::init(true),
62  cl::desc("Insert falign after call instruction for Hexagon target"));
63 
64 void HexagonAsmPrinter::EmitAlignment(unsigned NumBits,
65  const GlobalValue *GV) const {
66  // For basic block level alignment, use ".falign".
67  if (!GV) {
68  OutStreamer.EmitRawText(StringRef("\t.falign"));
69  return;
70  }
71 
72  AsmPrinter::EmitAlignment(NumBits, GV);
73 }
74 
75 void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
76  raw_ostream &O) {
77  const MachineOperand &MO = MI->getOperand(OpNo);
78 
79  switch (MO.getType()) {
80  default: llvm_unreachable ("<unknown operand type>");
83  return;
85  O << MO.getImm();
86  return;
88  O << *MO.getMBB()->getSymbol();
89  return;
91  O << *GetJTISymbol(MO.getIndex());
92  // FIXME: PIC relocation model.
93  return;
95  O << *GetCPISymbol(MO.getIndex());
96  return;
99  return;
101  // Computing the address of a global symbol, not calling it.
102  O << *getSymbol(MO.getGlobal());
103  printOffset(MO.getOffset(), O);
104  return;
105  }
106 }
107 
108 //
109 // isBlockOnlyReachableByFallthrough - We need to override this since the
110 // default AsmPrinter does not print labels for any basic block that
111 // is only reachable by a fall through. That works for all cases except
112 // for the case in which the basic block is reachable by a fall through but
113 // through an indirect from a jump table. In this case, the jump table
114 // will contain a label not defined by AsmPrinter.
115 //
118  if (MBB->hasAddressTaken()) {
119  return false;
120  }
122 }
123 
124 
125 /// PrintAsmOperand - Print out an operand for an inline asm expression.
126 ///
128  unsigned AsmVariant,
129  const char *ExtraCode,
130  raw_ostream &OS) {
131  // Does this asm operand have a single letter operand modifier?
132  if (ExtraCode && ExtraCode[0]) {
133  if (ExtraCode[1] != 0) return true; // Unknown modifier.
134 
135  switch (ExtraCode[0]) {
136  default:
137  // See if this is a generic print operand
138  return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS);
139  case 'c': // Don't print "$" before a global var name or constant.
140  // Hexagon never has a prefix.
141  printOperand(MI, OpNo, OS);
142  return false;
143  case 'L': // Write second word of DImode reference.
144  // Verify that this operand has two consecutive registers.
145  if (!MI->getOperand(OpNo).isReg() ||
146  OpNo+1 == MI->getNumOperands() ||
147  !MI->getOperand(OpNo+1).isReg())
148  return true;
149  ++OpNo; // Return the high-part.
150  break;
151  case 'I':
152  // Write 'i' if an integer constant, otherwise nothing. Used to print
153  // addi vs add, etc.
154  if (MI->getOperand(OpNo).isImm())
155  OS << "i";
156  return false;
157  }
158  }
159 
160  printOperand(MI, OpNo, OS);
161  return false;
162 }
163 
165  unsigned OpNo, unsigned AsmVariant,
166  const char *ExtraCode,
167  raw_ostream &O) {
168  if (ExtraCode && ExtraCode[0])
169  return true; // Unknown modifier.
170 
171  const MachineOperand &Base = MI->getOperand(OpNo);
172  const MachineOperand &Offset = MI->getOperand(OpNo+1);
173 
174  if (Base.isReg())
175  printOperand(MI, OpNo, O);
176  else
177  llvm_unreachable("Unimplemented");
178 
179  if (Offset.isImm()) {
180  if (Offset.getImm())
181  O << " + #" << Offset.getImm();
182  }
183  else
184  llvm_unreachable("Unimplemented");
185 
186  return false;
187 }
188 
190  unsigned OpNo,
191  raw_ostream &O) {
192  llvm_unreachable("Unimplemented");
193 }
194 
195 
196 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
197 /// the current output stream.
198 ///
200  if (MI->isBundle()) {
201  std::vector<const MachineInstr*> BundleMIs;
202 
203  const MachineBasicBlock *MBB = MI->getParent();
205  ++MII;
206  unsigned int IgnoreCount = 0;
207  while (MII != MBB->end() && MII->isInsideBundle()) {
208  const MachineInstr *MInst = MII;
209  if (MInst->getOpcode() == TargetOpcode::DBG_VALUE ||
211  IgnoreCount++;
212  ++MII;
213  continue;
214  }
215  //BundleMIs.push_back(&*MII);
216  BundleMIs.push_back(MInst);
217  ++MII;
218  }
219  unsigned Size = BundleMIs.size();
220  assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!");
221  for (unsigned Index = 0; Index < Size; Index++) {
222  HexagonMCInst MCI;
223  MCI.setPacketStart(Index == 0);
224  MCI.setPacketEnd(Index == (Size-1));
225 
226  HexagonLowerToMC(BundleMIs[Index], MCI, *this);
228  }
229  }
230  else {
231  HexagonMCInst MCI;
232  if (MI->getOpcode() == Hexagon::ENDLOOP0) {
233  MCI.setPacketStart(true);
234  MCI.setPacketEnd(true);
235  }
236  HexagonLowerToMC(MI, MCI, *this);
238  }
239 
240  return;
241 }
242 
243 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
244 /// Don't print things like \n or \0.
245 // static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
246 // for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
247 // Name != E; ++Name)
248 // if (isprint(*Name))
249 // OS << *Name;
250 // }
251 
252 
254  int OpNo, raw_ostream &O) {
255  const MachineOperand &MO1 = MI->getOperand(OpNo);
256  const MachineOperand &MO2 = MI->getOperand(OpNo+1);
257 
259  << " + #"
260  << MO2.getImm();
261 }
262 
263 
265  raw_ostream &O) {
266  const MachineOperand &MO = MI->getOperand(OpNo);
267  assert( (MO.getType() == MachineOperand::MO_GlobalAddress) &&
268  "Expecting global address");
269 
270  O << *getSymbol(MO.getGlobal());
271  if (MO.getOffset() != 0) {
272  O << " + ";
273  O << MO.getOffset();
274  }
275 }
276 
278  raw_ostream &O) {
279  const MachineOperand &MO = MI->getOperand(OpNo);
280  assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) &&
281  "Expecting jump table index");
282 
283  // Hexagon_TODO: Do we need name mangling?
284  O << *GetJTISymbol(MO.getIndex());
285 }
286 
288  raw_ostream &O) {
289  const MachineOperand &MO = MI->getOperand(OpNo);
290  assert( (MO.getType() == MachineOperand::MO_ConstantPoolIndex) &&
291  "Expecting constant pool index");
292 
293  // Hexagon_TODO: Do we need name mangling?
294  O << *GetCPISymbol(MO.getIndex());
295 }
296 
298  unsigned SyntaxVariant,
299  const MCAsmInfo &MAI,
300  const MCInstrInfo &MII,
301  const MCRegisterInfo &MRI,
302  const MCSubtargetInfo &STI) {
303  if (SyntaxVariant == 0)
304  return(new HexagonInstPrinter(MAI, MII, MRI));
305  else
306  return NULL;
307 }
308 
311 
314 }
const GlobalValue * getGlobal() const
bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const
virtual void EmitAlignment(unsigned NumBits, const GlobalValue *GV=0) const
void EmitRawText(const Twine &String)
Definition: MCStreamer.cpp:582
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:277
MachineBasicBlock * getMBB() const
static cl::opt< bool > AlignCalls("hexagon-align-calls", cl::Hidden, cl::init(true), cl::desc("Insert falign after call instruction for Hexagon target"))
void HexagonLowerToMC(const MachineInstr *MI, HexagonMCInst &MCI, HexagonAsmPrinter &AP)
virtual void EmitInstruction(const MCInst &Inst)=0
const char * getSymbolName() const
static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn)
const MCInstrInfo * MII
Definition: AsmPrinter.h:68
void printGlobalOperand(const MachineInstr *MI, int OpNo, raw_ostream &O)
Address of indexed Jump Table for switch.
unsigned getBundleSize() const
void setPacketEnd(bool Y)
Definition: HexagonMCInst.h:41
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
GetJTISymbol - Return the symbol for the specified jump table entry.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
unsigned getNumOperands() const
Definition: MachineInstr.h:265
void printJumpTable(const MachineInstr *MI, int OpNo, raw_ostream &O)
int getOpcode() const
Definition: MachineInstr.h:261
MCStreamer & OutStreamer
Definition: AsmPrinter.h:78
int64_t getImm() const
Address of indexed Constant in Constant Pool.
static const char * getRegisterName(unsigned RegNo)
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:119
bool isBundle() const
Definition: MachineInstr.h:666
void setPacketStart(bool Y)
Definition: HexagonMCInst.h:40
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:314
void printPredicateOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
const MCInstrInfo & MII
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
static MCInstPrinter * createHexagonMCInstPrinter(const Target &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI)
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
void printConstantPool(const MachineInstr *MI, int OpNo, raw_ostream &O)
void printOffset(int64_t Offset, raw_ostream &OS) const
printOffset - This is just convenient handler for printing offsets.
int64_t getOffset() const
virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const
MCSymbol * getSymbol() const
void LLVMInitializeHexagonAsmPrinter()
void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
MachineOperandType getType() const
virtual void EmitInstruction(const MachineInstr *MI)
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
Definition: TargetOpcodes.h:52
DBG_VALUE - a mapping of the llvm.dbg.value intrinsic.
Definition: TargetOpcodes.h:69
void EmitAlignment(unsigned NumBits, const GlobalValue *GV=0) const
MCSymbol * GetCPISymbol(unsigned CPID) const
GetCPISymbol - Return the symbol for the specified constant pool entry.
unsigned getReg() const
getReg - Returns the register number.
const MCRegisterInfo & MRI
Target TheHexagonTarget
void printAddrModeBasePlusOffset(const MachineInstr *MI, int OpNo, raw_ostream &O)
MCSymbol * GetExternalSymbolSymbol(StringRef Sym) const
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
MachineBasicBlock reference.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Address of a global value.
Name of external global symbol.