]>
git.proxmox.com Git - rustc.git/blob - src/llvm/lib/Target/R600/AMDGPUMCInstLower.cpp
1 //===- AMDGPUMCInstLower.cpp - Lower AMDGPU MachineInstr to an MCInst -----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief Code to lower AMDGPU MachineInstrs to their corresponding MCInst.
13 //===----------------------------------------------------------------------===//
16 #include "AMDGPUMCInstLower.h"
17 #include "AMDGPUAsmPrinter.h"
18 #include "AMDGPUTargetMachine.h"
19 #include "InstPrinter/AMDGPUInstPrinter.h"
20 #include "R600InstrInfo.h"
21 #include "SIInstrInfo.h"
22 #include "llvm/CodeGen/MachineBasicBlock.h"
23 #include "llvm/CodeGen/MachineInstr.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"
31 #include "llvm/MC/MCObjectStreamer.h"
32 #include "llvm/MC/MCStreamer.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/Format.h"
39 AMDGPUMCInstLower::AMDGPUMCInstLower(MCContext
&ctx
, const AMDGPUSubtarget
&st
):
43 void AMDGPUMCInstLower::lower(const MachineInstr
*MI
, MCInst
&OutMI
) const {
45 int MCOpcode
= ST
.getInstrInfo()->pseudoToMCOpcode(MI
->getOpcode());
48 LLVMContext
&C
= MI
->getParent()->getParent()->getFunction()->getContext();
49 C
.emitError("AMDGPUMCInstLower::lower - Pseudo instruction doesn't have "
50 "a target-specific version: " + Twine(MI
->getOpcode()));
53 OutMI
.setOpcode(MCOpcode
);
55 for (const MachineOperand
&MO
: MI
->explicit_operands()) {
57 switch (MO
.getType()) {
59 llvm_unreachable("unknown operand type");
60 case MachineOperand::MO_Immediate
:
61 MCOp
= MCOperand::CreateImm(MO
.getImm());
63 case MachineOperand::MO_Register
:
64 MCOp
= MCOperand::CreateReg(MO
.getReg());
66 case MachineOperand::MO_MachineBasicBlock
:
67 MCOp
= MCOperand::CreateExpr(MCSymbolRefExpr::Create(
68 MO
.getMBB()->getSymbol(), Ctx
));
70 case MachineOperand::MO_GlobalAddress
: {
71 const GlobalValue
*GV
= MO
.getGlobal();
72 MCSymbol
*Sym
= Ctx
.GetOrCreateSymbol(StringRef(GV
->getName()));
73 MCOp
= MCOperand::CreateExpr(MCSymbolRefExpr::Create(Sym
, Ctx
));
76 case MachineOperand::MO_TargetIndex
: {
77 assert(MO
.getIndex() == AMDGPU::TI_CONSTDATA_START
);
78 MCSymbol
*Sym
= Ctx
.GetOrCreateSymbol(StringRef(END_OF_TEXT_LABEL_NAME
));
79 const MCSymbolRefExpr
*Expr
= MCSymbolRefExpr::Create(Sym
, Ctx
);
80 MCOp
= MCOperand::CreateExpr(Expr
);
83 case MachineOperand::MO_ExternalSymbol
: {
84 MCSymbol
*Sym
= Ctx
.GetOrCreateSymbol(StringRef(MO
.getSymbolName()));
85 const MCSymbolRefExpr
*Expr
= MCSymbolRefExpr::Create(Sym
, Ctx
);
86 MCOp
= MCOperand::CreateExpr(Expr
);
90 OutMI
.addOperand(MCOp
);
94 void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr
*MI
) {
95 AMDGPUMCInstLower
MCInstLowering(OutContext
,
96 MF
->getTarget().getSubtarget
<AMDGPUSubtarget
>());
100 if (!TM
.getSubtargetImpl()->getInstrInfo()->verifyInstruction(MI
, Err
)) {
101 errs() << "Warning: Illegal instruction detected: " << Err
<< "\n";
105 if (MI
->isBundle()) {
106 const MachineBasicBlock
*MBB
= MI
->getParent();
107 MachineBasicBlock::const_instr_iterator I
= MI
;
109 while (I
!= MBB
->end() && I
->isInsideBundle()) {
115 MCInstLowering
.lower(MI
, TmpInst
);
116 EmitToStreamer(OutStreamer
, TmpInst
);
119 // Disassemble instruction/operands to text.
120 DisasmLines
.resize(DisasmLines
.size() + 1);
121 std::string
&DisasmLine
= DisasmLines
.back();
122 raw_string_ostream
DisasmStream(DisasmLine
);
124 AMDGPUInstPrinter
InstPrinter(*TM
.getMCAsmInfo(),
125 *TM
.getSubtargetImpl()->getInstrInfo(),
126 *TM
.getSubtargetImpl()->getRegisterInfo());
127 InstPrinter
.printInst(&TmpInst
, DisasmStream
, StringRef());
129 // Disassemble instruction/operands to hex representation.
130 SmallVector
<MCFixup
, 4> Fixups
;
131 SmallVector
<char, 16> CodeBytes
;
132 raw_svector_ostream
CodeStream(CodeBytes
);
134 MCObjectStreamer
&ObjStreamer
= (MCObjectStreamer
&)OutStreamer
;
135 MCCodeEmitter
&InstEmitter
= ObjStreamer
.getAssembler().getEmitter();
136 InstEmitter
.EncodeInstruction(TmpInst
, CodeStream
, Fixups
,
137 TM
.getSubtarget
<MCSubtargetInfo
>());
140 HexLines
.resize(HexLines
.size() + 1);
141 std::string
&HexLine
= HexLines
.back();
142 raw_string_ostream
HexStream(HexLine
);
144 for (size_t i
= 0; i
< CodeBytes
.size(); i
+= 4) {
145 unsigned int CodeDWord
= *(unsigned int *)&CodeBytes
[i
];
146 HexStream
<< format("%s%08X", (i
> 0 ? " " : ""), CodeDWord
);
149 DisasmStream
.flush();
150 DisasmLineMaxLen
= std::max(DisasmLineMaxLen
, DisasmLine
.size());