LLVM 18.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),
65}
66
69 const MCSubtargetInfo &STI) const {
70
71 MCInst TmpInst;
72
73 uint32_t Binary;
74
75 TmpInst =
76 MCInstBuilder(MI.getOpcode() == CSKY::JBT_E ? CSKY::BF16 : CSKY::BT16)
77 .addOperand(MI.getOperand(0))
78 .addImm(6);
79 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
80 writeData(Binary, 2, CB);
81
82 if (!STI.hasFeature(CSKY::Has2E3))
83 TmpInst = MCInstBuilder(CSKY::BR32)
84 .addOperand(MI.getOperand(1))
85 .addOperand(MI.getOperand(2));
86 else
87 TmpInst = MCInstBuilder(CSKY::JMPI32).addOperand(MI.getOperand(2));
88 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
89 Fixups[Fixups.size() - 1].setOffset(2);
90 writeData(Binary, 4, CB);
91}
92
95 const MCSubtargetInfo &STI) const {
96
97 MCInst TmpInst;
98 uint32_t Binary;
99 unsigned Size = MI.getOpcode() == CSKY::NEG32 ? 4 : 2;
100
101 TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
102 .addOperand(MI.getOperand(0))
103 .addOperand(MI.getOperand(1));
104 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
105 writeData(Binary, Size, CB);
106
107 TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
108 .addOperand(MI.getOperand(0))
109 .addOperand(MI.getOperand(0))
110 .addImm(1);
111 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
112 writeData(Binary, Size, CB);
113}
114
117 const MCSubtargetInfo &STI) const {
118
119 MCInst TmpInst;
120 uint32_t Binary;
121 unsigned Size = MI.getOpcode() == CSKY::RSUBI32 ? 4 : 2;
122
123 TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
124 .addOperand(MI.getOperand(0))
125 .addOperand(MI.getOperand(1));
126 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
127 writeData(Binary, Size, CB);
128
129 TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
130 .addOperand(MI.getOperand(0))
131 .addOperand(MI.getOperand(0))
132 .addImm(MI.getOperand(2).getImm() + 1);
133 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
134 writeData(Binary, Size, CB);
135}
136
140 const MCSubtargetInfo &STI) const {
141 const MCInstrDesc &Desc = MII.get(MI.getOpcode());
142 unsigned Size = Desc.getSize();
143
144 MCInst TmpInst;
145
146 switch (MI.getOpcode()) {
147 default:
148 TmpInst = MI;
149 break;
150 case CSKY::JBT_E:
151 case CSKY::JBF_E:
152 expandJBTF(MI, CB, Fixups, STI);
153 MCNumEmitted += 2;
154 return;
155 case CSKY::NEG32:
156 case CSKY::NEG16:
157 expandNEG(MI, CB, Fixups, STI);
158 MCNumEmitted += 2;
159 return;
160 case CSKY::RSUBI32:
161 case CSKY::RSUBI16:
162 expandRSUBI(MI, CB, Fixups, STI);
163 MCNumEmitted += 2;
164 return;
165 case CSKY::JBSR32:
166 TmpInst = MCInstBuilder(CSKY::BSR32).addOperand(MI.getOperand(0));
167 break;
168 case CSKY::JBR16:
169 TmpInst = MCInstBuilder(CSKY::BR16).addOperand(MI.getOperand(0));
170 break;
171 case CSKY::JBR32:
172 TmpInst = MCInstBuilder(CSKY::BR32).addOperand(MI.getOperand(0));
173 break;
174 case CSKY::JBT16:
175 TmpInst = MCInstBuilder(CSKY::BT16)
176 .addOperand(MI.getOperand(0))
177 .addOperand(MI.getOperand(1));
178 break;
179 case CSKY::JBT32:
180 TmpInst = MCInstBuilder(CSKY::BT32)
181 .addOperand(MI.getOperand(0))
182 .addOperand(MI.getOperand(1));
183 break;
184 case CSKY::JBF16:
185 TmpInst = MCInstBuilder(CSKY::BF16)
186 .addOperand(MI.getOperand(0))
187 .addOperand(MI.getOperand(1));
188 break;
189 case CSKY::JBF32:
190 TmpInst = MCInstBuilder(CSKY::BF32)
191 .addOperand(MI.getOperand(0))
192 .addOperand(MI.getOperand(1));
193 break;
194 case CSKY::LRW32_Gen:
195 TmpInst = MCInstBuilder(CSKY::LRW32)
196 .addOperand(MI.getOperand(0))
197 .addOperand(MI.getOperand(2));
198 break;
199 case CSKY::LRW16_Gen:
200 TmpInst = MCInstBuilder(CSKY::LRW16)
201 .addOperand(MI.getOperand(0))
202 .addOperand(MI.getOperand(2));
203 break;
204 case CSKY::CMPLEI32:
205 TmpInst = MCInstBuilder(CSKY::CMPLTI32)
206 .addOperand(MI.getOperand(0))
207 .addOperand(MI.getOperand(1))
208 .addImm(MI.getOperand(2).getImm() + 1);
209 break;
210 case CSKY::CMPLEI16:
211 TmpInst = MCInstBuilder(CSKY::CMPLTI16)
212 .addOperand(MI.getOperand(0))
213 .addOperand(MI.getOperand(1))
214 .addImm(MI.getOperand(2).getImm() + 1);
215 break;
216 case CSKY::ROTRI32:
217 TmpInst = MCInstBuilder(CSKY::ROTLI32)
218 .addOperand(MI.getOperand(0))
219 .addOperand(MI.getOperand(1))
220 .addImm(32 - MI.getOperand(2).getImm());
221 break;
222 case CSKY::BGENI:
223 auto V = 1 << MI.getOperand(1).getImm();
224 TmpInst =
225 MCInstBuilder(CSKY::MOVI32).addOperand(MI.getOperand(0)).addImm(V);
226 break;
227 }
228
229 ++MCNumEmitted;
230 writeData(getBinaryCodeForInstr(TmpInst, Fixups, STI), Size, CB);
231}
232
233unsigned
236 const MCSubtargetInfo &STI) const {
237 if (MO.isReg())
238 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
239
240 if (MO.isImm())
241 return static_cast<unsigned>(MO.getImm());
242
243 llvm_unreachable("Unhandled expression!");
244 return 0;
245}
246
247unsigned
250 const MCSubtargetInfo &STI) const {
251 assert(MI.getOperand(Idx).isReg() && "Unexpected MO type.");
252 assert(MI.getOperand(Idx + 1).isImm() && "Unexpected MO type.");
253
254 unsigned Ry = MI.getOperand(Idx).getReg();
255 unsigned Rz = MI.getOperand(Idx + 1).getImm();
256
257 unsigned Imm = Ctx.getRegisterInfo()->getEncodingValue(Rz) -
259
260 return ((Ctx.getRegisterInfo()->getEncodingValue(Ry) << 5) | Imm);
261}
262
263unsigned
266 const MCSubtargetInfo &STI) const {
267 unsigned Reg1 =
268 Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op).getReg());
269 unsigned Reg2 =
270 Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op + 1).getReg());
271
272 unsigned Binary = ((Reg1 & 0x1f) << 5) | (Reg2 - Reg1);
273
274 return Binary;
275}
276
277unsigned CSKYMCCodeEmitter::getImmJMPIX(const MCInst &MI, unsigned Idx,
279 const MCSubtargetInfo &STI) const {
280 if (MI.getOperand(Idx).getImm() == 16)
281 return 0;
282 else if (MI.getOperand(Idx).getImm() == 24)
283 return 1;
284 else if (MI.getOperand(Idx).getImm() == 32)
285 return 2;
286 else if (MI.getOperand(Idx).getImm() == 40)
287 return 3;
288 else
289 assert(0);
290}
291
293 const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Expr);
294
295 switch (CSKYExpr->getKind()) {
296 default:
297 llvm_unreachable("Unhandled fixup kind!");
316 }
317}
318
320 MCContext &Ctx) {
321 return new CSKYMCCodeEmitter(Ctx, MCII);
322}
323
324#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:76
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:448
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:67
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:37
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:577
#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:96
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.