LLVM 19.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"
26
27using namespace llvm;
28
29namespace {
30
31class R600MCCodeEmitter : public MCCodeEmitter {
32 const MCRegisterInfo &MRI;
33 const MCInstrInfo &MCII;
34
35public:
36 R600MCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri)
37 : MRI(mri), MCII(mcii) {}
38 R600MCCodeEmitter(const R600MCCodeEmitter &) = delete;
39 R600MCCodeEmitter &operator=(const R600MCCodeEmitter &) = delete;
40
41 /// Encode the instruction and write it to the OS.
44 const MCSubtargetInfo &STI) const override;
45
46 /// \returns the encoding for an MCOperand.
47 uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
49 const MCSubtargetInfo &STI) const;
50
51private:
54
55 unsigned getHWReg(unsigned regNo) const;
56
57 uint64_t getBinaryCodeForInstr(const MCInst &MI,
59 const MCSubtargetInfo &STI) const;
60};
61
62} // end anonymous namespace
63
69};
70
71enum FCInstr {
79};
80
82 MCContext &Ctx) {
83 return new R600MCCodeEmitter(MCII, *Ctx.getRegisterInfo());
84}
85
86void R600MCCodeEmitter::encodeInstruction(const MCInst &MI,
89 const MCSubtargetInfo &STI) const {
90 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
91 if (MI.getOpcode() == R600::RETURN ||
92 MI.getOpcode() == R600::FETCH_CLAUSE ||
93 MI.getOpcode() == R600::ALU_CLAUSE ||
94 MI.getOpcode() == R600::BUNDLE ||
95 MI.getOpcode() == R600::KILL) {
96 return;
97 } else 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(),
112 MI.getOperand(3).getImm(),
113 MI.getOperand(4).getImm(),
114 MI.getOperand(5).getImm()
115 };
116 int64_t Offsets[3] = {
117 MI.getOperand(6).getImm() & 0x1F,
118 MI.getOperand(7).getImm() & 0x1F,
119 MI.getOperand(8).getImm() & 0x1F
120 };
121
122 uint64_t Word01 = getBinaryCodeForInstr(MI, Fixups, STI);
123 uint32_t Word2 = Sampler << 15 | SrcSelect[ELEMENT_X] << 20 |
124 SrcSelect[ELEMENT_Y] << 23 | SrcSelect[ELEMENT_Z] << 26 |
125 SrcSelect[ELEMENT_W] << 29 | Offsets[0] << 0 | Offsets[1] << 5 |
126 Offsets[2] << 10;
127
128 emit(Word01, CB);
129 emit(Word2, CB);
130 emit((uint32_t)0, CB);
131 } else {
132 uint64_t Inst = getBinaryCodeForInstr(MI, Fixups, STI);
133 if ((STI.hasFeature(R600::FeatureR600ALUInst)) &&
134 ((Desc.TSFlags & R600_InstFlag::OP1) ||
135 Desc.TSFlags & R600_InstFlag::OP2)) {
136 uint64_t ISAOpCode = Inst & (0x3FFULL << 39);
137 Inst &= ~(0x3FFULL << 39);
138 Inst |= ISAOpCode << 1;
139 }
140 emit(Inst, CB);
141 }
142}
143
144void R600MCCodeEmitter::emit(uint32_t Value, SmallVectorImpl<char> &CB) const {
146}
147
148void R600MCCodeEmitter::emit(uint64_t Value, SmallVectorImpl<char> &CB) const {
150}
151
152unsigned R600MCCodeEmitter::getHWReg(unsigned RegNo) const {
153 return MRI.getEncodingValue(RegNo) & HW_REG_MASK;
154}
155
156uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI,
157 const MCOperand &MO,
159 const MCSubtargetInfo &STI) const {
160 if (MO.isReg()) {
161 if (HAS_NATIVE_OPERANDS(MCII.get(MI.getOpcode()).TSFlags))
162 return MRI.getEncodingValue(MO.getReg());
163 return getHWReg(MO.getReg());
164 }
165
166 if (MO.isExpr()) {
167 // We put rodata at the end of code section, then map the entire
168 // code secetion as vtx buf. Thus the section relative address is the
169 // correct one.
170 // Each R600 literal instruction has two operands
171 // We can't easily get the order of the current one, so compare against
172 // the first one and adjust offset.
173 const unsigned offset = (&MO == &MI.getOperand(0)) ? 0 : 4;
174 Fixups.push_back(MCFixup::create(offset, MO.getExpr(), FK_SecRel_4, MI.getLoc()));
175 return 0;
176 }
177
178 assert(MO.isImm());
179 return MO.getImm();
180}
181
182#include "R600GenMCCodeEmitter.inc"
unsigned const MachineRegisterInfo * MRI
dxil metadata emit
Given that RA is a live value
static unsigned getHWReg(const SIInstrInfo *TII, const MachineInstr &RegInstr)
IRTranslator LLVM IR MI
#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_ELSE
@ FC_BREAK_PREDICATE
@ FC_ENDIF
Provides R600 specific target descriptions.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
MCCodeEmitter & operator=(const MCCodeEmitter &)=delete
Context object for machine code objects.
Definition: MCContext.h:76
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:448
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:87
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
int64_t getImm() const
Definition: MCInst.h:80
bool isImm() const
Definition: MCInst.h:62
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69
bool isReg() const
Definition: MCInst.h:61
const MCExpr * getExpr() const
Definition: MCInst.h:114
bool isExpr() const
Definition: MCInst.h:65
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
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...
Definition: SmallVector.h:586
LLVM Value Representation.
Definition: Value.h:74
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1522
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition: Endian.h:91
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MCCodeEmitter * createR600MCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
@ FK_SecRel_4
A four-byte section relative fixup.
Definition: MCFixup.h:42
Description of the encoding of one expression Op.