LLVM 19.0.0git
CSKYMCCodeEmitter.cpp
Go to the documentation of this file.
1//===-- CSKYMCCodeEmitter.cpp - CSKY Code Emitter interface ---------------===//
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// This file implements the CSKYMCCodeEmitter class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CSKYMCCodeEmitter.h"
14#include "CSKYMCExpr.h"
16#include "llvm/ADT/Statistic.h"
18#include "llvm/MC/MCInstrInfo.h"
23
24using namespace llvm;
25
26#define DEBUG_TYPE "csky-mccode-emitter"
27
28STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
29
32 const MCSubtargetInfo &STI) const {
33 const MCOperand &MO = MI.getOperand(Idx);
34 assert(MO.isImm() && "Unexpected MO type.");
35 return MO.getImm() - 1;
36}
37
38unsigned
41 const MCSubtargetInfo &STI) const {
42 const MCOperand &MO = MI.getOperand(Idx);
43 assert(MO.isImm() && "Unexpected MO type.");
44
45 auto V = (MO.getImm() <= 3) ? 4 : MO.getImm();
46 return V - 1;
47}
48
49unsigned
52 const MCSubtargetInfo &STI) const {
53 const MCOperand &MSB = MI.getOperand(Idx);
54 const MCOperand &LSB = MI.getOperand(Idx + 1);
55 assert(MSB.isImm() && LSB.isImm() && "Unexpected MO type.");
56
57 return MSB.getImm() - LSB.getImm();
58}
59
60static void writeData(uint32_t Bin, unsigned Size, SmallVectorImpl<char> &CB) {
61 if (Size == 4)
62 support::endian::write(CB, static_cast<uint16_t>(Bin >> 16),
64 support::endian::write(CB, static_cast<uint16_t>(Bin),
66}
67
70 const MCSubtargetInfo &STI) const {
71
72 MCInst TmpInst;
73
74 uint32_t Binary;
75
76 TmpInst =
77 MCInstBuilder(MI.getOpcode() == CSKY::JBT_E ? CSKY::BF16 : CSKY::BT16)
78 .addOperand(MI.getOperand(0))
79 .addImm(6);
80 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
81 writeData(Binary, 2, CB);
82
83 if (!STI.hasFeature(CSKY::Has2E3))
84 TmpInst = MCInstBuilder(CSKY::BR32)
85 .addOperand(MI.getOperand(1))
86 .addOperand(MI.getOperand(2));
87 else
88 TmpInst = MCInstBuilder(CSKY::JMPI32).addOperand(MI.getOperand(2));
89 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
90 Fixups[Fixups.size() - 1].setOffset(2);
91 writeData(Binary, 4, CB);
92}
93
96 const MCSubtargetInfo &STI) const {
97
98 MCInst TmpInst;
99 uint32_t Binary;
100 unsigned Size = MI.getOpcode() == CSKY::NEG32 ? 4 : 2;
101
102 TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
103 .addOperand(MI.getOperand(0))
104 .addOperand(MI.getOperand(1));
105 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
106 writeData(Binary, Size, CB);
107
108 TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
109 .addOperand(MI.getOperand(0))
110 .addOperand(MI.getOperand(0))
111 .addImm(1);
112 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
113 writeData(Binary, Size, CB);
114}
115
118 const MCSubtargetInfo &STI) const {
119
120 MCInst TmpInst;
121 uint32_t Binary;
122 unsigned Size = MI.getOpcode() == CSKY::RSUBI32 ? 4 : 2;
123
124 TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
125 .addOperand(MI.getOperand(0))
126 .addOperand(MI.getOperand(1));
127 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
128 writeData(Binary, Size, CB);
129
130 TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
131 .addOperand(MI.getOperand(0))
132 .addOperand(MI.getOperand(0))
133 .addImm(MI.getOperand(2).getImm() + 1);
134 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
135 writeData(Binary, Size, CB);
136}
137
141 const MCSubtargetInfo &STI) const {
142 const MCInstrDesc &Desc = MII.get(MI.getOpcode());
143 unsigned Size = Desc.getSize();
144
145 MCInst TmpInst;
146
147 switch (MI.getOpcode()) {
148 default:
149 TmpInst = MI;
150 break;
151 case CSKY::JBT_E:
152 case CSKY::JBF_E:
153 expandJBTF(MI, CB, Fixups, STI);
154 MCNumEmitted += 2;
155 return;
156 case CSKY::NEG32:
157 case CSKY::NEG16:
158 expandNEG(MI, CB, Fixups, STI);
159 MCNumEmitted += 2;
160 return;
161 case CSKY::RSUBI32:
162 case CSKY::RSUBI16:
163 expandRSUBI(MI, CB, Fixups, STI);
164 MCNumEmitted += 2;
165 return;
166 case CSKY::JBSR32:
167 TmpInst = MCInstBuilder(CSKY::BSR32).addOperand(MI.getOperand(0));
168 break;
169 case CSKY::JBR16:
170 TmpInst = MCInstBuilder(CSKY::BR16).addOperand(MI.getOperand(0));
171 break;
172 case CSKY::JBR32:
173 TmpInst = MCInstBuilder(CSKY::BR32).addOperand(MI.getOperand(0));
174 break;
175 case CSKY::JBT16:
176 TmpInst = MCInstBuilder(CSKY::BT16)
177 .addOperand(MI.getOperand(0))
178 .addOperand(MI.getOperand(1));
179 break;
180 case CSKY::JBT32:
181 TmpInst = MCInstBuilder(CSKY::BT32)
182 .addOperand(MI.getOperand(0))
183 .addOperand(MI.getOperand(1));
184 break;
185 case CSKY::JBF16:
186 TmpInst = MCInstBuilder(CSKY::BF16)
187 .addOperand(MI.getOperand(0))
188 .addOperand(MI.getOperand(1));
189 break;
190 case CSKY::JBF32:
191 TmpInst = MCInstBuilder(CSKY::BF32)
192 .addOperand(MI.getOperand(0))
193 .addOperand(MI.getOperand(1));
194 break;
195 case CSKY::LRW32_Gen:
196 TmpInst = MCInstBuilder(CSKY::LRW32)
197 .addOperand(MI.getOperand(0))
198 .addOperand(MI.getOperand(2));
199 break;
200 case CSKY::LRW16_Gen:
201 TmpInst = MCInstBuilder(CSKY::LRW16)
202 .addOperand(MI.getOperand(0))
203 .addOperand(MI.getOperand(2));
204 break;
205 case CSKY::CMPLEI32:
206 TmpInst = MCInstBuilder(CSKY::CMPLTI32)
207 .addOperand(MI.getOperand(0))
208 .addOperand(MI.getOperand(1))
209 .addImm(MI.getOperand(2).getImm() + 1);
210 break;
211 case CSKY::CMPLEI16:
212 TmpInst = MCInstBuilder(CSKY::CMPLTI16)
213 .addOperand(MI.getOperand(0))
214 .addOperand(MI.getOperand(1))
215 .addImm(MI.getOperand(2).getImm() + 1);
216 break;
217 case CSKY::ROTRI32:
218 TmpInst = MCInstBuilder(CSKY::ROTLI32)
219 .addOperand(MI.getOperand(0))
220 .addOperand(MI.getOperand(1))
221 .addImm(32 - MI.getOperand(2).getImm());
222 break;
223 case CSKY::BGENI:
224 auto V = 1 << MI.getOperand(1).getImm();
225 TmpInst =
226 MCInstBuilder(CSKY::MOVI32).addOperand(MI.getOperand(0)).addImm(V);
227 break;
228 }
229
230 ++MCNumEmitted;
231 writeData(getBinaryCodeForInstr(TmpInst, Fixups, STI), Size, CB);
232}
233
234unsigned
237 const MCSubtargetInfo &STI) const {
238 if (MO.isReg())
239 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
240
241 if (MO.isImm())
242 return static_cast<unsigned>(MO.getImm());
243
244 llvm_unreachable("Unhandled expression!");
245 return 0;
246}
247
248unsigned
251 const MCSubtargetInfo &STI) const {
252 assert(MI.getOperand(Idx).isReg() && "Unexpected MO type.");
253 assert(MI.getOperand(Idx + 1).isImm() && "Unexpected MO type.");
254
255 unsigned Ry = MI.getOperand(Idx).getReg();
256 unsigned Rz = MI.getOperand(Idx + 1).getImm();
257
258 unsigned Imm = Ctx.getRegisterInfo()->getEncodingValue(Rz) -
260
261 return ((Ctx.getRegisterInfo()->getEncodingValue(Ry) << 5) | Imm);
262}
263
264unsigned
267 const MCSubtargetInfo &STI) const {
268 unsigned Reg1 =
269 Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op).getReg());
270 unsigned Reg2 =
271 Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op + 1).getReg());
272
273 unsigned Binary = ((Reg1 & 0x1f) << 5) | (Reg2 - Reg1);
274
275 return Binary;
276}
277
278unsigned CSKYMCCodeEmitter::getImmJMPIX(const MCInst &MI, unsigned Idx,
280 const MCSubtargetInfo &STI) const {
281 if (MI.getOperand(Idx).getImm() == 16)
282 return 0;
283 else if (MI.getOperand(Idx).getImm() == 24)
284 return 1;
285 else if (MI.getOperand(Idx).getImm() == 32)
286 return 2;
287 else if (MI.getOperand(Idx).getImm() == 40)
288 return 3;
289 else
290 assert(0);
291}
292
294 const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Expr);
295
296 switch (CSKYExpr->getKind()) {
297 default:
298 llvm_unreachable("Unhandled fixup kind!");
317 }
318}
319
321 MCContext &Ctx) {
322 return new CSKYMCCodeEmitter(Ctx, MCII);
323}
324
325#include "CSKYGenMCCodeEmitter.inc"
static void writeData(uint32_t Bin, unsigned Size, SmallVectorImpl< char > &CB)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Size
IRTranslator LLVM IR MI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
unsigned getRegisterSeqOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getOImmOpValue(const MCInst &MI, unsigned Idx, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
uint64_t getBinaryCodeForInstr(const MCInst &MI, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
void expandJBTF(const MCInst &MI, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getImmOpValueMSBSize(const MCInst &MI, unsigned Idx, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
MCFixupKind getTargetFixup(const MCExpr *Expr) const
void expandRSUBI(const MCInst &MI, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
void expandNEG(const MCInst &MI, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getRegSeqImmOpValue(const MCInst &MI, unsigned Idx, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getImmOpValueIDLY(const MCInst &MI, unsigned Idx, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const override
Encode the given Inst to bytes and append to CB.
unsigned getImmJMPIX(const MCInst &MI, unsigned Idx, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
VariantKind getKind() const
Definition: CSKYMCExpr.h:51
This class represents an Operation in the Expression.
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
Context object for machine code objects.
Definition: MCContext.h:81
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:455
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
MCInstBuilder & addOperand(const MCOperand &Op)
Add an operand.
Definition: MCInstBuilder.h:73
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:43
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
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:63
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
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
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
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ fixup_csky_plt_imm18_scale4
@ fixup_csky_got_imm18_scale4
@ fixup_csky_addr_hi16
@ fixup_csky_addr_lo16
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
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
MCCodeEmitter * createCSKYMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
Description of the encoding of one expression Op.