LLVM  6.0.0svn
AArch64MCCodeEmitter.cpp
Go to the documentation of this file.
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 
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"
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  unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue,
167  const MCSubtargetInfo &STI) const;
168 
169  void encodeInstruction(const MCInst &MI, raw_ostream &OS,
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,
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");
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
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);
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 ||
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 
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 
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(
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 
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
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()) {
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.
566  Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), Fixup));
567  return;
568  } else if (MI.getOpcode() == AArch64::CompilerBarrier) {
569  // This just prevents the compiler from reordering accesses, no actual code.
570  return;
571  }
572 
573  uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
574  support::endian::Writer<support::little>(OS).write<uint32_t>(Binary);
575  ++MCNumEmitted; // Keep track of the # of mi's emitted.
576 }
577 
578 unsigned
579 AArch64MCCodeEmitter::fixMulHigh(const MCInst &MI,
580  unsigned EncodedValue,
581  const MCSubtargetInfo &STI) const {
582  // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
583  // (i.e. all bits 1) but is ignored by the processor.
584  EncodedValue |= 0x1f << 10;
585  return EncodedValue;
586 }
587 
588 template<int hasRs, int hasRt2> unsigned
589 AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
590  unsigned EncodedValue,
591  const MCSubtargetInfo &STI) const {
592  if (!hasRs) EncodedValue |= 0x001F0000;
593  if (!hasRt2) EncodedValue |= 0x00007C00;
594 
595  return EncodedValue;
596 }
597 
598 unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
599  const MCInst &MI, unsigned EncodedValue, const MCSubtargetInfo &STI) const {
600  // The Rm field of FCMP and friends is unused - it should be assembled
601  // as 0, but is ignored by the processor.
602  EncodedValue &= ~(0x1f << 16);
603  return EncodedValue;
604 }
605 
606 #define ENABLE_INSTR_PREDICATE_VERIFIER
607 #include "AArch64GenMCCodeEmitter.inc"
608 
610  const MCRegisterInfo &MRI,
611  MCContext &Ctx) {
612  return new AArch64MCCodeEmitter(MCII, Ctx);
613 }
bool isImm() const
Definition: MCInst.h:59
VariantKind getKind() const
Get the kind of this expression.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
bool isReg() const
Definition: MCInst.h:58
STATISTIC(NumFunctions, "Total number of functions")
static Lanai::Fixups FixupKind(const MCExpr *Expr)
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:65
Context object for machine code objects.
Definition: MCContext.h:59
const MCExpr * getExpr() const
Definition: MCInst.h:96
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:159
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
int64_t getImm() const
Definition: MCInst.h:76
unsigned const MachineRegisterInfo * MRI
Container class for subtarget features.
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:22
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:23
bool isExpr() const
Definition: MCInst.h:61
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:82
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
PowerPC TLS Dynamic Call Fixup
MCCodeEmitter * createAArch64MCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx)
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:180
SMLoc getLoc() const
Definition: MCInst.h:178
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
MCSubtargetInfo - Generic base class for all target subtargets.
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...
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
IRTranslator LLVM IR MI
unsigned getOpcode() const
Definition: MCInst.h:172
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:35