LLVM  3.7.0
AMDGPUMCInstLower.cpp
Go to the documentation of this file.
1 //===- AMDGPUMCInstLower.cpp - Lower AMDGPU MachineInstr to an MCInst -----===//
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 /// \file
11 /// \brief Code to lower AMDGPU MachineInstrs to their corresponding MCInst.
12 //
13 //===----------------------------------------------------------------------===//
14 //
15 
16 #include "AMDGPUMCInstLower.h"
17 #include "AMDGPUAsmPrinter.h"
18 #include "AMDGPUTargetMachine.h"
20 #include "R600InstrInfo.h"
21 #include "SIInstrInfo.h"
24 #include "llvm/IR/Constants.h"
25 #include "llvm/IR/Function.h"
26 #include "llvm/IR/GlobalVariable.h"
27 #include "llvm/MC/MCCodeEmitter.h"
28 #include "llvm/MC/MCContext.h"
29 #include "llvm/MC/MCExpr.h"
30 #include "llvm/MC/MCInst.h"
32 #include "llvm/MC/MCStreamer.h"
34 #include "llvm/Support/Format.h"
35 #include <algorithm>
36 
37 using namespace llvm;
38 
40  Ctx(ctx), ST(st)
41 { }
42 
43 void AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
44 
45  int MCOpcode = ST.getInstrInfo()->pseudoToMCOpcode(MI->getOpcode());
46 
47  if (MCOpcode == -1) {
49  C.emitError("AMDGPUMCInstLower::lower - Pseudo instruction doesn't have "
50  "a target-specific version: " + Twine(MI->getOpcode()));
51  }
52 
53  OutMI.setOpcode(MCOpcode);
54 
55  for (const MachineOperand &MO : MI->explicit_operands()) {
56  MCOperand MCOp;
57  switch (MO.getType()) {
58  default:
59  llvm_unreachable("unknown operand type");
61  MCOp = MCOperand::createImm(MO.getImm());
62  break;
64  MCOp = MCOperand::createReg(MO.getReg());
65  break;
68  MO.getMBB()->getSymbol(), Ctx));
69  break;
71  const GlobalValue *GV = MO.getGlobal();
72  MCSymbol *Sym = Ctx.getOrCreateSymbol(StringRef(GV->getName()));
74  break;
75  }
77  assert(MO.getIndex() == AMDGPU::TI_CONSTDATA_START);
79  const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
80  MCOp = MCOperand::createExpr(Expr);
81  break;
82  }
84  MCSymbol *Sym = Ctx.getOrCreateSymbol(StringRef(MO.getSymbolName()));
85  const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
86  MCOp = MCOperand::createExpr(Expr);
87  break;
88  }
89  }
90  OutMI.addOperand(MCOp);
91  }
92 }
93 
96  AMDGPUMCInstLower MCInstLowering(OutContext, STI);
97 
98 #ifdef _DEBUG
99  StringRef Err;
100  if (!STI.getInstrInfo()->verifyInstruction(MI, Err)) {
101  errs() << "Warning: Illegal instruction detected: " << Err << "\n";
102  MI->dump();
103  }
104 #endif
105  if (MI->isBundle()) {
106  const MachineBasicBlock *MBB = MI->getParent();
108  ++I;
109  while (I != MBB->end() && I->isInsideBundle()) {
110  EmitInstruction(I);
111  ++I;
112  }
113  } else {
114  MCInst TmpInst;
115  MCInstLowering.lower(MI, TmpInst);
116  EmitToStreamer(*OutStreamer, TmpInst);
117 
118  if (STI.dumpCode()) {
119  // Disassemble instruction/operands to text.
120  DisasmLines.resize(DisasmLines.size() + 1);
121  std::string &DisasmLine = DisasmLines.back();
122  raw_string_ostream DisasmStream(DisasmLine);
123 
124  AMDGPUInstPrinter InstPrinter(*TM.getMCAsmInfo(),
127  InstPrinter.printInst(&TmpInst, DisasmStream, StringRef(),
128  MF->getSubtarget());
129 
130  // Disassemble instruction/operands to hex representation.
132  SmallVector<char, 16> CodeBytes;
133  raw_svector_ostream CodeStream(CodeBytes);
134 
135  auto &ObjStreamer = static_cast<MCObjectStreamer&>(*OutStreamer);
136  MCCodeEmitter &InstEmitter = ObjStreamer.getAssembler().getEmitter();
137  InstEmitter.encodeInstruction(TmpInst, CodeStream, Fixups,
139  CodeStream.flush();
140 
141  HexLines.resize(HexLines.size() + 1);
142  std::string &HexLine = HexLines.back();
143  raw_string_ostream HexStream(HexLine);
144 
145  for (size_t i = 0; i < CodeBytes.size(); i += 4) {
146  unsigned int CodeDWord = *(unsigned int *)&CodeBytes[i];
147  HexStream << format("%s%08X", (i > 0 ? " " : ""), CodeDWord);
148  }
149 
150  DisasmStream.flush();
151  DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLine.size());
152  }
153  }
154 }
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:223
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:83
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:315
Interface definition for R600InstrInfo.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
iterator_range< mop_iterator > explicit_operands()
Definition: MachineInstr.h:301
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:78
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:129
#define END_OF_TEXT_LABEL_NAME
Definition: AMDGPU.h:88
const MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:86
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:488
MachineBasicBlock reference.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
int pseudoToMCOpcode(int Opcode) const
Return a target-specific opcode if Opcode is a pseudo instruction.
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:188
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
Target-dependent index+offset operand.
virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
Name of external global symbol.
const AMDGPUInstrInfo * getInstrInfo() const override
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:159
AMDGPUMCInstLower(MCContext &ctx, const AMDGPUSubtarget &ST)
Context object for machine code objects.
Definition: MCContext.h:48
void emitError(unsigned LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
void EmitInstruction(const MachineInstr *MI) override
Implemented in AMDGPUMCInstLower.cpp.
Streaming object file generation interface.
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
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:120
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:111
bool isBundle() const
Definition: MachineInstr.h:775
Address of a global value.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:41
This file contains the declarations for the subclasses of Constant, which represent the different fla...
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:23
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:70
The AMDGPU TargetMachine interface definition for hw codgen targets.
std::vector< std::string > HexLines
void setOpcode(unsigned Op)
Definition: MCInst.h:158
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
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:148
void dump() const
std::vector< std::string > DisasmLines
Representation of each machine instruction.
Definition: MachineInstr.h:51
void lower(const MachineInstr *MI, MCInst &OutMI) const
Lower a MachineInstr to an MCInst.
Interface definition for SIInstrInfo.
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:111
#define I(x, y, z)
Definition: MD5.cpp:54
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) override
Print the specified MCInst to the specified raw_ostream.
AMDGPU Assembly printer class.
MCSubtargetInfo - Generic base class for all target subtargets.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:465
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
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
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117