LLVM 22.0.0git
R600MCCodeEmitter.cpp
Go to the documentation of this file.
1//===- R600MCCodeEmitter.cpp - Code Emitter for R600->Cayman GPU families -===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10///
11/// The R600 code emitter produces machine code that can be executed
12/// directly on the GPU device.
13//
14//===----------------------------------------------------------------------===//
15
17#include "R600Defines.h"
19#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCInstrInfo.h"
25
26using namespace llvm;
27
28namespace {
29
30class R600MCCodeEmitter : public MCCodeEmitter {
31 const MCRegisterInfo &MRI;
32 const MCInstrInfo &MCII;
33
34public:
35 R600MCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri)
36 : MRI(mri), MCII(mcii) {}
37 R600MCCodeEmitter(const R600MCCodeEmitter &) = delete;
38 R600MCCodeEmitter &operator=(const R600MCCodeEmitter &) = delete;
39
40 /// Encode the instruction and write it to the OS.
41 void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
42 SmallVectorImpl<MCFixup> &Fixups,
43 const MCSubtargetInfo &STI) const override;
44
45 /// \returns the encoding for an MCOperand.
46 uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
47 SmallVectorImpl<MCFixup> &Fixups,
48 const MCSubtargetInfo &STI) const;
49
50private:
51 void emit(uint32_t value, SmallVectorImpl<char> &CB) const;
52 void emit(uint64_t value, SmallVectorImpl<char> &CB) const;
53
54 unsigned getHWReg(MCRegister Reg) const;
55
56 uint64_t getBinaryCodeForInstr(const MCInst &MI,
57 SmallVectorImpl<MCFixup> &Fixups,
58 const MCSubtargetInfo &STI) const;
59};
60
61} // end anonymous namespace
62
69
79
81 MCContext &Ctx) {
82 return new R600MCCodeEmitter(MCII, *Ctx.getRegisterInfo());
83}
84
85void R600MCCodeEmitter::encodeInstruction(const MCInst &MI,
88 const MCSubtargetInfo &STI) const {
89 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
90 if (MI.getOpcode() == R600::RETURN ||
91 MI.getOpcode() == R600::FETCH_CLAUSE ||
92 MI.getOpcode() == R600::ALU_CLAUSE ||
93 MI.getOpcode() == R600::BUNDLE ||
94 MI.getOpcode() == R600::KILL) {
95 return;
96 }
97 if (IS_VTX(Desc)) {
98 uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups, STI);
99 uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset
100 if (!(STI.hasFeature(R600::FeatureCaymanISA))) {
101 InstWord2 |= 1 << 19; // Mega-Fetch bit
102 }
103
104 emit(InstWord01, CB);
105 emit(InstWord2, CB);
106 emit((uint32_t)0, CB);
107 } else if (IS_TEX(Desc)) {
108 int64_t Sampler = MI.getOperand(14).getImm();
109
110 int64_t SrcSelect[4] = {
111 MI.getOperand(2).getImm(), MI.getOperand(3).getImm(),
112 MI.getOperand(4).getImm(), MI.getOperand(5).getImm()};
113 int64_t Offsets[3] = {MI.getOperand(6).getImm() & 0x1F,
114 MI.getOperand(7).getImm() & 0x1F,
115 MI.getOperand(8).getImm() & 0x1F};
116
117 uint64_t Word01 = getBinaryCodeForInstr(MI, Fixups, STI);
118 uint32_t Word2 = Sampler << 15 | SrcSelect[ELEMENT_X] << 20 |
119 SrcSelect[ELEMENT_Y] << 23 | SrcSelect[ELEMENT_Z] << 26 |
120 SrcSelect[ELEMENT_W] << 29 | Offsets[0] << 0 |
121 Offsets[1] << 5 | Offsets[2] << 10;
122
123 emit(Word01, CB);
124 emit(Word2, CB);
125 emit((uint32_t)0, CB);
126 } else {
127 uint64_t Inst = getBinaryCodeForInstr(MI, Fixups, STI);
128 if ((STI.hasFeature(R600::FeatureR600ALUInst)) &&
129 ((Desc.TSFlags & R600_InstFlag::OP1) ||
130 Desc.TSFlags & R600_InstFlag::OP2)) {
131 uint64_t ISAOpCode = Inst & (0x3FFULL << 39);
132 Inst &= ~(0x3FFULL << 39);
133 Inst |= ISAOpCode << 1;
134 }
135 emit(Inst, CB);
136 }
137}
138
139void R600MCCodeEmitter::emit(uint32_t Value, SmallVectorImpl<char> &CB) const {
141}
142
143void R600MCCodeEmitter::emit(uint64_t Value, SmallVectorImpl<char> &CB) const {
145}
146
147unsigned R600MCCodeEmitter::getHWReg(MCRegister Reg) const {
148 return MRI.getEncodingValue(Reg) & HW_REG_MASK;
149}
150
151uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI,
152 const MCOperand &MO,
153 SmallVectorImpl<MCFixup> &Fixups,
154 const MCSubtargetInfo &STI) const {
155 if (MO.isReg()) {
156 if (HAS_NATIVE_OPERANDS(MCII.get(MI.getOpcode()).TSFlags))
157 return MRI.getEncodingValue(MO.getReg());
158 return getHWReg(MO.getReg());
159 }
160
161 if (MO.isExpr()) {
162 // We put rodata at the end of code section, then map the entire
163 // code secetion as vtx buf. Thus the section relative address is the
164 // correct one.
165 // Each R600 literal instruction has two operands
166 // We can't easily get the order of the current one, so compare against
167 // the first one and adjust offset.
168 const unsigned offset = (&MO == &MI.getOperand(0)) ? 0 : 4;
169 Fixups.push_back(MCFixup::create(offset, MO.getExpr(), FK_SecRel_4));
170 return 0;
171 }
172
173 assert(MO.isImm());
174 return MO.getImm();
175}
176
177#include "R600GenMCCodeEmitter.inc"
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static unsigned getHWReg(const SIInstrInfo *TII, const MachineInstr &RegInstr)
IRTranslator LLVM IR MI
Register Reg
#define HAS_NATIVE_OPERANDS(Flags)
Definition R600Defines.h:50
#define IS_VTX(desc)
Definition R600Defines.h:59
#define HW_REG_MASK
Defines for extracting register information from register encoding.
Definition R600Defines.h:53
#define IS_TEX(desc)
Definition R600Defines.h:60
@ ELEMENT_W
@ ELEMENT_Y
@ ELEMENT_Z
@ ELEMENT_X
@ FC_ENDLOOP
@ FC_IF_PREDICATE
@ FC_BGNLOOP
@ FC_CONTINUE
@ FC_BREAK_PREDICATE
Provides R600 specific target descriptions.
MCCodeEmitter - Generic instruction encoding interface.
Context object for machine code objects.
Definition MCContext.h:83
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
Definition MCFixup.h:86
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition MCInstrInfo.h:64
int64_t getImm() const
Definition MCInst.h:84
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Offsets
Offsets in bytes from the start of the input buffer.
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition Endian.h:92
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
Op::Description Desc
MCCodeEmitter * createR600MCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
@ FK_SecRel_4
A four-byte section relative fixup.
Definition MCFixup.h:41