LCOV - code coverage report
Current view: top level - lib/Target/AArch64/MCTargetDesc - AArch64MCCodeEmitter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 125 126 99.2 %
Date: 2017-09-14 15:23:50 Functions: 16 17 94.1 %
Legend: Lines: hit not hit

          Line data    Source code
       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         321 :       : Ctx(ctx), MCII(mcii) {}
      51             :   AArch64MCCodeEmitter(const AArch64MCCodeEmitter &) = delete;
      52             :   void operator=(const AArch64MCCodeEmitter &) = delete;
      53         321 :   ~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       29150 :   if (MO.isReg())
     198       47418 :     return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
     199             : 
     200             :   assert(MO.isImm() && "did not expect relocated expression");
     201        5441 :   return static_cast<unsigned>(MO.getImm());
     202             : }
     203             : 
     204             : template<unsigned FixupKind> uint32_t
     205         705 : AArch64MCCodeEmitter::getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
     206             :                                            SmallVectorImpl<MCFixup> &Fixups,
     207             :                                            const MCSubtargetInfo &STI) const {
     208         705 :   const MCOperand &MO = MI.getOperand(OpIdx);
     209         705 :   uint32_t ImmVal = 0;
     210             : 
     211         705 :   if (MO.isImm())
     212         277 :     ImmVal = static_cast<uint32_t>(MO.getImm());
     213             :   else {
     214             :     assert(MO.isExpr() && "unable to encode load/store imm operand");
     215         428 :     MCFixupKind Kind = MCFixupKind(FixupKind);
     216         856 :     Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
     217             :     ++MCNumFixups;
     218             :   }
     219             : 
     220         705 :   return ImmVal;
     221             : }
     222             : 
     223             : /// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
     224             : /// target.
     225             : uint32_t
     226         177 : AArch64MCCodeEmitter::getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
     227             :                                          SmallVectorImpl<MCFixup> &Fixups,
     228             :                                          const MCSubtargetInfo &STI) const {
     229         177 :   const MCOperand &MO = MI.getOperand(OpIdx);
     230             : 
     231             :   // If the destination is an immediate, we have nothing to do.
     232         177 :   if (MO.isImm())
     233          13 :     return MO.getImm();
     234             :   assert(MO.isExpr() && "Unexpected target type!");
     235         164 :   const MCExpr *Expr = MO.getExpr();
     236             : 
     237         164 :   MCFixupKind Kind = MI.getOpcode() == AArch64::ADR
     238         164 :                          ? MCFixupKind(AArch64::fixup_aarch64_pcrel_adr_imm21)
     239         164 :                          : MCFixupKind(AArch64::fixup_aarch64_pcrel_adrp_imm21);
     240         328 :   Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
     241             : 
     242         164 :   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         428 : AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
     253             :                                           SmallVectorImpl<MCFixup> &Fixups,
     254             :                                           const MCSubtargetInfo &STI) const {
     255             :   // Suboperands are [imm, shifter].
     256         428 :   const MCOperand &MO = MI.getOperand(OpIdx);
     257         856 :   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         856 :   unsigned ShiftVal = AArch64_AM::getShiftValue(MO1.getImm());
     261             :   assert((ShiftVal == 0 || ShiftVal == 12) &&
     262             :          "unexpected shift value for add/sub immediate");
     263         428 :   if (MO.isImm())
     264         151 :     return MO.getImm() | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
     265             :   assert(MO.isExpr() && "Unable to encode MCOperand!");
     266         277 :   const MCExpr *Expr = MO.getExpr();
     267             : 
     268             :   // Encode the 12 bits of the fixup.
     269         277 :   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_add_imm12);
     270         554 :   Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
     271             : 
     272         277 :   ++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         156 :   if (const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
     277         156 :     AArch64MCExpr::VariantKind RefKind = A64E->getKind();
     278         312 :     if (RefKind == AArch64MCExpr::VK_TPREL_HI12 ||
     279         156 :         RefKind == AArch64MCExpr::VK_DTPREL_HI12)
     280             :       ShiftVal = 12;
     281             :   }
     282         255 :   return ShiftVal == 0 ? 0 : (1 << ShiftVal);
     283             : }
     284             : 
     285             : /// getCondBranchTargetOpValue - Return the encoded value for a conditional
     286             : /// branch target.
     287         102 : uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
     288             :     const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
     289             :     const MCSubtargetInfo &STI) const {
     290         102 :   const MCOperand &MO = MI.getOperand(OpIdx);
     291             : 
     292             :   // If the destination is an immediate, we have nothing to do.
     293         102 :   if (MO.isImm())
     294          13 :     return MO.getImm();
     295             :   assert(MO.isExpr() && "Unexpected target type!");
     296             : 
     297          89 :   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch19);
     298         178 :   Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
     299             : 
     300          89 :   ++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          34 : AArch64MCCodeEmitter::getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
     310             :                                             SmallVectorImpl<MCFixup> &Fixups,
     311             :                                             const MCSubtargetInfo &STI) const {
     312          34 :   const MCOperand &MO = MI.getOperand(OpIdx);
     313             : 
     314             :   // If the destination is an immediate, we have nothing to do.
     315          34 :   if (MO.isImm())
     316           2 :     return MO.getImm();
     317             :   assert(MO.isExpr() && "Unexpected target type!");
     318             : 
     319          32 :   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_ldr_pcrel_imm19);
     320          64 :   Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
     321             : 
     322          32 :   ++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         101 :   unsigned SignExtend = MI.getOperand(OpIdx).getImm();
     333         202 :   unsigned DoShift = MI.getOperand(OpIdx + 1).getImm();
     334         101 :   return (SignExtend << 1) | DoShift;
     335             : }
     336             : 
     337             : uint32_t
     338         269 : AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
     339             :                                             SmallVectorImpl<MCFixup> &Fixups,
     340             :                                             const MCSubtargetInfo &STI) const {
     341         269 :   const MCOperand &MO = MI.getOperand(OpIdx);
     342             : 
     343         269 :   if (MO.isImm())
     344          70 :     return MO.getImm();
     345             :   assert(MO.isExpr() && "Unexpected movz/movk immediate");
     346             : 
     347         398 :   Fixups.push_back(MCFixup::create(
     348         199 :       0, MO.getExpr(), MCFixupKind(AArch64::fixup_aarch64_movw), MI.getLoc()));
     349             : 
     350         199 :   ++MCNumFixups;
     351             : 
     352             :   return 0;
     353             : }
     354             : 
     355             : /// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
     356             : /// branch target.
     357          27 : uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
     358             :     const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
     359             :     const MCSubtargetInfo &STI) const {
     360          27 :   const MCOperand &MO = MI.getOperand(OpIdx);
     361             : 
     362             :   // If the destination is an immediate, we have nothing to do.
     363          27 :   if (MO.isImm())
     364           3 :     return MO.getImm();
     365             :   assert(MO.isExpr() && "Unexpected ADR target type!");
     366             : 
     367          24 :   MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch14);
     368          48 :   Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
     369             : 
     370          24 :   ++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          92 : AArch64MCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
     380             :                                              SmallVectorImpl<MCFixup> &Fixups,
     381             :                                              const MCSubtargetInfo &STI) const {
     382          92 :   const MCOperand &MO = MI.getOperand(OpIdx);
     383             : 
     384             :   // If the destination is an immediate, we have nothing to do.
     385          92 :   if (MO.isImm())
     386           7 :     return MO.getImm();
     387             :   assert(MO.isExpr() && "Unexpected ADR target type!");
     388             : 
     389          85 :   MCFixupKind Kind = MI.getOpcode() == AArch64::BL
     390          85 :                          ? MCFixupKind(AArch64::fixup_aarch64_pcrel_call26)
     391          85 :                          : MCFixupKind(AArch64::fixup_aarch64_pcrel_branch26);
     392         170 :   Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc()));
     393             : 
     394          85 :   ++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         116 :   const MCOperand &MO = MI.getOperand(OpIdx);
     411             :   assert(MO.isImm() && "Expected an immediate value for the shift amount!");
     412             : 
     413         116 :   switch (MO.getImm()) {
     414             :   default:
     415             :     break;
     416             :   case 0:
     417             :     return 0;
     418          32 :   case 8:
     419             :     return 1;
     420          16 :   case 16:
     421             :     return 2;
     422          16 :   case 24:
     423             :     return 3;
     424             :   }
     425             : 
     426           0 :   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          88 :   const MCOperand &MO = MI.getOperand(OpIdx);
     435             :   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
     436          88 :   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         100 :   const MCOperand &MO = MI.getOperand(OpIdx);
     444             :   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
     445         100 :   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         120 :   const MCOperand &MO = MI.getOperand(OpIdx);
     453             :   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
     454         120 :   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         108 :   const MCOperand &MO = MI.getOperand(OpIdx);
     462             :   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
     463         108 :   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          48 :   const MCOperand &MO = MI.getOperand(OpIdx);
     471             :   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
     472          48 :   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          20 :   const MCOperand &MO = MI.getOperand(OpIdx);
     480             :   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
     481          20 :   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          50 :   const MCOperand &MO = MI.getOperand(OpIdx);
     489             :   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
     490          50 :   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          50 :   const MCOperand &MO = MI.getOperand(OpIdx);
     498             :   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
     499          50 :   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          50 :   const MCOperand &MO = MI.getOperand(OpIdx);
     507             :   assert(MO.isImm() && "Expected an immediate value for the scale amount!");
     508          50 :   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          16 :   const MCOperand &MO = MI.getOperand(OpIdx);
     517             :   assert(MO.isImm() &&
     518             :          "Expected an immediate value for the move shift amount!");
     519          32 :   unsigned ShiftVal = AArch64_AM::getShiftValue(MO.getImm());
     520             :   assert((ShiftVal == 8 || ShiftVal == 16) && "Invalid shift amount!");
     521          16 :   return ShiftVal == 8 ? 0 : 1;
     522             : }
     523             : 
     524         119 : 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         119 :   MCOperand UImm16MO = MI.getOperand(1);
     531             : 
     532             :   // Nothing to do if there's no fixup.
     533         119 :   if (UImm16MO.isImm())
     534             :     return EncodedValue;
     535             : 
     536         168 :   const AArch64MCExpr *A64E = cast<AArch64MCExpr>(UImm16MO.getExpr());
     537             :   switch (A64E->getKind()) {
     538          51 :   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          51 :     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       11345 : void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
     556             :                                              SmallVectorImpl<MCFixup> &Fixups,
     557             :                                              const MCSubtargetInfo &STI) const {
     558       11345 :   verifyInstructionPredicates(MI,
     559             :                               computeAvailableFeatures(STI.getFeatureBits()));
     560             : 
     561       11345 :   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          21 :     MCFixupKind Fixup = MCFixupKind(AArch64::fixup_aarch64_tlsdesc_call);
     566          63 :     Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), Fixup));
     567          21 :     return;
     568       11324 :   } else if (MI.getOpcode() == AArch64::CompilerBarrier) {
     569             :     // This just prevents the compiler from reordering accesses, no actual code.
     570             :     return;
     571             :   }
     572             : 
     573       11323 :   uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
     574       22646 :   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          10 :   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          48 :   if (!hasRs) EncodedValue |= 0x001F0000;
     593          56 :   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          17 :   EncodedValue &= ~(0x1f << 16);
     603             :   return EncodedValue;
     604             : }
     605             : 
     606             : #define ENABLE_INSTR_PREDICATE_VERIFIER
     607             : #include "AArch64GenMCCodeEmitter.inc"
     608             : 
     609         321 : MCCodeEmitter *llvm::createAArch64MCCodeEmitter(const MCInstrInfo &MCII,
     610             :                                                 const MCRegisterInfo &MRI,
     611             :                                                 MCContext &Ctx) {
     612         642 :   return new AArch64MCCodeEmitter(MCII, Ctx);
     613             : }

Generated by: LCOV version 1.13