1 | //=- LoongArchMCCodeEmitter.cpp - Convert LoongArch code to machine code --===// |
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 LoongArchMCCodeEmitter class. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "LoongArchFixupKinds.h" |
14 | #include "MCTargetDesc/LoongArchBaseInfo.h" |
15 | #include "MCTargetDesc/LoongArchMCExpr.h" |
16 | #include "MCTargetDesc/LoongArchMCTargetDesc.h" |
17 | #include "llvm/MC/MCCodeEmitter.h" |
18 | #include "llvm/MC/MCContext.h" |
19 | #include "llvm/MC/MCInstBuilder.h" |
20 | #include "llvm/MC/MCInstrInfo.h" |
21 | #include "llvm/MC/MCRegisterInfo.h" |
22 | #include "llvm/MC/MCSubtargetInfo.h" |
23 | #include "llvm/Support/Casting.h" |
24 | #include "llvm/Support/EndianStream.h" |
25 | |
26 | using namespace llvm; |
27 | |
28 | #define DEBUG_TYPE "mccodeemitter" |
29 | |
30 | namespace { |
31 | class LoongArchMCCodeEmitter : public MCCodeEmitter { |
32 | LoongArchMCCodeEmitter(const LoongArchMCCodeEmitter &) = delete; |
33 | void operator=(const LoongArchMCCodeEmitter &) = delete; |
34 | MCContext &Ctx; |
35 | MCInstrInfo const &MCII; |
36 | |
37 | public: |
38 | LoongArchMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII) |
39 | : Ctx(ctx), MCII(MCII) {} |
40 | |
41 | ~LoongArchMCCodeEmitter() override {} |
42 | |
43 | void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB, |
44 | SmallVectorImpl<MCFixup> &Fixups, |
45 | const MCSubtargetInfo &STI) const override; |
46 | |
47 | template <unsigned Opc> |
48 | void expandToVectorLDI(const MCInst &MI, SmallVectorImpl<char> &CB, |
49 | SmallVectorImpl<MCFixup> &Fixups, |
50 | const MCSubtargetInfo &STI) const; |
51 | |
52 | void expandAddTPRel(const MCInst &MI, SmallVectorImpl<char> &CB, |
53 | SmallVectorImpl<MCFixup> &Fixups, |
54 | const MCSubtargetInfo &STI) const; |
55 | |
56 | /// TableGen'erated function for getting the binary encoding for an |
57 | /// instruction. |
58 | uint64_t getBinaryCodeForInstr(const MCInst &MI, |
59 | SmallVectorImpl<MCFixup> &Fixups, |
60 | const MCSubtargetInfo &STI) const; |
61 | |
62 | /// Return binary encoding of operand. If the machine operand requires |
63 | /// relocation, record the relocation and return zero. |
64 | unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, |
65 | SmallVectorImpl<MCFixup> &Fixups, |
66 | const MCSubtargetInfo &STI) const; |
67 | |
68 | /// Return binary encoding of an immediate operand specified by OpNo. |
69 | /// The value returned is the value of the immediate minus 1. |
70 | /// Note that this function is dedicated to specific immediate types, |
71 | /// e.g. uimm2_plus1. |
72 | unsigned getImmOpValueSub1(const MCInst &MI, unsigned OpNo, |
73 | SmallVectorImpl<MCFixup> &Fixups, |
74 | const MCSubtargetInfo &STI) const; |
75 | |
76 | /// Return binary encoding of an immediate operand specified by OpNo. |
77 | /// The value returned is the value of the immediate shifted right |
78 | // arithmetically by N. |
79 | /// Note that this function is dedicated to specific immediate types, |
80 | /// e.g. simm14_lsl2, simm16_lsl2, simm21_lsl2 and simm26_lsl2. |
81 | template <unsigned N> |
82 | unsigned getImmOpValueAsr(const MCInst &MI, unsigned OpNo, |
83 | SmallVectorImpl<MCFixup> &Fixups, |
84 | const MCSubtargetInfo &STI) const { |
85 | const MCOperand &MO = MI.getOperand(i: OpNo); |
86 | if (MO.isImm()) { |
87 | unsigned Res = MI.getOperand(i: OpNo).getImm(); |
88 | assert((Res & ((1U << N) - 1U)) == 0 && "lowest N bits are non-zero" ); |
89 | return Res >> N; |
90 | } |
91 | return getExprOpValue(MI, MO, Fixups, STI); |
92 | } |
93 | |
94 | unsigned getExprOpValue(const MCInst &MI, const MCOperand &MO, |
95 | SmallVectorImpl<MCFixup> &Fixups, |
96 | const MCSubtargetInfo &STI) const; |
97 | }; |
98 | } // end namespace |
99 | |
100 | unsigned |
101 | LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, |
102 | SmallVectorImpl<MCFixup> &Fixups, |
103 | const MCSubtargetInfo &STI) const { |
104 | |
105 | if (MO.isReg()) |
106 | return Ctx.getRegisterInfo()->getEncodingValue(RegNo: MO.getReg()); |
107 | |
108 | if (MO.isImm()) |
109 | return static_cast<unsigned>(MO.getImm()); |
110 | |
111 | // MO must be an Expr. |
112 | assert(MO.isExpr()); |
113 | return getExprOpValue(MI, MO, Fixups, STI); |
114 | } |
115 | |
116 | unsigned |
117 | LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo, |
118 | SmallVectorImpl<MCFixup> &Fixups, |
119 | const MCSubtargetInfo &STI) const { |
120 | return MI.getOperand(i: OpNo).getImm() - 1; |
121 | } |
122 | |
123 | unsigned |
124 | LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO, |
125 | SmallVectorImpl<MCFixup> &Fixups, |
126 | const MCSubtargetInfo &STI) const { |
127 | assert(MO.isExpr() && "getExprOpValue expects only expressions" ); |
128 | bool RelaxCandidate = false; |
129 | bool EnableRelax = STI.hasFeature(Feature: LoongArch::FeatureRelax); |
130 | const MCExpr *Expr = MO.getExpr(); |
131 | MCExpr::ExprKind Kind = Expr->getKind(); |
132 | LoongArch::Fixups FixupKind = LoongArch::fixup_loongarch_invalid; |
133 | if (Kind == MCExpr::Target) { |
134 | const LoongArchMCExpr *LAExpr = cast<LoongArchMCExpr>(Val: Expr); |
135 | |
136 | RelaxCandidate = LAExpr->getRelaxHint(); |
137 | switch (LAExpr->getKind()) { |
138 | case LoongArchMCExpr::VK_LoongArch_None: |
139 | case LoongArchMCExpr::VK_LoongArch_Invalid: |
140 | llvm_unreachable("Unhandled fixup kind!" ); |
141 | case LoongArchMCExpr::VK_LoongArch_TLS_LE_ADD_R: |
142 | llvm_unreachable("VK_LoongArch_TLS_LE_ADD_R should not represent an " |
143 | "instruction operand" ); |
144 | case LoongArchMCExpr::VK_LoongArch_B16: |
145 | FixupKind = LoongArch::fixup_loongarch_b16; |
146 | break; |
147 | case LoongArchMCExpr::VK_LoongArch_B21: |
148 | FixupKind = LoongArch::fixup_loongarch_b21; |
149 | break; |
150 | case LoongArchMCExpr::VK_LoongArch_B26: |
151 | case LoongArchMCExpr::VK_LoongArch_CALL: |
152 | case LoongArchMCExpr::VK_LoongArch_CALL_PLT: |
153 | FixupKind = LoongArch::fixup_loongarch_b26; |
154 | break; |
155 | case LoongArchMCExpr::VK_LoongArch_ABS_HI20: |
156 | FixupKind = LoongArch::fixup_loongarch_abs_hi20; |
157 | break; |
158 | case LoongArchMCExpr::VK_LoongArch_ABS_LO12: |
159 | FixupKind = LoongArch::fixup_loongarch_abs_lo12; |
160 | break; |
161 | case LoongArchMCExpr::VK_LoongArch_ABS64_LO20: |
162 | FixupKind = LoongArch::fixup_loongarch_abs64_lo20; |
163 | break; |
164 | case LoongArchMCExpr::VK_LoongArch_ABS64_HI12: |
165 | FixupKind = LoongArch::fixup_loongarch_abs64_hi12; |
166 | break; |
167 | case LoongArchMCExpr::VK_LoongArch_PCALA_HI20: |
168 | FixupKind = LoongArch::fixup_loongarch_pcala_hi20; |
169 | break; |
170 | case LoongArchMCExpr::VK_LoongArch_PCALA_LO12: |
171 | FixupKind = LoongArch::fixup_loongarch_pcala_lo12; |
172 | break; |
173 | case LoongArchMCExpr::VK_LoongArch_PCALA64_LO20: |
174 | FixupKind = LoongArch::fixup_loongarch_pcala64_lo20; |
175 | break; |
176 | case LoongArchMCExpr::VK_LoongArch_PCALA64_HI12: |
177 | FixupKind = LoongArch::fixup_loongarch_pcala64_hi12; |
178 | break; |
179 | case LoongArchMCExpr::VK_LoongArch_GOT_PC_HI20: |
180 | FixupKind = LoongArch::fixup_loongarch_got_pc_hi20; |
181 | break; |
182 | case LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12: |
183 | FixupKind = LoongArch::fixup_loongarch_got_pc_lo12; |
184 | break; |
185 | case LoongArchMCExpr::VK_LoongArch_GOT64_PC_LO20: |
186 | FixupKind = LoongArch::fixup_loongarch_got64_pc_lo20; |
187 | break; |
188 | case LoongArchMCExpr::VK_LoongArch_GOT64_PC_HI12: |
189 | FixupKind = LoongArch::fixup_loongarch_got64_pc_hi12; |
190 | break; |
191 | case LoongArchMCExpr::VK_LoongArch_GOT_HI20: |
192 | FixupKind = LoongArch::fixup_loongarch_got_hi20; |
193 | break; |
194 | case LoongArchMCExpr::VK_LoongArch_GOT_LO12: |
195 | FixupKind = LoongArch::fixup_loongarch_got_lo12; |
196 | break; |
197 | case LoongArchMCExpr::VK_LoongArch_GOT64_LO20: |
198 | FixupKind = LoongArch::fixup_loongarch_got64_lo20; |
199 | break; |
200 | case LoongArchMCExpr::VK_LoongArch_GOT64_HI12: |
201 | FixupKind = LoongArch::fixup_loongarch_got64_hi12; |
202 | break; |
203 | case LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20: |
204 | FixupKind = LoongArch::fixup_loongarch_tls_le_hi20; |
205 | break; |
206 | case LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12: |
207 | FixupKind = LoongArch::fixup_loongarch_tls_le_lo12; |
208 | break; |
209 | case LoongArchMCExpr::VK_LoongArch_TLS_LE64_LO20: |
210 | FixupKind = LoongArch::fixup_loongarch_tls_le64_lo20; |
211 | break; |
212 | case LoongArchMCExpr::VK_LoongArch_TLS_LE64_HI12: |
213 | FixupKind = LoongArch::fixup_loongarch_tls_le64_hi12; |
214 | break; |
215 | case LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_HI20: |
216 | FixupKind = LoongArch::fixup_loongarch_tls_ie_pc_hi20; |
217 | break; |
218 | case LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_LO12: |
219 | FixupKind = LoongArch::fixup_loongarch_tls_ie_pc_lo12; |
220 | break; |
221 | case LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_LO20: |
222 | FixupKind = LoongArch::fixup_loongarch_tls_ie64_pc_lo20; |
223 | break; |
224 | case LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_HI12: |
225 | FixupKind = LoongArch::fixup_loongarch_tls_ie64_pc_hi12; |
226 | break; |
227 | case LoongArchMCExpr::VK_LoongArch_TLS_IE_HI20: |
228 | FixupKind = LoongArch::fixup_loongarch_tls_ie_hi20; |
229 | break; |
230 | case LoongArchMCExpr::VK_LoongArch_TLS_IE_LO12: |
231 | FixupKind = LoongArch::fixup_loongarch_tls_ie_lo12; |
232 | break; |
233 | case LoongArchMCExpr::VK_LoongArch_TLS_IE64_LO20: |
234 | FixupKind = LoongArch::fixup_loongarch_tls_ie64_lo20; |
235 | break; |
236 | case LoongArchMCExpr::VK_LoongArch_TLS_IE64_HI12: |
237 | FixupKind = LoongArch::fixup_loongarch_tls_ie64_hi12; |
238 | break; |
239 | case LoongArchMCExpr::VK_LoongArch_TLS_LD_PC_HI20: |
240 | FixupKind = LoongArch::fixup_loongarch_tls_ld_pc_hi20; |
241 | break; |
242 | case LoongArchMCExpr::VK_LoongArch_TLS_LD_HI20: |
243 | FixupKind = LoongArch::fixup_loongarch_tls_ld_hi20; |
244 | break; |
245 | case LoongArchMCExpr::VK_LoongArch_TLS_GD_PC_HI20: |
246 | FixupKind = LoongArch::fixup_loongarch_tls_gd_pc_hi20; |
247 | break; |
248 | case LoongArchMCExpr::VK_LoongArch_TLS_GD_HI20: |
249 | FixupKind = LoongArch::fixup_loongarch_tls_gd_hi20; |
250 | break; |
251 | case LoongArchMCExpr::VK_LoongArch_CALL36: |
252 | FixupKind = LoongArch::fixup_loongarch_call36; |
253 | break; |
254 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC_PC_HI20: |
255 | FixupKind = LoongArch::fixup_loongarch_tls_desc_pc_hi20; |
256 | break; |
257 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC_PC_LO12: |
258 | FixupKind = LoongArch::fixup_loongarch_tls_desc_pc_lo12; |
259 | break; |
260 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC64_PC_LO20: |
261 | FixupKind = LoongArch::fixup_loongarch_tls_desc64_pc_lo20; |
262 | break; |
263 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC64_PC_HI12: |
264 | FixupKind = LoongArch::fixup_loongarch_tls_desc64_pc_hi12; |
265 | break; |
266 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC_HI20: |
267 | FixupKind = LoongArch::fixup_loongarch_tls_desc_hi20; |
268 | break; |
269 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC_LO12: |
270 | FixupKind = LoongArch::fixup_loongarch_tls_desc_lo12; |
271 | break; |
272 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC64_LO20: |
273 | FixupKind = LoongArch::fixup_loongarch_tls_desc64_lo20; |
274 | break; |
275 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC64_HI12: |
276 | FixupKind = LoongArch::fixup_loongarch_tls_desc64_hi12; |
277 | break; |
278 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC_LD: |
279 | FixupKind = LoongArch::fixup_loongarch_tls_desc_ld; |
280 | break; |
281 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC_CALL: |
282 | FixupKind = LoongArch::fixup_loongarch_tls_desc_call; |
283 | break; |
284 | case LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20_R: |
285 | FixupKind = LoongArch::fixup_loongarch_tls_le_hi20_r; |
286 | break; |
287 | case LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12_R: |
288 | FixupKind = LoongArch::fixup_loongarch_tls_le_lo12_r; |
289 | break; |
290 | case LoongArchMCExpr::VK_LoongArch_PCREL20_S2: |
291 | FixupKind = LoongArch::fixup_loongarch_pcrel20_s2; |
292 | break; |
293 | case LoongArchMCExpr::VK_LoongArch_TLS_LD_PCREL20_S2: |
294 | FixupKind = LoongArch::fixup_loongarch_tls_ld_pcrel20_s2; |
295 | break; |
296 | case LoongArchMCExpr::VK_LoongArch_TLS_GD_PCREL20_S2: |
297 | FixupKind = LoongArch::fixup_loongarch_tls_gd_pcrel20_s2; |
298 | break; |
299 | case LoongArchMCExpr::VK_LoongArch_TLS_DESC_PCREL20_S2: |
300 | FixupKind = LoongArch::fixup_loongarch_tls_desc_pcrel20_s2; |
301 | break; |
302 | } |
303 | } else if (Kind == MCExpr::SymbolRef && |
304 | cast<MCSymbolRefExpr>(Val: Expr)->getKind() == |
305 | MCSymbolRefExpr::VK_None) { |
306 | switch (MI.getOpcode()) { |
307 | default: |
308 | break; |
309 | case LoongArch::BEQ: |
310 | case LoongArch::BNE: |
311 | case LoongArch::BLT: |
312 | case LoongArch::BGE: |
313 | case LoongArch::BLTU: |
314 | case LoongArch::BGEU: |
315 | FixupKind = LoongArch::fixup_loongarch_b16; |
316 | break; |
317 | case LoongArch::BEQZ: |
318 | case LoongArch::BNEZ: |
319 | case LoongArch::BCEQZ: |
320 | case LoongArch::BCNEZ: |
321 | FixupKind = LoongArch::fixup_loongarch_b21; |
322 | break; |
323 | case LoongArch::B: |
324 | case LoongArch::BL: |
325 | FixupKind = LoongArch::fixup_loongarch_b26; |
326 | break; |
327 | } |
328 | } |
329 | |
330 | assert(FixupKind != LoongArch::fixup_loongarch_invalid && |
331 | "Unhandled expression!" ); |
332 | |
333 | Fixups.push_back( |
334 | Elt: MCFixup::create(Offset: 0, Value: Expr, Kind: MCFixupKind(FixupKind), Loc: MI.getLoc())); |
335 | |
336 | // Emit an R_LARCH_RELAX if linker relaxation is enabled and LAExpr has relax |
337 | // hint. |
338 | if (EnableRelax && RelaxCandidate) { |
339 | const MCConstantExpr *Dummy = MCConstantExpr::create(Value: 0, Ctx); |
340 | Fixups.push_back(Elt: MCFixup::create( |
341 | Offset: 0, Value: Dummy, Kind: MCFixupKind(LoongArch::fixup_loongarch_relax), Loc: MI.getLoc())); |
342 | } |
343 | |
344 | return 0; |
345 | } |
346 | |
347 | template <unsigned Opc> |
348 | void LoongArchMCCodeEmitter::expandToVectorLDI( |
349 | const MCInst &MI, SmallVectorImpl<char> &CB, |
350 | SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { |
351 | int64_t Imm = MI.getOperand(i: 1).getImm() & 0x3FF; |
352 | switch (MI.getOpcode()) { |
353 | case LoongArch::PseudoVREPLI_B: |
354 | case LoongArch::PseudoXVREPLI_B: |
355 | break; |
356 | case LoongArch::PseudoVREPLI_H: |
357 | case LoongArch::PseudoXVREPLI_H: |
358 | Imm |= 0x400; |
359 | break; |
360 | case LoongArch::PseudoVREPLI_W: |
361 | case LoongArch::PseudoXVREPLI_W: |
362 | Imm |= 0x800; |
363 | break; |
364 | case LoongArch::PseudoVREPLI_D: |
365 | case LoongArch::PseudoXVREPLI_D: |
366 | Imm |= 0xC00; |
367 | break; |
368 | } |
369 | MCInst TmpInst = MCInstBuilder(Opc).addOperand(Op: MI.getOperand(i: 0)).addImm(Val: Imm); |
370 | uint32_t Binary = getBinaryCodeForInstr(MI: TmpInst, Fixups, STI); |
371 | support::endian::write(Out&: CB, V: Binary, E: llvm::endianness::little); |
372 | } |
373 | |
374 | void LoongArchMCCodeEmitter::expandAddTPRel(const MCInst &MI, |
375 | SmallVectorImpl<char> &CB, |
376 | SmallVectorImpl<MCFixup> &Fixups, |
377 | const MCSubtargetInfo &STI) const { |
378 | MCOperand Rd = MI.getOperand(i: 0); |
379 | MCOperand Rj = MI.getOperand(i: 1); |
380 | MCOperand Rk = MI.getOperand(i: 2); |
381 | MCOperand Symbol = MI.getOperand(i: 3); |
382 | assert(Symbol.isExpr() && |
383 | "Expected expression as third input to TP-relative add" ); |
384 | |
385 | const LoongArchMCExpr *Expr = dyn_cast<LoongArchMCExpr>(Val: Symbol.getExpr()); |
386 | assert(Expr && |
387 | Expr->getKind() == LoongArchMCExpr::VK_LoongArch_TLS_LE_ADD_R && |
388 | "Expected %le_add_r relocation on TP-relative symbol" ); |
389 | |
390 | // Emit the correct %le_add_r relocation for the symbol. |
391 | // TODO: Emit R_LARCH_RELAX for %le_add_r where the relax feature is enabled. |
392 | Fixups.push_back(Elt: MCFixup::create( |
393 | Offset: 0, Value: Expr, Kind: MCFixupKind(LoongArch::fixup_loongarch_tls_le_add_r), |
394 | Loc: MI.getLoc())); |
395 | |
396 | // Emit a normal ADD instruction with the given operands. |
397 | unsigned ADD = MI.getOpcode() == LoongArch::PseudoAddTPRel_D |
398 | ? LoongArch::ADD_D |
399 | : LoongArch::ADD_W; |
400 | MCInst TmpInst = |
401 | MCInstBuilder(ADD).addOperand(Op: Rd).addOperand(Op: Rj).addOperand(Op: Rk); |
402 | uint32_t Binary = getBinaryCodeForInstr(MI: TmpInst, Fixups, STI); |
403 | support::endian::write(Out&: CB, V: Binary, E: llvm::endianness::little); |
404 | } |
405 | |
406 | void LoongArchMCCodeEmitter::encodeInstruction( |
407 | const MCInst &MI, SmallVectorImpl<char> &CB, |
408 | SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { |
409 | const MCInstrDesc &Desc = MCII.get(Opcode: MI.getOpcode()); |
410 | // Get byte count of instruction. |
411 | unsigned Size = Desc.getSize(); |
412 | |
413 | switch (MI.getOpcode()) { |
414 | default: |
415 | break; |
416 | case LoongArch::PseudoVREPLI_B: |
417 | case LoongArch::PseudoVREPLI_H: |
418 | case LoongArch::PseudoVREPLI_W: |
419 | case LoongArch::PseudoVREPLI_D: |
420 | return expandToVectorLDI<LoongArch::VLDI>(MI, CB, Fixups, STI); |
421 | case LoongArch::PseudoXVREPLI_B: |
422 | case LoongArch::PseudoXVREPLI_H: |
423 | case LoongArch::PseudoXVREPLI_W: |
424 | case LoongArch::PseudoXVREPLI_D: |
425 | return expandToVectorLDI<LoongArch::XVLDI>(MI, CB, Fixups, STI); |
426 | case LoongArch::PseudoAddTPRel_W: |
427 | case LoongArch::PseudoAddTPRel_D: |
428 | return expandAddTPRel(MI, CB, Fixups, STI); |
429 | } |
430 | |
431 | switch (Size) { |
432 | default: |
433 | llvm_unreachable("Unhandled encodeInstruction length!" ); |
434 | case 4: { |
435 | uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); |
436 | support::endian::write(Out&: CB, V: Bits, E: llvm::endianness::little); |
437 | break; |
438 | } |
439 | } |
440 | } |
441 | |
442 | MCCodeEmitter *llvm::createLoongArchMCCodeEmitter(const MCInstrInfo &MCII, |
443 | MCContext &Ctx) { |
444 | return new LoongArchMCCodeEmitter(Ctx, MCII); |
445 | } |
446 | |
447 | #include "LoongArchGenMCCodeEmitter.inc" |
448 | |