Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp
35294 views
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"
15
#include "MCTargetDesc/CSKYMCTargetDesc.h"
16
#include "llvm/ADT/Statistic.h"
17
#include "llvm/MC/MCInstBuilder.h"
18
#include "llvm/MC/MCInstrInfo.h"
19
#include "llvm/MC/MCRegisterInfo.h"
20
#include "llvm/MC/MCSubtargetInfo.h"
21
#include "llvm/Support/Casting.h"
22
#include "llvm/Support/EndianStream.h"
23
24
using namespace llvm;
25
26
#define DEBUG_TYPE "csky-mccode-emitter"
27
28
STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
29
30
unsigned CSKYMCCodeEmitter::getOImmOpValue(const MCInst &MI, unsigned Idx,
31
SmallVectorImpl<MCFixup> &Fixups,
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
38
unsigned
39
CSKYMCCodeEmitter::getImmOpValueIDLY(const MCInst &MI, unsigned Idx,
40
SmallVectorImpl<MCFixup> &Fixups,
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
49
unsigned
50
CSKYMCCodeEmitter::getImmOpValueMSBSize(const MCInst &MI, unsigned Idx,
51
SmallVectorImpl<MCFixup> &Fixups,
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
60
static 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),
63
llvm::endianness::little);
64
support::endian::write(CB, static_cast<uint16_t>(Bin),
65
llvm::endianness::little);
66
}
67
68
void CSKYMCCodeEmitter::expandJBTF(const MCInst &MI, SmallVectorImpl<char> &CB,
69
SmallVectorImpl<MCFixup> &Fixups,
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
94
void CSKYMCCodeEmitter::expandNEG(const MCInst &MI, SmallVectorImpl<char> &CB,
95
SmallVectorImpl<MCFixup> &Fixups,
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
116
void CSKYMCCodeEmitter::expandRSUBI(const MCInst &MI, SmallVectorImpl<char> &CB,
117
SmallVectorImpl<MCFixup> &Fixups,
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
138
void CSKYMCCodeEmitter::encodeInstruction(const MCInst &MI,
139
SmallVectorImpl<char> &CB,
140
SmallVectorImpl<MCFixup> &Fixups,
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
234
unsigned
235
CSKYMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
236
SmallVectorImpl<MCFixup> &Fixups,
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
248
unsigned
249
CSKYMCCodeEmitter::getRegSeqImmOpValue(const MCInst &MI, unsigned Idx,
250
SmallVectorImpl<MCFixup> &Fixups,
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) -
259
Ctx.getRegisterInfo()->getEncodingValue(Ry);
260
261
return ((Ctx.getRegisterInfo()->getEncodingValue(Ry) << 5) | Imm);
262
}
263
264
unsigned
265
CSKYMCCodeEmitter::getRegisterSeqOpValue(const MCInst &MI, unsigned Op,
266
SmallVectorImpl<MCFixup> &Fixups,
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
278
unsigned CSKYMCCodeEmitter::getImmJMPIX(const MCInst &MI, unsigned Idx,
279
SmallVectorImpl<MCFixup> &Fixups,
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
293
MCFixupKind CSKYMCCodeEmitter::getTargetFixup(const MCExpr *Expr) const {
294
const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Expr);
295
296
switch (CSKYExpr->getKind()) {
297
default:
298
llvm_unreachable("Unhandled fixup kind!");
299
case CSKYMCExpr::VK_CSKY_ADDR:
300
return MCFixupKind(CSKY::fixup_csky_addr32);
301
case CSKYMCExpr::VK_CSKY_ADDR_HI16:
302
return MCFixupKind(CSKY::fixup_csky_addr_hi16);
303
case CSKYMCExpr::VK_CSKY_ADDR_LO16:
304
return MCFixupKind(CSKY::fixup_csky_addr_lo16);
305
case CSKYMCExpr::VK_CSKY_GOT:
306
return MCFixupKind(CSKY::fixup_csky_got32);
307
case CSKYMCExpr::VK_CSKY_GOTPC:
308
return MCFixupKind(CSKY::fixup_csky_gotpc);
309
case CSKYMCExpr::VK_CSKY_GOTOFF:
310
return MCFixupKind(CSKY::fixup_csky_gotoff);
311
case CSKYMCExpr::VK_CSKY_PLT:
312
return MCFixupKind(CSKY::fixup_csky_plt32);
313
case CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4:
314
return MCFixupKind(CSKY::fixup_csky_plt_imm18_scale4);
315
case CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4:
316
return MCFixupKind(CSKY::fixup_csky_got_imm18_scale4);
317
}
318
}
319
320
MCCodeEmitter *llvm::createCSKYMCCodeEmitter(const MCInstrInfo &MCII,
321
MCContext &Ctx) {
322
return new CSKYMCCodeEmitter(Ctx, MCII);
323
}
324
325
#include "CSKYGenMCCodeEmitter.inc"
326
327