LCOV - code coverage report
Current view: top level - lib/Target/ARM/MCTargetDesc - ARMMCCodeEmitter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 137 501 27.3 %
Date: 2018-10-20 13:21:21 Functions: 8 67 11.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM 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 ARMMCCodeEmitter class.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "MCTargetDesc/ARMAddressingModes.h"
      15             : #include "MCTargetDesc/ARMBaseInfo.h"
      16             : #include "MCTargetDesc/ARMFixupKinds.h"
      17             : #include "MCTargetDesc/ARMMCExpr.h"
      18             : #include "llvm/ADT/APFloat.h"
      19             : #include "llvm/ADT/APInt.h"
      20             : #include "llvm/ADT/SmallVector.h"
      21             : #include "llvm/ADT/Statistic.h"
      22             : #include "llvm/ADT/Triple.h"
      23             : #include "llvm/MC/MCCodeEmitter.h"
      24             : #include "llvm/MC/MCContext.h"
      25             : #include "llvm/MC/MCExpr.h"
      26             : #include "llvm/MC/MCFixup.h"
      27             : #include "llvm/MC/MCInst.h"
      28             : #include "llvm/MC/MCInstrDesc.h"
      29             : #include "llvm/MC/MCInstrInfo.h"
      30             : #include "llvm/MC/MCRegisterInfo.h"
      31             : #include "llvm/MC/MCSubtargetInfo.h"
      32             : #include "llvm/Support/Casting.h"
      33             : #include "llvm/Support/Compiler.h"
      34             : #include "llvm/Support/ErrorHandling.h"
      35             : #include "llvm/Support/MathExtras.h"
      36             : #include "llvm/Support/raw_ostream.h"
      37             : #include <algorithm>
      38             : #include <cassert>
      39             : #include <cstdint>
      40             : #include <cstdlib>
      41             : 
      42             : using namespace llvm;
      43             : 
      44             : #define DEBUG_TYPE "mccodeemitter"
      45             : 
      46             : STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
      47             : STATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");
      48             : 
      49             : namespace {
      50             : 
      51             : class ARMMCCodeEmitter : public MCCodeEmitter {
      52             :   const MCInstrInfo &MCII;
      53             :   const MCContext &CTX;
      54             :   bool IsLittleEndian;
      55             : 
      56             : public:
      57             :   ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool IsLittle)
      58         951 :     : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) {
      59             :   }
      60             :   ARMMCCodeEmitter(const ARMMCCodeEmitter &) = delete;
      61             :   ARMMCCodeEmitter &operator=(const ARMMCCodeEmitter &) = delete;
      62         944 :   ~ARMMCCodeEmitter() override = default;
      63             : 
      64           0 :   bool isThumb(const MCSubtargetInfo &STI) const {
      65           0 :     return STI.getFeatureBits()[ARM::ModeThumb];
      66             :   }
      67             : 
      68           0 :   bool isThumb2(const MCSubtargetInfo &STI) const {
      69        6191 :     return isThumb(STI) && STI.getFeatureBits()[ARM::FeatureThumb2];
      70             :   }
      71             : 
      72             :   bool isTargetMachO(const MCSubtargetInfo &STI) const {
      73             :     const Triple &TT = STI.getTargetTriple();
      74             :     return TT.isOSBinFormatMachO();
      75             :   }
      76             : 
      77             :   unsigned getMachineSoImmOpValue(unsigned SoImm) const;
      78             : 
      79             :   // getBinaryCodeForInstr - TableGen'erated function for getting the
      80             :   // binary encoding for an instruction.
      81             :   uint64_t getBinaryCodeForInstr(const MCInst &MI,
      82             :                                  SmallVectorImpl<MCFixup> &Fixups,
      83             :                                  const MCSubtargetInfo &STI) const;
      84             : 
      85             :   /// getMachineOpValue - Return binary encoding of operand. If the machine
      86             :   /// operand requires relocation, record the relocation and return zero.
      87             :   unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
      88             :                              SmallVectorImpl<MCFixup> &Fixups,
      89             :                              const MCSubtargetInfo &STI) const;
      90             : 
      91             :   /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of
      92             :   /// the specified operand. This is used for operands with :lower16: and
      93             :   /// :upper16: prefixes.
      94             :   uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
      95             :                                SmallVectorImpl<MCFixup> &Fixups,
      96             :                                const MCSubtargetInfo &STI) const;
      97             : 
      98             :   bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
      99             :                               unsigned &Reg, unsigned &Imm,
     100             :                               SmallVectorImpl<MCFixup> &Fixups,
     101             :                               const MCSubtargetInfo &STI) const;
     102             : 
     103             :   /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate
     104             :   /// BL branch target.
     105             :   uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
     106             :                                    SmallVectorImpl<MCFixup> &Fixups,
     107             :                                    const MCSubtargetInfo &STI) const;
     108             : 
     109             :   /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
     110             :   /// BLX branch target.
     111             :   uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
     112             :                                     SmallVectorImpl<MCFixup> &Fixups,
     113             :                                     const MCSubtargetInfo &STI) const;
     114             : 
     115             :   /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
     116             :   uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
     117             :                                    SmallVectorImpl<MCFixup> &Fixups,
     118             :                                    const MCSubtargetInfo &STI) const;
     119             : 
     120             :   /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
     121             :   uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
     122             :                                     SmallVectorImpl<MCFixup> &Fixups,
     123             :                                     const MCSubtargetInfo &STI) const;
     124             : 
     125             :   /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
     126             :   uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
     127             :                                    SmallVectorImpl<MCFixup> &Fixups,
     128             :                                    const MCSubtargetInfo &STI) const;
     129             : 
     130             :   /// getBranchTargetOpValue - Return encoding info for 24-bit immediate
     131             :   /// branch target.
     132             :   uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
     133             :                                   SmallVectorImpl<MCFixup> &Fixups,
     134             :                                   const MCSubtargetInfo &STI) const;
     135             : 
     136             :   /// getThumbBranchTargetOpValue - Return encoding info for 24-bit
     137             :   /// immediate Thumb2 direct branch target.
     138             :   uint32_t getThumbBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
     139             :                                        SmallVectorImpl<MCFixup> &Fixups,
     140             :                                        const MCSubtargetInfo &STI) const;
     141             : 
     142             :   /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate
     143             :   /// branch target.
     144             :   uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
     145             :                                      SmallVectorImpl<MCFixup> &Fixups,
     146             :                                      const MCSubtargetInfo &STI) const;
     147             :   uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
     148             :                                  SmallVectorImpl<MCFixup> &Fixups,
     149             :                                  const MCSubtargetInfo &STI) const;
     150             :   uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
     151             :                                   SmallVectorImpl<MCFixup> &Fixups,
     152             :                                   const MCSubtargetInfo &STI) const;
     153             : 
     154             :   /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
     155             :   /// ADR label target.
     156             :   uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
     157             :                               SmallVectorImpl<MCFixup> &Fixups,
     158             :                               const MCSubtargetInfo &STI) const;
     159             :   uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
     160             :                               SmallVectorImpl<MCFixup> &Fixups,
     161             :                               const MCSubtargetInfo &STI) const;
     162             :   uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
     163             :                               SmallVectorImpl<MCFixup> &Fixups,
     164             :                               const MCSubtargetInfo &STI) const;
     165             : 
     166             : 
     167             :   /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
     168             :   /// operand.
     169             :   uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
     170             :                                    SmallVectorImpl<MCFixup> &Fixups,
     171             :                                    const MCSubtargetInfo &STI) const;
     172             : 
     173             :   /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.
     174             :   uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
     175             :                                          SmallVectorImpl<MCFixup> &Fixups,
     176             :                                          const MCSubtargetInfo &STI) const;
     177             : 
     178             :   /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
     179             :   /// operand.
     180             :   uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
     181             :                                    SmallVectorImpl<MCFixup> &Fixups,
     182             :                                    const MCSubtargetInfo &STI) const;
     183             : 
     184             :   /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2'
     185             :   /// operand.
     186             :   uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
     187             :                                    SmallVectorImpl<MCFixup> &Fixups,
     188             :                                    const MCSubtargetInfo &STI) const;
     189             : 
     190             :   /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2'
     191             :   /// operand.
     192             :   uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
     193             :                               SmallVectorImpl<MCFixup> &Fixups,
     194             :                               const MCSubtargetInfo &STI) const;
     195             : 
     196             : 
     197             :   /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
     198             :   /// operand as needed by load/store instructions.
     199             :   uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
     200             :                                SmallVectorImpl<MCFixup> &Fixups,
     201             :                                const MCSubtargetInfo &STI) const;
     202             : 
     203             :   /// getLdStmModeOpValue - Return encoding for load/store multiple mode.
     204             :   uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,
     205             :                                SmallVectorImpl<MCFixup> &Fixups,
     206             :                                const MCSubtargetInfo &STI) const {
     207             :     ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();
     208             :     switch (Mode) {
     209             :     default: llvm_unreachable("Unknown addressing sub-mode!");
     210             :     case ARM_AM::da: return 0;
     211             :     case ARM_AM::ia: return 1;
     212             :     case ARM_AM::db: return 2;
     213             :     case ARM_AM::ib: return 3;
     214             :     }
     215             :   }
     216             : 
     217             :   /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
     218             :   ///
     219           0 :   unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {
     220           0 :     switch (ShOpc) {
     221             :     case ARM_AM::no_shift:
     222             :     case ARM_AM::lsl: return 0;
     223           0 :     case ARM_AM::lsr: return 1;
     224           0 :     case ARM_AM::asr: return 2;
     225           0 :     case ARM_AM::ror:
     226           0 :     case ARM_AM::rrx: return 3;
     227             :     }
     228           0 :     llvm_unreachable("Invalid ShiftOpc!");
     229             :   }
     230             : 
     231             :   /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
     232             :   uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
     233             :                                      SmallVectorImpl<MCFixup> &Fixups,
     234             :                                      const MCSubtargetInfo &STI) const;
     235             : 
     236             :   /// getPostIdxRegOpValue - Return encoding for postidx_reg operands.
     237             :   uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
     238             :                                 SmallVectorImpl<MCFixup> &Fixups,
     239             :                                 const MCSubtargetInfo &STI) const;
     240             : 
     241             :   /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
     242             :   uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
     243             :                                      SmallVectorImpl<MCFixup> &Fixups,
     244             :                                      const MCSubtargetInfo &STI) const;
     245             : 
     246             :   /// getAddrMode3OpValue - Return encoding for addrmode3 operands.
     247             :   uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
     248             :                                SmallVectorImpl<MCFixup> &Fixups,
     249             :                                const MCSubtargetInfo &STI) const;
     250             : 
     251             :   /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12'
     252             :   /// operand.
     253             :   uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
     254             :                                      SmallVectorImpl<MCFixup> &Fixups,
     255             :                                      const MCSubtargetInfo &STI) const;
     256             : 
     257             :   /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
     258             :   uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
     259             :                                 SmallVectorImpl<MCFixup> &Fixups,
     260             :                                 const MCSubtargetInfo &STI) const;
     261             : 
     262             :   /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
     263             :   uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
     264             :                                 SmallVectorImpl<MCFixup> &Fixups,
     265             :                                 const MCSubtargetInfo &STI) const;
     266             : 
     267             :   /// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand.
     268             :   uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
     269             :                                SmallVectorImpl<MCFixup> &Fixups,
     270             :                                const MCSubtargetInfo &STI) const;
     271             : 
     272             :   /// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand.
     273             :   uint32_t getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx,
     274             :                                SmallVectorImpl<MCFixup> &Fixups,
     275             :                                const MCSubtargetInfo &STI) const;
     276             : 
     277             :   /// getCCOutOpValue - Return encoding of the 's' bit.
     278           0 :   unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
     279             :                            SmallVectorImpl<MCFixup> &Fixups,
     280             :                            const MCSubtargetInfo &STI) const {
     281             :     // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
     282             :     // '1' respectively.
     283        6641 :     return MI.getOperand(Op).getReg() == ARM::CPSR;
     284             :   }
     285             : 
     286             :   /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
     287             :   unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
     288             :                            SmallVectorImpl<MCFixup> &Fixups,
     289             :                            const MCSubtargetInfo &STI) const {
     290             :     const MCOperand &MO = MI.getOperand(Op);
     291             : 
     292             :     // We expect MO to be an immediate or an expression,
     293             :     // if it is an immediate - that's fine, just encode the value.
     294             :     // Otherwise - create a Fixup.
     295             :     if (MO.isExpr()) {
     296             :       const MCExpr *Expr = MO.getExpr();
     297             :       // In instruction code this value always encoded as lowest 12 bits,
     298             :       // so we don't have to perform any specific adjustments.
     299             :       // Due to requirements of relocatable records we have to use FK_Data_4.
     300             :       // See ARMELFObjectWriter::ExplicitRelSym and
     301             :       //     ARMELFObjectWriter::GetRelocTypeInner for more details.
     302             :       MCFixupKind Kind = MCFixupKind(FK_Data_4);
     303             :       Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
     304             :       return 0;
     305             :     }
     306             : 
     307             :     unsigned SoImm = MO.getImm();
     308             :     int SoImmVal = ARM_AM::getSOImmVal(SoImm);
     309             :     assert(SoImmVal != -1 && "Not a valid so_imm value!");
     310             : 
     311             :     // Encode rotate_imm.
     312             :     unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
     313             :       << ARMII::SoRotImmShift;
     314             : 
     315             :     // Encode immed_8.
     316             :     Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
     317             :     return Binary;
     318             :   }
     319             : 
     320           0 :   unsigned getModImmOpValue(const MCInst &MI, unsigned Op,
     321             :                             SmallVectorImpl<MCFixup> &Fixups,
     322             :                             const MCSubtargetInfo &ST) const {
     323             :     const MCOperand &MO = MI.getOperand(Op);
     324             : 
     325             :     // Support for fixups (MCFixup)
     326           0 :     if (MO.isExpr()) {
     327           0 :       const MCExpr *Expr = MO.getExpr();
     328             :       // Fixups resolve to plain values that need to be encoded.
     329             :       MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_mod_imm);
     330           0 :       Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
     331           0 :       return 0;
     332             :     }
     333             : 
     334             :     // Immediate is already in its encoded format
     335           0 :     return MO.getImm();
     336             :   }
     337             : 
     338             :   /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
     339           0 :   unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
     340             :                            SmallVectorImpl<MCFixup> &Fixups,
     341             :                            const MCSubtargetInfo &STI) const {
     342             :     const MCOperand &MO = MI.getOperand(Op);
     343             : 
     344             :     // Support for fixups (MCFixup)
     345           0 :     if (MO.isExpr()) {
     346           0 :       const MCExpr *Expr = MO.getExpr();
     347             :       // Fixups resolve to plain values that need to be encoded.
     348             :       MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_so_imm);
     349           0 :       Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
     350           0 :       return 0;
     351             :     }
     352           0 :     unsigned SoImm = MO.getImm();
     353           0 :     unsigned Encoded =  ARM_AM::getT2SOImmVal(SoImm);
     354             :     assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
     355           0 :     return Encoded;
     356             :   }
     357             : 
     358             :   unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
     359             :     SmallVectorImpl<MCFixup> &Fixups,
     360             :     const MCSubtargetInfo &STI) const;
     361             :   unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
     362             :     SmallVectorImpl<MCFixup> &Fixups,
     363             :     const MCSubtargetInfo &STI) const;
     364             :   unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
     365             :     SmallVectorImpl<MCFixup> &Fixups,
     366             :     const MCSubtargetInfo &STI) const;
     367             : 
     368             :   /// getSORegOpValue - Return an encoded so_reg shifted register value.
     369             :   unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,
     370             :                            SmallVectorImpl<MCFixup> &Fixups,
     371             :                            const MCSubtargetInfo &STI) const;
     372             :   unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,
     373             :                            SmallVectorImpl<MCFixup> &Fixups,
     374             :                            const MCSubtargetInfo &STI) const;
     375             :   unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
     376             :                              SmallVectorImpl<MCFixup> &Fixups,
     377             :                              const MCSubtargetInfo &STI) const;
     378             : 
     379           0 :   unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
     380             :                                    SmallVectorImpl<MCFixup> &Fixups,
     381             :                                    const MCSubtargetInfo &STI) const {
     382          56 :     return 64 - MI.getOperand(Op).getImm();
     383             :   }
     384             : 
     385             :   unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
     386             :                                       SmallVectorImpl<MCFixup> &Fixups,
     387             :                                       const MCSubtargetInfo &STI) const;
     388             : 
     389             :   unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
     390             :                                   SmallVectorImpl<MCFixup> &Fixups,
     391             :                                   const MCSubtargetInfo &STI) const;
     392             :   unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
     393             :                                       SmallVectorImpl<MCFixup> &Fixups,
     394             :                                       const MCSubtargetInfo &STI) const;
     395             :   unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
     396             :                                         SmallVectorImpl<MCFixup> &Fixups,
     397             :                                         const MCSubtargetInfo &STI) const;
     398             :   unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
     399             :                                         SmallVectorImpl<MCFixup> &Fixups,
     400             :                                         const MCSubtargetInfo &STI) const;
     401             :   unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
     402             :                                      SmallVectorImpl<MCFixup> &Fixups,
     403             :                                      const MCSubtargetInfo &STI) const;
     404             : 
     405             :   unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op,
     406             :                              SmallVectorImpl<MCFixup> &Fixups,
     407             :                              const MCSubtargetInfo &STI) const;
     408             :   unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op,
     409             :                               SmallVectorImpl<MCFixup> &Fixups,
     410             :                               const MCSubtargetInfo &STI) const;
     411             :   unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op,
     412             :                               SmallVectorImpl<MCFixup> &Fixups,
     413             :                               const MCSubtargetInfo &STI) const;
     414             :   unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op,
     415             :                               SmallVectorImpl<MCFixup> &Fixups,
     416             :                               const MCSubtargetInfo &STI) const;
     417             : 
     418             :   unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op,
     419             :                                  SmallVectorImpl<MCFixup> &Fixups,
     420             :                                  const MCSubtargetInfo &STI) const;
     421             : 
     422             :   unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
     423             :                                       unsigned EncodedValue,
     424             :                                       const MCSubtargetInfo &STI) const;
     425             :   unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,
     426             :                                           unsigned EncodedValue,
     427             :                                           const MCSubtargetInfo &STI) const;
     428             :   unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
     429             :                                     unsigned EncodedValue,
     430             :                                     const MCSubtargetInfo &STI) const;
     431             :   unsigned NEONThumb2V8PostEncoder(const MCInst &MI,
     432             :                                    unsigned EncodedValue,
     433             :                                    const MCSubtargetInfo &STI) const;
     434             : 
     435             :   unsigned VFPThumb2PostEncoder(const MCInst &MI,
     436             :                                 unsigned EncodedValue,
     437             :                                 const MCSubtargetInfo &STI) const;
     438             : 
     439             :   void EmitByte(unsigned char C, raw_ostream &OS) const {
     440           0 :     OS << (char)C;
     441             :   }
     442             : 
     443           0 :   void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
     444             :     // Output the constant in little endian byte order.
     445           0 :     for (unsigned i = 0; i != Size; ++i) {
     446           0 :       unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
     447           0 :       EmitByte((Val >> Shift) & 0xff, OS);
     448             :     }
     449           0 :   }
     450             : 
     451             :   void encodeInstruction(const MCInst &MI, raw_ostream &OS,
     452             :                          SmallVectorImpl<MCFixup> &Fixups,
     453             :                          const MCSubtargetInfo &STI) const override;
     454             : };
     455             : 
     456             : } // end anonymous namespace
     457             : 
     458             : /// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
     459             : /// instructions, and rewrite them to their Thumb2 form if we are currently in
     460             : /// Thumb2 mode.
     461           0 : unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
     462             :                                                  unsigned EncodedValue,
     463             :                                                  const MCSubtargetInfo &STI) const {
     464             :   if (isThumb2(STI)) {
     465             :     // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
     466             :     // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
     467             :     // set to 1111.
     468             :     unsigned Bit24 = EncodedValue & 0x01000000;
     469        1004 :     unsigned Bit28 = Bit24 << 4;
     470        1004 :     EncodedValue &= 0xEFFFFFFF;
     471        1004 :     EncodedValue |= Bit28;
     472        1004 :     EncodedValue |= 0x0F000000;
     473             :   }
     474             : 
     475           0 :   return EncodedValue;
     476             : }
     477             : 
     478             : /// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
     479             : /// instructions, and rewrite them to their Thumb2 form if we are currently in
     480             : /// Thumb2 mode.
     481           0 : unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
     482             :                                                  unsigned EncodedValue,
     483             :                                                  const MCSubtargetInfo &STI) const {
     484             :   if (isThumb2(STI)) {
     485        1196 :     EncodedValue &= 0xF0FFFFFF;
     486        1196 :     EncodedValue |= 0x09000000;
     487             :   }
     488             : 
     489           0 :   return EncodedValue;
     490             : }
     491             : 
     492             : /// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
     493             : /// instructions, and rewrite them to their Thumb2 form if we are currently in
     494             : /// Thumb2 mode.
     495           0 : unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
     496             :                                                  unsigned EncodedValue,
     497             :                                                  const MCSubtargetInfo &STI) const {
     498             :   if (isThumb2(STI)) {
     499          29 :     EncodedValue &= 0x00FFFFFF;
     500          29 :     EncodedValue |= 0xEE000000;
     501             :   }
     502             : 
     503           0 :   return EncodedValue;
     504             : }
     505             : 
     506             : /// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form
     507             : /// if we are in Thumb2.
     508           0 : unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,
     509             :                                                  unsigned EncodedValue,
     510             :                                                  const MCSubtargetInfo &STI) const {
     511             :   if (isThumb2(STI)) {
     512         101 :     EncodedValue |= 0xC000000; // Set bits 27-26
     513             :   }
     514             : 
     515           0 :   return EncodedValue;
     516             : }
     517             : 
     518             : /// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
     519             : /// them to their Thumb2 form if we are currently in Thumb2 mode.
     520           0 : unsigned ARMMCCodeEmitter::
     521             : VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue,
     522             :                      const MCSubtargetInfo &STI) const {
     523             :   if (isThumb2(STI)) {
     524         686 :     EncodedValue &= 0x0FFFFFFF;
     525         686 :     EncodedValue |= 0xE0000000;
     526             :   }
     527           0 :   return EncodedValue;
     528             : }
     529             : 
     530             : /// getMachineOpValue - Return binary encoding of operand. If the machine
     531             : /// operand requires relocation, record the relocation and return zero.
     532           0 : unsigned ARMMCCodeEmitter::
     533             : getMachineOpValue(const MCInst &MI, const MCOperand &MO,
     534             :                   SmallVectorImpl<MCFixup> &Fixups,
     535             :                   const MCSubtargetInfo &STI) const {
     536           0 :   if (MO.isReg()) {
     537           0 :     unsigned Reg = MO.getReg();
     538           0 :     unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
     539             : 
     540             :     // Q registers are encoded as 2x their register number.
     541           0 :     switch (Reg) {
     542           0 :     default:
     543           0 :       return RegNo;
     544           0 :     case ARM::Q0:  case ARM::Q1:  case ARM::Q2:  case ARM::Q3:
     545             :     case ARM::Q4:  case ARM::Q5:  case ARM::Q6:  case ARM::Q7:
     546             :     case ARM::Q8:  case ARM::Q9:  case ARM::Q10: case ARM::Q11:
     547             :     case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
     548           0 :       return 2 * RegNo;
     549             :     }
     550           0 :   } else if (MO.isImm()) {
     551           0 :     return static_cast<unsigned>(MO.getImm());
     552           0 :   } else if (MO.isFPImm()) {
     553           0 :     return static_cast<unsigned>(APFloat(MO.getFPImm())
     554           0 :                      .bitcastToAPInt().getHiBits(32).getLimitedValue());
     555             :   }
     556             : 
     557           0 :   llvm_unreachable("Unable to encode MCOperand!");
     558             : }
     559             : 
     560             : /// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
     561           0 : bool ARMMCCodeEmitter::
     562             : EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
     563             :                        unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups,
     564             :                        const MCSubtargetInfo &STI) const {
     565             :   const MCOperand &MO  = MI.getOperand(OpIdx);
     566           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
     567             : 
     568        3804 :   Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
     569             : 
     570        3804 :   int32_t SImm = MO1.getImm();
     571             :   bool isAdd = true;
     572             : 
     573             :   // Special value for #-0
     574        3804 :   if (SImm == INT32_MIN) {
     575             :     SImm = 0;
     576             :     isAdd = false;
     577             :   }
     578             : 
     579             :   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
     580        3802 :   if (SImm < 0) {
     581           9 :     SImm = -SImm;
     582             :     isAdd = false;
     583             :   }
     584             : 
     585        3804 :   Imm = SImm;
     586           0 :   return isAdd;
     587             : }
     588             : 
     589             : /// getBranchTargetOpValue - Helper function to get the branch target operand,
     590             : /// which is either an immediate or requires a fixup.
     591           0 : static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
     592             :                                        unsigned FixupKind,
     593             :                                        SmallVectorImpl<MCFixup> &Fixups,
     594             :                                        const MCSubtargetInfo &STI) {
     595             :   const MCOperand &MO = MI.getOperand(OpIdx);
     596             : 
     597             :   // If the destination is an immediate, we have nothing to do.
     598           0 :   if (MO.isImm()) return MO.getImm();
     599             :   assert(MO.isExpr() && "Unexpected branch target type!");
     600           0 :   const MCExpr *Expr = MO.getExpr();
     601             :   MCFixupKind Kind = MCFixupKind(FixupKind);
     602           0 :   Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
     603             : 
     604             :   // All of the information is in the fixup.
     605           0 :   return 0;
     606             : }
     607             : 
     608             : // Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are
     609             : // determined by negating them and XOR'ing them with bit 23.
     610             : static int32_t encodeThumbBLOffset(int32_t offset) {
     611           0 :   offset >>= 1;
     612           0 :   uint32_t S  = (offset & 0x800000) >> 23;
     613           0 :   uint32_t J1 = (offset & 0x400000) >> 22;
     614           0 :   uint32_t J2 = (offset & 0x200000) >> 21;
     615           0 :   J1 = (~J1 & 0x1);
     616           0 :   J2 = (~J2 & 0x1);
     617           0 :   J1 ^= S;
     618           0 :   J2 ^= S;
     619             : 
     620           0 :   offset &= ~0x600000;
     621           0 :   offset |= J1 << 22;
     622           0 :   offset |= J2 << 21;
     623             : 
     624             :   return offset;
     625             : }
     626             : 
     627             : /// getThumbBLTargetOpValue - Return encoding info for immediate branch target.
     628           0 : uint32_t ARMMCCodeEmitter::
     629             : getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
     630             :                         SmallVectorImpl<MCFixup> &Fixups,
     631             :                         const MCSubtargetInfo &STI) const {
     632           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     633           0 :   if (MO.isExpr())
     634           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl,
     635           0 :                                     Fixups, STI);
     636           0 :   return encodeThumbBLOffset(MO.getImm());
     637             : }
     638             : 
     639             : /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
     640             : /// BLX branch target.
     641           0 : uint32_t ARMMCCodeEmitter::
     642             : getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
     643             :                          SmallVectorImpl<MCFixup> &Fixups,
     644             :                          const MCSubtargetInfo &STI) const {
     645           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     646           0 :   if (MO.isExpr())
     647           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx,
     648           0 :                                     Fixups, STI);
     649           0 :   return encodeThumbBLOffset(MO.getImm());
     650             : }
     651             : 
     652             : /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
     653           0 : uint32_t ARMMCCodeEmitter::
     654             : getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
     655             :                         SmallVectorImpl<MCFixup> &Fixups,
     656             :                         const MCSubtargetInfo &STI) const {
     657           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     658           0 :   if (MO.isExpr())
     659           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br,
     660           0 :                                     Fixups, STI);
     661           0 :   return (MO.getImm() >> 1);
     662             : }
     663             : 
     664             : /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
     665           0 : uint32_t ARMMCCodeEmitter::
     666             : getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
     667             :                          SmallVectorImpl<MCFixup> &Fixups,
     668             :                          const MCSubtargetInfo &STI) const {
     669           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     670           0 :   if (MO.isExpr())
     671           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc,
     672           0 :                                     Fixups, STI);
     673           0 :   return (MO.getImm() >> 1);
     674             : }
     675             : 
     676             : /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
     677           0 : uint32_t ARMMCCodeEmitter::
     678             : getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
     679             :                         SmallVectorImpl<MCFixup> &Fixups,
     680             :                         const MCSubtargetInfo &STI) const {
     681           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     682           0 :   if (MO.isExpr())
     683           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups, STI);
     684           0 :   return (MO.getImm() >> 1);
     685             : }
     686             : 
     687             : /// Return true if this branch has a non-always predication
     688        1021 : static bool HasConditionalBranch(const MCInst &MI) {
     689        1021 :   int NumOp = MI.getNumOperands();
     690        1021 :   if (NumOp >= 2) {
     691         833 :     for (int i = 0; i < NumOp-1; ++i) {
     692         625 :       const MCOperand &MCOp1 = MI.getOperand(i);
     693         625 :       const MCOperand &MCOp2 = MI.getOperand(i + 1);
     694         625 :       if (MCOp1.isImm() && MCOp2.isReg() &&
     695         312 :           (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) {
     696         312 :         if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL)
     697             :           return true;
     698             :       }
     699             :     }
     700             :   }
     701             :   return false;
     702             : }
     703             : 
     704             : /// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
     705             : /// target.
     706           0 : uint32_t ARMMCCodeEmitter::
     707             : getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
     708             :                        SmallVectorImpl<MCFixup> &Fixups,
     709             :                        const MCSubtargetInfo &STI) const {
     710             :   // FIXME: This really, really shouldn't use TargetMachine. We don't want
     711             :   // coupling between MC and TM anywhere we can help it.
     712             :   if (isThumb2(STI))
     713             :     return
     714           0 :       ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups, STI);
     715           0 :   return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI);
     716             : }
     717             : 
     718             : /// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
     719             : /// target.
     720           0 : uint32_t ARMMCCodeEmitter::
     721             : getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
     722             :                           SmallVectorImpl<MCFixup> &Fixups,
     723             :                           const MCSubtargetInfo &STI) const {
     724           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     725           0 :   if (MO.isExpr()) {
     726           0 :     if (HasConditionalBranch(MI))
     727           0 :       return ::getBranchTargetOpValue(MI, OpIdx,
     728           0 :                                       ARM::fixup_arm_condbranch, Fixups, STI);
     729           0 :     return ::getBranchTargetOpValue(MI, OpIdx,
     730           0 :                                     ARM::fixup_arm_uncondbranch, Fixups, STI);
     731             :   }
     732             : 
     733           0 :   return MO.getImm() >> 2;
     734             : }
     735             : 
     736           0 : uint32_t ARMMCCodeEmitter::
     737             : getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
     738             :                           SmallVectorImpl<MCFixup> &Fixups,
     739             :                           const MCSubtargetInfo &STI) const {
     740           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     741           0 :   if (MO.isExpr()) {
     742           0 :     if (HasConditionalBranch(MI))
     743           0 :       return ::getBranchTargetOpValue(MI, OpIdx,
     744           0 :                                       ARM::fixup_arm_condbl, Fixups, STI);
     745           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups, STI);
     746             :   }
     747             : 
     748           0 :   return MO.getImm() >> 2;
     749             : }
     750             : 
     751           0 : uint32_t ARMMCCodeEmitter::
     752             : getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
     753             :                           SmallVectorImpl<MCFixup> &Fixups,
     754             :                           const MCSubtargetInfo &STI) const {
     755           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     756           0 :   if (MO.isExpr())
     757           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups, STI);
     758             : 
     759           0 :   return MO.getImm() >> 1;
     760             : }
     761             : 
     762             : /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
     763             : /// immediate branch target.
     764           0 : uint32_t ARMMCCodeEmitter::getThumbBranchTargetOpValue(
     765             :     const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
     766             :     const MCSubtargetInfo &STI) const {
     767             :   unsigned Val = 0;
     768           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     769             : 
     770           0 :   if(MO.isExpr())
     771           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups, STI);
     772             :   else
     773           0 :     Val = MO.getImm() >> 1;
     774             : 
     775           0 :   bool I  = (Val & 0x800000);
     776           0 :   bool J1 = (Val & 0x400000);
     777           0 :   bool J2 = (Val & 0x200000);
     778           0 :   if (I ^ J1)
     779           0 :     Val &= ~0x400000;
     780             :   else
     781           0 :     Val |= 0x400000;
     782             : 
     783           0 :   if (I ^ J2)
     784           0 :     Val &= ~0x200000;
     785             :   else
     786           0 :     Val |= 0x200000;
     787             : 
     788             :   return Val;
     789             : }
     790             : 
     791             : /// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate
     792             : /// ADR label target.
     793           0 : uint32_t ARMMCCodeEmitter::
     794             : getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
     795             :                    SmallVectorImpl<MCFixup> &Fixups,
     796             :                    const MCSubtargetInfo &STI) const {
     797           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     798           0 :   if (MO.isExpr())
     799           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12,
     800           0 :                                     Fixups, STI);
     801             :   int64_t offset = MO.getImm();
     802             :   uint32_t Val = 0x2000;
     803             : 
     804             :   int SoImmVal;
     805           0 :   if (offset == INT32_MIN) {
     806             :     Val = 0x1000;
     807             :     SoImmVal = 0;
     808           0 :   } else if (offset < 0) {
     809             :     Val = 0x1000;
     810           0 :     offset *= -1;
     811           0 :     SoImmVal = ARM_AM::getSOImmVal(offset);
     812           0 :     if(SoImmVal == -1) {
     813             :       Val = 0x2000;
     814             :       offset *= -1;
     815           0 :       SoImmVal = ARM_AM::getSOImmVal(offset);
     816             :     }
     817             :   } else {
     818           0 :     SoImmVal = ARM_AM::getSOImmVal(offset);
     819           0 :     if(SoImmVal == -1) {
     820             :       Val = 0x1000;
     821           0 :       offset *= -1;
     822           0 :       SoImmVal = ARM_AM::getSOImmVal(offset);
     823             :     }
     824             :   }
     825             : 
     826             :   assert(SoImmVal != -1 && "Not a valid so_imm value!");
     827             : 
     828           0 :   Val |= SoImmVal;
     829           0 :   return Val;
     830             : }
     831             : 
     832             : /// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
     833             : /// target.
     834           0 : uint32_t ARMMCCodeEmitter::
     835             : getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
     836             :                    SmallVectorImpl<MCFixup> &Fixups,
     837             :                    const MCSubtargetInfo &STI) const {
     838           0 :   const MCOperand MO = MI.getOperand(OpIdx);
     839           0 :   if (MO.isExpr())
     840           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
     841           0 :                                     Fixups, STI);
     842           0 :   int32_t Val = MO.getImm();
     843           0 :   if (Val == INT32_MIN)
     844             :     Val = 0x1000;
     845           0 :   else if (Val < 0) {
     846           0 :     Val *= -1;
     847           0 :     Val |= 0x1000;
     848             :   }
     849           0 :   return Val;
     850             : }
     851             : 
     852             : /// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
     853             : /// target.
     854           0 : uint32_t ARMMCCodeEmitter::
     855             : getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
     856             :                    SmallVectorImpl<MCFixup> &Fixups,
     857             :                    const MCSubtargetInfo &STI) const {
     858          26 :   const MCOperand MO = MI.getOperand(OpIdx);
     859          26 :   if (MO.isExpr())
     860          13 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10,
     861           0 :                                     Fixups, STI);
     862          13 :   return MO.getImm();
     863             : }
     864             : 
     865             : /// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg'
     866             : /// operand.
     867           0 : uint32_t ARMMCCodeEmitter::
     868             : getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
     869             :                               SmallVectorImpl<MCFixup> &,
     870             :                               const MCSubtargetInfo &STI) const {
     871             :   // [Rn, Rm]
     872             :   //   {5-3} = Rm
     873             :   //   {2-0} = Rn
     874             :   const MCOperand &MO1 = MI.getOperand(OpIdx);
     875           0 :   const MCOperand &MO2 = MI.getOperand(OpIdx + 1);
     876          44 :   unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
     877          44 :   unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO2.getReg());
     878          44 :   return (Rm << 3) | Rn;
     879             : }
     880             : 
     881             : /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
     882        3298 : uint32_t ARMMCCodeEmitter::
     883             : getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
     884             :                         SmallVectorImpl<MCFixup> &Fixups,
     885             :                         const MCSubtargetInfo &STI) const {
     886             :   // {17-13} = reg
     887             :   // {12}    = (U)nsigned (add == '1', sub == '0')
     888             :   // {11-0}  = imm12
     889             :   unsigned Reg, Imm12;
     890             :   bool isAdd = true;
     891             :   // If The first operand isn't a register, we have a label reference.
     892             :   const MCOperand &MO = MI.getOperand(OpIdx);
     893        3298 :   if (!MO.isReg()) {
     894         106 :     Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
     895             :     Imm12 = 0;
     896             : 
     897         106 :     if (MO.isExpr()) {
     898          58 :       const MCExpr *Expr = MO.getExpr();
     899             :       isAdd = false ; // 'U' bit is set as part of the fixup.
     900             : 
     901             :       MCFixupKind Kind;
     902             :       if (isThumb2(STI))
     903             :         Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
     904             :       else
     905             :         Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
     906         116 :       Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
     907             : 
     908             :       ++MCNumCPRelocations;
     909             :     } else {
     910             :       Reg = ARM::PC;
     911          48 :       int32_t Offset = MO.getImm();
     912          48 :       if (Offset == INT32_MIN) {
     913             :         Offset = 0;
     914             :         isAdd = false;
     915          32 :       } else if (Offset < 0) {
     916          32 :         Offset *= -1;
     917             :         isAdd = false;
     918             :       }
     919          48 :       Imm12 = Offset;
     920             :     }
     921             :   } else
     922        3192 :     isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups, STI);
     923             : 
     924        3298 :   uint32_t Binary = Imm12 & 0xfff;
     925             :   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
     926        3298 :   if (isAdd)
     927        3181 :     Binary |= (1 << 12);
     928        3298 :   Binary |= (Reg << 13);
     929        3298 :   return Binary;
     930             : }
     931             : 
     932             : /// getT2Imm8s4OpValue - Return encoding info for
     933             : /// '+/- imm8<<2' operand.
     934           0 : uint32_t ARMMCCodeEmitter::
     935             : getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
     936             :                    SmallVectorImpl<MCFixup> &Fixups,
     937             :                    const MCSubtargetInfo &STI) const {
     938             :   // FIXME: The immediate operand should have already been encoded like this
     939             :   // before ever getting here. The encoder method should just need to combine
     940             :   // the MI operands for the register and the offset into a single
     941             :   // representation for the complex operand in the .td file. This isn't just
     942             :   // style, unfortunately. As-is, we can't represent the distinct encoding
     943             :   // for #-0.
     944             : 
     945             :   // {8}    = (U)nsigned (add == '1', sub == '0')
     946             :   // {7-0}  = imm8
     947          48 :   int32_t Imm8 = MI.getOperand(OpIdx).getImm();
     948             :   bool isAdd = Imm8 >= 0;
     949             : 
     950             :   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
     951          48 :   if (Imm8 < 0)
     952          23 :     Imm8 = -(uint32_t)Imm8;
     953             : 
     954             :   // Scaled by 4.
     955          48 :   Imm8 /= 4;
     956             : 
     957          48 :   uint32_t Binary = Imm8 & 0xff;
     958             :   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
     959          48 :   if (isAdd)
     960          25 :     Binary |= (1 << 8);
     961           0 :   return Binary;
     962             : }
     963             : 
     964             : /// getT2AddrModeImm8s4OpValue - Return encoding info for
     965             : /// 'reg +/- imm8<<2' operand.
     966           0 : uint32_t ARMMCCodeEmitter::
     967             : getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
     968             :                         SmallVectorImpl<MCFixup> &Fixups,
     969             :                         const MCSubtargetInfo &STI) const {
     970             :   // {12-9} = reg
     971             :   // {8}    = (U)nsigned (add == '1', sub == '0')
     972             :   // {7-0}  = imm8
     973             :   unsigned Reg, Imm8;
     974             :   bool isAdd = true;
     975             :   // If The first operand isn't a register, we have a label reference.
     976             :   const MCOperand &MO = MI.getOperand(OpIdx);
     977           0 :   if (!MO.isReg()) {
     978           0 :     Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
     979             :     Imm8 = 0;
     980             :     isAdd = false ; // 'U' bit is set as part of the fixup.
     981             : 
     982             :     assert(MO.isExpr() && "Unexpected machine operand type!");
     983           0 :     const MCExpr *Expr = MO.getExpr();
     984             :     MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
     985           0 :     Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
     986             : 
     987             :     ++MCNumCPRelocations;
     988             :   } else
     989           0 :     isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);
     990             : 
     991             :   // FIXME: The immediate operand should have already been encoded like this
     992             :   // before ever getting here. The encoder method should just need to combine
     993             :   // the MI operands for the register and the offset into a single
     994             :   // representation for the complex operand in the .td file. This isn't just
     995             :   // style, unfortunately. As-is, we can't represent the distinct encoding
     996             :   // for #-0.
     997           0 :   uint32_t Binary = (Imm8 >> 2) & 0xff;
     998             :   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
     999           0 :   if (isAdd)
    1000           0 :     Binary |= (1 << 8);
    1001           0 :   Binary |= (Reg << 9);
    1002           0 :   return Binary;
    1003             : }
    1004             : 
    1005             : /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for
    1006             : /// 'reg + imm8<<2' operand.
    1007           0 : uint32_t ARMMCCodeEmitter::
    1008             : getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
    1009             :                         SmallVectorImpl<MCFixup> &Fixups,
    1010             :                         const MCSubtargetInfo &STI) const {
    1011             :   // {11-8} = reg
    1012             :   // {7-0}  = imm8
    1013             :   const MCOperand &MO = MI.getOperand(OpIdx);
    1014           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
    1015          34 :   unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
    1016          34 :   unsigned Imm8 = MO1.getImm();
    1017          34 :   return (Reg << 8) | Imm8;
    1018             : }
    1019             : 
    1020             : uint32_t
    1021           0 : ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
    1022             :                                       SmallVectorImpl<MCFixup> &Fixups,
    1023             :                                       const MCSubtargetInfo &STI) const {
    1024             :   // {20-16} = imm{15-12}
    1025             :   // {11-0}  = imm{11-0}
    1026             :   const MCOperand &MO = MI.getOperand(OpIdx);
    1027           0 :   if (MO.isImm())
    1028             :     // Hi / lo 16 bits already extracted during earlier passes.
    1029           0 :     return static_cast<unsigned>(MO.getImm());
    1030             : 
    1031             :   // Handle :upper16: and :lower16: assembly prefixes.
    1032           0 :   const MCExpr *E = MO.getExpr();
    1033             :   MCFixupKind Kind;
    1034           0 :   if (E->getKind() == MCExpr::Target) {
    1035             :     const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E);
    1036           0 :     E = ARM16Expr->getSubExpr();
    1037             : 
    1038             :     if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(E)) {
    1039           0 :       const int64_t Value = MCE->getValue();
    1040           0 :       if (Value > UINT32_MAX)
    1041           0 :         report_fatal_error("constant value truncated (limited to 32-bit)");
    1042             : 
    1043           0 :       switch (ARM16Expr->getKind()) {
    1044           0 :       case ARMMCExpr::VK_ARM_HI16:
    1045           0 :         return (int32_t(Value) & 0xffff0000) >> 16;
    1046           0 :       case ARMMCExpr::VK_ARM_LO16:
    1047           0 :         return (int32_t(Value) & 0x0000ffff);
    1048           0 :       default: llvm_unreachable("Unsupported ARMFixup");
    1049             :       }
    1050             :     }
    1051             : 
    1052           0 :     switch (ARM16Expr->getKind()) {
    1053           0 :     default: llvm_unreachable("Unsupported ARMFixup");
    1054             :     case ARMMCExpr::VK_ARM_HI16:
    1055           0 :       Kind = MCFixupKind(isThumb(STI) ? ARM::fixup_t2_movt_hi16
    1056             :                                       : ARM::fixup_arm_movt_hi16);
    1057             :       break;
    1058             :     case ARMMCExpr::VK_ARM_LO16:
    1059           0 :       Kind = MCFixupKind(isThumb(STI) ? ARM::fixup_t2_movw_lo16
    1060             :                                       : ARM::fixup_arm_movw_lo16);
    1061             :       break;
    1062             :     }
    1063             : 
    1064           0 :     Fixups.push_back(MCFixup::create(0, E, Kind, MI.getLoc()));
    1065           0 :     return 0;
    1066             :   }
    1067             :   // If the expression doesn't have :upper16: or :lower16: on it,
    1068             :   // it's just a plain immediate expression, previously those evaluated to
    1069             :   // the lower 16 bits of the expression regardless of whether
    1070             :   // we have a movt or a movw, but that led to misleadingly results.
    1071             :   // This is disallowed in the AsmParser in validateInstruction()
    1072             :   // so this should never happen.
    1073           0 :   llvm_unreachable("expression without :upper16: or :lower16:");
    1074             : }
    1075             : 
    1076           0 : uint32_t ARMMCCodeEmitter::
    1077             : getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
    1078             :                     SmallVectorImpl<MCFixup> &Fixups,
    1079             :                     const MCSubtargetInfo &STI) const {
    1080             :   const MCOperand &MO = MI.getOperand(OpIdx);
    1081           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx+1);
    1082           0 :   const MCOperand &MO2 = MI.getOperand(OpIdx+2);
    1083           0 :   unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
    1084           0 :   unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
    1085           0 :   unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
    1086             :   bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
    1087             :   ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
    1088             :   unsigned SBits = getShiftOp(ShOp);
    1089             : 
    1090             :   // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift
    1091             :   // amount. However, it would be an easy mistake to make so check here.
    1092             :   assert((ShImm & ~0x1f) == 0 && "Out of range shift amount");
    1093             : 
    1094             :   // {16-13} = Rn
    1095             :   // {12}    = isAdd
    1096             :   // {11-0}  = shifter
    1097             :   //  {3-0}  = Rm
    1098             :   //  {4}    = 0
    1099             :   //  {6-5}  = type
    1100             :   //  {11-7} = imm
    1101             :   uint32_t Binary = Rm;
    1102           0 :   Binary |= Rn << 13;
    1103           0 :   Binary |= SBits << 5;
    1104           0 :   Binary |= ShImm << 7;
    1105           0 :   if (isAdd)
    1106           0 :     Binary |= 1 << 12;
    1107           0 :   return Binary;
    1108             : }
    1109             : 
    1110           0 : uint32_t ARMMCCodeEmitter::
    1111             : getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
    1112             :                           SmallVectorImpl<MCFixup> &Fixups,
    1113             :                           const MCSubtargetInfo &STI) const {
    1114             :   // {13}     1 == imm12, 0 == Rm
    1115             :   // {12}     isAdd
    1116             :   // {11-0}   imm12/Rm
    1117             :   const MCOperand &MO = MI.getOperand(OpIdx);
    1118           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx+1);
    1119           0 :   unsigned Imm = MO1.getImm();
    1120           0 :   bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
    1121           0 :   bool isReg = MO.getReg() != 0;
    1122             :   uint32_t Binary = ARM_AM::getAM2Offset(Imm);
    1123             :   // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
    1124           0 :   if (isReg) {
    1125             :     ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);
    1126           0 :     Binary <<= 7;                    // Shift amount is bits [11:7]
    1127           0 :     Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]
    1128           0 :     Binary |= CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); // Rm is bits [3:0]
    1129             :   }
    1130           0 :   return Binary | (isAdd << 12) | (isReg << 13);
    1131             : }
    1132             : 
    1133           0 : uint32_t ARMMCCodeEmitter::
    1134             : getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
    1135             :                      SmallVectorImpl<MCFixup> &Fixups,
    1136             :                      const MCSubtargetInfo &STI) const {
    1137             :   // {4}      isAdd
    1138             :   // {3-0}    Rm
    1139             :   const MCOperand &MO = MI.getOperand(OpIdx);
    1140           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx+1);
    1141          12 :   bool isAdd = MO1.getImm() != 0;
    1142          24 :   return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()) | (isAdd << 4);
    1143             : }
    1144             : 
    1145           0 : uint32_t ARMMCCodeEmitter::
    1146             : getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
    1147             :                           SmallVectorImpl<MCFixup> &Fixups,
    1148             :                           const MCSubtargetInfo &STI) const {
    1149             :   // {9}      1 == imm8, 0 == Rm
    1150             :   // {8}      isAdd
    1151             :   // {7-4}    imm7_4/zero
    1152             :   // {3-0}    imm3_0/Rm
    1153             :   const MCOperand &MO = MI.getOperand(OpIdx);
    1154           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx+1);
    1155           0 :   unsigned Imm = MO1.getImm();
    1156           0 :   bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
    1157           0 :   bool isImm = MO.getReg() == 0;
    1158           0 :   uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
    1159             :   // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
    1160           0 :   if (!isImm)
    1161           0 :     Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
    1162           0 :   return Imm8 | (isAdd << 8) | (isImm << 9);
    1163             : }
    1164             : 
    1165           0 : uint32_t ARMMCCodeEmitter::
    1166             : getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
    1167             :                     SmallVectorImpl<MCFixup> &Fixups,
    1168             :                     const MCSubtargetInfo &STI) const {
    1169             :   // {13}     1 == imm8, 0 == Rm
    1170             :   // {12-9}   Rn
    1171             :   // {8}      isAdd
    1172             :   // {7-4}    imm7_4/zero
    1173             :   // {3-0}    imm3_0/Rm
    1174             :   const MCOperand &MO = MI.getOperand(OpIdx);
    1175           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx+1);
    1176           0 :   const MCOperand &MO2 = MI.getOperand(OpIdx+2);
    1177             : 
    1178             :   // If The first operand isn't a register, we have a label reference.
    1179           0 :   if (!MO.isReg()) {
    1180           0 :     unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
    1181             : 
    1182             :     assert(MO.isExpr() && "Unexpected machine operand type!");
    1183           0 :     const MCExpr *Expr = MO.getExpr();
    1184             :     MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled);
    1185           0 :     Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
    1186             : 
    1187             :     ++MCNumCPRelocations;
    1188           0 :     return (Rn << 9) | (1 << 13);
    1189             :   }
    1190           0 :   unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
    1191           0 :   unsigned Imm = MO2.getImm();
    1192           0 :   bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
    1193           0 :   bool isImm = MO1.getReg() == 0;
    1194           0 :   uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
    1195             :   // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
    1196           0 :   if (!isImm)
    1197           0 :     Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
    1198           0 :   return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
    1199             : }
    1200             : 
    1201             : /// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands.
    1202           0 : uint32_t ARMMCCodeEmitter::
    1203             : getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
    1204             :                           SmallVectorImpl<MCFixup> &Fixups,
    1205             :                           const MCSubtargetInfo &STI) const {
    1206             :   // [SP, #imm]
    1207             :   //   {7-0} = imm8
    1208           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
    1209             :   assert(MI.getOperand(OpIdx).getReg() == ARM::SP &&
    1210             :          "Unexpected base register!");
    1211             : 
    1212             :   // The immediate is already shifted for the implicit zeroes, so no change
    1213             :   // here.
    1214         924 :   return MO1.getImm() & 0xff;
    1215             : }
    1216             : 
    1217             : /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
    1218           0 : uint32_t ARMMCCodeEmitter::
    1219             : getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
    1220             :                      SmallVectorImpl<MCFixup> &Fixups,
    1221             :                      const MCSubtargetInfo &STI) const {
    1222             :   // [Rn, #imm]
    1223             :   //   {7-3} = imm5
    1224             :   //   {2-0} = Rn
    1225             :   const MCOperand &MO = MI.getOperand(OpIdx);
    1226           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
    1227        2203 :   unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
    1228        2203 :   unsigned Imm5 = MO1.getImm();
    1229        2203 :   return ((Imm5 & 0x1f) << 3) | Rn;
    1230             : }
    1231             : 
    1232             : /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
    1233           0 : uint32_t ARMMCCodeEmitter::
    1234             : getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
    1235             :                      SmallVectorImpl<MCFixup> &Fixups,
    1236             :                      const MCSubtargetInfo &STI) const {
    1237           0 :   const MCOperand MO = MI.getOperand(OpIdx);
    1238           0 :   if (MO.isExpr())
    1239           0 :     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups, STI);
    1240           0 :   return (MO.getImm() >> 2);
    1241             : }
    1242             : 
    1243             : /// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand.
    1244         728 : uint32_t ARMMCCodeEmitter::
    1245             : getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
    1246             :                     SmallVectorImpl<MCFixup> &Fixups,
    1247             :                     const MCSubtargetInfo &STI) const {
    1248             :   // {12-9} = reg
    1249             :   // {8}    = (U)nsigned (add == '1', sub == '0')
    1250             :   // {7-0}  = imm8
    1251             :   unsigned Reg, Imm8;
    1252             :   bool isAdd;
    1253             :   // If The first operand isn't a register, we have a label reference.
    1254             :   const MCOperand &MO = MI.getOperand(OpIdx);
    1255         728 :   if (!MO.isReg()) {
    1256         148 :     Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
    1257             :     Imm8 = 0;
    1258             :     isAdd = false; // 'U' bit is handled as part of the fixup.
    1259             : 
    1260             :     assert(MO.isExpr() && "Unexpected machine operand type!");
    1261         148 :     const MCExpr *Expr = MO.getExpr();
    1262             :     MCFixupKind Kind;
    1263             :     if (isThumb2(STI))
    1264             :       Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
    1265             :     else
    1266             :       Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
    1267         296 :     Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
    1268             : 
    1269             :     ++MCNumCPRelocations;
    1270             :   } else {
    1271         580 :     EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);
    1272         580 :     isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
    1273             :   }
    1274             : 
    1275             :   uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
    1276             :   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
    1277         728 :   if (isAdd)
    1278         362 :     Binary |= (1 << 8);
    1279         728 :   Binary |= (Reg << 9);
    1280         728 :   return Binary;
    1281             : }
    1282             : 
    1283             : /// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand.
    1284          32 : uint32_t ARMMCCodeEmitter::
    1285             : getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx,
    1286             :                     SmallVectorImpl<MCFixup> &Fixups,
    1287             :                     const MCSubtargetInfo &STI) const {
    1288             :   // {12-9} = reg
    1289             :   // {8}    = (U)nsigned (add == '1', sub == '0')
    1290             :   // {7-0}  = imm8
    1291             :   unsigned Reg, Imm8;
    1292             :   bool isAdd;
    1293             :   // If The first operand isn't a register, we have a label reference.
    1294             :   const MCOperand &MO = MI.getOperand(OpIdx);
    1295          32 :   if (!MO.isReg()) {
    1296           0 :     Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
    1297             :     Imm8 = 0;
    1298             :     isAdd = false; // 'U' bit is handled as part of the fixup.
    1299             : 
    1300             :     assert(MO.isExpr() && "Unexpected machine operand type!");
    1301           0 :     const MCExpr *Expr = MO.getExpr();
    1302             :     MCFixupKind Kind;
    1303             :     if (isThumb2(STI))
    1304             :       Kind = MCFixupKind(ARM::fixup_t2_pcrel_9);
    1305             :     else
    1306             :       Kind = MCFixupKind(ARM::fixup_arm_pcrel_9);
    1307           0 :     Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
    1308             : 
    1309             :     ++MCNumCPRelocations;
    1310             :   } else {
    1311          32 :     EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);
    1312          32 :     isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
    1313             :   }
    1314             : 
    1315             :   uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
    1316             :   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
    1317          32 :   if (isAdd)
    1318          16 :     Binary |= (1 << 8);
    1319          32 :   Binary |= (Reg << 9);
    1320          32 :   return Binary;
    1321             : }
    1322             : 
    1323           0 : unsigned ARMMCCodeEmitter::
    1324             : getSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
    1325             :                 SmallVectorImpl<MCFixup> &Fixups,
    1326             :                 const MCSubtargetInfo &STI) const {
    1327             :   // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
    1328             :   // shifted. The second is Rs, the amount to shift by, and the third specifies
    1329             :   // the type of the shift.
    1330             :   //
    1331             :   // {3-0} = Rm.
    1332             :   // {4}   = 1
    1333             :   // {6-5} = type
    1334             :   // {11-8} = Rs
    1335             :   // {7}    = 0
    1336             : 
    1337             :   const MCOperand &MO  = MI.getOperand(OpIdx);
    1338           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
    1339           0 :   const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
    1340           0 :   ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
    1341             : 
    1342             :   // Encode Rm.
    1343           0 :   unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
    1344             : 
    1345             :   // Encode the shift opcode.
    1346             :   unsigned SBits = 0;
    1347           0 :   unsigned Rs = MO1.getReg();
    1348           0 :   if (Rs) {
    1349             :     // Set shift operand (bit[7:4]).
    1350             :     // LSL - 0001
    1351             :     // LSR - 0011
    1352             :     // ASR - 0101
    1353             :     // ROR - 0111
    1354           0 :     switch (SOpc) {
    1355           0 :     default: llvm_unreachable("Unknown shift opc!");
    1356             :     case ARM_AM::lsl: SBits = 0x1; break;
    1357           0 :     case ARM_AM::lsr: SBits = 0x3; break;
    1358           0 :     case ARM_AM::asr: SBits = 0x5; break;
    1359           0 :     case ARM_AM::ror: SBits = 0x7; break;
    1360             :     }
    1361             :   }
    1362             : 
    1363           0 :   Binary |= SBits << 4;
    1364             : 
    1365             :   // Encode the shift operation Rs.
    1366             :   // Encode Rs bit[11:8].
    1367             :   assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
    1368           0 :   return Binary | (CTX.getRegisterInfo()->getEncodingValue(Rs) << ARMII::RegRsShift);
    1369             : }
    1370             : 
    1371           0 : unsigned ARMMCCodeEmitter::
    1372             : getSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
    1373             :                 SmallVectorImpl<MCFixup> &Fixups,
    1374             :                 const MCSubtargetInfo &STI) const {
    1375             :   // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
    1376             :   // shifted. The second is the amount to shift by.
    1377             :   //
    1378             :   // {3-0} = Rm.
    1379             :   // {4}   = 0
    1380             :   // {6-5} = type
    1381             :   // {11-7} = imm
    1382             : 
    1383             :   const MCOperand &MO  = MI.getOperand(OpIdx);
    1384           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
    1385           0 :   ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
    1386             : 
    1387             :   // Encode Rm.
    1388           0 :   unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
    1389             : 
    1390             :   // Encode the shift opcode.
    1391             :   unsigned SBits = 0;
    1392             : 
    1393             :   // Set shift operand (bit[6:4]).
    1394             :   // LSL - 000
    1395             :   // LSR - 010
    1396             :   // ASR - 100
    1397             :   // ROR - 110
    1398             :   // RRX - 110 and bit[11:8] clear.
    1399           0 :   switch (SOpc) {
    1400           0 :   default: llvm_unreachable("Unknown shift opc!");
    1401             :   case ARM_AM::lsl: SBits = 0x0; break;
    1402           0 :   case ARM_AM::lsr: SBits = 0x2; break;
    1403           0 :   case ARM_AM::asr: SBits = 0x4; break;
    1404           0 :   case ARM_AM::ror: SBits = 0x6; break;
    1405           0 :   case ARM_AM::rrx:
    1406           0 :     Binary |= 0x60;
    1407           0 :     return Binary;
    1408             :   }
    1409             : 
    1410             :   // Encode shift_imm bit[11:7].
    1411           0 :   Binary |= SBits << 4;
    1412             :   unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm());
    1413             :   assert(Offset < 32 && "Offset must be in range 0-31!");
    1414           0 :   return Binary | (Offset << 7);
    1415             : }
    1416             : 
    1417             : 
    1418           0 : unsigned ARMMCCodeEmitter::
    1419             : getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
    1420             :                 SmallVectorImpl<MCFixup> &Fixups,
    1421             :                 const MCSubtargetInfo &STI) const {
    1422             :   const MCOperand &MO1 = MI.getOperand(OpNum);
    1423           0 :   const MCOperand &MO2 = MI.getOperand(OpNum+1);
    1424           0 :   const MCOperand &MO3 = MI.getOperand(OpNum+2);
    1425             : 
    1426             :   // Encoded as [Rn, Rm, imm].
    1427             :   // FIXME: Needs fixup support.
    1428         252 :   unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
    1429         252 :   Value <<= 4;
    1430         252 :   Value |= CTX.getRegisterInfo()->getEncodingValue(MO2.getReg());
    1431         252 :   Value <<= 2;
    1432         252 :   Value |= MO3.getImm();
    1433             : 
    1434           0 :   return Value;
    1435             : }
    1436             : 
    1437           0 : unsigned ARMMCCodeEmitter::
    1438             : getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
    1439             :                          SmallVectorImpl<MCFixup> &Fixups,
    1440             :                          const MCSubtargetInfo &STI) const {
    1441             :   const MCOperand &MO1 = MI.getOperand(OpNum);
    1442           0 :   const MCOperand &MO2 = MI.getOperand(OpNum+1);
    1443             : 
    1444             :   // FIXME: Needs fixup support.
    1445         151 :   unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
    1446             : 
    1447             :   // Even though the immediate is 8 bits long, we need 9 bits in order
    1448             :   // to represent the (inverse of the) sign bit.
    1449         151 :   Value <<= 9;
    1450         151 :   int32_t tmp = (int32_t)MO2.getImm();
    1451         151 :   if (tmp < 0)
    1452          55 :     tmp = abs(tmp);
    1453             :   else
    1454          96 :     Value |= 256; // Set the ADD bit
    1455         151 :   Value |= tmp & 255;
    1456           0 :   return Value;
    1457             : }
    1458             : 
    1459           0 : unsigned ARMMCCodeEmitter::
    1460             : getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
    1461             :                          SmallVectorImpl<MCFixup> &Fixups,
    1462             :                          const MCSubtargetInfo &STI) const {
    1463             :   const MCOperand &MO1 = MI.getOperand(OpNum);
    1464             : 
    1465             :   // FIXME: Needs fixup support.
    1466             :   unsigned Value = 0;
    1467         954 :   int32_t tmp = (int32_t)MO1.getImm();
    1468         954 :   if (tmp < 0)
    1469          18 :     tmp = abs(tmp);
    1470             :   else
    1471             :     Value |= 256; // Set the ADD bit
    1472         954 :   Value |= tmp & 255;
    1473           0 :   return Value;
    1474             : }
    1475             : 
    1476           0 : unsigned ARMMCCodeEmitter::
    1477             : getT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
    1478             :                 SmallVectorImpl<MCFixup> &Fixups,
    1479             :                 const MCSubtargetInfo &STI) const {
    1480             :   // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
    1481             :   // shifted. The second is the amount to shift by.
    1482             :   //
    1483             :   // {3-0} = Rm.
    1484             :   // {4}   = 0
    1485             :   // {6-5} = type
    1486             :   // {11-7} = imm
    1487             : 
    1488             :   const MCOperand &MO  = MI.getOperand(OpIdx);
    1489           0 :   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
    1490           0 :   ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
    1491             : 
    1492             :   // Encode Rm.
    1493           0 :   unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
    1494             : 
    1495             :   // Encode the shift opcode.
    1496             :   unsigned SBits = 0;
    1497             :   // Set shift operand (bit[6:4]).
    1498             :   // LSL - 000
    1499             :   // LSR - 010
    1500             :   // ASR - 100
    1501             :   // ROR - 110
    1502           0 :   switch (SOpc) {
    1503           0 :   default: llvm_unreachable("Unknown shift opc!");
    1504             :   case ARM_AM::lsl: SBits = 0x0; break;
    1505           0 :   case ARM_AM::lsr: SBits = 0x2; break;
    1506           0 :   case ARM_AM::asr: SBits = 0x4; break;
    1507           0 :   case ARM_AM::rrx: LLVM_FALLTHROUGH;
    1508           0 :   case ARM_AM::ror: SBits = 0x6; break;
    1509             :   }
    1510             : 
    1511           0 :   Binary |= SBits << 4;
    1512           0 :   if (SOpc == ARM_AM::rrx)
    1513           0 :     return Binary;
    1514             : 
    1515             :   // Encode shift_imm bit[11:7].
    1516           0 :   return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
    1517             : }
    1518             : 
    1519           0 : unsigned ARMMCCodeEmitter::
    1520             : getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
    1521             :                                SmallVectorImpl<MCFixup> &Fixups,
    1522             :                                const MCSubtargetInfo &STI) const {
    1523             :   // 10 bits. lower 5 bits are the lsb of the mask, high five bits are the
    1524             :   // msb of the mask.
    1525             :   const MCOperand &MO = MI.getOperand(Op);
    1526          75 :   uint32_t v = ~MO.getImm();
    1527          75 :   uint32_t lsb = countTrailingZeros(v);
    1528          75 :   uint32_t msb = (32 - countLeadingZeros (v)) - 1;
    1529             :   assert(v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
    1530          75 :   return lsb | (msb << 5);
    1531             : }
    1532             : 
    1533           0 : unsigned ARMMCCodeEmitter::
    1534             : getRegisterListOpValue(const MCInst &MI, unsigned Op,
    1535             :                        SmallVectorImpl<MCFixup> &Fixups,
    1536             :                        const MCSubtargetInfo &STI) const {
    1537             :   // VLDM/VSTM:
    1538             :   //   {12-8} = Vd
    1539             :   //   {7-0}  = Number of registers
    1540             :   //
    1541             :   // LDM/STM:
    1542             :   //   {15-0}  = Bitfield of GPRs.
    1543           0 :   unsigned Reg = MI.getOperand(Op).getReg();
    1544           0 :   bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg);
    1545           0 :   bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg);
    1546             : 
    1547             :   unsigned Binary = 0;
    1548             : 
    1549           0 :   if (SPRRegs || DPRRegs) {
    1550             :     // VLDM/VSTM
    1551           0 :     unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
    1552           0 :     unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;
    1553           0 :     Binary |= (RegNo & 0x1f) << 8;
    1554           0 :     if (SPRRegs)
    1555           0 :       Binary |= NumRegs;
    1556             :     else
    1557           0 :       Binary |= NumRegs * 2;
    1558             :   } else {
    1559           0 :     const MCRegisterInfo &MRI = *CTX.getRegisterInfo();
    1560             :     assert(std::is_sorted(MI.begin() + Op, MI.end(),
    1561             :                           [&](const MCOperand &LHS, const MCOperand &RHS) {
    1562             :                             return MRI.getEncodingValue(LHS.getReg()) <
    1563             :                                    MRI.getEncodingValue(RHS.getReg());
    1564             :                           }));
    1565             : 
    1566           0 :     for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {
    1567           0 :       unsigned RegNo = MRI.getEncodingValue(MI.getOperand(I).getReg());
    1568           0 :       Binary |= 1 << RegNo;
    1569             :     }
    1570             :   }
    1571             : 
    1572           0 :   return Binary;
    1573             : }
    1574             : 
    1575             : /// getAddrMode6AddressOpValue - Encode an addrmode6 register number along
    1576             : /// with the alignment operand.
    1577           0 : unsigned ARMMCCodeEmitter::
    1578             : getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
    1579             :                            SmallVectorImpl<MCFixup> &Fixups,
    1580             :                            const MCSubtargetInfo &STI) const {
    1581             :   const MCOperand &Reg = MI.getOperand(Op);
    1582           0 :   const MCOperand &Imm = MI.getOperand(Op + 1);
    1583             : 
    1584        1415 :   unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
    1585             :   unsigned Align = 0;
    1586             : 
    1587        1415 :   switch (Imm.getImm()) {
    1588             :   default: break;
    1589           0 :   case 2:
    1590             :   case 4:
    1591           0 :   case 8:  Align = 0x01; break;
    1592           0 :   case 16: Align = 0x02; break;
    1593           0 :   case 32: Align = 0x03; break;
    1594             :   }
    1595             : 
    1596        1415 :   return RegNo | (Align << 4);
    1597             : }
    1598             : 
    1599             : /// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number
    1600             : /// along  with the alignment operand for use in VST1 and VLD1 with size 32.
    1601           0 : unsigned ARMMCCodeEmitter::
    1602             : getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
    1603             :                                     SmallVectorImpl<MCFixup> &Fixups,
    1604             :                                     const MCSubtargetInfo &STI) const {
    1605             :   const MCOperand &Reg = MI.getOperand(Op);
    1606           0 :   const MCOperand &Imm = MI.getOperand(Op + 1);
    1607             : 
    1608          19 :   unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
    1609             :   unsigned Align = 0;
    1610             : 
    1611          19 :   switch (Imm.getImm()) {
    1612             :   default: break;
    1613             :   case 8:
    1614             :   case 16:
    1615             :   case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes.
    1616             :   case 2: Align = 0x00; break;
    1617          12 :   case 4: Align = 0x03; break;
    1618             :   }
    1619             : 
    1620          19 :   return RegNo | (Align << 4);
    1621             : }
    1622             : 
    1623             : 
    1624             : /// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and
    1625             : /// alignment operand for use in VLD-dup instructions.  This is the same as
    1626             : /// getAddrMode6AddressOpValue except for the alignment encoding, which is
    1627             : /// different for VLD4-dup.
    1628           0 : unsigned ARMMCCodeEmitter::
    1629             : getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
    1630             :                               SmallVectorImpl<MCFixup> &Fixups,
    1631             :                               const MCSubtargetInfo &STI) const {
    1632             :   const MCOperand &Reg = MI.getOperand(Op);
    1633           0 :   const MCOperand &Imm = MI.getOperand(Op + 1);
    1634             : 
    1635           0 :   unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
    1636             :   unsigned Align = 0;
    1637             : 
    1638           0 :   switch (Imm.getImm()) {
    1639             :   default: break;
    1640           0 :   case 2:
    1641             :   case 4:
    1642           0 :   case 8:  Align = 0x01; break;
    1643           0 :   case 16: Align = 0x03; break;
    1644             :   }
    1645             : 
    1646           0 :   return RegNo | (Align << 4);
    1647             : }
    1648             : 
    1649           0 : unsigned ARMMCCodeEmitter::
    1650             : getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
    1651             :                           SmallVectorImpl<MCFixup> &Fixups,
    1652             :                           const MCSubtargetInfo &STI) const {
    1653             :   const MCOperand &MO = MI.getOperand(Op);
    1654         529 :   if (MO.getReg() == 0) return 0x0D;
    1655         309 :   return CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
    1656             : }
    1657             : 
    1658           0 : unsigned ARMMCCodeEmitter::
    1659             : getShiftRight8Imm(const MCInst &MI, unsigned Op,
    1660             :                   SmallVectorImpl<MCFixup> &Fixups,
    1661             :                   const MCSubtargetInfo &STI) const {
    1662          98 :   return 8 - MI.getOperand(Op).getImm();
    1663             : }
    1664             : 
    1665           0 : unsigned ARMMCCodeEmitter::
    1666             : getShiftRight16Imm(const MCInst &MI, unsigned Op,
    1667             :                    SmallVectorImpl<MCFixup> &Fixups,
    1668             :                    const MCSubtargetInfo &STI) const {
    1669          98 :   return 16 - MI.getOperand(Op).getImm();
    1670             : }
    1671             : 
    1672           0 : unsigned ARMMCCodeEmitter::
    1673             : getShiftRight32Imm(const MCInst &MI, unsigned Op,
    1674             :                    SmallVectorImpl<MCFixup> &Fixups,
    1675             :                    const MCSubtargetInfo &STI) const {
    1676          98 :   return 32 - MI.getOperand(Op).getImm();
    1677             : }
    1678             : 
    1679           0 : unsigned ARMMCCodeEmitter::
    1680             : getShiftRight64Imm(const MCInst &MI, unsigned Op,
    1681             :                    SmallVectorImpl<MCFixup> &Fixups,
    1682             :                    const MCSubtargetInfo &STI) const {
    1683          80 :   return 64 - MI.getOperand(Op).getImm();
    1684             : }
    1685             : 
    1686       41932 : void ARMMCCodeEmitter::
    1687             : encodeInstruction(const MCInst &MI, raw_ostream &OS,
    1688             :                   SmallVectorImpl<MCFixup> &Fixups,
    1689             :                   const MCSubtargetInfo &STI) const {
    1690             :   // Pseudo instructions don't get encoded.
    1691       41932 :   const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
    1692       41932 :   uint64_t TSFlags = Desc.TSFlags;
    1693       41932 :   if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)
    1694             :     return;
    1695             : 
    1696             :   int Size;
    1697       83862 :   if (Desc.getSize() == 2 || Desc.getSize() == 4)
    1698             :     Size = Desc.getSize();
    1699             :   else
    1700           0 :     llvm_unreachable("Unexpected instruction size!");
    1701             : 
    1702       41931 :   uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
    1703             :   // Thumb 32-bit wide instructions need to emit the high order halfword
    1704             :   // first.
    1705       41931 :   if (isThumb(STI) && Size == 4) {
    1706       13067 :     EmitConstant(Binary >> 16, 2, OS);
    1707       13067 :     EmitConstant(Binary & 0xffff, 2, OS);
    1708             :   } else
    1709       28864 :     EmitConstant(Binary, Size, OS);
    1710             :   ++MCNumEmitted;  // Keep track of the # of mi's emitted.
    1711             : }
    1712             : 
    1713             : #include "ARMGenMCCodeEmitter.inc"
    1714             : 
    1715         932 : MCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII,
    1716             :                                               const MCRegisterInfo &MRI,
    1717             :                                               MCContext &Ctx) {
    1718         932 :   return new ARMMCCodeEmitter(MCII, Ctx, true);
    1719             : }
    1720             : 
    1721          19 : MCCodeEmitter *llvm::createARMBEMCCodeEmitter(const MCInstrInfo &MCII,
    1722             :                                               const MCRegisterInfo &MRI,
    1723             :                                               MCContext &Ctx) {
    1724          19 :   return new ARMMCCodeEmitter(MCII, Ctx, false);
    1725             : }

Generated by: LCOV version 1.13