brintos

brintos / llvm-project-archived public Read only

0
0
Text · 76.5 KiB · 4a87c63 Raw
2100 lines · cpp
1//===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM code to machine code -------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the ARMMCCodeEmitter class.10//11//===----------------------------------------------------------------------===//12 13#include "MCTargetDesc/ARMAddressingModes.h"14#include "MCTargetDesc/ARMBaseInfo.h"15#include "MCTargetDesc/ARMFixupKinds.h"16#include "MCTargetDesc/ARMMCAsmInfo.h"17#include "llvm/ADT/APFloat.h"18#include "llvm/ADT/APInt.h"19#include "llvm/ADT/SmallVector.h"20#include "llvm/ADT/Statistic.h"21#include "llvm/MC/MCCodeEmitter.h"22#include "llvm/MC/MCContext.h"23#include "llvm/MC/MCExpr.h"24#include "llvm/MC/MCFixup.h"25#include "llvm/MC/MCInst.h"26#include "llvm/MC/MCInstrDesc.h"27#include "llvm/MC/MCInstrInfo.h"28#include "llvm/MC/MCRegisterInfo.h"29#include "llvm/MC/MCSubtargetInfo.h"30#include "llvm/Support/Casting.h"31#include "llvm/Support/Compiler.h"32#include "llvm/Support/EndianStream.h"33#include "llvm/Support/MathExtras.h"34#include "llvm/TargetParser/Triple.h"35#include <cassert>36#include <cstdint>37#include <cstdlib>38 39using namespace llvm;40 41#define DEBUG_TYPE "mccodeemitter"42 43STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");44STATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");45 46namespace {47 48class ARMMCCodeEmitter : public MCCodeEmitter {49  const MCInstrInfo &MCII;50  MCContext &CTX;51  bool IsLittleEndian;52 53public:54  ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool IsLittle)55    : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) {56  }57  ARMMCCodeEmitter(const ARMMCCodeEmitter &) = delete;58  ARMMCCodeEmitter &operator=(const ARMMCCodeEmitter &) = delete;59  ~ARMMCCodeEmitter() override = default;60 61  bool isThumb(const MCSubtargetInfo &STI) const {62    return STI.hasFeature(ARM::ModeThumb);63  }64 65  bool isThumb2(const MCSubtargetInfo &STI) const {66    return isThumb(STI) && STI.hasFeature(ARM::FeatureThumb2);67  }68 69  bool isTargetMachO(const MCSubtargetInfo &STI) const {70    const Triple &TT = STI.getTargetTriple();71    return TT.isOSBinFormatMachO();72  }73 74  unsigned getMachineSoImmOpValue(unsigned SoImm) const;75 76  // getBinaryCodeForInstr - TableGen'erated function for getting the77  // binary encoding for an instruction.78  uint64_t getBinaryCodeForInstr(const MCInst &MI,79                                 SmallVectorImpl<MCFixup> &Fixups,80                                 const MCSubtargetInfo &STI) const;81 82  /// getMachineOpValue - Return binary encoding of operand. If the machine83  /// operand requires relocation, record the relocation and return zero.84  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,85                             SmallVectorImpl<MCFixup> &Fixups,86                             const MCSubtargetInfo &STI) const;87 88  /// getHiLoImmOpValue - Return the encoding for either the hi / low 16-bit, or89  /// high/middle-high/middle-low/low 8 bits of the specified operand. This is90  /// used for operands with :lower16:, :upper16: :lower0_7:, :lower8_15:,91  /// :higher0_7:, and :higher8_15: prefixes.92  uint32_t getHiLoImmOpValue(const MCInst &MI, unsigned OpIdx,93                             SmallVectorImpl<MCFixup> &Fixups,94                             const MCSubtargetInfo &STI) const;95 96  bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,97                              unsigned &Reg, unsigned &Imm,98                              SmallVectorImpl<MCFixup> &Fixups,99                              const MCSubtargetInfo &STI) const;100 101  /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate102  /// BL branch target.103  uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,104                                   SmallVectorImpl<MCFixup> &Fixups,105                                   const MCSubtargetInfo &STI) const;106 107  /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate108  /// BLX branch target.109  uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,110                                    SmallVectorImpl<MCFixup> &Fixups,111                                    const MCSubtargetInfo &STI) const;112 113  /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.114  uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,115                                   SmallVectorImpl<MCFixup> &Fixups,116                                   const MCSubtargetInfo &STI) const;117 118  /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.119  uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,120                                    SmallVectorImpl<MCFixup> &Fixups,121                                    const MCSubtargetInfo &STI) const;122 123  /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.124  uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,125                                   SmallVectorImpl<MCFixup> &Fixups,126                                   const MCSubtargetInfo &STI) const;127 128  /// getBranchTargetOpValue - Return encoding info for 24-bit immediate129  /// branch target.130  uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,131                                  SmallVectorImpl<MCFixup> &Fixups,132                                  const MCSubtargetInfo &STI) const;133 134  /// getThumbBranchTargetOpValue - Return encoding info for 24-bit135  /// immediate Thumb2 direct branch target.136  uint32_t getThumbBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,137                                       SmallVectorImpl<MCFixup> &Fixups,138                                       const MCSubtargetInfo &STI) const;139 140  /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate141  /// branch target.142  uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,143                                     SmallVectorImpl<MCFixup> &Fixups,144                                     const MCSubtargetInfo &STI) const;145  uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,146                                 SmallVectorImpl<MCFixup> &Fixups,147                                 const MCSubtargetInfo &STI) const;148  uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,149                                  SmallVectorImpl<MCFixup> &Fixups,150                                  const MCSubtargetInfo &STI) const;151 152  /// getAdrLabelOpValue - Return encoding info for 12-bit immediate153  /// ADR label target.154  uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,155                              SmallVectorImpl<MCFixup> &Fixups,156                              const MCSubtargetInfo &STI) const;157  uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,158                              SmallVectorImpl<MCFixup> &Fixups,159                              const MCSubtargetInfo &STI) const;160  uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,161                              SmallVectorImpl<MCFixup> &Fixups,162                              const MCSubtargetInfo &STI) const;163 164  uint32_t getITMaskOpValue(const MCInst &MI, unsigned OpIdx,165                            SmallVectorImpl<MCFixup> &Fixups,166                            const MCSubtargetInfo &STI) const;167 168  /// getMVEShiftImmOpValue - Return encoding info for the 'sz:imm5'169  /// operand.170  uint32_t getMVEShiftImmOpValue(const MCInst &MI, unsigned OpIdx,171                                 SmallVectorImpl<MCFixup> &Fixups,172                                 const MCSubtargetInfo &STI) const;173 174  /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'175  /// operand.176  uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,177                                   SmallVectorImpl<MCFixup> &Fixups,178                                   const MCSubtargetInfo &STI) const;179 180  /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.181  uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,182                                         SmallVectorImpl<MCFixup> &Fixups,183                                         const MCSubtargetInfo &STI) const;184 185  /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'186  /// operand.187  uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,188                                   SmallVectorImpl<MCFixup> &Fixups,189                                   const MCSubtargetInfo &STI) const;190 191  /// getT2AddrModeImm7s4OpValue - Return encoding info for 'reg +/- imm7<<2'192  /// operand.193  uint32_t getT2AddrModeImm7s4OpValue(const MCInst &MI, unsigned OpIdx,194                                      SmallVectorImpl<MCFixup> &Fixups,195                                      const MCSubtargetInfo &STI) const;196 197  /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2'198  /// operand.199  uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,200                                   SmallVectorImpl<MCFixup> &Fixups,201                                   const MCSubtargetInfo &STI) const;202 203  /// getT2ScaledImmOpValue - Return encoding info for '+/- immX<<Y'204  /// operand.205  template<unsigned Bits, unsigned Shift>206  uint32_t getT2ScaledImmOpValue(const MCInst &MI, unsigned OpIdx,207                                 SmallVectorImpl<MCFixup> &Fixups,208                                 const MCSubtargetInfo &STI) const;209 210  /// getMveAddrModeRQOpValue - Return encoding info for 'reg, vreg'211  /// operand.212  uint32_t getMveAddrModeRQOpValue(const MCInst &MI, unsigned OpIdx,213                                   SmallVectorImpl<MCFixup> &Fixups,214                                   const MCSubtargetInfo &STI) const;215 216  /// getMveAddrModeQOpValue - Return encoding info for 'reg +/- imm7<<{shift}'217  /// operand.218  template<int shift>219  uint32_t getMveAddrModeQOpValue(const MCInst &MI, unsigned OpIdx,220                                  SmallVectorImpl<MCFixup> &Fixups,221                                  const MCSubtargetInfo &STI) const;222 223  /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'224  /// operand as needed by load/store instructions.225  uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,226                               SmallVectorImpl<MCFixup> &Fixups,227                               const MCSubtargetInfo &STI) const;228 229  /// getLdStmModeOpValue - Return encoding for load/store multiple mode.230  uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,231                               SmallVectorImpl<MCFixup> &Fixups,232                               const MCSubtargetInfo &STI) const {233    ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();234    switch (Mode) {235    default: llvm_unreachable("Unknown addressing sub-mode!");236    case ARM_AM::da: return 0;237    case ARM_AM::ia: return 1;238    case ARM_AM::db: return 2;239    case ARM_AM::ib: return 3;240    }241  }242 243  /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.244  ///245  unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {246    switch (ShOpc) {247    case ARM_AM::no_shift:248    case ARM_AM::lsl: return 0;249    case ARM_AM::lsr: return 1;250    case ARM_AM::asr: return 2;251    case ARM_AM::ror:252    case ARM_AM::rrx: return 3;253    default:254      llvm_unreachable("Invalid ShiftOpc!");255    }256  }257 258  /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.259  uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,260                                     SmallVectorImpl<MCFixup> &Fixups,261                                     const MCSubtargetInfo &STI) const;262 263  /// getPostIdxRegOpValue - Return encoding for postidx_reg operands.264  uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,265                                SmallVectorImpl<MCFixup> &Fixups,266                                const MCSubtargetInfo &STI) const;267 268  /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.269  uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,270                                     SmallVectorImpl<MCFixup> &Fixups,271                                     const MCSubtargetInfo &STI) const;272 273  /// getAddrMode3OpValue - Return encoding for addrmode3 operands.274  uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,275                               SmallVectorImpl<MCFixup> &Fixups,276                               const MCSubtargetInfo &STI) const;277 278  /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12'279  /// operand.280  uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,281                                     SmallVectorImpl<MCFixup> &Fixups,282                                     const MCSubtargetInfo &STI) const;283 284  /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.285  uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,286                                SmallVectorImpl<MCFixup> &Fixups,287                                const MCSubtargetInfo &STI) const;288 289  /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.290  uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,291                                SmallVectorImpl<MCFixup> &Fixups,292                                const MCSubtargetInfo &STI) const;293 294  /// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand.295  uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,296                               SmallVectorImpl<MCFixup> &Fixups,297                               const MCSubtargetInfo &STI) const;298 299  /// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand.300  uint32_t getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx,301                               SmallVectorImpl<MCFixup> &Fixups,302                               const MCSubtargetInfo &STI) const;303 304  /// getCCOutOpValue - Return encoding of the 's' bit.305  unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,306                           SmallVectorImpl<MCFixup> &Fixups,307                           const MCSubtargetInfo &STI) const {308    // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or309    // '1' respectively.310    return MI.getOperand(Op).getReg() == ARM::CPSR;311  }312 313  unsigned getModImmOpValue(const MCInst &MI, unsigned Op,314                            SmallVectorImpl<MCFixup> &Fixups,315                            const MCSubtargetInfo &ST) const;316 317  /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.318  unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,319                             SmallVectorImpl<MCFixup> &Fixups,320                             const MCSubtargetInfo &STI) const;321 322  unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,323    SmallVectorImpl<MCFixup> &Fixups,324    const MCSubtargetInfo &STI) const;325  template<unsigned Bits, unsigned Shift>326  unsigned getT2AddrModeImmOpValue(const MCInst &MI, unsigned OpNum,327    SmallVectorImpl<MCFixup> &Fixups,328    const MCSubtargetInfo &STI) const;329  unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,330    SmallVectorImpl<MCFixup> &Fixups,331    const MCSubtargetInfo &STI) const;332 333  /// getSORegOpValue - Return an encoded so_reg shifted register value.334  unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,335                           SmallVectorImpl<MCFixup> &Fixups,336                           const MCSubtargetInfo &STI) const;337  unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,338                           SmallVectorImpl<MCFixup> &Fixups,339                           const MCSubtargetInfo &STI) const;340  unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,341                             SmallVectorImpl<MCFixup> &Fixups,342                             const MCSubtargetInfo &STI) const;343 344  unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,345                                   SmallVectorImpl<MCFixup> &Fixups,346                                   const MCSubtargetInfo &STI) const {347    return 64 - MI.getOperand(Op).getImm();348  }349 350  unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,351                                      SmallVectorImpl<MCFixup> &Fixups,352                                      const MCSubtargetInfo &STI) const;353 354  unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,355                                  SmallVectorImpl<MCFixup> &Fixups,356                                  const MCSubtargetInfo &STI) const;357  unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,358                                      SmallVectorImpl<MCFixup> &Fixups,359                                      const MCSubtargetInfo &STI) const;360  unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,361                                        SmallVectorImpl<MCFixup> &Fixups,362                                        const MCSubtargetInfo &STI) const;363  unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,364                                        SmallVectorImpl<MCFixup> &Fixups,365                                        const MCSubtargetInfo &STI) const;366  unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,367                                     SmallVectorImpl<MCFixup> &Fixups,368                                     const MCSubtargetInfo &STI) const;369 370  unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op,371                             SmallVectorImpl<MCFixup> &Fixups,372                             const MCSubtargetInfo &STI) const;373  unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op,374                              SmallVectorImpl<MCFixup> &Fixups,375                              const MCSubtargetInfo &STI) const;376  unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op,377                              SmallVectorImpl<MCFixup> &Fixups,378                              const MCSubtargetInfo &STI) const;379  unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op,380                              SmallVectorImpl<MCFixup> &Fixups,381                              const MCSubtargetInfo &STI) const;382 383  unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op,384                                 SmallVectorImpl<MCFixup> &Fixups,385                                 const MCSubtargetInfo &STI) const;386 387  unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,388                                      unsigned EncodedValue,389                                      const MCSubtargetInfo &STI) const;390  unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,391                                          unsigned EncodedValue,392                                          const MCSubtargetInfo &STI) const;393  unsigned NEONThumb2DupPostEncoder(const MCInst &MI,394                                    unsigned EncodedValue,395                                    const MCSubtargetInfo &STI) const;396  unsigned NEONThumb2V8PostEncoder(const MCInst &MI,397                                   unsigned EncodedValue,398                                   const MCSubtargetInfo &STI) const;399 400  unsigned VFPThumb2PostEncoder(const MCInst &MI,401                                unsigned EncodedValue,402                                const MCSubtargetInfo &STI) const;403 404  uint32_t getPowerTwoOpValue(const MCInst &MI, unsigned OpIdx,405                              SmallVectorImpl<MCFixup> &Fixups,406                              const MCSubtargetInfo &STI) const;407 408  void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,409                         SmallVectorImpl<MCFixup> &Fixups,410                         const MCSubtargetInfo &STI) const override;411 412  template <bool isNeg, ARM::Fixups fixup>413  uint32_t getBFTargetOpValue(const MCInst &MI, unsigned OpIdx,414                              SmallVectorImpl<MCFixup> &Fixups,415                              const MCSubtargetInfo &STI) const;416 417  uint32_t getBFAfterTargetOpValue(const MCInst &MI, unsigned OpIdx,418                                   SmallVectorImpl<MCFixup> &Fixups,419                                   const MCSubtargetInfo &STI) const;420 421  uint32_t getVPTMaskOpValue(const MCInst &MI, unsigned OpIdx,422                             SmallVectorImpl<MCFixup> &Fixups,423                             const MCSubtargetInfo &STI) const;424  uint32_t getRestrictedCondCodeOpValue(const MCInst &MI, unsigned OpIdx,425                                        SmallVectorImpl<MCFixup> &Fixups,426                                        const MCSubtargetInfo &STI) const;427  template <unsigned size>428  uint32_t getMVEPairVectorIndexOpValue(const MCInst &MI, unsigned OpIdx,429                                        SmallVectorImpl<MCFixup> &Fixups,430                                        const MCSubtargetInfo &STI) const;431};432 433} // end anonymous namespace434 435static void addFixup(SmallVectorImpl<MCFixup> &Fixups, uint32_t Offset,436                     const MCExpr *Value, uint16_t Kind) {437  bool PCRel = false;438  switch (Kind) {439  case ARM::fixup_arm_ldst_pcrel_12:440  case ARM::fixup_t2_ldst_pcrel_12:441  case ARM::fixup_arm_pcrel_10_unscaled:442  case ARM::fixup_arm_pcrel_10:443  case ARM::fixup_t2_pcrel_10:444  case ARM::fixup_arm_pcrel_9:445  case ARM::fixup_t2_pcrel_9:446  case ARM::fixup_thumb_adr_pcrel_10:447  case ARM::fixup_arm_adr_pcrel_12:448  case ARM::fixup_t2_adr_pcrel_12:449  case ARM::fixup_arm_condbranch:450  case ARM::fixup_arm_uncondbranch:451  case ARM::fixup_t2_condbranch:452  case ARM::fixup_t2_uncondbranch:453  case ARM::fixup_arm_thumb_br:454  case ARM::fixup_arm_uncondbl:455  case ARM::fixup_arm_condbl:456  case ARM::fixup_arm_blx:457  case ARM::fixup_arm_thumb_bl:458  case ARM::fixup_arm_thumb_blx:459  case ARM::fixup_arm_thumb_cb:460  case ARM::fixup_arm_thumb_cp:461  case ARM::fixup_arm_thumb_bcc:462  case ARM::fixup_bf_branch:463  case ARM::fixup_bf_target:464  case ARM::fixup_bfl_target:465  case ARM::fixup_bfc_target:466  case ARM::fixup_wls:467  case ARM::fixup_le:468    PCRel = true;469  }470  Fixups.push_back(MCFixup::create(Offset, Value, Kind, PCRel));471}472 473/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing474/// instructions, and rewrite them to their Thumb2 form if we are currently in475/// Thumb2 mode.476unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,477                                                 unsigned EncodedValue,478                                                 const MCSubtargetInfo &STI) const {479  if (isThumb2(STI)) {480    // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved481    // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are482    // set to 1111.483    unsigned Bit24 = EncodedValue & 0x01000000;484    unsigned Bit28 = Bit24 << 4;485    EncodedValue &= 0xEFFFFFFF;486    EncodedValue |= Bit28;487    EncodedValue |= 0x0F000000;488  }489 490  return EncodedValue;491}492 493/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store494/// instructions, and rewrite them to their Thumb2 form if we are currently in495/// Thumb2 mode.496unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,497                                                 unsigned EncodedValue,498                                                 const MCSubtargetInfo &STI) const {499  if (isThumb2(STI)) {500    EncodedValue &= 0xF0FFFFFF;501    EncodedValue |= 0x09000000;502  }503 504  return EncodedValue;505}506 507/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup508/// instructions, and rewrite them to their Thumb2 form if we are currently in509/// Thumb2 mode.510unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,511                                                 unsigned EncodedValue,512                                                 const MCSubtargetInfo &STI) const {513  if (isThumb2(STI)) {514    EncodedValue &= 0x00FFFFFF;515    EncodedValue |= 0xEE000000;516  }517 518  return EncodedValue;519}520 521/// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form522/// if we are in Thumb2.523unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,524                                                 unsigned EncodedValue,525                                                 const MCSubtargetInfo &STI) const {526  if (isThumb2(STI)) {527    EncodedValue |= 0xC000000; // Set bits 27-26528  }529 530  return EncodedValue;531}532 533/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite534/// them to their Thumb2 form if we are currently in Thumb2 mode.535unsigned ARMMCCodeEmitter::536VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue,537                     const MCSubtargetInfo &STI) const {538  if (isThumb2(STI)) {539    EncodedValue &= 0x0FFFFFFF;540    EncodedValue |= 0xE0000000;541  }542  return EncodedValue;543}544 545/// getMachineOpValue - Return binary encoding of operand. If the machine546/// operand requires relocation, record the relocation and return zero.547unsigned ARMMCCodeEmitter::548getMachineOpValue(const MCInst &MI, const MCOperand &MO,549                  SmallVectorImpl<MCFixup> &Fixups,550                  const MCSubtargetInfo &STI) const {551  if (MO.isReg()) {552    MCRegister Reg = MO.getReg();553    unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);554 555    // In NEON, Q registers are encoded as 2x their register number,556    // because they're using the same indices as the D registers they557    // overlap. In MVE, there are no 64-bit vector instructions, so558    // the encodings all refer to Q-registers by their literal559    // register number.560 561    if (STI.hasFeature(ARM::HasMVEIntegerOps))562      return RegNo;563 564    switch (Reg.id()) {565    default:566      return RegNo;567    case ARM::Q0:  case ARM::Q1:  case ARM::Q2:  case ARM::Q3:568    case ARM::Q4:  case ARM::Q5:  case ARM::Q6:  case ARM::Q7:569    case ARM::Q8:  case ARM::Q9:  case ARM::Q10: case ARM::Q11:570    case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:571      return 2 * RegNo;572    }573  } else if (MO.isImm()) {574    return static_cast<unsigned>(MO.getImm());575  } else if (MO.isDFPImm()) {576    return static_cast<unsigned>(APFloat(bit_cast<double>(MO.getDFPImm()))577                                     .bitcastToAPInt()578                                     .getHiBits(32)579                                     .getLimitedValue());580  }581 582  llvm_unreachable("Unable to encode MCOperand!");583}584 585/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.586bool ARMMCCodeEmitter::587EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,588                       unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups,589                       const MCSubtargetInfo &STI) const {590  const MCOperand &MO  = MI.getOperand(OpIdx);591  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);592 593  Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());594 595  int32_t SImm = MO1.getImm();596  bool isAdd = true;597 598  // Special value for #-0599  if (SImm == INT32_MIN) {600    SImm = 0;601    isAdd = false;602  }603 604  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.605  if (SImm < 0) {606    SImm = -SImm;607    isAdd = false;608  }609 610  Imm = SImm;611  return isAdd;612}613 614/// getBranchTargetOpValue - Helper function to get the branch target operand,615/// which is either an immediate or requires a fixup.616static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,617                                       unsigned FixupKind,618                                       SmallVectorImpl<MCFixup> &Fixups,619                                       const MCSubtargetInfo &STI) {620  const MCOperand &MO = MI.getOperand(OpIdx);621 622  // If the destination is an immediate, we have nothing to do.623  if (MO.isImm()) return MO.getImm();624  assert(MO.isExpr() && "Unexpected branch target type!");625  const MCExpr *Expr = MO.getExpr();626  MCFixupKind Kind = MCFixupKind(FixupKind);627  addFixup(Fixups, 0, Expr, Kind);628 629  // All of the information is in the fixup.630  return 0;631}632 633// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are634// determined by negating them and XOR'ing them with bit 23.635static int32_t encodeThumbBLOffset(int32_t offset) {636  offset >>= 1;637  uint32_t S  = (offset & 0x800000) >> 23;638  uint32_t J1 = (offset & 0x400000) >> 22;639  uint32_t J2 = (offset & 0x200000) >> 21;640  J1 = (~J1 & 0x1);641  J2 = (~J2 & 0x1);642  J1 ^= S;643  J2 ^= S;644 645  offset &= ~0x600000;646  offset |= J1 << 22;647  offset |= J2 << 21;648 649  return offset;650}651 652/// getThumbBLTargetOpValue - Return encoding info for immediate branch target.653uint32_t ARMMCCodeEmitter::654getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,655                        SmallVectorImpl<MCFixup> &Fixups,656                        const MCSubtargetInfo &STI) const {657  const MCOperand MO = MI.getOperand(OpIdx);658  if (MO.isExpr())659    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl,660                                    Fixups, STI);661  return encodeThumbBLOffset(MO.getImm());662}663 664/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate665/// BLX branch target.666uint32_t ARMMCCodeEmitter::667getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,668                         SmallVectorImpl<MCFixup> &Fixups,669                         const MCSubtargetInfo &STI) const {670  const MCOperand MO = MI.getOperand(OpIdx);671  if (MO.isExpr())672    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx,673                                    Fixups, STI);674  return encodeThumbBLOffset(MO.getImm());675}676 677/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.678uint32_t ARMMCCodeEmitter::679getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,680                        SmallVectorImpl<MCFixup> &Fixups,681                        const MCSubtargetInfo &STI) const {682  const MCOperand MO = MI.getOperand(OpIdx);683  if (MO.isExpr())684    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br,685                                    Fixups, STI);686  return (MO.getImm() >> 1);687}688 689/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.690uint32_t ARMMCCodeEmitter::691getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,692                         SmallVectorImpl<MCFixup> &Fixups,693                         const MCSubtargetInfo &STI) const {694  const MCOperand MO = MI.getOperand(OpIdx);695  if (MO.isExpr())696    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc,697                                    Fixups, STI);698  return (MO.getImm() >> 1);699}700 701/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.702uint32_t ARMMCCodeEmitter::703getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,704                        SmallVectorImpl<MCFixup> &Fixups,705                        const MCSubtargetInfo &STI) const {706  const MCOperand MO = MI.getOperand(OpIdx);707  if (MO.isExpr())708    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups, STI);709  return (MO.getImm() >> 1);710}711 712/// Return true if this branch has a non-always predication713static bool HasConditionalBranch(const MCInst &MI) {714  int NumOp = MI.getNumOperands();715  if (NumOp >= 2) {716    for (int i = 0; i < NumOp-1; ++i) {717      const MCOperand &MCOp1 = MI.getOperand(i);718      const MCOperand &MCOp2 = MI.getOperand(i + 1);719      if (MCOp1.isImm() && MCOp2.isReg() &&720          (!MCOp2.getReg() || MCOp2.getReg() == ARM::CPSR)) {721        if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL)722          return true;723      }724    }725  }726  return false;727}728 729/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch730/// target.731uint32_t ARMMCCodeEmitter::732getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,733                       SmallVectorImpl<MCFixup> &Fixups,734                       const MCSubtargetInfo &STI) const {735  // FIXME: This really, really shouldn't use TargetMachine. We don't want736  // coupling between MC and TM anywhere we can help it.737  if (isThumb2(STI))738    return739      ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups, STI);740  return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI);741}742 743/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch744/// target.745uint32_t ARMMCCodeEmitter::746getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,747                          SmallVectorImpl<MCFixup> &Fixups,748                          const MCSubtargetInfo &STI) const {749  const MCOperand MO = MI.getOperand(OpIdx);750  if (MO.isExpr()) {751    if (HasConditionalBranch(MI))752      return ::getBranchTargetOpValue(MI, OpIdx,753                                      ARM::fixup_arm_condbranch, Fixups, STI);754    return ::getBranchTargetOpValue(MI, OpIdx,755                                    ARM::fixup_arm_uncondbranch, Fixups, STI);756  }757 758  return MO.getImm() >> 2;759}760 761uint32_t ARMMCCodeEmitter::762getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,763                          SmallVectorImpl<MCFixup> &Fixups,764                          const MCSubtargetInfo &STI) const {765  const MCOperand MO = MI.getOperand(OpIdx);766  if (MO.isExpr()) {767    if (HasConditionalBranch(MI))768      return ::getBranchTargetOpValue(MI, OpIdx,769                                      ARM::fixup_arm_condbl, Fixups, STI);770    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups, STI);771  }772 773  return MO.getImm() >> 2;774}775 776uint32_t ARMMCCodeEmitter::777getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,778                          SmallVectorImpl<MCFixup> &Fixups,779                          const MCSubtargetInfo &STI) const {780  const MCOperand MO = MI.getOperand(OpIdx);781  if (MO.isExpr())782    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups, STI);783 784  return MO.getImm() >> 1;785}786 787/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit788/// immediate branch target.789uint32_t ARMMCCodeEmitter::getThumbBranchTargetOpValue(790    const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,791    const MCSubtargetInfo &STI) const {792  unsigned Val = 0;793  const MCOperand MO = MI.getOperand(OpIdx);794 795  if(MO.isExpr())796    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups, STI);797  else798    Val = MO.getImm() >> 1;799 800  bool I  = (Val & 0x800000);801  bool J1 = (Val & 0x400000);802  bool J2 = (Val & 0x200000);803  if (I ^ J1)804    Val &= ~0x400000;805  else806    Val |= 0x400000;807 808  if (I ^ J2)809    Val &= ~0x200000;810  else811    Val |= 0x200000;812 813  return Val;814}815 816/// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate817/// ADR label target.818uint32_t ARMMCCodeEmitter::819getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,820                   SmallVectorImpl<MCFixup> &Fixups,821                   const MCSubtargetInfo &STI) const {822  const MCOperand MO = MI.getOperand(OpIdx);823  if (MO.isExpr())824    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12,825                                    Fixups, STI);826  int64_t offset = MO.getImm();827  uint32_t Val = 0x2000;828 829  int SoImmVal;830  if (offset == INT32_MIN) {831    Val = 0x1000;832    SoImmVal = 0;833  } else if (offset < 0) {834    Val = 0x1000;835    offset *= -1;836    SoImmVal = ARM_AM::getSOImmVal(offset);837    if(SoImmVal == -1) {838      Val = 0x2000;839      offset *= -1;840      SoImmVal = ARM_AM::getSOImmVal(offset);841    }842  } else {843    SoImmVal = ARM_AM::getSOImmVal(offset);844    if(SoImmVal == -1) {845      Val = 0x1000;846      offset *= -1;847      SoImmVal = ARM_AM::getSOImmVal(offset);848    }849  }850 851  assert(SoImmVal != -1 && "Not a valid so_imm value!");852 853  Val |= SoImmVal;854  return Val;855}856 857/// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label858/// target.859uint32_t ARMMCCodeEmitter::860getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,861                   SmallVectorImpl<MCFixup> &Fixups,862                   const MCSubtargetInfo &STI) const {863  const MCOperand MO = MI.getOperand(OpIdx);864  if (MO.isExpr())865    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,866                                    Fixups, STI);867  int32_t Val = MO.getImm();868  if (Val == INT32_MIN)869    Val = 0x1000;870  else if (Val < 0) {871    Val *= -1;872    Val |= 0x1000;873  }874  return Val;875}876 877/// getITMaskOpValue - Return the architectural encoding of an IT878/// predication mask, given the MCOperand format.879uint32_t ARMMCCodeEmitter::880getITMaskOpValue(const MCInst &MI, unsigned OpIdx,881                 SmallVectorImpl<MCFixup> &Fixups,882                 const MCSubtargetInfo &STI) const {883  const MCOperand MaskMO = MI.getOperand(OpIdx);884  assert(MaskMO.isImm() && "Unexpected operand type!");885 886  unsigned Mask = MaskMO.getImm();887 888  // IT masks are encoded as a sequence of replacement low-order bits889  // for the condition code. So if the low bit of the starting890  // condition code is 1, then we have to flip all the bits above the891  // terminating bit (which is the lowest 1 bit).892  assert(OpIdx > 0 && "IT mask appears first!");893  const MCOperand CondMO = MI.getOperand(OpIdx-1);894  assert(CondMO.isImm() && "Unexpected operand type!");895  if (CondMO.getImm() & 1) {896    unsigned LowBit = Mask & -Mask;897    unsigned BitsAboveLowBit = 0xF & (-LowBit << 1);898    Mask ^= BitsAboveLowBit;899  }900 901  return Mask;902}903 904/// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label905/// target.906uint32_t ARMMCCodeEmitter::907getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,908                   SmallVectorImpl<MCFixup> &Fixups,909                   const MCSubtargetInfo &STI) const {910  const MCOperand MO = MI.getOperand(OpIdx);911  if (MO.isExpr())912    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10,913                                    Fixups, STI);914  return MO.getImm();915}916 917/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg'918/// operand.919uint32_t ARMMCCodeEmitter::920getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,921                              SmallVectorImpl<MCFixup> &,922                              const MCSubtargetInfo &STI) const {923  // [Rn, Rm]924  //   {5-3} = Rm925  //   {2-0} = Rn926  const MCOperand &MO1 = MI.getOperand(OpIdx);927  const MCOperand &MO2 = MI.getOperand(OpIdx + 1);928  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());929  unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO2.getReg());930  return (Rm << 3) | Rn;931}932 933/// getMVEShiftImmOpValue - Return encoding info for the 'sz:imm5'934/// operand.935uint32_t936ARMMCCodeEmitter::getMVEShiftImmOpValue(const MCInst &MI, unsigned OpIdx,937                                        SmallVectorImpl<MCFixup> &Fixups,938                                        const MCSubtargetInfo &STI) const {939  // {4-0} = szimm5940  // The value we are trying to encode is an immediate between either the941  // range of [1-7] or [1-15] depending on whether we are dealing with the942  // u8/s8 or the u16/s16 variants respectively.943  // This value is encoded as follows, if ShiftImm is the value within those944  // ranges then the encoding szimm5 = ShiftImm + size, where size is either 8945  // or 16.946 947  unsigned Size, ShiftImm;948  switch(MI.getOpcode()) {949    case ARM::MVE_VSHLL_imms16bh:950    case ARM::MVE_VSHLL_imms16th:951    case ARM::MVE_VSHLL_immu16bh:952    case ARM::MVE_VSHLL_immu16th:953      Size = 16;954      break;955    case ARM::MVE_VSHLL_imms8bh:956    case ARM::MVE_VSHLL_imms8th:957    case ARM::MVE_VSHLL_immu8bh:958    case ARM::MVE_VSHLL_immu8th:959      Size = 8;960      break;961    default:962      llvm_unreachable("Use of operand not supported by this instruction");963  }964  ShiftImm = MI.getOperand(OpIdx).getImm();965  return Size + ShiftImm;966}967 968/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.969uint32_t ARMMCCodeEmitter::970getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,971                        SmallVectorImpl<MCFixup> &Fixups,972                        const MCSubtargetInfo &STI) const {973  // {17-13} = reg974  // {12}    = (U)nsigned (add == '1', sub == '0')975  // {11-0}  = imm12976  unsigned Reg = 0, Imm12 = 0;977  bool isAdd = true;978  // If The first operand isn't a register, we have a label reference.979  const MCOperand &MO = MI.getOperand(OpIdx);980  if (MO.isReg()) {981    const MCOperand &MO1 = MI.getOperand(OpIdx + 1);982    if (MO1.isImm()) {983      isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups, STI);984    } else if (MO1.isExpr()) {985      assert(!isThumb(STI) && !isThumb2(STI) &&986             "Thumb mode requires different encoding");987      Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());988      isAdd = false; // 'U' bit is set as part of the fixup.989      MCFixupKind Kind = ARM::fixup_arm_ldst_abs_12;990      addFixup(Fixups, 0, MO1.getExpr(), Kind);991    }992  } else if (MO.isExpr()) {993    Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC.994    isAdd = false; // 'U' bit is set as part of the fixup.995    MCFixupKind Kind;996    if (isThumb2(STI))997      Kind = ARM::fixup_t2_ldst_pcrel_12;998    else999      Kind = ARM::fixup_arm_ldst_pcrel_12;1000    addFixup(Fixups, 0, MO.getExpr(), Kind);1001 1002    ++MCNumCPRelocations;1003  } else {1004    Reg = ARM::PC;1005    int32_t Offset = MO.getImm();1006    if (Offset == INT32_MIN) {1007      Offset = 0;1008      isAdd = false;1009    } else if (Offset < 0) {1010      Offset *= -1;1011      isAdd = false;1012    }1013    Imm12 = Offset;1014  }1015  uint32_t Binary = Imm12 & 0xfff;1016  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.1017  if (isAdd)1018    Binary |= (1 << 12);1019  Binary |= (Reg << 13);1020  return Binary;1021}1022 1023template<unsigned Bits, unsigned Shift>1024uint32_t ARMMCCodeEmitter::1025getT2ScaledImmOpValue(const MCInst &MI, unsigned OpIdx,1026                      SmallVectorImpl<MCFixup> &Fixups,1027                      const MCSubtargetInfo &STI) const {1028  // FIXME: The immediate operand should have already been encoded like this1029  // before ever getting here. The encoder method should just need to combine1030  // the MI operands for the register and the offset into a single1031  // representation for the complex operand in the .td file. This isn't just1032  // style, unfortunately. As-is, we can't represent the distinct encoding1033  // for #-0.1034 1035  // {Bits}    = (U)nsigned (add == '1', sub == '0')1036  // {(Bits-1)-0}  = immediate1037  int32_t Imm = MI.getOperand(OpIdx).getImm();1038  bool isAdd = Imm >= 0;1039 1040  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.1041  if (Imm < 0)1042    Imm = -(uint32_t)Imm;1043 1044  Imm >>= Shift;1045 1046  uint32_t Binary = Imm & ((1U << Bits) - 1);1047  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.1048  if (isAdd)1049    Binary |= (1U << Bits);1050  return Binary;1051}1052 1053/// getMveAddrModeRQOpValue - Return encoding info for 'reg, vreg'1054/// operand.1055uint32_t ARMMCCodeEmitter::1056getMveAddrModeRQOpValue(const MCInst &MI, unsigned OpIdx,1057                        SmallVectorImpl<MCFixup> &Fixups,1058                        const MCSubtargetInfo &STI) const {1059    // {6-3} Rn1060    // {2-0} Qm1061    const MCOperand &M0 = MI.getOperand(OpIdx);1062    const MCOperand &M1 = MI.getOperand(OpIdx + 1);1063 1064    unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(M0.getReg());1065    unsigned Qm = CTX.getRegisterInfo()->getEncodingValue(M1.getReg());1066 1067    assert(Qm < 8 && "Qm is supposed to be encodable in 3 bits");1068 1069    return (Rn << 3) | Qm;1070}1071 1072/// getMveAddrModeRQOpValue - Return encoding info for 'reg, vreg'1073/// operand.1074template<int shift>1075uint32_t ARMMCCodeEmitter::1076getMveAddrModeQOpValue(const MCInst &MI, unsigned OpIdx,1077                        SmallVectorImpl<MCFixup> &Fixups,1078                        const MCSubtargetInfo &STI) const {1079    // {10-8} Qm1080    // {7-0} Imm1081    const MCOperand &M0 = MI.getOperand(OpIdx);1082    const MCOperand &M1 = MI.getOperand(OpIdx + 1);1083 1084    unsigned Qm = CTX.getRegisterInfo()->getEncodingValue(M0.getReg());1085    int32_t Imm = M1.getImm();1086 1087    bool isAdd = Imm >= 0;1088 1089    Imm >>= shift;1090 1091    if (!isAdd)1092      Imm = -(uint32_t)Imm;1093 1094    Imm &= 0x7f;1095 1096    if (isAdd)1097      Imm |= 0x80;1098 1099    assert(Qm < 8 && "Qm is supposed to be encodable in 3 bits");1100 1101    return (Qm << 8) | Imm;1102}1103 1104/// getT2AddrModeImm8s4OpValue - Return encoding info for1105/// 'reg +/- imm8<<2' operand.1106uint32_t ARMMCCodeEmitter::1107getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,1108                        SmallVectorImpl<MCFixup> &Fixups,1109                        const MCSubtargetInfo &STI) const {1110  // {12-9} = reg1111  // {8}    = (U)nsigned (add == '1', sub == '0')1112  // {7-0}  = imm81113  unsigned Reg, Imm8;1114  bool isAdd = true;1115  // If The first operand isn't a register, we have a label reference.1116  const MCOperand &MO = MI.getOperand(OpIdx);1117  if (!MO.isReg()) {1118    Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.1119    Imm8 = 0;1120    isAdd = false ; // 'U' bit is set as part of the fixup.1121 1122    assert(MO.isExpr() && "Unexpected machine operand type!");1123    const MCExpr *Expr = MO.getExpr();1124    MCFixupKind Kind = ARM::fixup_t2_pcrel_10;1125    addFixup(Fixups, 0, Expr, Kind);1126 1127    ++MCNumCPRelocations;1128  } else1129    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);1130 1131  // FIXME: The immediate operand should have already been encoded like this1132  // before ever getting here. The encoder method should just need to combine1133  // the MI operands for the register and the offset into a single1134  // representation for the complex operand in the .td file. This isn't just1135  // style, unfortunately. As-is, we can't represent the distinct encoding1136  // for #-0.1137  assert(((Imm8 & 0x3) == 0) && "Not a valid immediate!");1138  uint32_t Binary = (Imm8 >> 2) & 0xff;1139  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.1140  if (isAdd)1141    Binary |= (1 << 8);1142  Binary |= (Reg << 9);1143  return Binary;1144}1145 1146/// getT2AddrModeImm7s4OpValue - Return encoding info for1147/// 'reg +/- imm7<<2' operand.1148uint32_t1149ARMMCCodeEmitter::getT2AddrModeImm7s4OpValue(const MCInst &MI, unsigned OpIdx,1150                                             SmallVectorImpl<MCFixup> &Fixups,1151                                             const MCSubtargetInfo &STI) const {1152  // {11-8} = reg1153  // {7}    = (A)dd (add == '1', sub == '0')1154  // {6-0}  = imm71155  unsigned Reg, Imm7;1156  // If The first operand isn't a register, we have a label reference.1157  bool isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm7, Fixups, STI);1158 1159  // FIXME: The immediate operand should have already been encoded like this1160  // before ever getting here. The encoder method should just need to combine1161  // the MI operands for the register and the offset into a single1162  // representation for the complex operand in the .td file. This isn't just1163  // style, unfortunately. As-is, we can't represent the distinct encoding1164  // for #-0.1165  uint32_t Binary = (Imm7 >> 2) & 0xff;1166  // Immediate is always encoded as positive. The 'A' bit controls add vs sub.1167  if (isAdd)1168    Binary |= (1 << 7);1169  Binary |= (Reg << 8);1170  return Binary;1171}1172 1173/// getT2AddrModeImm0_1020s4OpValue - Return encoding info for1174/// 'reg + imm8<<2' operand.1175uint32_t ARMMCCodeEmitter::1176getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,1177                        SmallVectorImpl<MCFixup> &Fixups,1178                        const MCSubtargetInfo &STI) const {1179  // {11-8} = reg1180  // {7-0}  = imm81181  const MCOperand &MO = MI.getOperand(OpIdx);1182  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);1183  unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());1184  unsigned Imm8 = MO1.getImm();1185  return (Reg << 8) | Imm8;1186}1187 1188uint32_t ARMMCCodeEmitter::getHiLoImmOpValue(const MCInst &MI, unsigned OpIdx,1189                                             SmallVectorImpl<MCFixup> &Fixups,1190                                             const MCSubtargetInfo &STI) const {1191  // {20-16} = imm{15-12}1192  // {11-0}  = imm{11-0}1193  const MCOperand &MO = MI.getOperand(OpIdx);1194  if (MO.isImm())1195    // Hi / lo bits already extracted during earlier passes.1196    return static_cast<unsigned>(MO.getImm());1197 1198  // Handle :upper16:, :lower16:, :upper8_15:, :upper0_7:, :lower8_15:1199  // :lower0_7: assembly prefixes.1200  const MCExpr *E = MO.getExpr();1201  MCFixupKind Kind;1202  if (E->getKind() == MCExpr::Specifier) {1203    auto *ARM16Expr = cast<MCSpecifierExpr>(E);1204    E = ARM16Expr->getSubExpr();1205 1206    if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(E)) {1207      const int64_t Value = MCE->getValue();1208      if (Value > UINT32_MAX)1209        report_fatal_error("constant value truncated (limited to 32-bit)");1210 1211      switch (ARM16Expr->getSpecifier()) {1212      case ARM::S_HI16:1213        return (int32_t(Value) & 0xffff0000) >> 16;1214      case ARM::S_LO16:1215        return (int32_t(Value) & 0x0000ffff);1216 1217      case ARM::S_HI_8_15:1218        return (int32_t(Value) & 0xff000000) >> 24;1219      case ARM::S_HI_0_7:1220        return (int32_t(Value) & 0x00ff0000) >> 16;1221      case ARM::S_LO_8_15:1222        return (int32_t(Value) & 0x0000ff00) >> 8;1223      case ARM::S_LO_0_7:1224        return (int32_t(Value) & 0x000000ff);1225 1226      default: llvm_unreachable("Unsupported ARMFixup");1227      }1228    }1229 1230    switch (ARM16Expr->getSpecifier()) {1231    default: llvm_unreachable("Unsupported ARMFixup");1232    case ARM::S_HI16:1233      Kind = MCFixupKind(isThumb(STI) ? ARM::fixup_t2_movt_hi161234                                      : ARM::fixup_arm_movt_hi16);1235      break;1236    case ARM::S_LO16:1237      Kind = MCFixupKind(isThumb(STI) ? ARM::fixup_t2_movw_lo161238                                      : ARM::fixup_arm_movw_lo16);1239      break;1240    case ARM::S_HI_8_15:1241      if (!isThumb(STI))1242        llvm_unreachable(":upper_8_15: not supported in Arm state");1243      Kind = ARM::fixup_arm_thumb_upper_8_15;1244      break;1245    case ARM::S_HI_0_7:1246      if (!isThumb(STI))1247        llvm_unreachable(":upper_0_7: not supported in Arm state");1248      Kind = ARM::fixup_arm_thumb_upper_0_7;1249      break;1250    case ARM::S_LO_8_15:1251      if (!isThumb(STI))1252        llvm_unreachable(":lower_8_15: not supported in Arm state");1253      Kind = ARM::fixup_arm_thumb_lower_8_15;1254      break;1255    case ARM::S_LO_0_7:1256      if (!isThumb(STI))1257        llvm_unreachable(":lower_0_7: not supported in Arm state");1258      Kind = ARM::fixup_arm_thumb_lower_0_7;1259      break;1260    }1261 1262    addFixup(Fixups, 0, E, Kind);1263    return 0;1264  }1265  // If the expression doesn't have :upper16:, :lower16: on it, it's just a1266  // plain immediate expression, previously those evaluated to the lower 16 bits1267  // of the expression regardless of whether we have a movt or a movw, but that1268  // led to misleadingly results.  This is disallowed in the AsmParser in1269  // validateInstruction() so this should never happen.  The same holds for1270  // thumb1 :upper8_15:, :upper0_7:, lower8_15: or :lower0_7: with movs or adds.1271  llvm_unreachable("expression without :upper16:, :lower16:, :upper8_15:,"1272                   ":upper0_7:, lower8_15: or :lower0_7:");1273}1274 1275uint32_t ARMMCCodeEmitter::1276getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,1277                    SmallVectorImpl<MCFixup> &Fixups,1278                    const MCSubtargetInfo &STI) const {1279  const MCOperand &MO = MI.getOperand(OpIdx);1280  const MCOperand &MO1 = MI.getOperand(OpIdx+1);1281  const MCOperand &MO2 = MI.getOperand(OpIdx+2);1282  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());1283  unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());1284  unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());1285  bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;1286  ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());1287  unsigned SBits = getShiftOp(ShOp);1288 1289  // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift1290  // amount. However, it would be an easy mistake to make so check here.1291  assert((ShImm & ~0x1f) == 0 && "Out of range shift amount");1292 1293  // {16-13} = Rn1294  // {12}    = isAdd1295  // {11-0}  = shifter1296  //  {3-0}  = Rm1297  //  {4}    = 01298  //  {6-5}  = type1299  //  {11-7} = imm1300  uint32_t Binary = Rm;1301  Binary |= Rn << 13;1302  Binary |= SBits << 5;1303  Binary |= ShImm << 7;1304  if (isAdd)1305    Binary |= 1 << 12;1306  return Binary;1307}1308 1309uint32_t ARMMCCodeEmitter::1310getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,1311                          SmallVectorImpl<MCFixup> &Fixups,1312                          const MCSubtargetInfo &STI) const {1313  // {13}     1 == imm12, 0 == Rm1314  // {12}     isAdd1315  // {11-0}   imm12/Rm1316  const MCOperand &MO = MI.getOperand(OpIdx);1317  const MCOperand &MO1 = MI.getOperand(OpIdx+1);1318  unsigned Imm = MO1.getImm();1319  bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;1320  bool isReg = MO.getReg().isValid();1321  uint32_t Binary = ARM_AM::getAM2Offset(Imm);1322  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm121323  if (isReg) {1324    ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);1325    Binary <<= 7;                    // Shift amount is bits [11:7]1326    Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]1327    Binary |= CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); // Rm is bits [3:0]1328  }1329  return Binary | (isAdd << 12) | (isReg << 13);1330}1331 1332uint32_t ARMMCCodeEmitter::1333getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,1334                     SmallVectorImpl<MCFixup> &Fixups,1335                     const MCSubtargetInfo &STI) const {1336  // {4}      isAdd1337  // {3-0}    Rm1338  const MCOperand &MO = MI.getOperand(OpIdx);1339  const MCOperand &MO1 = MI.getOperand(OpIdx+1);1340  bool isAdd = MO1.getImm() != 0;1341  return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()) | (isAdd << 4);1342}1343 1344uint32_t ARMMCCodeEmitter::1345getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,1346                          SmallVectorImpl<MCFixup> &Fixups,1347                          const MCSubtargetInfo &STI) const {1348  // {9}      1 == imm8, 0 == Rm1349  // {8}      isAdd1350  // {7-4}    imm7_4/zero1351  // {3-0}    imm3_0/Rm1352  const MCOperand &MO = MI.getOperand(OpIdx);1353  const MCOperand &MO1 = MI.getOperand(OpIdx+1);1354  unsigned Imm = MO1.getImm();1355  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;1356  bool isImm = !MO.getReg().isValid();1357  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);1358  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm81359  if (!isImm)1360    Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());1361  return Imm8 | (isAdd << 8) | (isImm << 9);1362}1363 1364uint32_t ARMMCCodeEmitter::1365getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,1366                    SmallVectorImpl<MCFixup> &Fixups,1367                    const MCSubtargetInfo &STI) const {1368  // {13}     1 == imm8, 0 == Rm1369  // {12-9}   Rn1370  // {8}      isAdd1371  // {7-4}    imm7_4/zero1372  // {3-0}    imm3_0/Rm1373  const MCOperand &MO = MI.getOperand(OpIdx);1374  const MCOperand &MO1 = MI.getOperand(OpIdx+1);1375  const MCOperand &MO2 = MI.getOperand(OpIdx+2);1376 1377  // If The first operand isn't a register, we have a label reference.1378  if (!MO.isReg()) {1379    unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.1380 1381    assert(MO.isExpr() && "Unexpected machine operand type!");1382    const MCExpr *Expr = MO.getExpr();1383    MCFixupKind Kind = ARM::fixup_arm_pcrel_10_unscaled;1384    addFixup(Fixups, 0, Expr, Kind);1385 1386    ++MCNumCPRelocations;1387    return (Rn << 9) | (1 << 13);1388  }1389  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());1390  unsigned Imm = MO2.getImm();1391  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;1392  bool isImm = !MO1.getReg().isValid();1393  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);1394  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm81395  if (!isImm)1396    Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());1397  return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);1398}1399 1400/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands.1401uint32_t ARMMCCodeEmitter::1402getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,1403                          SmallVectorImpl<MCFixup> &Fixups,1404                          const MCSubtargetInfo &STI) const {1405  // [SP, #imm]1406  //   {7-0} = imm81407  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);1408  assert(MI.getOperand(OpIdx).getReg() == ARM::SP &&1409         "Unexpected base register!");1410 1411  // The immediate is already shifted for the implicit zeroes, so no change1412  // here.1413  return MO1.getImm() & 0xff;1414}1415 1416/// getAddrModeISOpValue - Encode the t_addrmode_is# operands.1417uint32_t ARMMCCodeEmitter::1418getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,1419                     SmallVectorImpl<MCFixup> &Fixups,1420                     const MCSubtargetInfo &STI) const {1421  // [Rn, #imm]1422  //   {7-3} = imm51423  //   {2-0} = Rn1424  const MCOperand &MO = MI.getOperand(OpIdx);1425  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);1426  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());1427  unsigned Imm5 = MO1.getImm();1428  return ((Imm5 & 0x1f) << 3) | Rn;1429}1430 1431/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.1432uint32_t ARMMCCodeEmitter::1433getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,1434                     SmallVectorImpl<MCFixup> &Fixups,1435                     const MCSubtargetInfo &STI) const {1436  const MCOperand MO = MI.getOperand(OpIdx);1437  if (MO.isExpr())1438    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups, STI);1439  return (MO.getImm() >> 2);1440}1441 1442/// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand.1443uint32_t ARMMCCodeEmitter::1444getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,1445                    SmallVectorImpl<MCFixup> &Fixups,1446                    const MCSubtargetInfo &STI) const {1447  // {12-9} = reg1448  // {8}    = (U)nsigned (add == '1', sub == '0')1449  // {7-0}  = imm81450  unsigned Reg, Imm8;1451  bool isAdd;1452  // If The first operand isn't a register, we have a label reference.1453  const MCOperand &MO = MI.getOperand(OpIdx);1454  if (!MO.isReg()) {1455    Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.1456    Imm8 = 0;1457    isAdd = false; // 'U' bit is handled as part of the fixup.1458 1459    assert(MO.isExpr() && "Unexpected machine operand type!");1460    const MCExpr *Expr = MO.getExpr();1461    MCFixupKind Kind;1462    if (isThumb2(STI))1463      Kind = ARM::fixup_t2_pcrel_10;1464    else1465      Kind = ARM::fixup_arm_pcrel_10;1466    addFixup(Fixups, 0, Expr, Kind);1467 1468    ++MCNumCPRelocations;1469  } else {1470    EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);1471    isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;1472  }1473 1474  uint32_t Binary = ARM_AM::getAM5Offset(Imm8);1475  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.1476  if (isAdd)1477    Binary |= (1 << 8);1478  Binary |= (Reg << 9);1479  return Binary;1480}1481 1482/// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand.1483uint32_t ARMMCCodeEmitter::1484getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx,1485                    SmallVectorImpl<MCFixup> &Fixups,1486                    const MCSubtargetInfo &STI) const {1487  // {12-9} = reg1488  // {8}    = (U)nsigned (add == '1', sub == '0')1489  // {7-0}  = imm81490  unsigned Reg, Imm8;1491  bool isAdd;1492  // If The first operand isn't a register, we have a label reference.1493  const MCOperand &MO = MI.getOperand(OpIdx);1494  if (!MO.isReg()) {1495    Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.1496    Imm8 = 0;1497    isAdd = false; // 'U' bit is handled as part of the fixup.1498 1499    assert(MO.isExpr() && "Unexpected machine operand type!");1500    const MCExpr *Expr = MO.getExpr();1501    MCFixupKind Kind;1502    if (isThumb2(STI))1503      Kind = ARM::fixup_t2_pcrel_9;1504    else1505      Kind = ARM::fixup_arm_pcrel_9;1506    addFixup(Fixups, 0, Expr, Kind);1507 1508    ++MCNumCPRelocations;1509  } else {1510    EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);1511    isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;1512  }1513 1514  uint32_t Binary = ARM_AM::getAM5Offset(Imm8);1515  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.1516  if (isAdd)1517    Binary |= (1 << 8);1518  Binary |= (Reg << 9);1519  return Binary;1520}1521 1522unsigned ARMMCCodeEmitter::getModImmOpValue(const MCInst &MI, unsigned Op,1523                                            SmallVectorImpl<MCFixup> &Fixups,1524                                            const MCSubtargetInfo &ST) const {1525  const MCOperand &MO = MI.getOperand(Op);1526 1527  // Support for fixups (MCFixup)1528  if (MO.isExpr()) {1529    const MCExpr *Expr = MO.getExpr();1530    // Fixups resolve to plain values that need to be encoded.1531    MCFixupKind Kind = ARM::fixup_arm_mod_imm;1532    addFixup(Fixups, 0, Expr, Kind);1533    return 0;1534  }1535 1536  // Immediate is already in its encoded format1537  return MO.getImm();1538}1539 1540unsigned ARMMCCodeEmitter::getT2SOImmOpValue(const MCInst &MI, unsigned Op,1541                                             SmallVectorImpl<MCFixup> &Fixups,1542                                             const MCSubtargetInfo &STI) const {1543  const MCOperand &MO = MI.getOperand(Op);1544 1545  // Support for fixups (MCFixup)1546  if (MO.isExpr()) {1547    const MCExpr *Expr = MO.getExpr();1548    // Fixups resolve to plain values that need to be encoded.1549    MCFixupKind Kind = ARM::fixup_t2_so_imm;1550    addFixup(Fixups, 0, Expr, Kind);1551    return 0;1552  }1553  unsigned SoImm = MO.getImm();1554  unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm);1555  assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");1556  return Encoded;1557}1558 1559unsigned ARMMCCodeEmitter::1560getSORegRegOpValue(const MCInst &MI, unsigned OpIdx,1561                SmallVectorImpl<MCFixup> &Fixups,1562                const MCSubtargetInfo &STI) const {1563  // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be1564  // shifted. The second is Rs, the amount to shift by, and the third specifies1565  // the type of the shift.1566  //1567  // {3-0} = Rm.1568  // {4}   = 11569  // {6-5} = type1570  // {11-8} = Rs1571  // {7}    = 01572 1573  const MCOperand &MO  = MI.getOperand(OpIdx);1574  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);1575  const MCOperand &MO2 = MI.getOperand(OpIdx + 2);1576  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());1577 1578  // Encode Rm.1579  unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());1580 1581  // Encode the shift opcode.1582  unsigned SBits = 0;1583  MCRegister Rs = MO1.getReg();1584  if (Rs) {1585    // Set shift operand (bit[7:4]).1586    // LSL - 00011587    // LSR - 00111588    // ASR - 01011589    // ROR - 01111590    switch (SOpc) {1591    default: llvm_unreachable("Unknown shift opc!");1592    case ARM_AM::lsl: SBits = 0x1; break;1593    case ARM_AM::lsr: SBits = 0x3; break;1594    case ARM_AM::asr: SBits = 0x5; break;1595    case ARM_AM::ror: SBits = 0x7; break;1596    }1597  }1598 1599  Binary |= SBits << 4;1600 1601  // Encode the shift operation Rs.1602  // Encode Rs bit[11:8].1603  assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);1604  return Binary | (CTX.getRegisterInfo()->getEncodingValue(Rs) << ARMII::RegRsShift);1605}1606 1607unsigned ARMMCCodeEmitter::1608getSORegImmOpValue(const MCInst &MI, unsigned OpIdx,1609                SmallVectorImpl<MCFixup> &Fixups,1610                const MCSubtargetInfo &STI) const {1611  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be1612  // shifted. The second is the amount to shift by.1613  //1614  // {3-0} = Rm.1615  // {4}   = 01616  // {6-5} = type1617  // {11-7} = imm1618 1619  const MCOperand &MO  = MI.getOperand(OpIdx);1620  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);1621  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());1622 1623  // Encode Rm.1624  unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());1625 1626  // Encode the shift opcode.1627  unsigned SBits = 0;1628 1629  // Set shift operand (bit[6:4]).1630  // LSL - 0001631  // LSR - 0101632  // ASR - 1001633  // ROR - 1101634  // RRX - 110 and bit[11:8] clear.1635  switch (SOpc) {1636  default: llvm_unreachable("Unknown shift opc!");1637  case ARM_AM::lsl: SBits = 0x0; break;1638  case ARM_AM::lsr: SBits = 0x2; break;1639  case ARM_AM::asr: SBits = 0x4; break;1640  case ARM_AM::ror: SBits = 0x6; break;1641  case ARM_AM::rrx:1642    Binary |= 0x60;1643    return Binary;1644  }1645 1646  // Encode shift_imm bit[11:7].1647  Binary |= SBits << 4;1648  unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm());1649  assert(Offset < 32 && "Offset must be in range 0-31!");1650  return Binary | (Offset << 7);1651}1652 1653 1654unsigned ARMMCCodeEmitter::1655getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,1656                SmallVectorImpl<MCFixup> &Fixups,1657                const MCSubtargetInfo &STI) const {1658  const MCOperand &MO1 = MI.getOperand(OpNum);1659  const MCOperand &MO2 = MI.getOperand(OpNum+1);1660  const MCOperand &MO3 = MI.getOperand(OpNum+2);1661 1662  // Encoded as [Rn, Rm, imm].1663  // FIXME: Needs fixup support.1664  unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());1665  Value <<= 4;1666  Value |= CTX.getRegisterInfo()->getEncodingValue(MO2.getReg());1667  Value <<= 2;1668  Value |= MO3.getImm();1669 1670  return Value;1671}1672 1673template<unsigned Bits, unsigned Shift>1674unsigned ARMMCCodeEmitter::1675getT2AddrModeImmOpValue(const MCInst &MI, unsigned OpNum,1676                        SmallVectorImpl<MCFixup> &Fixups,1677                        const MCSubtargetInfo &STI) const {1678  const MCOperand &MO1 = MI.getOperand(OpNum);1679  const MCOperand &MO2 = MI.getOperand(OpNum+1);1680 1681  // FIXME: Needs fixup support.1682  unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());1683 1684  // If the immediate is B bits long, we need B+1 bits in order1685  // to represent the (inverse of the) sign bit.1686  Value <<= (Bits + 1);1687  int32_t tmp = (int32_t)MO2.getImm();1688  if (tmp == INT32_MIN) { // represents subtracting zero rather than adding it1689    tmp = 0;1690  } else if (tmp < 0) {1691    tmp = abs(tmp);1692  } else {1693    Value |= (1U << Bits); // Set the ADD bit1694  }1695  Value |= (tmp >> Shift) & ((1U << Bits) - 1);1696  return Value;1697}1698 1699unsigned ARMMCCodeEmitter::1700getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,1701                         SmallVectorImpl<MCFixup> &Fixups,1702                         const MCSubtargetInfo &STI) const {1703  const MCOperand &MO1 = MI.getOperand(OpNum);1704 1705  // FIXME: Needs fixup support.1706  unsigned Value = 0;1707  auto tmp = static_cast<uint32_t>(MO1.getImm());1708  if (static_cast<int32_t>(tmp) < 0)1709    tmp = -tmp;1710  else1711    Value |= 256; // Set the ADD bit1712  Value |= tmp & 255;1713  return Value;1714}1715 1716unsigned ARMMCCodeEmitter::1717getT2SORegOpValue(const MCInst &MI, unsigned OpIdx,1718                SmallVectorImpl<MCFixup> &Fixups,1719                const MCSubtargetInfo &STI) const {1720  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be1721  // shifted. The second is the amount to shift by.1722  //1723  // {3-0} = Rm.1724  // {4}   = 01725  // {6-5} = type1726  // {11-7} = imm1727 1728  const MCOperand &MO  = MI.getOperand(OpIdx);1729  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);1730  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());1731 1732  // Encode Rm.1733  unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());1734 1735  // Encode the shift opcode.1736  unsigned SBits = 0;1737  // Set shift operand (bit[6:4]).1738  // LSL - 0001739  // LSR - 0101740  // ASR - 1001741  // ROR - 1101742  switch (SOpc) {1743  default: llvm_unreachable("Unknown shift opc!");1744  case ARM_AM::lsl: SBits = 0x0; break;1745  case ARM_AM::lsr: SBits = 0x2; break;1746  case ARM_AM::asr: SBits = 0x4; break;1747  case ARM_AM::rrx: [[fallthrough]];1748  case ARM_AM::ror: SBits = 0x6; break;1749  }1750 1751  Binary |= SBits << 4;1752  if (SOpc == ARM_AM::rrx)1753    return Binary;1754 1755  // Encode shift_imm bit[11:7].1756  return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;1757}1758 1759unsigned ARMMCCodeEmitter::1760getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,1761                               SmallVectorImpl<MCFixup> &Fixups,1762                               const MCSubtargetInfo &STI) const {1763  // 10 bits. lower 5 bits are the lsb of the mask, high five bits are the1764  // msb of the mask.1765  const MCOperand &MO = MI.getOperand(Op);1766  uint32_t v = ~MO.getImm();1767  uint32_t lsb = llvm::countr_zero(v);1768  uint32_t msb = llvm::Log2_32(v);1769  assert(v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");1770  return lsb | (msb << 5);1771}1772 1773unsigned ARMMCCodeEmitter::1774getRegisterListOpValue(const MCInst &MI, unsigned Op,1775                       SmallVectorImpl<MCFixup> &Fixups,1776                       const MCSubtargetInfo &STI) const {1777  // VLDM/VSTM/VSCCLRM:1778  //   {12-8} = Vd1779  //   {7-0}  = Number of registers1780  //1781  // LDM/STM:1782  //   {15-0}  = Bitfield of GPRs.1783  MCRegister Reg = MI.getOperand(Op).getReg();1784  bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg);1785  bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg);1786 1787  unsigned Binary = 0;1788 1789  if (SPRRegs || DPRRegs || Reg == ARM::VPR) {1790    // VLDM/VSTM/VSCCLRM1791    unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);1792    unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;1793    Binary |= (RegNo & 0x1f) << 8;1794 1795    if (MI.getOpcode() == ARM::VSCCLRMD)1796      // Ignore VPR1797      --NumRegs;1798    else if (MI.getOpcode() == ARM::VSCCLRMS) {1799      // The register list can contain both S registers and D registers, with D1800      // registers counting as two registers. VPR doesn't count towards the1801      // number of registers.1802      NumRegs = 0;1803      for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {1804        Reg = MI.getOperand(I).getReg();1805        if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))1806          NumRegs += 1;1807        else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))1808          NumRegs += 2;1809      }1810    }1811    if (SPRRegs)1812      Binary |= NumRegs;1813    else1814      Binary |= NumRegs * 2;1815  } else {1816    const MCRegisterInfo &MRI = *CTX.getRegisterInfo();1817    assert(is_sorted(drop_begin(MI, Op),1818                     [&](const MCOperand &LHS, const MCOperand &RHS) {1819                       return MRI.getEncodingValue(LHS.getReg()) <1820                              MRI.getEncodingValue(RHS.getReg());1821                     }));1822    for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {1823      unsigned RegNo = MRI.getEncodingValue(MI.getOperand(I).getReg());1824      Binary |= 1 << RegNo;1825    }1826  }1827 1828  return Binary;1829}1830 1831/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along1832/// with the alignment operand.1833unsigned ARMMCCodeEmitter::1834getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,1835                           SmallVectorImpl<MCFixup> &Fixups,1836                           const MCSubtargetInfo &STI) const {1837  const MCOperand &Reg = MI.getOperand(Op);1838  const MCOperand &Imm = MI.getOperand(Op + 1);1839 1840  unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());1841  unsigned Align = 0;1842 1843  switch (Imm.getImm()) {1844  default: break;1845  case 2:1846  case 4:1847  case 8:  Align = 0x01; break;1848  case 16: Align = 0x02; break;1849  case 32: Align = 0x03; break;1850  }1851 1852  return RegNo | (Align << 4);1853}1854 1855/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number1856/// along  with the alignment operand for use in VST1 and VLD1 with size 32.1857unsigned ARMMCCodeEmitter::1858getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,1859                                    SmallVectorImpl<MCFixup> &Fixups,1860                                    const MCSubtargetInfo &STI) const {1861  const MCOperand &Reg = MI.getOperand(Op);1862  const MCOperand &Imm = MI.getOperand(Op + 1);1863 1864  unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());1865  unsigned Align = 0;1866 1867  switch (Imm.getImm()) {1868  default: break;1869  case 8:1870  case 16:1871  case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes.1872  case 2: Align = 0x00; break;1873  case 4: Align = 0x03; break;1874  }1875 1876  return RegNo | (Align << 4);1877}1878 1879 1880/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and1881/// alignment operand for use in VLD-dup instructions.  This is the same as1882/// getAddrMode6AddressOpValue except for the alignment encoding, which is1883/// different for VLD4-dup.1884unsigned ARMMCCodeEmitter::1885getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,1886                              SmallVectorImpl<MCFixup> &Fixups,1887                              const MCSubtargetInfo &STI) const {1888  const MCOperand &Reg = MI.getOperand(Op);1889  const MCOperand &Imm = MI.getOperand(Op + 1);1890 1891  unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());1892  unsigned Align = 0;1893 1894  switch (Imm.getImm()) {1895  default: break;1896  case 2:1897  case 4:1898  case 8:  Align = 0x01; break;1899  case 16: Align = 0x03; break;1900  }1901 1902  return RegNo | (Align << 4);1903}1904 1905unsigned ARMMCCodeEmitter::1906getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,1907                          SmallVectorImpl<MCFixup> &Fixups,1908                          const MCSubtargetInfo &STI) const {1909  const MCOperand &MO = MI.getOperand(Op);1910  if (!MO.getReg())1911    return 0x0D;1912  return CTX.getRegisterInfo()->getEncodingValue(MO.getReg());1913}1914 1915unsigned ARMMCCodeEmitter::1916getShiftRight8Imm(const MCInst &MI, unsigned Op,1917                  SmallVectorImpl<MCFixup> &Fixups,1918                  const MCSubtargetInfo &STI) const {1919  return 8 - MI.getOperand(Op).getImm();1920}1921 1922unsigned ARMMCCodeEmitter::1923getShiftRight16Imm(const MCInst &MI, unsigned Op,1924                   SmallVectorImpl<MCFixup> &Fixups,1925                   const MCSubtargetInfo &STI) const {1926  return 16 - MI.getOperand(Op).getImm();1927}1928 1929unsigned ARMMCCodeEmitter::1930getShiftRight32Imm(const MCInst &MI, unsigned Op,1931                   SmallVectorImpl<MCFixup> &Fixups,1932                   const MCSubtargetInfo &STI) const {1933  return 32 - MI.getOperand(Op).getImm();1934}1935 1936unsigned ARMMCCodeEmitter::1937getShiftRight64Imm(const MCInst &MI, unsigned Op,1938                   SmallVectorImpl<MCFixup> &Fixups,1939                   const MCSubtargetInfo &STI) const {1940  return 64 - MI.getOperand(Op).getImm();1941}1942 1943void ARMMCCodeEmitter::encodeInstruction(const MCInst &MI,1944                                         SmallVectorImpl<char> &CB,1945                                         SmallVectorImpl<MCFixup> &Fixups,1946                                         const MCSubtargetInfo &STI) const {1947  // Pseudo instructions don't get encoded.1948  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());1949  uint64_t TSFlags = Desc.TSFlags;1950  if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)1951    return;1952 1953  int Size;1954  if (Desc.getSize() == 2 || Desc.getSize() == 4)1955    Size = Desc.getSize();1956  else1957    llvm_unreachable("Unexpected instruction size!");1958 1959  auto Endian =1960      IsLittleEndian ? llvm::endianness::little : llvm::endianness::big;1961  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);1962  if (Size == 2) {1963    support::endian::write<uint16_t>(CB, Binary, Endian);1964  } else if (isThumb(STI)) {1965    // Thumb 32-bit wide instructions need to emit the high order halfword1966    // first.1967    support::endian::write<uint16_t>(CB, Binary >> 16, Endian);1968    support::endian::write<uint16_t>(CB, Binary & 0xffff, Endian);1969  } else {1970    support::endian::write<uint32_t>(CB, Binary, Endian);1971  }1972  ++MCNumEmitted;  // Keep track of the # of mi's emitted.1973}1974 1975template <bool isNeg, ARM::Fixups fixup>1976uint32_t1977ARMMCCodeEmitter::getBFTargetOpValue(const MCInst &MI, unsigned OpIdx,1978                                     SmallVectorImpl<MCFixup> &Fixups,1979                                     const MCSubtargetInfo &STI) const {1980  const MCOperand MO = MI.getOperand(OpIdx);1981  if (MO.isExpr())1982    return ::getBranchTargetOpValue(MI, OpIdx, fixup, Fixups, STI);1983  return isNeg ? -(MO.getImm() >> 1) : (MO.getImm() >> 1);1984}1985 1986uint32_t1987ARMMCCodeEmitter::getBFAfterTargetOpValue(const MCInst &MI, unsigned OpIdx,1988                                          SmallVectorImpl<MCFixup> &Fixups,1989                                          const MCSubtargetInfo &STI) const {1990  const MCOperand MO = MI.getOperand(OpIdx);1991  const MCOperand BranchMO = MI.getOperand(0);1992 1993  if (MO.isExpr()) {1994    assert(BranchMO.isExpr());1995    const MCExpr *DiffExpr = MCBinaryExpr::createSub(1996        MO.getExpr(), BranchMO.getExpr(), CTX);1997    MCFixupKind Kind = ARM::fixup_bfcsel_else_target;1998    addFixup(Fixups, 0, DiffExpr, Kind);1999    return 0;2000  }2001 2002  assert(MO.isImm() && BranchMO.isImm());2003  int Diff = MO.getImm() - BranchMO.getImm();2004  assert(Diff == 4 || Diff == 2);2005 2006  return Diff == 4;2007}2008 2009uint32_t ARMMCCodeEmitter::getVPTMaskOpValue(const MCInst &MI, unsigned OpIdx,2010                                             SmallVectorImpl<MCFixup> &Fixups,2011                                             const MCSubtargetInfo &STI)const {2012  const MCOperand MO = MI.getOperand(OpIdx);2013  assert(MO.isImm() && "Unexpected operand type!");2014 2015  int Value = MO.getImm();2016  int Imm = 0;2017 2018  // VPT Masks are actually encoded as a series of invert/don't invert bits,2019  // rather than true/false bits.2020  unsigned PrevBit = 0;2021  for (int i = 3; i >= 0; --i) {2022    unsigned Bit = (Value >> i) & 1;2023 2024    // Check if we are at the end of the mask.2025    if ((Value & ~(~0U << i)) == 0) {2026      Imm |= (1 << i);2027      break;2028    }2029 2030    // Convert the bit in the mask based on the previous bit.2031    if (Bit != PrevBit)2032      Imm |= (1 << i);2033 2034    PrevBit = Bit;2035  }2036 2037  return Imm;2038}2039 2040uint32_t ARMMCCodeEmitter::getRestrictedCondCodeOpValue(2041    const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,2042    const MCSubtargetInfo &STI) const {2043 2044  const MCOperand MO = MI.getOperand(OpIdx);2045  assert(MO.isImm() && "Unexpected operand type!");2046 2047  switch (MO.getImm()) {2048  default:2049    assert(0 && "Unexpected Condition!");2050    return 0;2051  case ARMCC::HS:2052  case ARMCC::EQ:2053    return 0;2054  case ARMCC::HI:2055  case ARMCC::NE:2056    return 1;2057  case ARMCC::GE:2058    return 4;2059  case ARMCC::LT:2060    return 5;2061  case ARMCC::GT:2062    return 6;2063  case ARMCC::LE:2064    return 7;2065  }2066}2067 2068uint32_t ARMMCCodeEmitter::2069getPowerTwoOpValue(const MCInst &MI, unsigned OpIdx,2070                   SmallVectorImpl<MCFixup> &Fixups,2071                   const MCSubtargetInfo &STI) const {2072  const MCOperand &MO = MI.getOperand(OpIdx);2073  assert(MO.isImm() && "Unexpected operand type!");2074  return llvm::countr_zero((uint64_t)MO.getImm());2075}2076 2077template <unsigned start>2078uint32_t ARMMCCodeEmitter::2079getMVEPairVectorIndexOpValue(const MCInst &MI, unsigned OpIdx,2080                             SmallVectorImpl<MCFixup> &Fixups,2081                             const MCSubtargetInfo &STI) const {2082  const MCOperand MO = MI.getOperand(OpIdx);2083  assert(MO.isImm() && "Unexpected operand type!");2084 2085  int Value = MO.getImm();2086  return Value - start;2087}2088 2089#include "ARMGenMCCodeEmitter.inc"2090 2091MCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII,2092                                              MCContext &Ctx) {2093  return new ARMMCCodeEmitter(MCII, Ctx, true);2094}2095 2096MCCodeEmitter *llvm::createARMBEMCCodeEmitter(const MCInstrInfo &MCII,2097                                              MCContext &Ctx) {2098  return new ARMMCCodeEmitter(MCII, Ctx, false);2099}2100