]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
Vendor import of llvm trunk r291274:
[FreeBSD/FreeBSD.git] / lib / Target / AArch64 / MCTargetDesc / AArch64MCCodeEmitter.cpp
1 //=- AArch64/AArch64MCCodeEmitter.cpp - Convert AArch64 code to machine code-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the AArch64MCCodeEmitter class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "MCTargetDesc/AArch64AddressingModes.h"
15 #include "MCTargetDesc/AArch64FixupKinds.h"
16 #include "MCTargetDesc/AArch64MCExpr.h"
17 #include "Utils/AArch64BaseInfo.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/Statistic.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   unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue,
167                    const MCSubtargetInfo &STI) const;
168
169   void encodeInstruction(const MCInst &MI, raw_ostream &OS,
170                          SmallVectorImpl<MCFixup> &Fixups,
171                          const MCSubtargetInfo &STI) const override;
172
173   unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue,
174                       const MCSubtargetInfo &STI) const;
175
176   template<int hasRs, int hasRt2> unsigned
177   fixLoadStoreExclusive(const MCInst &MI, unsigned EncodedValue,
178                         const MCSubtargetInfo &STI) const;
179
180   unsigned fixOneOperandFPComparison(const MCInst &MI, unsigned EncodedValue,
181                                      const MCSubtargetInfo &STI) const;
182
183 private:
184   uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
185   void verifyInstructionPredicates(const MCInst &MI,
186                                    uint64_t AvailableFeatures) const;
187 };
188
189 } // end anonymous namespace
190
191 /// getMachineOpValue - Return binary encoding of operand. If the machine
192 /// operand requires relocation, record the relocation and return zero.
193 unsigned
194 AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
195                                         SmallVectorImpl<MCFixup> &Fixups,
196                                         const MCSubtargetInfo &STI) const {
197   if (MO.isReg())
198     return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
199
200   assert(MO.isImm() && "did not expect relocated expression");
201   return static_cast<unsigned>(MO.getImm());
202 }
203
204 template<unsigned FixupKind> uint32_t
205 AArch64MCCodeEmitter::getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
206                                            SmallVectorImpl<MCFixup> &Fixups,
207                                            const MCSubtargetInfo &STI) const {
208   const MCOperand &MO = MI.getOperand(OpIdx);
209   uint32_t ImmVal = 0;
210
211   if (MO.isImm())
212     ImmVal = static_cast<uint32_t>(MO.getImm());
213   else {
214     assert(MO.isExpr() && "unable to encode load/store imm operand");
215     MCFixupKind Kind = MCFixupKind(FixupKind);
216     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
217     ++MCNumFixups;
218   }
219
220   return ImmVal;
221 }
222
223 /// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
224 /// target.
225 uint32_t
226 AArch64MCCodeEmitter::getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
227                                          SmallVectorImpl<MCFixup> &Fixups,
228                                          const MCSubtargetInfo &STI) const {
229   const MCOperand &MO = MI.getOperand(OpIdx);
230
231   // If the destination is an immediate, we have nothing to do.
232   if (MO.isImm())
233     return MO.getImm();
234   assert(MO.isExpr() && "Unexpected target type!");
235   const MCExpr *Expr = MO.getExpr();
236
237   MCFixupKind Kind = MI.getOpcode() == AArch64::ADR
238                          ? MCFixupKind(AArch64::fixup_aarch64_pcrel_adr_imm21)
239                          : MCFixupKind(AArch64::fixup_aarch64_pcrel_adrp_imm21);
240   Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
241
242   MCNumFixups += 1;
243
244   // All of the information is in the fixup.
245   return 0;
246 }
247
248 /// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and
249 /// the 2-bit shift field.  The shift field is stored in bits 13-14 of the
250 /// return value.
251 uint32_t
252 AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
253                                           SmallVectorImpl<MCFixup> &Fixups,
254                                           const MCSubtargetInfo &STI) const {
255   // Suboperands are [imm, shifter].
256   const MCOperand &MO = MI.getOperand(OpIdx);
257   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
258   assert(AArch64_AM::getShiftType(MO1.getImm()) == AArch64_AM::LSL &&
259          "unexpected shift type for add/sub immediate");
260   unsigned ShiftVal = AArch64_AM::getShiftValue(MO1.getImm());
261   assert((ShiftVal == 0 || ShiftVal == 12) &&
262          "unexpected shift value for add/sub immediate");
263   if (MO.isImm())
264     return MO.getImm() | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
265   assert(MO.isExpr() && "Unable to encode MCOperand!");
266   const MCExpr *Expr = MO.getExpr();
267
268   // Encode the 12 bits of the fixup.
269   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_add_imm12);
270   Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
271
272   ++MCNumFixups;
273
274   // Set the shift bit of the add instruction for relocation types
275   // R_AARCH64_TLSLE_ADD_TPREL_HI12 and R_AARCH64_TLSLD_ADD_DTPREL_HI12.
276   if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
277     AArch64MCExpr::VariantKind RefKind = A64E->getKind();
278     if (RefKind == AArch64MCExpr::VK_TPREL_HI12 ||
279         RefKind == AArch64MCExpr::VK_DTPREL_HI12)
280       ShiftVal = 12;
281   }
282   return ShiftVal == 0 ? 0 : (1 << ShiftVal);
283 }
284
285 /// getCondBranchTargetOpValue - Return the encoded value for a conditional
286 /// branch target.
287 uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
288     const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
289     const MCSubtargetInfo &STI) const {
290   const MCOperand &MO = MI.getOperand(OpIdx);
291
292   // If the destination is an immediate, we have nothing to do.
293   if (MO.isImm())
294     return MO.getImm();
295   assert(MO.isExpr() && "Unexpected target type!");
296
297   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch19);
298   Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
299
300   ++MCNumFixups;
301
302   // All of the information is in the fixup.
303   return 0;
304 }
305
306 /// getLoadLiteralOpValue - Return the encoded value for a load-literal
307 /// pc-relative address.
308 uint32_t
309 AArch64MCCodeEmitter::getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
310                                             SmallVectorImpl<MCFixup> &Fixups,
311                                             const MCSubtargetInfo &STI) const {
312   const MCOperand &MO = MI.getOperand(OpIdx);
313
314   // If the destination is an immediate, we have nothing to do.
315   if (MO.isImm())
316     return MO.getImm();
317   assert(MO.isExpr() && "Unexpected target type!");
318
319   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_ldr_pcrel_imm19);
320   Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
321
322   ++MCNumFixups;
323
324   // All of the information is in the fixup.
325   return 0;
326 }
327
328 uint32_t
329 AArch64MCCodeEmitter::getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
330                                           SmallVectorImpl<MCFixup> &Fixups,
331                                           const MCSubtargetInfo &STI) const {
332   unsigned SignExtend = MI.getOperand(OpIdx).getImm();
333   unsigned DoShift = MI.getOperand(OpIdx + 1).getImm();
334   return (SignExtend << 1) | DoShift;
335 }
336
337 uint32_t
338 AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
339                                             SmallVectorImpl<MCFixup> &Fixups,
340                                             const MCSubtargetInfo &STI) const {
341   const MCOperand &MO = MI.getOperand(OpIdx);
342
343   if (MO.isImm())
344     return MO.getImm();
345   assert(MO.isExpr() && "Unexpected movz/movk immediate");
346
347   Fixups.push_back(MCFixup::create(
348       0, MO.getExpr(), MCFixupKind(AArch64::fixup_aarch64_movw), MI.getLoc()));
349
350   ++MCNumFixups;
351
352   return 0;
353 }
354
355 /// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
356 /// branch target.
357 uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
358     const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
359     const MCSubtargetInfo &STI) const {
360   const MCOperand &MO = MI.getOperand(OpIdx);
361
362   // If the destination is an immediate, we have nothing to do.
363   if (MO.isImm())
364     return MO.getImm();
365   assert(MO.isExpr() && "Unexpected ADR target type!");
366
367   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch14);
368   Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
369
370   ++MCNumFixups;
371
372   // All of the information is in the fixup.
373   return 0;
374 }
375
376 /// getBranchTargetOpValue - Return the encoded value for an unconditional
377 /// branch target.
378 uint32_t
379 AArch64MCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
380                                              SmallVectorImpl<MCFixup> &Fixups,
381                                              const MCSubtargetInfo &STI) const {
382   const MCOperand &MO = MI.getOperand(OpIdx);
383
384   // If the destination is an immediate, we have nothing to do.
385   if (MO.isImm())
386     return MO.getImm();
387   assert(MO.isExpr() && "Unexpected ADR target type!");
388
389   MCFixupKind Kind = MI.getOpcode() == AArch64::BL
390                          ? MCFixupKind(AArch64::fixup_aarch64_pcrel_call26)
391                          : MCFixupKind(AArch64::fixup_aarch64_pcrel_branch26);
392   Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
393
394   ++MCNumFixups;
395
396   // All of the information is in the fixup.
397   return 0;
398 }
399
400 /// getVecShifterOpValue - Return the encoded value for the vector shifter:
401 ///
402 ///   00 -> 0
403 ///   01 -> 8
404 ///   10 -> 16
405 ///   11 -> 24
406 uint32_t
407 AArch64MCCodeEmitter::getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
408                                            SmallVectorImpl<MCFixup> &Fixups,
409                                            const MCSubtargetInfo &STI) const {
410   const MCOperand &MO = MI.getOperand(OpIdx);
411   assert(MO.isImm() && "Expected an immediate value for the shift amount!");
412
413   switch (MO.getImm()) {
414   default:
415     break;
416   case 0:
417     return 0;
418   case 8:
419     return 1;
420   case 16:
421     return 2;
422   case 24:
423     return 3;
424   }
425
426   llvm_unreachable("Invalid value for vector shift amount!");
427 }
428
429 /// getFixedPointScaleOpValue - Return the encoded value for the
430 // FP-to-fixed-point scale factor.
431 uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
432     const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
433     const MCSubtargetInfo &STI) const {
434   const MCOperand &MO = MI.getOperand(OpIdx);
435   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
436   return 64 - MO.getImm();
437 }
438
439 uint32_t
440 AArch64MCCodeEmitter::getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
441                                             SmallVectorImpl<MCFixup> &Fixups,
442                                             const MCSubtargetInfo &STI) const {
443   const MCOperand &MO = MI.getOperand(OpIdx);
444   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
445   return 64 - MO.getImm();
446 }
447
448 uint32_t
449 AArch64MCCodeEmitter::getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
450                                             SmallVectorImpl<MCFixup> &Fixups,
451                                             const MCSubtargetInfo &STI) const {
452   const MCOperand &MO = MI.getOperand(OpIdx);
453   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
454   return 32 - MO.getImm();
455 }
456
457 uint32_t
458 AArch64MCCodeEmitter::getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
459                                             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 16 - MO.getImm();
464 }
465
466 uint32_t
467 AArch64MCCodeEmitter::getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
468                                            SmallVectorImpl<MCFixup> &Fixups,
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 8 - MO.getImm();
473 }
474
475 uint32_t
476 AArch64MCCodeEmitter::getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
477                                             SmallVectorImpl<MCFixup> &Fixups,
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 MO.getImm() - 64;
482 }
483
484 uint32_t
485 AArch64MCCodeEmitter::getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
486                                             SmallVectorImpl<MCFixup> &Fixups,
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 MO.getImm() - 32;
491 }
492
493 uint32_t
494 AArch64MCCodeEmitter::getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
495                                             SmallVectorImpl<MCFixup> &Fixups,
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 MO.getImm() - 16;
500 }
501
502 uint32_t
503 AArch64MCCodeEmitter::getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
504                                            SmallVectorImpl<MCFixup> &Fixups,
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() - 8;
509 }
510
511 /// getMoveVecShifterOpValue - Return the encoded value for the vector move
512 /// shifter (MSL).
513 uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(
514     const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
515     const MCSubtargetInfo &STI) const {
516   const MCOperand &MO = MI.getOperand(OpIdx);
517   assert(MO.isImm() &&
518          "Expected an immediate value for the move shift amount!");
519   unsigned ShiftVal = AArch64_AM::getShiftValue(MO.getImm());
520   assert((ShiftVal == 8 || ShiftVal == 16) && "Invalid shift amount!");
521   return ShiftVal == 8 ? 0 : 1;
522 }
523
524 unsigned AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
525                                        const MCSubtargetInfo &STI) const {
526   // If one of the signed fixup kinds is applied to a MOVZ instruction, the
527   // eventual result could be either a MOVZ or a MOVN. It's the MCCodeEmitter's
528   // job to ensure that any bits possibly affected by this are 0. This means we
529   // must zero out bit 30 (essentially emitting a MOVN).
530   MCOperand UImm16MO = MI.getOperand(1);
531
532   // Nothing to do if there's no fixup.
533   if (UImm16MO.isImm())
534     return EncodedValue;
535
536   const AArch64MCExpr *A64E = cast<AArch64MCExpr>(UImm16MO.getExpr());
537   switch (A64E->getKind()) {
538   case AArch64MCExpr::VK_DTPREL_G2:
539   case AArch64MCExpr::VK_DTPREL_G1:
540   case AArch64MCExpr::VK_DTPREL_G0:
541   case AArch64MCExpr::VK_GOTTPREL_G1:
542   case AArch64MCExpr::VK_TPREL_G2:
543   case AArch64MCExpr::VK_TPREL_G1:
544   case AArch64MCExpr::VK_TPREL_G0:
545     return EncodedValue & ~(1u << 30);
546   default:
547     // Nothing to do for an unsigned fixup.
548     return EncodedValue;
549   }
550
551
552   return EncodedValue & ~(1u << 30);
553 }
554
555 void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
556                                              SmallVectorImpl<MCFixup> &Fixups,
557                                              const MCSubtargetInfo &STI) const {
558   verifyInstructionPredicates(MI,
559                               computeAvailableFeatures(STI.getFeatureBits()));
560
561   if (MI.getOpcode() == AArch64::TLSDESCCALL) {
562     // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the
563     // following (BLR) instruction. It doesn't emit any code itself so it
564     // doesn't go through the normal TableGenerated channels.
565     MCFixupKind Fixup = MCFixupKind(AArch64::fixup_aarch64_tlsdesc_call);
566     Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), Fixup));
567     return;
568   }
569
570   uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
571   support::endian::Writer<support::little>(OS).write<uint32_t>(Binary);
572   ++MCNumEmitted; // Keep track of the # of mi's emitted.
573 }
574
575 unsigned
576 AArch64MCCodeEmitter::fixMulHigh(const MCInst &MI,
577                                  unsigned EncodedValue,
578                                  const MCSubtargetInfo &STI) const {
579   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
580   // (i.e. all bits 1) but is ignored by the processor.
581   EncodedValue |= 0x1f << 10;
582   return EncodedValue;
583 }
584
585 template<int hasRs, int hasRt2> unsigned
586 AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
587                                             unsigned EncodedValue,
588                                             const MCSubtargetInfo &STI) const {
589   if (!hasRs) EncodedValue |= 0x001F0000;
590   if (!hasRt2) EncodedValue |= 0x00007C00;
591
592   return EncodedValue;
593 }
594
595 unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
596     const MCInst &MI, unsigned EncodedValue, const MCSubtargetInfo &STI) const {
597   // The Rm field of FCMP and friends is unused - it should be assembled
598   // as 0, but is ignored by the processor.
599   EncodedValue &= ~(0x1f << 16);
600   return EncodedValue;
601 }
602
603 #define ENABLE_INSTR_PREDICATE_VERIFIER
604 #include "AArch64GenMCCodeEmitter.inc"
605
606 MCCodeEmitter *llvm::createAArch64MCCodeEmitter(const MCInstrInfo &MCII,
607                                                 const MCRegisterInfo &MRI,
608                                                 MCContext &Ctx) {
609   return new AArch64MCCodeEmitter(MCII, Ctx);
610 }