LLVM  3.7.0
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 #include "Hexagon.h"
17 #include "HexagonAsmPrinter.h"
19 #include "HexagonSubtarget.h"
20 #include "HexagonTargetMachine.h"
24 #include "llvm/ADT/SmallString.h"
25 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/ADT/StringExtras.h"
33 #include "llvm/IR/Constants.h"
34 #include "llvm/IR/DataLayout.h"
35 #include "llvm/IR/DerivedTypes.h"
36 #include "llvm/IR/Mangler.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"
56 
57 using namespace llvm;
58 
59 #define DEBUG_TYPE "asm-printer"
60 
62  "hexagon-align-calls", cl::Hidden, cl::init(true),
63  cl::desc("Insert falign after call instruction for Hexagon target"));
64 
66  std::unique_ptr<MCStreamer> Streamer)
67  : AsmPrinter(TM, std::move(Streamer)), Subtarget(nullptr) {}
68 
69 void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
70  raw_ostream &O) {
71  const MachineOperand &MO = MI->getOperand(OpNo);
72 
73  switch (MO.getType()) {
74  default: llvm_unreachable ("<unknown operand type>");
77  return;
79  O << MO.getImm();
80  return;
82  MO.getMBB()->getSymbol()->print(O, MAI);
83  return;
85  GetCPISymbol(MO.getIndex())->print(O, MAI);
86  return;
88  // Computing the address of a global symbol, not calling it.
89  getSymbol(MO.getGlobal())->print(O, MAI);
90  printOffset(MO.getOffset(), O);
91  return;
92  }
93 }
94 
95 //
96 // isBlockOnlyReachableByFallthrough - We need to override this since the
97 // default AsmPrinter does not print labels for any basic block that
98 // is only reachable by a fall through. That works for all cases except
99 // for the case in which the basic block is reachable by a fall through but
100 // through an indirect from a jump table. In this case, the jump table
101 // will contain a label not defined by AsmPrinter.
102 //
105  if (MBB->hasAddressTaken()) {
106  return false;
107  }
109 }
110 
111 
112 /// PrintAsmOperand - Print out an operand for an inline asm expression.
113 ///
115  unsigned AsmVariant,
116  const char *ExtraCode,
117  raw_ostream &OS) {
118  // Does this asm operand have a single letter operand modifier?
119  if (ExtraCode && ExtraCode[0]) {
120  if (ExtraCode[1] != 0) return true; // Unknown modifier.
121 
122  switch (ExtraCode[0]) {
123  default:
124  // See if this is a generic print operand
125  return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS);
126  case 'c': // Don't print "$" before a global var name or constant.
127  // Hexagon never has a prefix.
128  printOperand(MI, OpNo, OS);
129  return false;
130  case 'L': // Write second word of DImode reference.
131  // Verify that this operand has two consecutive registers.
132  if (!MI->getOperand(OpNo).isReg() ||
133  OpNo+1 == MI->getNumOperands() ||
134  !MI->getOperand(OpNo+1).isReg())
135  return true;
136  ++OpNo; // Return the high-part.
137  break;
138  case 'I':
139  // Write 'i' if an integer constant, otherwise nothing. Used to print
140  // addi vs add, etc.
141  if (MI->getOperand(OpNo).isImm())
142  OS << "i";
143  return false;
144  }
145  }
146 
147  printOperand(MI, OpNo, OS);
148  return false;
149 }
150 
152  unsigned OpNo, unsigned AsmVariant,
153  const char *ExtraCode,
154  raw_ostream &O) {
155  if (ExtraCode && ExtraCode[0])
156  return true; // Unknown modifier.
157 
158  const MachineOperand &Base = MI->getOperand(OpNo);
159  const MachineOperand &Offset = MI->getOperand(OpNo+1);
160 
161  if (Base.isReg())
162  printOperand(MI, OpNo, O);
163  else
164  llvm_unreachable("Unimplemented");
165 
166  if (Offset.isImm()) {
167  if (Offset.getImm())
168  O << " + #" << Offset.getImm();
169  }
170  else
171  llvm_unreachable("Unimplemented");
172 
173  return false;
174 }
175 
176 
177 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
178 /// the current output stream.
179 ///
181  MCInst MCB;
184 
185  if (MI->isBundle()) {
186  const MachineBasicBlock* MBB = MI->getParent();
188  unsigned IgnoreCount = 0;
189 
190  for (++MII; MII != MBB->end() && MII->isInsideBundle(); ++MII) {
191  if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
192  MII->getOpcode() == TargetOpcode::IMPLICIT_DEF)
193  ++IgnoreCount;
194  else {
195  HexagonLowerToMC(MII, MCB, *this);
196  }
197  }
198  }
199  else {
200  HexagonLowerToMC(MI, MCB, *this);
202  }
203  // Examine the packet and try to find instructions that can be converted
204  // to compounds.
206  OutStreamer->getContext(), MCB);
207  // Examine the packet and convert pairs of instructions to duplex
208  // instructions when possible.
209  SmallVector<DuplexCandidate, 8> possibleDuplexes;
211  *Subtarget->getInstrInfo(), MCB);
212  HexagonMCShuffle(*Subtarget->getInstrInfo(), *Subtarget,
213  OutStreamer->getContext(), MCB, possibleDuplexes);
215 }
216 
219 }
const GlobalValue * getGlobal() const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:83
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:339
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:51
MachineBasicBlock * getMBB() const
void tryCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI)
tryCompound - Given a bundle check for compound insns when one is found update the contents fo the bu...
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, MCInst &MCI, HexagonAsmPrinter &AP)
MachineBasicBlock reference.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
bool isReg() const
isReg - Tests if this is a MO_Register operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:271
SmallVector< DuplexCandidate, 8 > getDuplexPossibilties(MCInstrInfo const &MCII, MCInst const &MCB)
int64_t getImm() const
HexagonAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
void EmitInstruction(const MachineInstr *MI) override
printMachineInstruction – Print out a single Hexagon MI in Darwin syntax to the current output stream...
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
static const char * getRegisterName(unsigned RegNo)
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:120
DBG_VALUE - a mapping of the llvm.dbg.value intrinsic.
Definition: TargetOpcodes.h:69
bool isBundle() const
Definition: MachineInstr.h:775
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
Definition: TargetOpcodes.h:52
Address of a global value.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:325
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:74
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant...
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:66
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
void printOffset(int64_t Offset, raw_ostream &OS) const
This is just convenient handler for printing offsets.
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...
int64_t getOffset() const
Return the offset from the symbol in this operand.
virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const
Return true if the basic block has exactly one predecessor and the control transfer mechanism between...
MCSymbol * getSymbol() const
getSymbol - Return the MCSymbol for this basic block.
void LLVMInitializeHexagonAsmPrinter()
void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
void setOpcode(unsigned Op)
Definition: MCInst.h:158
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS) override
PrintAsmOperand - Print out an operand for an inline asm expression.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
Module.h This file contains the declarations for the Module class.
bool HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &)
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:148
BUNDLE - This instruction represents an instruction bundle.
Definition: TargetOpcodes.h:91
Representation of each machine instruction.
Definition: MachineInstr.h:51
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
bool hasAddressTaken() const
hasAddressTaken - Test whether this block is potentially the target of an indirect branch...
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
unsigned getReg() const
getReg - Returns the register number.
const HexagonInstrInfo * getInstrInfo() const override
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
Primary interface to the complete machine description for the target machine.
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
virtual void print(raw_ostream &O, const Module *M) const
print - Print out the internal state of the pass.
Definition: Pass.cpp:111
bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const override
Return true if the basic block has exactly one predecessor and the control transfer mechanism between...
Address of indexed Constant in Constant Pool.
Target TheHexagonTarget
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117