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 "CSKYMCAsmInfo.h"
14 #include "MCTargetDesc/CSKYFixupKinds.h"
15 #include "MCTargetDesc/CSKYMCAsmInfo.h"
16 #include "MCTargetDesc/CSKYMCTargetDesc.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/MC/MCCodeEmitter.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCInstBuilder.h"
21 #include "llvm/MC/MCInstrInfo.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/EndianStream.h"
26
27 using namespace llvm;
28
29 #define DEBUG_TYPE "csky-mccode-emitter"
30
31 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
32
addFixup(SmallVectorImpl<MCFixup> & Fixups,uint32_t Offset,const MCExpr * Value,uint16_t Kind)33 static void addFixup(SmallVectorImpl<MCFixup> &Fixups, uint32_t Offset,
34 const MCExpr *Value, uint16_t Kind) {
35 bool PCRel = false;
36 switch (Kind) {
37 case CSKY::Fixups::fixup_csky_pcrel_imm16_scale2:
38 case CSKY::Fixups::fixup_csky_pcrel_uimm16_scale4:
39 case CSKY::Fixups::fixup_csky_pcrel_imm26_scale2:
40 case CSKY::Fixups::fixup_csky_pcrel_imm18_scale2:
41 case CSKY::Fixups::fixup_csky_gotpc:
42 case CSKY::Fixups::fixup_csky_pcrel_imm10_scale2:
43 case CSKY::Fixups::fixup_csky_pcrel_uimm7_scale4:
44 case CSKY::Fixups::fixup_csky_pcrel_uimm8_scale4:
45 PCRel = true;
46 }
47 Fixups.push_back(MCFixup::create(Offset, Value, Kind, PCRel));
48 }
49
50 namespace {
51 class CSKYMCCodeEmitter : public MCCodeEmitter {
52 MCContext &Ctx;
53 const MCInstrInfo &MII;
54
55 public:
CSKYMCCodeEmitter(MCContext & Ctx,const MCInstrInfo & MII)56 CSKYMCCodeEmitter(MCContext &Ctx, const MCInstrInfo &MII)
57 : Ctx(Ctx), MII(MII) {}
58
~CSKYMCCodeEmitter()59 ~CSKYMCCodeEmitter() {}
60
61 void encodeInstruction(const MCInst &Inst, SmallVectorImpl<char> &CB,
62 SmallVectorImpl<MCFixup> &Fixups,
63 const MCSubtargetInfo &STI) const override;
64
65 // Generated by tablegen.
66 uint64_t getBinaryCodeForInstr(const MCInst &MI,
67 SmallVectorImpl<MCFixup> &Fixups,
68 const MCSubtargetInfo &STI) const;
69
70 // Default encoding method used by tablegen.
71 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
72 SmallVectorImpl<MCFixup> &Fixups,
73 const MCSubtargetInfo &STI) const;
74
75 template <int shift = 0>
getImmOpValue(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const76 unsigned getImmOpValue(const MCInst &MI, unsigned Idx,
77 SmallVectorImpl<MCFixup> &Fixups,
78 const MCSubtargetInfo &STI) const {
79 const MCOperand &MO = MI.getOperand(Idx);
80 if (MO.isImm())
81 return (MO.getImm() >> shift);
82
83 assert(MO.isExpr() && "Unexpected MO type.");
84
85 MCFixupKind Kind = getTargetFixup(MO.getExpr());
86 addFixup(Fixups, 0, MO.getExpr(), Kind);
87 return 0;
88 }
89
90 unsigned getRegSeqImmOpValue(const MCInst &MI, unsigned Idx,
91 SmallVectorImpl<MCFixup> &Fixups,
92 const MCSubtargetInfo &STI) const;
93
94 unsigned getRegisterSeqOpValue(const MCInst &MI, unsigned Op,
95 SmallVectorImpl<MCFixup> &Fixups,
96 const MCSubtargetInfo &STI) const;
97
98 unsigned getOImmOpValue(const MCInst &MI, unsigned Idx,
99 SmallVectorImpl<MCFixup> &Fixups,
100 const MCSubtargetInfo &STI) const;
101
102 unsigned getImmOpValueIDLY(const MCInst &MI, unsigned Idx,
103 SmallVectorImpl<MCFixup> &Fixups,
104 const MCSubtargetInfo &STI) const;
105
106 unsigned getImmJMPIX(const MCInst &MI, unsigned Idx,
107 SmallVectorImpl<MCFixup> &Fixups,
108 const MCSubtargetInfo &STI) const;
109
110 unsigned getImmOpValueMSBSize(const MCInst &MI, unsigned Idx,
111 SmallVectorImpl<MCFixup> &Fixups,
112 const MCSubtargetInfo &STI) const;
113
getImmShiftOpValue(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const114 unsigned getImmShiftOpValue(const MCInst &MI, unsigned Idx,
115 SmallVectorImpl<MCFixup> &Fixups,
116 const MCSubtargetInfo &STI) const {
117 const MCOperand &MO = MI.getOperand(Idx);
118 assert(MO.isImm() && "Unexpected MO type.");
119 return 1 << MO.getImm();
120 }
121
122 MCFixupKind getTargetFixup(const MCExpr *Expr) const;
123
124 template <llvm::CSKY::Fixups FIXUP>
getBranchSymbolOpValue(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const125 unsigned getBranchSymbolOpValue(const MCInst &MI, unsigned Idx,
126 SmallVectorImpl<MCFixup> &Fixups,
127 const MCSubtargetInfo &STI) const {
128 const MCOperand &MO = MI.getOperand(Idx);
129
130 if (MO.isImm())
131 return MO.getImm() >> 1;
132
133 assert(MO.isExpr() && "Unexpected MO type.");
134
135 MCFixupKind Kind = MCFixupKind(FIXUP);
136 if (MO.getExpr()->getKind() == MCExpr::Specifier)
137 Kind = getTargetFixup(MO.getExpr());
138
139 addFixup(Fixups, 0, MO.getExpr(), Kind);
140 return 0;
141 }
142
143 template <llvm::CSKY::Fixups FIXUP>
getConstpoolSymbolOpValue(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const144 unsigned getConstpoolSymbolOpValue(const MCInst &MI, unsigned Idx,
145 SmallVectorImpl<MCFixup> &Fixups,
146 const MCSubtargetInfo &STI) const {
147 const MCOperand &MO = MI.getOperand(Idx);
148 assert(MO.isExpr() && "Unexpected MO type.");
149
150 MCFixupKind Kind = MCFixupKind(FIXUP);
151 if (MO.getExpr()->getKind() == MCExpr::Specifier)
152 Kind = getTargetFixup(MO.getExpr());
153
154 addFixup(Fixups, 0, MO.getExpr(), Kind);
155 return 0;
156 }
157
158 template <llvm::CSKY::Fixups FIXUP>
getDataSymbolOpValue(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const159 unsigned getDataSymbolOpValue(const MCInst &MI, unsigned Idx,
160 SmallVectorImpl<MCFixup> &Fixups,
161 const MCSubtargetInfo &STI) const {
162 const MCOperand &MO = MI.getOperand(Idx);
163 assert(MO.isExpr() && "Unexpected MO type.");
164
165 MCFixupKind Kind = MCFixupKind(FIXUP);
166 if (MO.getExpr()->getKind() == MCExpr::Specifier)
167 Kind = getTargetFixup(MO.getExpr());
168
169 addFixup(Fixups, 0, MO.getExpr(), Kind);
170 return 0;
171 }
172
getCallSymbolOpValue(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const173 unsigned getCallSymbolOpValue(const MCInst &MI, unsigned Idx,
174 SmallVectorImpl<MCFixup> &Fixups,
175 const MCSubtargetInfo &STI) const {
176 const MCOperand &MO = MI.getOperand(Idx);
177 assert(MO.isExpr() && "Unexpected MO type.");
178
179 MCFixupKind Kind = CSKY::fixup_csky_pcrel_imm26_scale2;
180 if (MO.getExpr()->getKind() == MCExpr::Specifier)
181 Kind = getTargetFixup(MO.getExpr());
182
183 addFixup(Fixups, 0, MO.getExpr(), Kind);
184 return 0;
185 }
186
getBareSymbolOpValue(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const187 unsigned getBareSymbolOpValue(const MCInst &MI, unsigned Idx,
188 SmallVectorImpl<MCFixup> &Fixups,
189 const MCSubtargetInfo &STI) const {
190 const MCOperand &MO = MI.getOperand(Idx);
191 assert(MO.isExpr() && "Unexpected MO type.");
192
193 MCFixupKind Kind = CSKY::fixup_csky_pcrel_imm18_scale2;
194 if (MO.getExpr()->getKind() == MCExpr::Specifier)
195 Kind = getTargetFixup(MO.getExpr());
196
197 addFixup(Fixups, 0, MO.getExpr(), Kind);
198 return 0;
199 }
200
201 void expandJBTF(const MCInst &MI, SmallVectorImpl<char> &CB,
202 SmallVectorImpl<MCFixup> &Fixups,
203 const MCSubtargetInfo &STI) const;
204 void expandNEG(const MCInst &MI, SmallVectorImpl<char> &CB,
205 SmallVectorImpl<MCFixup> &Fixups,
206 const MCSubtargetInfo &STI) const;
207 void expandRSUBI(const MCInst &MI, SmallVectorImpl<char> &CB,
208 SmallVectorImpl<MCFixup> &Fixups,
209 const MCSubtargetInfo &STI) const;
210 };
211 } // namespace
212
getOImmOpValue(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const213 unsigned CSKYMCCodeEmitter::getOImmOpValue(const MCInst &MI, unsigned Idx,
214 SmallVectorImpl<MCFixup> &Fixups,
215 const MCSubtargetInfo &STI) const {
216 const MCOperand &MO = MI.getOperand(Idx);
217 assert(MO.isImm() && "Unexpected MO type.");
218 return MO.getImm() - 1;
219 }
220
221 unsigned
getImmOpValueIDLY(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const222 CSKYMCCodeEmitter::getImmOpValueIDLY(const MCInst &MI, unsigned Idx,
223 SmallVectorImpl<MCFixup> &Fixups,
224 const MCSubtargetInfo &STI) const {
225 const MCOperand &MO = MI.getOperand(Idx);
226 assert(MO.isImm() && "Unexpected MO type.");
227
228 auto V = (MO.getImm() <= 3) ? 4 : MO.getImm();
229 return V - 1;
230 }
231
232 unsigned
getImmOpValueMSBSize(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const233 CSKYMCCodeEmitter::getImmOpValueMSBSize(const MCInst &MI, unsigned Idx,
234 SmallVectorImpl<MCFixup> &Fixups,
235 const MCSubtargetInfo &STI) const {
236 const MCOperand &MSB = MI.getOperand(Idx);
237 const MCOperand &LSB = MI.getOperand(Idx + 1);
238 assert(MSB.isImm() && LSB.isImm() && "Unexpected MO type.");
239
240 return MSB.getImm() - LSB.getImm();
241 }
242
writeData(uint32_t Bin,unsigned Size,SmallVectorImpl<char> & CB)243 static void writeData(uint32_t Bin, unsigned Size, SmallVectorImpl<char> &CB) {
244 if (Size == 4)
245 support::endian::write(CB, static_cast<uint16_t>(Bin >> 16),
246 llvm::endianness::little);
247 support::endian::write(CB, static_cast<uint16_t>(Bin),
248 llvm::endianness::little);
249 }
250
expandJBTF(const MCInst & MI,SmallVectorImpl<char> & CB,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const251 void CSKYMCCodeEmitter::expandJBTF(const MCInst &MI, SmallVectorImpl<char> &CB,
252 SmallVectorImpl<MCFixup> &Fixups,
253 const MCSubtargetInfo &STI) const {
254
255 MCInst TmpInst;
256
257 uint32_t Binary;
258
259 TmpInst =
260 MCInstBuilder(MI.getOpcode() == CSKY::JBT_E ? CSKY::BF16 : CSKY::BT16)
261 .addOperand(MI.getOperand(0))
262 .addImm(6);
263 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
264 writeData(Binary, 2, CB);
265
266 if (!STI.hasFeature(CSKY::Has2E3))
267 TmpInst = MCInstBuilder(CSKY::BR32)
268 .addOperand(MI.getOperand(1))
269 .addOperand(MI.getOperand(2));
270 else
271 TmpInst = MCInstBuilder(CSKY::JMPI32).addOperand(MI.getOperand(2));
272 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
273 Fixups[Fixups.size() - 1].setOffset(2);
274 writeData(Binary, 4, CB);
275 }
276
expandNEG(const MCInst & MI,SmallVectorImpl<char> & CB,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const277 void CSKYMCCodeEmitter::expandNEG(const MCInst &MI, SmallVectorImpl<char> &CB,
278 SmallVectorImpl<MCFixup> &Fixups,
279 const MCSubtargetInfo &STI) const {
280
281 MCInst TmpInst;
282 uint32_t Binary;
283 unsigned Size = MI.getOpcode() == CSKY::NEG32 ? 4 : 2;
284
285 TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
286 .addOperand(MI.getOperand(0))
287 .addOperand(MI.getOperand(1));
288 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
289 writeData(Binary, Size, CB);
290
291 TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
292 .addOperand(MI.getOperand(0))
293 .addOperand(MI.getOperand(0))
294 .addImm(1);
295 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
296 writeData(Binary, Size, CB);
297 }
298
expandRSUBI(const MCInst & MI,SmallVectorImpl<char> & CB,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const299 void CSKYMCCodeEmitter::expandRSUBI(const MCInst &MI, SmallVectorImpl<char> &CB,
300 SmallVectorImpl<MCFixup> &Fixups,
301 const MCSubtargetInfo &STI) const {
302
303 MCInst TmpInst;
304 uint32_t Binary;
305 unsigned Size = MI.getOpcode() == CSKY::RSUBI32 ? 4 : 2;
306
307 TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
308 .addOperand(MI.getOperand(0))
309 .addOperand(MI.getOperand(1));
310 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
311 writeData(Binary, Size, CB);
312
313 TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
314 .addOperand(MI.getOperand(0))
315 .addOperand(MI.getOperand(0))
316 .addImm(MI.getOperand(2).getImm() + 1);
317 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
318 writeData(Binary, Size, CB);
319 }
320
encodeInstruction(const MCInst & MI,SmallVectorImpl<char> & CB,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const321 void CSKYMCCodeEmitter::encodeInstruction(const MCInst &MI,
322 SmallVectorImpl<char> &CB,
323 SmallVectorImpl<MCFixup> &Fixups,
324 const MCSubtargetInfo &STI) const {
325 const MCInstrDesc &Desc = MII.get(MI.getOpcode());
326 unsigned Size = Desc.getSize();
327
328 MCInst TmpInst;
329
330 switch (MI.getOpcode()) {
331 default:
332 TmpInst = MI;
333 break;
334 case CSKY::JBT_E:
335 case CSKY::JBF_E:
336 expandJBTF(MI, CB, Fixups, STI);
337 MCNumEmitted += 2;
338 return;
339 case CSKY::NEG32:
340 case CSKY::NEG16:
341 expandNEG(MI, CB, Fixups, STI);
342 MCNumEmitted += 2;
343 return;
344 case CSKY::RSUBI32:
345 case CSKY::RSUBI16:
346 expandRSUBI(MI, CB, Fixups, STI);
347 MCNumEmitted += 2;
348 return;
349 case CSKY::JBSR32:
350 TmpInst = MCInstBuilder(CSKY::BSR32).addOperand(MI.getOperand(0));
351 break;
352 case CSKY::JBR16:
353 TmpInst = MCInstBuilder(CSKY::BR16).addOperand(MI.getOperand(0));
354 break;
355 case CSKY::JBR32:
356 TmpInst = MCInstBuilder(CSKY::BR32).addOperand(MI.getOperand(0));
357 break;
358 case CSKY::JBT16:
359 TmpInst = MCInstBuilder(CSKY::BT16)
360 .addOperand(MI.getOperand(0))
361 .addOperand(MI.getOperand(1));
362 break;
363 case CSKY::JBT32:
364 TmpInst = MCInstBuilder(CSKY::BT32)
365 .addOperand(MI.getOperand(0))
366 .addOperand(MI.getOperand(1));
367 break;
368 case CSKY::JBF16:
369 TmpInst = MCInstBuilder(CSKY::BF16)
370 .addOperand(MI.getOperand(0))
371 .addOperand(MI.getOperand(1));
372 break;
373 case CSKY::JBF32:
374 TmpInst = MCInstBuilder(CSKY::BF32)
375 .addOperand(MI.getOperand(0))
376 .addOperand(MI.getOperand(1));
377 break;
378 case CSKY::LRW32_Gen:
379 TmpInst = MCInstBuilder(CSKY::LRW32)
380 .addOperand(MI.getOperand(0))
381 .addOperand(MI.getOperand(2));
382 break;
383 case CSKY::LRW16_Gen:
384 TmpInst = MCInstBuilder(CSKY::LRW16)
385 .addOperand(MI.getOperand(0))
386 .addOperand(MI.getOperand(2));
387 break;
388 case CSKY::CMPLEI32:
389 TmpInst = MCInstBuilder(CSKY::CMPLTI32)
390 .addOperand(MI.getOperand(0))
391 .addOperand(MI.getOperand(1))
392 .addImm(MI.getOperand(2).getImm() + 1);
393 break;
394 case CSKY::CMPLEI16:
395 TmpInst = MCInstBuilder(CSKY::CMPLTI16)
396 .addOperand(MI.getOperand(0))
397 .addOperand(MI.getOperand(1))
398 .addImm(MI.getOperand(2).getImm() + 1);
399 break;
400 case CSKY::ROTRI32:
401 TmpInst = MCInstBuilder(CSKY::ROTLI32)
402 .addOperand(MI.getOperand(0))
403 .addOperand(MI.getOperand(1))
404 .addImm(32 - MI.getOperand(2).getImm());
405 break;
406 case CSKY::BGENI:
407 auto V = 1 << MI.getOperand(1).getImm();
408 TmpInst =
409 MCInstBuilder(CSKY::MOVI32).addOperand(MI.getOperand(0)).addImm(V);
410 break;
411 }
412
413 ++MCNumEmitted;
414 writeData(getBinaryCodeForInstr(TmpInst, Fixups, STI), Size, CB);
415 }
416
417 unsigned
getMachineOpValue(const MCInst & MI,const MCOperand & MO,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const418 CSKYMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
419 SmallVectorImpl<MCFixup> &Fixups,
420 const MCSubtargetInfo &STI) const {
421 if (MO.isReg())
422 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
423
424 if (MO.isImm())
425 return static_cast<unsigned>(MO.getImm());
426
427 llvm_unreachable("Unhandled expression!");
428 return 0;
429 }
430
431 unsigned
getRegSeqImmOpValue(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const432 CSKYMCCodeEmitter::getRegSeqImmOpValue(const MCInst &MI, unsigned Idx,
433 SmallVectorImpl<MCFixup> &Fixups,
434 const MCSubtargetInfo &STI) const {
435 assert(MI.getOperand(Idx).isReg() && "Unexpected MO type.");
436 assert(MI.getOperand(Idx + 1).isImm() && "Unexpected MO type.");
437
438 unsigned Ry = MI.getOperand(Idx).getReg();
439 unsigned Rz = MI.getOperand(Idx + 1).getImm();
440
441 unsigned Imm = Ctx.getRegisterInfo()->getEncodingValue(Rz) -
442 Ctx.getRegisterInfo()->getEncodingValue(Ry);
443
444 return ((Ctx.getRegisterInfo()->getEncodingValue(Ry) << 5) | Imm);
445 }
446
447 unsigned
getRegisterSeqOpValue(const MCInst & MI,unsigned Op,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const448 CSKYMCCodeEmitter::getRegisterSeqOpValue(const MCInst &MI, unsigned Op,
449 SmallVectorImpl<MCFixup> &Fixups,
450 const MCSubtargetInfo &STI) const {
451 unsigned Reg1 =
452 Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op).getReg());
453 unsigned Reg2 =
454 Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op + 1).getReg());
455
456 unsigned Binary = ((Reg1 & 0x1f) << 5) | (Reg2 - Reg1);
457
458 return Binary;
459 }
460
getImmJMPIX(const MCInst & MI,unsigned Idx,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const461 unsigned CSKYMCCodeEmitter::getImmJMPIX(const MCInst &MI, unsigned Idx,
462 SmallVectorImpl<MCFixup> &Fixups,
463 const MCSubtargetInfo &STI) const {
464 switch (MI.getOperand(Idx).getImm()) {
465 default:
466 llvm_unreachable("Unhandled jmpix imm!");
467 case 16:
468 return 0;
469 case 24:
470 return 1;
471 case 32:
472 return 2;
473 case 40:
474 return 3;
475 }
476 }
477
getTargetFixup(const MCExpr * Expr) const478 MCFixupKind CSKYMCCodeEmitter::getTargetFixup(const MCExpr *Expr) const {
479 const auto *CSKYExpr = cast<MCSpecifierExpr>(Expr);
480 switch (CSKYExpr->getSpecifier()) {
481 default:
482 llvm_unreachable("Unhandled fixup kind!");
483 case CSKY::S_ADDR:
484 return CSKY::fixup_csky_addr32;
485 case CSKY::S_ADDR_HI16:
486 return CSKY::fixup_csky_addr_hi16;
487 case CSKY::S_ADDR_LO16:
488 return CSKY::fixup_csky_addr_lo16;
489 case CSKY::S_GOT:
490 return CSKY::fixup_csky_got32;
491 case CSKY::S_GOTPC:
492 return CSKY::fixup_csky_gotpc;
493 case CSKY::S_GOTOFF:
494 return CSKY::fixup_csky_gotoff;
495 case CSKY::S_PLT:
496 return CSKY::fixup_csky_plt32;
497 case CSKY::S_PLT_IMM18_BY4:
498 return CSKY::fixup_csky_plt_imm18_scale4;
499 case CSKY::S_GOT_IMM18_BY4:
500 return CSKY::fixup_csky_got_imm18_scale4;
501 }
502 }
503
createCSKYMCCodeEmitter(const MCInstrInfo & MCII,MCContext & Ctx)504 MCCodeEmitter *llvm::createCSKYMCCodeEmitter(const MCInstrInfo &MCII,
505 MCContext &Ctx) {
506 return new CSKYMCCodeEmitter(Ctx, MCII);
507 }
508
509 #include "CSKYGenMCCodeEmitter.inc"
510