LLVM 20.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:
52 void emit(uint32_t value, SmallVectorImpl<char> &CB) const;
53 void emit(uint64_t value, SmallVectorImpl<char> &CB) const;
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 }
98 if (IS_VTX(Desc)) {
99 uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups, STI);
100 uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset
101 if (!(STI.hasFeature(R600::FeatureCaymanISA))) {
102 InstWord2 |= 1 << 19; // Mega-Fetch bit
103 }
104
105 emit(InstWord01, CB);
106 emit(InstWord2, CB);
107 emit((uint32_t)0, CB);
108 } else if (IS_TEX(Desc)) {
109 int64_t Sampler = MI.getOperand(14).getImm();
110
111 int64_t SrcSelect[4] = {
112 MI.getOperand(2).getImm(), MI.getOperand(3).getImm(),
113 MI.getOperand(4).getImm(), MI.getOperand(5).getImm()};
114 int64_t Offsets[3] = {MI.getOperand(6).getImm() & 0x1F,
115 MI.getOperand(7).getImm() & 0x1F,
116 MI.getOperand(8).getImm() & 0x1F};
117
118 uint64_t Word01 = getBinaryCodeForInstr(MI, Fixups, STI);
119 uint32_t Word2 = Sampler << 15 | SrcSelect[ELEMENT_X] << 20 |
120 SrcSelect[ELEMENT_Y] << 23 | SrcSelect[ELEMENT_Z] << 26 |
121 SrcSelect[ELEMENT_W] << 29 | Offsets[0] << 0 |
122 Offsets[1] << 5 | Offsets[2] << 10;
123
124 emit(Word01, CB);
125 emit(Word2, CB);
126 emit((uint32_t)0, CB);
127 } else {
128 uint64_t Inst = getBinaryCodeForInstr(MI, Fixups, STI);
129 if ((STI.hasFeature(R600::FeatureR600ALUInst)) &&
130 ((Desc.TSFlags & R600_InstFlag::OP1) ||
131 Desc.TSFlags & R600_InstFlag::OP2)) {
132 uint64_t ISAOpCode = Inst & (0x3FFULL << 39);
133 Inst &= ~(0x3FFULL << 39);
134 Inst |= ISAOpCode << 1;
135 }
136 emit(Inst, CB);
137 }
138}
139
140void R600MCCodeEmitter::emit(uint32_t Value, SmallVectorImpl<char> &CB) const {
142}
143
144void R600MCCodeEmitter::emit(uint64_t Value, SmallVectorImpl<char> &CB) const {
146}
147
148unsigned R600MCCodeEmitter::getHWReg(unsigned RegNo) const {
149 return MRI.getEncodingValue(RegNo) & HW_REG_MASK;
150}
151
152uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI,
153 const MCOperand &MO,
155 const MCSubtargetInfo &STI) const {
156 if (MO.isReg()) {
157 if (HAS_NATIVE_OPERANDS(MCII.get(MI.getOpcode()).TSFlags))
158 return MRI.getEncodingValue(MO.getReg());
159 return getHWReg(MO.getReg());
160 }
161
162 if (MO.isExpr()) {
163 // We put rodata at the end of code section, then map the entire
164 // code secetion as vtx buf. Thus the section relative address is the
165 // correct one.
166 // Each R600 literal instruction has two operands
167 // We can't easily get the order of the current one, so compare against
168 // the first one and adjust offset.
169 const unsigned offset = (&MO == &MI.getOperand(0)) ? 0 : 4;
170 Fixups.push_back(MCFixup::create(offset, MO.getExpr(), FK_SecRel_4, MI.getLoc()));
171 return 0;
172 }
173
174 assert(MO.isImm());
175 return MO.getImm();
176}
177
178#include "R600GenMCCodeEmitter.inc"
unsigned const MachineRegisterInfo * MRI
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:83
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:414
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:1589
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.
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.