LLVM 18.0.0git
AArch64MCCodeEmitter.cpp
Go to the documentation of this file.
1//=- AArch64/AArch64MCCodeEmitter.cpp - Convert AArch64 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 AArch64MCCodeEmitter class.
10//
11//===----------------------------------------------------------------------===//
12
18#include "llvm/ADT/Statistic.h"
21#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCFixup.h"
23#include "llvm/MC/MCInst.h"
24#include "llvm/MC/MCInstrInfo.h"
28#include "llvm/Support/Endian.h"
32#include <cassert>
33#include <cstdint>
34
35using namespace llvm;
36
37#define DEBUG_TYPE "mccodeemitter"
38
39STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
40STATISTIC(MCNumFixups, "Number of MC fixups created.");
41
42namespace {
43
44class AArch64MCCodeEmitter : public MCCodeEmitter {
45 MCContext &Ctx;
46
47public:
48 AArch64MCCodeEmitter(const MCInstrInfo &, MCContext &ctx) : Ctx(ctx) {}
49 AArch64MCCodeEmitter(const AArch64MCCodeEmitter &) = delete;
50 void operator=(const AArch64MCCodeEmitter &) = delete;
51 ~AArch64MCCodeEmitter() override = default;
52
53 // getBinaryCodeForInstr - TableGen'erated function for getting the
54 // binary encoding for an instruction.
55 uint64_t getBinaryCodeForInstr(const MCInst &MI,
57 const MCSubtargetInfo &STI) const;
58
59 /// getMachineOpValue - Return binary encoding of operand. If the machine
60 /// operand requires relocation, record the relocation and return zero.
61 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
63 const MCSubtargetInfo &STI) const;
64
65 /// getLdStUImm12OpValue - Return encoding info for 12-bit unsigned immediate
66 /// attached to a load, store or prfm instruction. If operand requires a
67 /// relocation, record it and return zero in that part of the encoding.
68 template <uint32_t FixupKind>
69 uint32_t getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
71 const MCSubtargetInfo &STI) const;
72
73 /// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
74 /// target.
75 uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
77 const MCSubtargetInfo &STI) const;
78
79 /// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and
80 /// the 2-bit shift field.
81 uint32_t getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
83 const MCSubtargetInfo &STI) const;
84
85 /// getCondBranchTargetOpValue - Return the encoded value for a conditional
86 /// branch target.
87 uint32_t getCondBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
89 const MCSubtargetInfo &STI) const;
90
91 /// getLoadLiteralOpValue - Return the encoded value for a load-literal
92 /// pc-relative address.
93 uint32_t getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
95 const MCSubtargetInfo &STI) const;
96
97 /// getMemExtendOpValue - Return the encoded value for a reg-extend load/store
98 /// instruction: bit 0 is whether a shift is present, bit 1 is whether the
99 /// operation is a sign extend (as opposed to a zero extend).
100 uint32_t getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
102 const MCSubtargetInfo &STI) const;
103
104 /// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
105 /// branch target.
106 uint32_t getTestBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
108 const MCSubtargetInfo &STI) const;
109
110 /// getBranchTargetOpValue - Return the encoded value for an unconditional
111 /// branch target.
112 uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
114 const MCSubtargetInfo &STI) const;
115
116 /// getMoveWideImmOpValue - Return the encoded value for the immediate operand
117 /// of a MOVZ or MOVK instruction.
118 uint32_t getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
120 const MCSubtargetInfo &STI) const;
121
122 /// getVecShifterOpValue - Return the encoded value for the vector shifter.
123 uint32_t getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
125 const MCSubtargetInfo &STI) const;
126
127 /// getMoveVecShifterOpValue - Return the encoded value for the vector move
128 /// shifter (MSL).
129 uint32_t getMoveVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
131 const MCSubtargetInfo &STI) const;
132
133 /// getFixedPointScaleOpValue - Return the encoded value for the
134 // FP-to-fixed-point scale factor.
135 uint32_t getFixedPointScaleOpValue(const MCInst &MI, unsigned OpIdx,
137 const MCSubtargetInfo &STI) const;
138
139 uint32_t getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
141 const MCSubtargetInfo &STI) const;
142 uint32_t getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
144 const MCSubtargetInfo &STI) const;
145 uint32_t getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
147 const MCSubtargetInfo &STI) const;
148 uint32_t getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
150 const MCSubtargetInfo &STI) const;
151 uint32_t getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
153 const MCSubtargetInfo &STI) const;
154 uint32_t getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
156 const MCSubtargetInfo &STI) const;
157 uint32_t getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
159 const MCSubtargetInfo &STI) const;
160 uint32_t getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
162 const MCSubtargetInfo &STI) const;
163
164 uint32_t getImm8OptLsl(const MCInst &MI, unsigned OpIdx,
166 const MCSubtargetInfo &STI) const;
167 uint32_t getSVEIncDecImm(const MCInst &MI, unsigned OpIdx,
169 const MCSubtargetInfo &STI) const;
170
171 unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue,
172 const MCSubtargetInfo &STI) const;
173
176 const MCSubtargetInfo &STI) const override;
177
178 unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue,
179 const MCSubtargetInfo &STI) const;
180
181 template<int hasRs, int hasRt2> unsigned
182 fixLoadStoreExclusive(const MCInst &MI, unsigned EncodedValue,
183 const MCSubtargetInfo &STI) const;
184
185 unsigned fixOneOperandFPComparison(const MCInst &MI, unsigned EncodedValue,
186 const MCSubtargetInfo &STI) const;
187
188 template <unsigned Multiple>
189 uint32_t EncodeRegAsMultipleOf(const MCInst &MI, unsigned OpIdx,
191 const MCSubtargetInfo &STI) const;
192 uint32_t EncodePPR_p8to15(const MCInst &MI, unsigned OpIdx,
194 const MCSubtargetInfo &STI) const;
195 uint32_t EncodePNR_p8to15(const MCInst &MI, unsigned OpIdx,
197 const MCSubtargetInfo &STI) const;
198
199 uint32_t EncodeZPR2StridedRegisterClass(const MCInst &MI, unsigned OpIdx,
201 const MCSubtargetInfo &STI) const;
202 uint32_t EncodeZPR4StridedRegisterClass(const MCInst &MI, unsigned OpIdx,
204 const MCSubtargetInfo &STI) const;
205
206 uint32_t EncodeMatrixTileListRegisterClass(const MCInst &MI, unsigned OpIdx,
208 const MCSubtargetInfo &STI) const;
209 template <unsigned BaseReg>
210 uint32_t encodeMatrixIndexGPR32(const MCInst &MI, unsigned OpIdx,
212 const MCSubtargetInfo &STI) const;
213};
214
215} // end anonymous namespace
216
217/// getMachineOpValue - Return binary encoding of operand. If the machine
218/// operand requires relocation, record the relocation and return zero.
219unsigned
220AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
222 const MCSubtargetInfo &STI) const {
223 if (MO.isReg())
224 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
225
226 assert(MO.isImm() && "did not expect relocated expression");
227 return static_cast<unsigned>(MO.getImm());
228}
229
230template<unsigned FixupKind> uint32_t
231AArch64MCCodeEmitter::getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
233 const MCSubtargetInfo &STI) const {
234 const MCOperand &MO = MI.getOperand(OpIdx);
235 uint32_t ImmVal = 0;
236
237 if (MO.isImm())
238 ImmVal = static_cast<uint32_t>(MO.getImm());
239 else {
240 assert(MO.isExpr() && "unable to encode load/store imm operand");
241 MCFixupKind Kind = MCFixupKind(FixupKind);
242 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
243 ++MCNumFixups;
244 }
245
246 return ImmVal;
247}
248
249/// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
250/// target.
252AArch64MCCodeEmitter::getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
254 const MCSubtargetInfo &STI) const {
255 const MCOperand &MO = MI.getOperand(OpIdx);
256
257 // If the destination is an immediate, we have nothing to do.
258 if (MO.isImm())
259 return MO.getImm();
260 assert(MO.isExpr() && "Unexpected target type!");
261 const MCExpr *Expr = MO.getExpr();
262
263 MCFixupKind Kind = MI.getOpcode() == AArch64::ADR
266 Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
267
268 MCNumFixups += 1;
269
270 // All of the information is in the fixup.
271 return 0;
272}
273
274/// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and
275/// the 2-bit shift field. The shift field is stored in bits 13-14 of the
276/// return value.
278AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
280 const MCSubtargetInfo &STI) const {
281 // Suboperands are [imm, shifter].
282 const MCOperand &MO = MI.getOperand(OpIdx);
283 const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
285 "unexpected shift type for add/sub immediate");
286 unsigned ShiftVal = AArch64_AM::getShiftValue(MO1.getImm());
287 assert((ShiftVal == 0 || ShiftVal == 12) &&
288 "unexpected shift value for add/sub immediate");
289 if (MO.isImm())
290 return MO.getImm() | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
291 assert(MO.isExpr() && "Unable to encode MCOperand!");
292 const MCExpr *Expr = MO.getExpr();
293
294 // Encode the 12 bits of the fixup.
296 Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
297
298 ++MCNumFixups;
299
300 // Set the shift bit of the add instruction for relocation types
301 // R_AARCH64_TLSLE_ADD_TPREL_HI12 and R_AARCH64_TLSLD_ADD_DTPREL_HI12.
302 if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
303 AArch64MCExpr::VariantKind RefKind = A64E->getKind();
304 if (RefKind == AArch64MCExpr::VK_TPREL_HI12 ||
307 ShiftVal = 12;
308 }
309 return ShiftVal == 0 ? 0 : (1 << ShiftVal);
310}
311
312/// getCondBranchTargetOpValue - Return the encoded value for a conditional
313/// branch target.
314uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
315 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
316 const MCSubtargetInfo &STI) const {
317 const MCOperand &MO = MI.getOperand(OpIdx);
318
319 // If the destination is an immediate, we have nothing to do.
320 if (MO.isImm())
321 return MO.getImm();
322 assert(MO.isExpr() && "Unexpected target type!");
323
325 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
326
327 ++MCNumFixups;
328
329 // All of the information is in the fixup.
330 return 0;
331}
332
333/// getLoadLiteralOpValue - Return the encoded value for a load-literal
334/// pc-relative address.
336AArch64MCCodeEmitter::getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
338 const MCSubtargetInfo &STI) const {
339 const MCOperand &MO = MI.getOperand(OpIdx);
340
341 // If the destination is an immediate, we have nothing to do.
342 if (MO.isImm())
343 return MO.getImm();
344 assert(MO.isExpr() && "Unexpected target type!");
345
347 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
348
349 ++MCNumFixups;
350
351 // All of the information is in the fixup.
352 return 0;
353}
354
356AArch64MCCodeEmitter::getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
358 const MCSubtargetInfo &STI) const {
359 unsigned SignExtend = MI.getOperand(OpIdx).getImm();
360 unsigned DoShift = MI.getOperand(OpIdx + 1).getImm();
361 return (SignExtend << 1) | DoShift;
362}
363
365AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
367 const MCSubtargetInfo &STI) const {
368 const MCOperand &MO = MI.getOperand(OpIdx);
369
370 if (MO.isImm())
371 return MO.getImm();
372 assert(MO.isExpr() && "Unexpected movz/movk immediate");
373
374 Fixups.push_back(MCFixup::create(
376
377 ++MCNumFixups;
378
379 return 0;
380}
381
382/// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
383/// branch target.
384uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
385 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
386 const MCSubtargetInfo &STI) const {
387 const MCOperand &MO = MI.getOperand(OpIdx);
388
389 // If the destination is an immediate, we have nothing to do.
390 if (MO.isImm())
391 return MO.getImm();
392 assert(MO.isExpr() && "Unexpected ADR target type!");
393
395 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
396
397 ++MCNumFixups;
398
399 // All of the information is in the fixup.
400 return 0;
401}
402
403/// getBranchTargetOpValue - Return the encoded value for an unconditional
404/// branch target.
406AArch64MCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
408 const MCSubtargetInfo &STI) const {
409 const MCOperand &MO = MI.getOperand(OpIdx);
410
411 // If the destination is an immediate, we have nothing to do.
412 if (MO.isImm())
413 return MO.getImm();
414 assert(MO.isExpr() && "Unexpected ADR target type!");
415
416 MCFixupKind Kind = MI.getOpcode() == AArch64::BL
419 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
420
421 ++MCNumFixups;
422
423 // All of the information is in the fixup.
424 return 0;
425}
426
427/// getVecShifterOpValue - Return the encoded value for the vector shifter:
428///
429/// 00 -> 0
430/// 01 -> 8
431/// 10 -> 16
432/// 11 -> 24
434AArch64MCCodeEmitter::getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
436 const MCSubtargetInfo &STI) const {
437 const MCOperand &MO = MI.getOperand(OpIdx);
438 assert(MO.isImm() && "Expected an immediate value for the shift amount!");
439
440 switch (MO.getImm()) {
441 default:
442 break;
443 case 0:
444 return 0;
445 case 8:
446 return 1;
447 case 16:
448 return 2;
449 case 24:
450 return 3;
451 }
452
453 llvm_unreachable("Invalid value for vector shift amount!");
454}
455
456/// getFixedPointScaleOpValue - Return the encoded value for the
457// FP-to-fixed-point scale factor.
458uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
459 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
460 const MCSubtargetInfo &STI) const {
461 const MCOperand &MO = MI.getOperand(OpIdx);
462 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
463 return 64 - MO.getImm();
464}
465
467AArch64MCCodeEmitter::getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
469 const MCSubtargetInfo &STI) const {
470 const MCOperand &MO = MI.getOperand(OpIdx);
471 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
472 return 64 - MO.getImm();
473}
474
476AArch64MCCodeEmitter::getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
478 const MCSubtargetInfo &STI) const {
479 const MCOperand &MO = MI.getOperand(OpIdx);
480 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
481 return 32 - MO.getImm();
482}
483
485AArch64MCCodeEmitter::getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
487 const MCSubtargetInfo &STI) const {
488 const MCOperand &MO = MI.getOperand(OpIdx);
489 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
490 return 16 - MO.getImm();
491}
492
494AArch64MCCodeEmitter::getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
496 const MCSubtargetInfo &STI) const {
497 const MCOperand &MO = MI.getOperand(OpIdx);
498 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
499 return 8 - MO.getImm();
500}
501
503AArch64MCCodeEmitter::getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
505 const MCSubtargetInfo &STI) const {
506 const MCOperand &MO = MI.getOperand(OpIdx);
507 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
508 return MO.getImm() - 64;
509}
510
512AArch64MCCodeEmitter::getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
514 const MCSubtargetInfo &STI) const {
515 const MCOperand &MO = MI.getOperand(OpIdx);
516 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
517 return MO.getImm() - 32;
518}
519
521AArch64MCCodeEmitter::getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
523 const MCSubtargetInfo &STI) const {
524 const MCOperand &MO = MI.getOperand(OpIdx);
525 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
526 return MO.getImm() - 16;
527}
528
530AArch64MCCodeEmitter::getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
532 const MCSubtargetInfo &STI) const {
533 const MCOperand &MO = MI.getOperand(OpIdx);
534 assert(MO.isImm() && "Expected an immediate value for the scale amount!");
535 return MO.getImm() - 8;
536}
537
538template <unsigned Multiple>
540AArch64MCCodeEmitter::EncodeRegAsMultipleOf(const MCInst &MI, unsigned OpIdx,
542 const MCSubtargetInfo &STI) const {
543 assert(llvm::isPowerOf2_32(Multiple) && "Multiple is not a power of 2");
544 auto RegOpnd = MI.getOperand(OpIdx).getReg();
545 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
546 return RegVal / Multiple;
547}
548
550AArch64MCCodeEmitter::EncodePPR_p8to15(const MCInst &MI, unsigned OpIdx,
552 const MCSubtargetInfo &STI) const {
553 auto RegOpnd = MI.getOperand(OpIdx).getReg();
554 return RegOpnd - AArch64::P8;
555}
556
558AArch64MCCodeEmitter::EncodePNR_p8to15(const MCInst &MI, unsigned OpIdx,
560 const MCSubtargetInfo &STI) const {
561 auto RegOpnd = MI.getOperand(OpIdx).getReg();
562 return RegOpnd - AArch64::PN8;
563}
564
565uint32_t AArch64MCCodeEmitter::EncodeZPR2StridedRegisterClass(
566 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
567 const MCSubtargetInfo &STI) const {
568 auto RegOpnd = MI.getOperand(OpIdx).getReg();
569 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
570 unsigned T = (RegVal & 0x10) >> 1;
571 unsigned Zt = RegVal & 0x7;
572 return T | Zt;
573}
574
575uint32_t AArch64MCCodeEmitter::EncodeZPR4StridedRegisterClass(
576 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
577 const MCSubtargetInfo &STI) const {
578 auto RegOpnd = MI.getOperand(OpIdx).getReg();
579 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
580 unsigned T = (RegVal & 0x10) >> 2;
581 unsigned Zt = RegVal & 0x3;
582 return T | Zt;
583}
584
585uint32_t AArch64MCCodeEmitter::EncodeMatrixTileListRegisterClass(
586 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
587 const MCSubtargetInfo &STI) const {
588 unsigned RegMask = MI.getOperand(OpIdx).getImm();
589 assert(RegMask <= 0xFF && "Invalid register mask!");
590 return RegMask;
591}
592
593template <unsigned BaseReg>
595AArch64MCCodeEmitter::encodeMatrixIndexGPR32(const MCInst &MI, unsigned OpIdx,
597 const MCSubtargetInfo &STI) const {
598 auto RegOpnd = MI.getOperand(OpIdx).getReg();
599 return RegOpnd - BaseReg;
600}
601
603AArch64MCCodeEmitter::getImm8OptLsl(const MCInst &MI, unsigned OpIdx,
605 const MCSubtargetInfo &STI) const {
606 // Test shift
607 auto ShiftOpnd = MI.getOperand(OpIdx + 1).getImm();
609 "Unexpected shift type for imm8_opt_lsl immediate.");
610
611 unsigned ShiftVal = AArch64_AM::getShiftValue(ShiftOpnd);
612 assert((ShiftVal == 0 || ShiftVal == 8) &&
613 "Unexpected shift value for imm8_opt_lsl immediate.");
614
615 // Test immediate
616 auto Immediate = MI.getOperand(OpIdx).getImm();
617 return (Immediate & 0xff) | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
618}
619
621AArch64MCCodeEmitter::getSVEIncDecImm(const MCInst &MI, unsigned OpIdx,
623 const MCSubtargetInfo &STI) const {
624 const MCOperand &MO = MI.getOperand(OpIdx);
625 assert(MO.isImm() && "Expected an immediate value!");
626 // Normalize 1-16 range to 0-15.
627 return MO.getImm() - 1;
628}
629
630/// getMoveVecShifterOpValue - Return the encoded value for the vector move
631/// shifter (MSL).
632uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(
633 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
634 const MCSubtargetInfo &STI) const {
635 const MCOperand &MO = MI.getOperand(OpIdx);
636 assert(MO.isImm() &&
637 "Expected an immediate value for the move shift amount!");
638 unsigned ShiftVal = AArch64_AM::getShiftValue(MO.getImm());
639 assert((ShiftVal == 8 || ShiftVal == 16) && "Invalid shift amount!");
640 return ShiftVal == 8 ? 0 : 1;
641}
642
643unsigned AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
644 const MCSubtargetInfo &STI) const {
645 // If one of the signed fixup kinds is applied to a MOVZ instruction, the
646 // eventual result could be either a MOVZ or a MOVN. It's the MCCodeEmitter's
647 // job to ensure that any bits possibly affected by this are 0. This means we
648 // must zero out bit 30 (essentially emitting a MOVN).
649 MCOperand UImm16MO = MI.getOperand(1);
650
651 // Nothing to do if there's no fixup.
652 if (UImm16MO.isImm())
653 return EncodedValue;
654
655 const MCExpr *E = UImm16MO.getExpr();
656 if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(E)) {
657 switch (A64E->getKind()) {
665 return EncodedValue & ~(1u << 30);
666 default:
667 // Nothing to do for an unsigned fixup.
668 return EncodedValue;
669 }
670 }
671
672 return EncodedValue;
673}
674
675void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI,
677
679 const MCSubtargetInfo &STI) const {
680 if (MI.getOpcode() == AArch64::TLSDESCCALL) {
681 // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the
682 // following (BLR) instruction. It doesn't emit any code itself so it
683 // doesn't go through the normal TableGenerated channels.
684 auto Reloc = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32
685 ? ELF::R_AARCH64_P32_TLSDESC_CALL
686 : ELF::R_AARCH64_TLSDESC_CALL;
687 Fixups.push_back(
688 MCFixup::create(0, MI.getOperand(0).getExpr(),
690 return;
691 }
692
693 if (MI.getOpcode() == AArch64::SPACE) {
694 // SPACE just increases basic block size, in both cases no actual code.
695 return;
696 }
697
698 uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
699 support::endian::write<uint32_t>(CB, Binary, support::little);
700 ++MCNumEmitted; // Keep track of the # of mi's emitted.
701}
702
703unsigned
704AArch64MCCodeEmitter::fixMulHigh(const MCInst &MI,
705 unsigned EncodedValue,
706 const MCSubtargetInfo &STI) const {
707 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
708 // (i.e. all bits 1) but is ignored by the processor.
709 EncodedValue |= 0x1f << 10;
710 return EncodedValue;
711}
712
713template<int hasRs, int hasRt2> unsigned
714AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
715 unsigned EncodedValue,
716 const MCSubtargetInfo &STI) const {
717 if (!hasRs) EncodedValue |= 0x001F0000;
718 if (!hasRt2) EncodedValue |= 0x00007C00;
719
720 return EncodedValue;
721}
722
723unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
724 const MCInst &MI, unsigned EncodedValue, const MCSubtargetInfo &STI) const {
725 // The Rm field of FCMP and friends is unused - it should be assembled
726 // as 0, but is ignored by the processor.
727 EncodedValue &= ~(0x1f << 16);
728 return EncodedValue;
729}
730
731#include "AArch64GenMCCodeEmitter.inc"
732
734 MCContext &Ctx) {
735 return new AArch64MCCodeEmitter(MCII, Ctx);
736}
static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, unsigned FixupKind, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI)
getBranchTargetOpValue - Helper function to get the branch target operand, which is either an immedia...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
IRTranslator LLVM IR MI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
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
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
MCCodeEmitter & operator=(const MCCodeEmitter &)=delete
Context object for machine code objects.
Definition: MCContext.h:76
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:86
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
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
const MCExpr * getExpr() const
Definition: MCInst.h:114
bool isExpr() const
Definition: MCInst.h:65
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
Definition: Triple.h:372
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:264
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:49
MCCodeEmitter * createAArch64MCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)