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 
13 #include "MCTargetDesc/AArch64AddressingModes.h"
14 #include "MCTargetDesc/AArch64FixupKinds.h"
15 #include "MCTargetDesc/AArch64MCExpr.h"
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"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/Endian.h"
29 #include "llvm/Support/EndianStream.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/raw_ostream.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,
58                                  SmallVectorImpl<MCFixup> &Fixups,
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,
64                              SmallVectorImpl<MCFixup> &Fixups,
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,
72                                 SmallVectorImpl<MCFixup> &Fixups,
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,
78                               SmallVectorImpl<MCFixup> &Fixups,
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,
84                                SmallVectorImpl<MCFixup> &Fixups,
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,
90                                       SmallVectorImpl<MCFixup> &Fixups,
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,
96                                  SmallVectorImpl<MCFixup> &Fixups,
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,
103                                SmallVectorImpl<MCFixup> &Fixups,
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,
109                                       SmallVectorImpl<MCFixup> &Fixups,
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,
115                                   SmallVectorImpl<MCFixup> &Fixups,
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,
121                                  SmallVectorImpl<MCFixup> &Fixups,
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,
126                                 SmallVectorImpl<MCFixup> &Fixups,
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,
132                                     SmallVectorImpl<MCFixup> &Fixups,
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,
138                                      SmallVectorImpl<MCFixup> &Fixups,
139                                      const MCSubtargetInfo &STI) const;
140 
141   uint32_t getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
142                                  SmallVectorImpl<MCFixup> &Fixups,
143                                  const MCSubtargetInfo &STI) const;
144   uint32_t getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
145                                  SmallVectorImpl<MCFixup> &Fixups,
146                                  const MCSubtargetInfo &STI) const;
147   uint32_t getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
148                                  SmallVectorImpl<MCFixup> &Fixups,
149                                  const MCSubtargetInfo &STI) const;
150   uint32_t getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
151                                 SmallVectorImpl<MCFixup> &Fixups,
152                                 const MCSubtargetInfo &STI) const;
153   uint32_t getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
154                                  SmallVectorImpl<MCFixup> &Fixups,
155                                  const MCSubtargetInfo &STI) const;
156   uint32_t getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
157                                  SmallVectorImpl<MCFixup> &Fixups,
158                                  const MCSubtargetInfo &STI) const;
159   uint32_t getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
160                                  SmallVectorImpl<MCFixup> &Fixups,
161                                  const MCSubtargetInfo &STI) const;
162   uint32_t getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
163                                 SmallVectorImpl<MCFixup> &Fixups,
164                                 const MCSubtargetInfo &STI) const;
165 
166   uint32_t getImm8OptLsl(const MCInst &MI, unsigned OpIdx,
167                          SmallVectorImpl<MCFixup> &Fixups,
168                          const MCSubtargetInfo &STI) const;
169   uint32_t getSVEIncDecImm(const MCInst &MI, unsigned OpIdx,
170                            SmallVectorImpl<MCFixup> &Fixups,
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,
177                          SmallVectorImpl<MCFixup> &Fixups,
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,
191                                              SmallVectorImpl<MCFixup> &Fixups,
192                                              const MCSubtargetInfo &STI) const;
193   uint32_t encodeMatrixIndexGPR32(const MCInst &MI, unsigned OpIdx,
194                                   SmallVectorImpl<MCFixup> &Fixups,
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,
210                                         SmallVectorImpl<MCFixup> &Fixups,
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,
221                                            SmallVectorImpl<MCFixup> &Fixups,
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");
230     MCFixupKind Kind = MCFixupKind(FixupKind);
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,
242                                          SmallVectorImpl<MCFixup> &Fixups,
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
253                          ? MCFixupKind(AArch64::fixup_aarch64_pcrel_adr_imm21)
254                          : MCFixupKind(AArch64::fixup_aarch64_pcrel_adrp_imm21);
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,
268                                           SmallVectorImpl<MCFixup> &Fixups,
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);
273   assert(AArch64_AM::getShiftType(MO1.getImm()) == AArch64_AM::LSL &&
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.
284   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_add_imm12);
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 ||
295         RefKind == AArch64MCExpr::VK_SECREL_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 
313   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch19);
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,
326                                             SmallVectorImpl<MCFixup> &Fixups,
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 
335   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_ldr_pcrel_imm19);
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,
346                                           SmallVectorImpl<MCFixup> &Fixups,
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,
355                                             SmallVectorImpl<MCFixup> &Fixups,
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 
383   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch14);
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
395 AArch64MCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
396                                              SmallVectorImpl<MCFixup> &Fixups,
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
406                          ? MCFixupKind(AArch64::fixup_aarch64_pcrel_call26)
407                          : MCFixupKind(AArch64::fixup_aarch64_pcrel_branch26);
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,
424                                            SmallVectorImpl<MCFixup> &Fixups,
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,
457                                             SmallVectorImpl<MCFixup> &Fixups,
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,
466                                             SmallVectorImpl<MCFixup> &Fixups,
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,
475                                             SmallVectorImpl<MCFixup> &Fixups,
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,
484                                            SmallVectorImpl<MCFixup> &Fixups,
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,
493                                             SmallVectorImpl<MCFixup> &Fixups,
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,
502                                             SmallVectorImpl<MCFixup> &Fixups,
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,
511                                             SmallVectorImpl<MCFixup> &Fixups,
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,
520                                            SmallVectorImpl<MCFixup> &Fixups,
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,
537                                              SmallVectorImpl<MCFixup> &Fixups,
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,
547                                     SmallVectorImpl<MCFixup> &Fixups,
548                                     const MCSubtargetInfo &STI) const {
549   // Test shift
550   auto ShiftOpnd = MI.getOperand(OpIdx + 1).getImm();
551   assert(AArch64_AM::getShiftType(ShiftOpnd) == AArch64_AM::LSL &&
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,
565                                            SmallVectorImpl<MCFixup> &Fixups,
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()) {
601     case AArch64MCExpr::VK_DTPREL_G2:
602     case AArch64MCExpr::VK_DTPREL_G1:
603     case AArch64MCExpr::VK_DTPREL_G0:
604     case AArch64MCExpr::VK_GOTTPREL_G1:
605     case AArch64MCExpr::VK_TPREL_G2:
606     case AArch64MCExpr::VK_TPREL_G1:
607     case AArch64MCExpr::VK_TPREL_G0:
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,
619                                              SmallVectorImpl<MCFixup> &Fixups,
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(),
633                         MCFixupKind(FirstLiteralRelocationKind + Reloc)));
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 
680 MCCodeEmitter *llvm::createAArch64MCCodeEmitter(const MCInstrInfo &MCII,
681                                                 MCContext &Ctx) {
682   return new AArch64MCCodeEmitter(MCII, Ctx);
683 }
684