LLVM  15.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 
16 #include "Utils/AArch64BaseInfo.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/Statistic.h"
19 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/MC/MCCodeEmitter.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"
25 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/Endian.h"
32 #include <cassert>
33 #include <cstdint>
34 
35 using namespace llvm;
36 
37 #define DEBUG_TYPE "mccodeemitter"
38 
39 STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
40 STATISTIC(MCNumFixups, "Number of MC fixups created.");
41 
42 namespace {
43 
44 class AArch64MCCodeEmitter : public MCCodeEmitter {
45  MCContext &Ctx;
46  const MCInstrInfo &MCII;
47 
48 public:
49  AArch64MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
50  : Ctx(ctx), MCII(mcii) {}
51  AArch64MCCodeEmitter(const AArch64MCCodeEmitter &) = delete;
52  void operator=(const AArch64MCCodeEmitter &) = delete;
53  ~AArch64MCCodeEmitter() override = default;
54 
55  // getBinaryCodeForInstr - TableGen'erated function for getting the
56  // binary encoding for an instruction.
57  uint64_t getBinaryCodeForInstr(const MCInst &MI,
59  const MCSubtargetInfo &STI) const;
60 
61  /// getMachineOpValue - Return binary encoding of operand. If the machine
62  /// operand requires relocation, record the relocation and return zero.
63  unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
65  const MCSubtargetInfo &STI) const;
66 
67  /// getLdStUImm12OpValue - Return encoding info for 12-bit unsigned immediate
68  /// attached to a load, store or prfm instruction. If operand requires a
69  /// relocation, record it and return zero in that part of the encoding.
70  template <uint32_t FixupKind>
71  uint32_t getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
73  const MCSubtargetInfo &STI) const;
74 
75  /// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
76  /// target.
77  uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
79  const MCSubtargetInfo &STI) const;
80 
81  /// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and
82  /// the 2-bit shift field.
83  uint32_t getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
85  const MCSubtargetInfo &STI) const;
86 
87  /// getCondBranchTargetOpValue - Return the encoded value for a conditional
88  /// branch target.
89  uint32_t getCondBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
91  const MCSubtargetInfo &STI) const;
92 
93  /// getLoadLiteralOpValue - Return the encoded value for a load-literal
94  /// pc-relative address.
95  uint32_t getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
97  const MCSubtargetInfo &STI) const;
98 
99  /// getMemExtendOpValue - Return the encoded value for a reg-extend load/store
100  /// instruction: bit 0 is whether a shift is present, bit 1 is whether the
101  /// operation is a sign extend (as opposed to a zero extend).
102  uint32_t getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
104  const MCSubtargetInfo &STI) const;
105 
106  /// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
107  /// branch target.
108  uint32_t getTestBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
110  const MCSubtargetInfo &STI) const;
111 
112  /// getBranchTargetOpValue - Return the encoded value for an unconditional
113  /// branch target.
114  uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
116  const MCSubtargetInfo &STI) const;
117 
118  /// getMoveWideImmOpValue - Return the encoded value for the immediate operand
119  /// of a MOVZ or MOVK instruction.
120  uint32_t getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
122  const MCSubtargetInfo &STI) const;
123 
124  /// getVecShifterOpValue - Return the encoded value for the vector shifter.
125  uint32_t getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
127  const MCSubtargetInfo &STI) const;
128 
129  /// getMoveVecShifterOpValue - Return the encoded value for the vector move
130  /// shifter (MSL).
131  uint32_t getMoveVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
133  const MCSubtargetInfo &STI) const;
134 
135  /// getFixedPointScaleOpValue - Return the encoded value for the
136  // FP-to-fixed-point scale factor.
137  uint32_t getFixedPointScaleOpValue(const MCInst &MI, unsigned OpIdx,
139  const MCSubtargetInfo &STI) const;
140 
141  uint32_t getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
143  const MCSubtargetInfo &STI) const;
144  uint32_t getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
146  const MCSubtargetInfo &STI) const;
147  uint32_t getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
149  const MCSubtargetInfo &STI) const;
150  uint32_t getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
152  const MCSubtargetInfo &STI) const;
153  uint32_t getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
155  const MCSubtargetInfo &STI) const;
156  uint32_t getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
158  const MCSubtargetInfo &STI) const;
159  uint32_t getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
161  const MCSubtargetInfo &STI) const;
162  uint32_t getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
164  const MCSubtargetInfo &STI) const;
165 
166  uint32_t getImm8OptLsl(const MCInst &MI, unsigned OpIdx,
168  const MCSubtargetInfo &STI) const;
169  uint32_t getSVEIncDecImm(const MCInst &MI, unsigned OpIdx,
171  const MCSubtargetInfo &STI) const;
172 
173  unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue,
174  const MCSubtargetInfo &STI) const;
175 
176  void encodeInstruction(const MCInst &MI, raw_ostream &OS,
178  const MCSubtargetInfo &STI) const override;
179 
180  unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue,
181  const MCSubtargetInfo &STI) const;
182 
183  template<int hasRs, int hasRt2> unsigned
184  fixLoadStoreExclusive(const MCInst &MI, unsigned EncodedValue,
185  const MCSubtargetInfo &STI) const;
186 
187  unsigned fixOneOperandFPComparison(const MCInst &MI, unsigned EncodedValue,
188  const MCSubtargetInfo &STI) const;
189 
190  uint32_t EncodeMatrixTileListRegisterClass(const MCInst &MI, unsigned OpIdx,
192  const MCSubtargetInfo &STI) const;
193  uint32_t encodeMatrixIndexGPR32(const MCInst &MI, unsigned OpIdx,
195  const MCSubtargetInfo &STI) const;
196 
197 private:
198  FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
199  void
200  verifyInstructionPredicates(const MCInst &MI,
201  const FeatureBitset &AvailableFeatures) const;
202 };
203 
204 } // end anonymous namespace
205 
206 /// getMachineOpValue - Return binary encoding of operand. If the machine
207 /// operand requires relocation, record the relocation and return zero.
208 unsigned
209 AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
211  const MCSubtargetInfo &STI) const {
212  if (MO.isReg())
213  return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
214 
215  assert(MO.isImm() && "did not expect relocated expression");
216  return static_cast<unsigned>(MO.getImm());
217 }
218 
219 template<unsigned FixupKind> uint32_t
220 AArch64MCCodeEmitter::getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
222  const MCSubtargetInfo &STI) const {
223  const MCOperand &MO = MI.getOperand(OpIdx);
224  uint32_t ImmVal = 0;
225 
226  if (MO.isImm())
227  ImmVal = static_cast<uint32_t>(MO.getImm());
228  else {
229  assert(MO.isExpr() && "unable to encode load/store imm operand");
231  Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
232  ++MCNumFixups;
233  }
234 
235  return ImmVal;
236 }
237 
238 /// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
239 /// target.
240 uint32_t
241 AArch64MCCodeEmitter::getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
243  const MCSubtargetInfo &STI) const {
244  const MCOperand &MO = MI.getOperand(OpIdx);
245 
246  // If the destination is an immediate, we have nothing to do.
247  if (MO.isImm())
248  return MO.getImm();
249  assert(MO.isExpr() && "Unexpected target type!");
250  const MCExpr *Expr = MO.getExpr();
251 
252  MCFixupKind Kind = MI.getOpcode() == AArch64::ADR
255  Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
256 
257  MCNumFixups += 1;
258 
259  // All of the information is in the fixup.
260  return 0;
261 }
262 
263 /// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and
264 /// the 2-bit shift field. The shift field is stored in bits 13-14 of the
265 /// return value.
266 uint32_t
267 AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
269  const MCSubtargetInfo &STI) const {
270  // Suboperands are [imm, shifter].
271  const MCOperand &MO = MI.getOperand(OpIdx);
272  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
274  "unexpected shift type for add/sub immediate");
275  unsigned ShiftVal = AArch64_AM::getShiftValue(MO1.getImm());
276  assert((ShiftVal == 0 || ShiftVal == 12) &&
277  "unexpected shift value for add/sub immediate");
278  if (MO.isImm())
279  return MO.getImm() | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
280  assert(MO.isExpr() && "Unable to encode MCOperand!");
281  const MCExpr *Expr = MO.getExpr();
282 
283  // Encode the 12 bits of the fixup.
285  Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
286 
287  ++MCNumFixups;
288 
289  // Set the shift bit of the add instruction for relocation types
290  // R_AARCH64_TLSLE_ADD_TPREL_HI12 and R_AARCH64_TLSLD_ADD_DTPREL_HI12.
291  if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
292  AArch64MCExpr::VariantKind RefKind = A64E->getKind();
293  if (RefKind == AArch64MCExpr::VK_TPREL_HI12 ||
294  RefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
296  ShiftVal = 12;
297  }
298  return ShiftVal == 0 ? 0 : (1 << ShiftVal);
299 }
300 
301 /// getCondBranchTargetOpValue - Return the encoded value for a conditional
302 /// branch target.
303 uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
304  const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
305  const MCSubtargetInfo &STI) const {
306  const MCOperand &MO = MI.getOperand(OpIdx);
307 
308  // If the destination is an immediate, we have nothing to do.
309  if (MO.isImm())
310  return MO.getImm();
311  assert(MO.isExpr() && "Unexpected target type!");
312 
314  Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
315 
316  ++MCNumFixups;
317 
318  // All of the information is in the fixup.
319  return 0;
320 }
321 
322 /// getLoadLiteralOpValue - Return the encoded value for a load-literal
323 /// pc-relative address.
324 uint32_t
325 AArch64MCCodeEmitter::getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
327  const MCSubtargetInfo &STI) const {
328  const MCOperand &MO = MI.getOperand(OpIdx);
329 
330  // If the destination is an immediate, we have nothing to do.
331  if (MO.isImm())
332  return MO.getImm();
333  assert(MO.isExpr() && "Unexpected target type!");
334 
336  Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
337 
338  ++MCNumFixups;
339 
340  // All of the information is in the fixup.
341  return 0;
342 }
343 
344 uint32_t
345 AArch64MCCodeEmitter::getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
347  const MCSubtargetInfo &STI) const {
348  unsigned SignExtend = MI.getOperand(OpIdx).getImm();
349  unsigned DoShift = MI.getOperand(OpIdx + 1).getImm();
350  return (SignExtend << 1) | DoShift;
351 }
352 
353 uint32_t
354 AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
356  const MCSubtargetInfo &STI) const {
357  const MCOperand &MO = MI.getOperand(OpIdx);
358 
359  if (MO.isImm())
360  return MO.getImm();
361  assert(MO.isExpr() && "Unexpected movz/movk immediate");
362 
363  Fixups.push_back(MCFixup::create(
364  0, MO.getExpr(), MCFixupKind(AArch64::fixup_aarch64_movw), MI.getLoc()));
365 
366  ++MCNumFixups;
367 
368  return 0;
369 }
370 
371 /// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
372 /// branch target.
373 uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
374  const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
375  const MCSubtargetInfo &STI) const {
376  const MCOperand &MO = MI.getOperand(OpIdx);
377 
378  // If the destination is an immediate, we have nothing to do.
379  if (MO.isImm())
380  return MO.getImm();
381  assert(MO.isExpr() && "Unexpected ADR target type!");
382 
384  Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
385 
386  ++MCNumFixups;
387 
388  // All of the information is in the fixup.
389  return 0;
390 }
391 
392 /// getBranchTargetOpValue - Return the encoded value for an unconditional
393 /// branch target.
394 uint32_t
397  const MCSubtargetInfo &STI) const {
398  const MCOperand &MO = MI.getOperand(OpIdx);
399 
400  // If the destination is an immediate, we have nothing to do.
401  if (MO.isImm())
402  return MO.getImm();
403  assert(MO.isExpr() && "Unexpected ADR target type!");
404 
405  MCFixupKind Kind = MI.getOpcode() == AArch64::BL
408  Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
409 
410  ++MCNumFixups;
411 
412  // All of the information is in the fixup.
413  return 0;
414 }
415 
416 /// getVecShifterOpValue - Return the encoded value for the vector shifter:
417 ///
418 /// 00 -> 0
419 /// 01 -> 8
420 /// 10 -> 16
421 /// 11 -> 24
422 uint32_t
423 AArch64MCCodeEmitter::getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
425  const MCSubtargetInfo &STI) const {
426  const MCOperand &MO = MI.getOperand(OpIdx);
427  assert(MO.isImm() && "Expected an immediate value for the shift amount!");
428 
429  switch (MO.getImm()) {
430  default:
431  break;
432  case 0:
433  return 0;
434  case 8:
435  return 1;
436  case 16:
437  return 2;
438  case 24:
439  return 3;
440  }
441 
442  llvm_unreachable("Invalid value for vector shift amount!");
443 }
444 
445 /// getFixedPointScaleOpValue - Return the encoded value for the
446 // FP-to-fixed-point scale factor.
447 uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
448  const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
449  const MCSubtargetInfo &STI) const {
450  const MCOperand &MO = MI.getOperand(OpIdx);
451  assert(MO.isImm() && "Expected an immediate value for the scale amount!");
452  return 64 - MO.getImm();
453 }
454 
455 uint32_t
456 AArch64MCCodeEmitter::getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
458  const MCSubtargetInfo &STI) const {
459  const MCOperand &MO = MI.getOperand(OpIdx);
460  assert(MO.isImm() && "Expected an immediate value for the scale amount!");
461  return 64 - MO.getImm();
462 }
463 
464 uint32_t
465 AArch64MCCodeEmitter::getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
467  const MCSubtargetInfo &STI) const {
468  const MCOperand &MO = MI.getOperand(OpIdx);
469  assert(MO.isImm() && "Expected an immediate value for the scale amount!");
470  return 32 - MO.getImm();
471 }
472 
473 uint32_t
474 AArch64MCCodeEmitter::getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
476  const MCSubtargetInfo &STI) const {
477  const MCOperand &MO = MI.getOperand(OpIdx);
478  assert(MO.isImm() && "Expected an immediate value for the scale amount!");
479  return 16 - MO.getImm();
480 }
481 
482 uint32_t
483 AArch64MCCodeEmitter::getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
485  const MCSubtargetInfo &STI) const {
486  const MCOperand &MO = MI.getOperand(OpIdx);
487  assert(MO.isImm() && "Expected an immediate value for the scale amount!");
488  return 8 - MO.getImm();
489 }
490 
491 uint32_t
492 AArch64MCCodeEmitter::getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
494  const MCSubtargetInfo &STI) const {
495  const MCOperand &MO = MI.getOperand(OpIdx);
496  assert(MO.isImm() && "Expected an immediate value for the scale amount!");
497  return MO.getImm() - 64;
498 }
499 
500 uint32_t
501 AArch64MCCodeEmitter::getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
503  const MCSubtargetInfo &STI) const {
504  const MCOperand &MO = MI.getOperand(OpIdx);
505  assert(MO.isImm() && "Expected an immediate value for the scale amount!");
506  return MO.getImm() - 32;
507 }
508 
509 uint32_t
510 AArch64MCCodeEmitter::getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
512  const MCSubtargetInfo &STI) const {
513  const MCOperand &MO = MI.getOperand(OpIdx);
514  assert(MO.isImm() && "Expected an immediate value for the scale amount!");
515  return MO.getImm() - 16;
516 }
517 
518 uint32_t
519 AArch64MCCodeEmitter::getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
521  const MCSubtargetInfo &STI) const {
522  const MCOperand &MO = MI.getOperand(OpIdx);
523  assert(MO.isImm() && "Expected an immediate value for the scale amount!");
524  return MO.getImm() - 8;
525 }
526 
527 uint32_t AArch64MCCodeEmitter::EncodeMatrixTileListRegisterClass(
528  const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
529  const MCSubtargetInfo &STI) const {
530  unsigned RegMask = MI.getOperand(OpIdx).getImm();
531  assert(RegMask <= 0xFF && "Invalid register mask!");
532  return RegMask;
533 }
534 
535 uint32_t
536 AArch64MCCodeEmitter::encodeMatrixIndexGPR32(const MCInst &MI, unsigned OpIdx,
538  const MCSubtargetInfo &STI) const {
539  auto RegOpnd = MI.getOperand(OpIdx).getReg();
540  assert(RegOpnd >= AArch64::W12 && RegOpnd <= AArch64::W15 &&
541  "Expected register in the range w12-w15!");
542  return RegOpnd - AArch64::W12;
543 }
544 
545 uint32_t
546 AArch64MCCodeEmitter::getImm8OptLsl(const MCInst &MI, unsigned OpIdx,
548  const MCSubtargetInfo &STI) const {
549  // Test shift
550  auto ShiftOpnd = MI.getOperand(OpIdx + 1).getImm();
552  "Unexpected shift type for imm8_opt_lsl immediate.");
553 
554  unsigned ShiftVal = AArch64_AM::getShiftValue(ShiftOpnd);
555  assert((ShiftVal == 0 || ShiftVal == 8) &&
556  "Unexpected shift value for imm8_opt_lsl immediate.");
557 
558  // Test immediate
559  auto Immediate = MI.getOperand(OpIdx).getImm();
560  return (Immediate & 0xff) | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
561 }
562 
563 uint32_t
564 AArch64MCCodeEmitter::getSVEIncDecImm(const MCInst &MI, unsigned OpIdx,
566  const MCSubtargetInfo &STI) const {
567  const MCOperand &MO = MI.getOperand(OpIdx);
568  assert(MO.isImm() && "Expected an immediate value!");
569  // Normalize 1-16 range to 0-15.
570  return MO.getImm() - 1;
571 }
572 
573 /// getMoveVecShifterOpValue - Return the encoded value for the vector move
574 /// shifter (MSL).
575 uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(
576  const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
577  const MCSubtargetInfo &STI) const {
578  const MCOperand &MO = MI.getOperand(OpIdx);
579  assert(MO.isImm() &&
580  "Expected an immediate value for the move shift amount!");
581  unsigned ShiftVal = AArch64_AM::getShiftValue(MO.getImm());
582  assert((ShiftVal == 8 || ShiftVal == 16) && "Invalid shift amount!");
583  return ShiftVal == 8 ? 0 : 1;
584 }
585 
586 unsigned AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
587  const MCSubtargetInfo &STI) const {
588  // If one of the signed fixup kinds is applied to a MOVZ instruction, the
589  // eventual result could be either a MOVZ or a MOVN. It's the MCCodeEmitter's
590  // job to ensure that any bits possibly affected by this are 0. This means we
591  // must zero out bit 30 (essentially emitting a MOVN).
592  MCOperand UImm16MO = MI.getOperand(1);
593 
594  // Nothing to do if there's no fixup.
595  if (UImm16MO.isImm())
596  return EncodedValue;
597 
598  const MCExpr *E = UImm16MO.getExpr();
599  if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(E)) {
600  switch (A64E->getKind()) {
608  return EncodedValue & ~(1u << 30);
609  default:
610  // Nothing to do for an unsigned fixup.
611  return EncodedValue;
612  }
613  }
614 
615  return EncodedValue;
616 }
617 
618 void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
620  const MCSubtargetInfo &STI) const {
621  verifyInstructionPredicates(MI,
622  computeAvailableFeatures(STI.getFeatureBits()));
623 
624  if (MI.getOpcode() == AArch64::TLSDESCCALL) {
625  // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the
626  // following (BLR) instruction. It doesn't emit any code itself so it
627  // doesn't go through the normal TableGenerated channels.
628  auto Reloc = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32
629  ? ELF::R_AARCH64_P32_TLSDESC_CALL
630  : ELF::R_AARCH64_TLSDESC_CALL;
631  Fixups.push_back(
632  MCFixup::create(0, MI.getOperand(0).getExpr(),
634  return;
635  }
636 
637  if (MI.getOpcode() == AArch64::CompilerBarrier ||
638  MI.getOpcode() == AArch64::SPACE) {
639  // CompilerBarrier just prevents the compiler from reordering accesses, and
640  // SPACE just increases basic block size, in both cases no actual code.
641  return;
642  }
643 
644  uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
645  support::endian::write<uint32_t>(OS, Binary, support::little);
646  ++MCNumEmitted; // Keep track of the # of mi's emitted.
647 }
648 
649 unsigned
650 AArch64MCCodeEmitter::fixMulHigh(const MCInst &MI,
651  unsigned EncodedValue,
652  const MCSubtargetInfo &STI) const {
653  // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
654  // (i.e. all bits 1) but is ignored by the processor.
655  EncodedValue |= 0x1f << 10;
656  return EncodedValue;
657 }
658 
659 template<int hasRs, int hasRt2> unsigned
660 AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
661  unsigned EncodedValue,
662  const MCSubtargetInfo &STI) const {
663  if (!hasRs) EncodedValue |= 0x001F0000;
664  if (!hasRt2) EncodedValue |= 0x00007C00;
665 
666  return EncodedValue;
667 }
668 
669 unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
670  const MCInst &MI, unsigned EncodedValue, const MCSubtargetInfo &STI) const {
671  // The Rm field of FCMP and friends is unused - it should be assembled
672  // as 0, but is ignored by the processor.
673  EncodedValue &= ~(0x1f << 16);
674  return EncodedValue;
675 }
676 
677 #define ENABLE_INSTR_PREDICATE_VERIFIER
678 #include "AArch64GenMCCodeEmitter.inc"
679 
681  MCContext &Ctx) {
682  return new AArch64MCCodeEmitter(MCII, Ctx);
683 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::Triple::GNUILP32
@ GNUILP32
Definition: Triple.h:233
llvm::FixupKind
static Lanai::Fixups FixupKind(const MCExpr *Expr)
Definition: LanaiMCCodeEmitter.cpp:90
llvm::AArch64_AM::LSL
@ LSL
Definition: AArch64AddressingModes.h:35
llvm::MCOperand::isReg
bool isReg() const
Definition: MCInst.h:61
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:74
llvm::AArch64::fixup_aarch64_pcrel_branch26
@ fixup_aarch64_pcrel_branch26
Definition: AArch64FixupKinds.h:52
llvm::AArch64::fixup_aarch64_add_imm12
@ fixup_aarch64_add_imm12
Definition: AArch64FixupKinds.h:26
MCCodeEmitter.h
llvm::AArch64::fixup_aarch64_ldr_pcrel_imm19
@ fixup_aarch64_ldr_pcrel_imm19
Definition: AArch64FixupKinds.h:38
Statistic.h
AArch64MCExpr.h
llvm::MCFixup::create
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:87
ErrorHandling.h
AArch64BaseInfo.h
llvm::FeatureBitset
Container class for subtarget features.
Definition: SubtargetFeature.h:40
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::msgpack::Type::Binary
@ Binary
llvm::ARCISD::BL
@ BL
Definition: ARCISelLowering.h:34
llvm::FirstLiteralRelocationKind
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:50
ELF.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::support::little
@ little
Definition: Endian.h:27
llvm::MCSubtargetInfo::getTargetTriple
const Triple & getTargetTriple() const
Definition: MCSubtargetInfo.h:108
MCContext.h
MCInstrInfo.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
MCInst.h
llvm::AArch64::Fixups
Fixups
Definition: AArch64FixupKinds.h:17
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:112
AArch64FixupKinds.h
llvm::SPIRV::ImageOperand::SignExtend
@ SignExtend
llvm::AArch64::fixup_aarch64_pcrel_branch19
@ fixup_aarch64_pcrel_branch19
Definition: AArch64FixupKinds.h:49
getBranchTargetOpValue
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...
Definition: ARMMCCodeEmitter.cpp:620
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::AArch64_AM::getShiftValue
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
Definition: AArch64AddressingModes.h:86
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
AArch64AddressingModes.h
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
llvm::AArch64MCExpr::VK_TPREL_G1
@ VK_TPREL_G1
Definition: AArch64MCExpr.h:100
uint64_t
llvm::AArch64MCExpr::VK_DTPREL_HI12
@ VK_DTPREL_HI12
Definition: AArch64MCExpr.h:92
MCRegisterInfo.h
llvm::AArch64MCExpr::VK_DTPREL_G2
@ VK_DTPREL_G2
Definition: AArch64MCExpr.h:87
llvm::AArch64MCExpr::VK_DTPREL_G0
@ VK_DTPREL_G0
Definition: AArch64MCExpr.h:90
llvm::AArch64::fixup_aarch64_pcrel_call26
@ fixup_aarch64_pcrel_call26
Definition: AArch64FixupKinds.h:56
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::AArch64MCExpr::VK_GOTTPREL_G1
@ VK_GOTTPREL_G1
Definition: AArch64MCExpr.h:97
llvm::AArch64MCExpr::VK_DTPREL_G1
@ VK_DTPREL_G1
Definition: AArch64MCExpr.h:88
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
uint32_t
MCFixup.h
llvm::AArch64ISD::ADR
@ ADR
Definition: AArch64ISelLowering.h:64
llvm::AArch64::fixup_aarch64_pcrel_branch14
@ fixup_aarch64_pcrel_branch14
Definition: AArch64FixupKinds.h:44
llvm::AArch64::fixup_aarch64_movw
@ fixup_aarch64_movw
Definition: AArch64FixupKinds.h:41
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
EndianStream.h
llvm::AArch64MCExpr::VK_TPREL_G2
@ VK_TPREL_G2
Definition: AArch64MCExpr.h:99
llvm::MCCodeEmitter
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
Casting.h
llvm::AArch64MCExpr
Definition: AArch64MCExpr.h:22
llvm::MCOperand::getExpr
const MCExpr * getExpr() const
Definition: MCInst.h:114
llvm::AArch64_AM::getShiftType
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
Definition: AArch64AddressingModes.h:74
llvm::MCOperand::isExpr
bool isExpr() const
Definition: MCInst.h:65
llvm::MCFixupKind
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
SmallVector.h
llvm::AArch64MCExpr::VariantKind
VariantKind
Definition: AArch64MCExpr.h:24
llvm::AArch64::fixup_aarch64_pcrel_adrp_imm21
@ fixup_aarch64_pcrel_adrp_imm21
Definition: AArch64FixupKinds.h:22
llvm::AArch64MCExpr::VK_TPREL_HI12
@ VK_TPREL_HI12
Definition: AArch64MCExpr.h:104
llvm::Triple::getEnvironment
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
Definition: Triple.h:362
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::AArch64MCExpr::VK_TPREL_G0
@ VK_TPREL_G0
Definition: AArch64MCExpr.h:102
raw_ostream.h
Endian.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::AArch64MCExpr::VK_SECREL_HI12
@ VK_SECREL_HI12
Definition: AArch64MCExpr.h:110
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::createAArch64MCCodeEmitter
MCCodeEmitter * createAArch64MCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
Definition: AArch64MCCodeEmitter.cpp:680
llvm::AArch64::fixup_aarch64_pcrel_adr_imm21
@ fixup_aarch64_pcrel_adr_imm21
Definition: AArch64FixupKinds.h:19
llvm::MCOperand::getReg
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69