ARMMCCodeEmitter.cpp revision 204aa64f30911f28c11e05ba2acf475d25c45fa0
16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM code to machine code -------===//
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                     The LLVM Compiler Infrastructure
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This file is distributed under the University of Illinois Open Source
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// License. See LICENSE.TXT for details.
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//===----------------------------------------------------------------------===//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This file implements the ARMMCCodeEmitter class.
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//===----------------------------------------------------------------------===//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DEBUG_TYPE "mccodeemitter"
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "MCTargetDesc/ARMAddressingModes.h"
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "MCTargetDesc/ARMBaseInfo.h"
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "MCTargetDesc/ARMFixupKinds.h"
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "MCTargetDesc/ARMMCExpr.h"
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "MCTargetDesc/ARMMCTargetDesc.h"
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "llvm/MC/MCCodeEmitter.h"
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "llvm/MC/MCExpr.h"
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "llvm/MC/MCInst.h"
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "llvm/MC/MCInstrInfo.h"
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "llvm/MC/MCRegisterInfo.h"
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "llvm/MC/MCSubtargetInfo.h"
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "llvm/ADT/APFloat.h"
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "llvm/ADT/Statistic.h"
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "llvm/Support/raw_ostream.h"
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennusing namespace llvm;
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennSTATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennSTATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennnamespace {
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennclass ARMMCCodeEmitter : public MCCodeEmitter {
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ARMMCCodeEmitter(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  void operator=(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCInstrInfo &MCII;
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCSubtargetInfo &STI;
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennpublic:
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ARMMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   MCContext &ctx)
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    : MCII(mcii), STI(sti) {
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ~ARMMCCodeEmitter() {}
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isThumb() const {
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // FIXME: Can tablegen auto-generate this?
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isThumb2() const {
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isTargetDarwin() const {
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Triple TT(STI.getTargetTriple());
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Triple::OSType OS = TT.getOS();
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return OS == Triple::Darwin || OS == Triple::MacOSX || OS == Triple::IOS;
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getMachineSoImmOpValue(unsigned SoImm) const;
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // getBinaryCodeForInstr - TableGen'erated function for getting the
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // binary encoding for an instruction.
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getBinaryCodeForInstr(const MCInst &MI,
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 SmallVectorImpl<MCFixup> &Fixups) const;
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getMachineOpValue - Return binary encoding of operand. If the machine
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// operand requires relocation, record the relocation and return zero.
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             SmallVectorImpl<MCFixup> &Fixups) const;
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// the specified operand. This is used for operands with :lower16: and
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// :upper16: prefixes.
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               SmallVectorImpl<MCFixup> &Fixups) const;
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              unsigned &Reg, unsigned &Imm,
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              SmallVectorImpl<MCFixup> &Fixups) const;
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// BL branch target.
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   SmallVectorImpl<MCFixup> &Fixups) const;
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// BLX branch target.
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    SmallVectorImpl<MCFixup> &Fixups) const;
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   SmallVectorImpl<MCFixup> &Fixups) const;
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    SmallVectorImpl<MCFixup> &Fixups) const;
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   SmallVectorImpl<MCFixup> &Fixups) const;
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getBranchTargetOpValue - Return encoding info for 24-bit immediate
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// branch target.
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  SmallVectorImpl<MCFixup> &Fixups) const;
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// immediate Thumb2 direct branch target.
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  SmallVectorImpl<MCFixup> &Fixups) const;
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// branch target.
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     SmallVectorImpl<MCFixup> &Fixups) const;
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     SmallVectorImpl<MCFixup> &Fixups) const;
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// ADR label target.
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              SmallVectorImpl<MCFixup> &Fixups) const;
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              SmallVectorImpl<MCFixup> &Fixups) const;
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              SmallVectorImpl<MCFixup> &Fixups) const;
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// operand.
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   SmallVectorImpl<MCFixup> &Fixups) const;
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                         SmallVectorImpl<MCFixup> &Fixups)const;
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// operand.
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   SmallVectorImpl<MCFixup> &Fixups) const;
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2'
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// operand.
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   SmallVectorImpl<MCFixup> &Fixups) const;
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2'
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// operand.
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              SmallVectorImpl<MCFixup> &Fixups) const;
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// operand as needed by load/store instructions.
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               SmallVectorImpl<MCFixup> &Fixups) const;
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getLdStmModeOpValue - Return encoding for load/store multiple mode.
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               SmallVectorImpl<MCFixup> &Fixups) const {
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch (Mode) {
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default: assert(0 && "Unknown addressing sub-mode!");
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::da: return 0;
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::ia: return 1;
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::db: return 2;
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::ib: return 3;
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch (ShOpc) {
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default: llvm_unreachable("Unknown shift opc!");
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::no_shift:
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::lsl: return 0;
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::lsr: return 1;
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::asr: return 2;
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::ror:
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::rrx: return 3;
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return 0;
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getAddrMode2OpValue - Return encoding for addrmode2 operands.
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               SmallVectorImpl<MCFixup> &Fixups) const;
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     SmallVectorImpl<MCFixup> &Fixups) const;
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getPostIdxRegOpValue - Return encoding for postidx_reg operands.
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                SmallVectorImpl<MCFixup> &Fixups) const;
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     SmallVectorImpl<MCFixup> &Fixups) const;
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getAddrMode3OpValue - Return encoding for addrmode3 operands.
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               SmallVectorImpl<MCFixup> &Fixups) const;
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12'
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// operand.
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     SmallVectorImpl<MCFixup> &Fixups) const;
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                SmallVectorImpl<MCFixup> &Fixups) const;
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                SmallVectorImpl<MCFixup> &Fixups) const;
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               SmallVectorImpl<MCFixup> &Fixups) const;
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getCCOutOpValue - Return encoding of the 's' bit.
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           SmallVectorImpl<MCFixup> &Fixups) const {
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // '1' respectively.
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return MI.getOperand(Op).getReg() == ARM::CPSR;
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           SmallVectorImpl<MCFixup> &Fixups) const {
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned SoImm = MI.getOperand(Op).getImm();
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int SoImmVal = ARM_AM::getSOImmVal(SoImm);
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert(SoImmVal != -1 && "Not a valid so_imm value!");
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Encode rotate_imm.
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      << ARMII::SoRotImmShift;
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Encode immed_8.
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Binary;
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           SmallVectorImpl<MCFixup> &Fixups) const {
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned SoImm = MI.getOperand(Op).getImm();
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned Encoded =  ARM_AM::getT2SOImmVal(SoImm);
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Encoded;
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    SmallVectorImpl<MCFixup> &Fixups) const;
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    SmallVectorImpl<MCFixup> &Fixups) const;
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    SmallVectorImpl<MCFixup> &Fixups) const;
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    SmallVectorImpl<MCFixup> &Fixups) const;
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// getSORegOpValue - Return an encoded so_reg shifted register value.
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           SmallVectorImpl<MCFixup> &Fixups) const;
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           SmallVectorImpl<MCFixup> &Fixups) const;
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             SmallVectorImpl<MCFixup> &Fixups) const;
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   SmallVectorImpl<MCFixup> &Fixups) const {
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return 64 - MI.getOperand(Op).getImm();
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      SmallVectorImpl<MCFixup> &Fixups) const;
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  SmallVectorImpl<MCFixup> &Fixups) const;
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      SmallVectorImpl<MCFixup> &Fixups) const;
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        SmallVectorImpl<MCFixup> &Fixups) const;
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        SmallVectorImpl<MCFixup> &Fixups) const;
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     SmallVectorImpl<MCFixup> &Fixups) const;
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op,
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             SmallVectorImpl<MCFixup> &Fixups) const;
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op,
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              SmallVectorImpl<MCFixup> &Fixups) const;
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op,
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              SmallVectorImpl<MCFixup> &Fixups) const;
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op,
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              SmallVectorImpl<MCFixup> &Fixups) const;
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op,
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 SmallVectorImpl<MCFixup> &Fixups) const;
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      unsigned EncodedValue) const;
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                          unsigned EncodedValue) const;
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    unsigned EncodedValue) const;
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned VFPThumb2PostEncoder(const MCInst &MI,
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                unsigned EncodedValue) const;
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  void EmitByte(unsigned char C, raw_ostream &OS) const {
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    OS << (char)C;
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Output the constant in little endian byte order.
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (unsigned i = 0; i != Size; ++i) {
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      EmitByte(Val & 255, OS);
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Val >>= 8;
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         SmallVectorImpl<MCFixup> &Fixups) const;
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // end anonymous namespace
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennMCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII,
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            const MCSubtargetInfo &STI,
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            MCContext &Ctx) {
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return new ARMMCCodeEmitter(MCII, STI, Ctx);
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// instructions, and rewrite them to their Thumb2 form if we are currently in
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// Thumb2 mode.
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 unsigned EncodedValue) const {
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isThumb2()) {
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // set to 1111.
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned Bit24 = EncodedValue & 0x01000000;
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned Bit28 = Bit24 << 4;
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EncodedValue &= 0xEFFFFFFF;
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EncodedValue |= Bit28;
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EncodedValue |= 0x0F000000;
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return EncodedValue;
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// instructions, and rewrite them to their Thumb2 form if we are currently in
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// Thumb2 mode.
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 unsigned EncodedValue) const {
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isThumb2()) {
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EncodedValue &= 0xF0FFFFFF;
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EncodedValue |= 0x09000000;
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return EncodedValue;
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// instructions, and rewrite them to their Thumb2 form if we are currently in
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// Thumb2 mode.
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 unsigned EncodedValue) const {
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isThumb2()) {
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EncodedValue &= 0x00FFFFFF;
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EncodedValue |= 0xEE000000;
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return EncodedValue;
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// them to their Thumb2 form if we are currently in Thumb2 mode.
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennVFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const {
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isThumb2()) {
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EncodedValue &= 0x0FFFFFFF;
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EncodedValue |= 0xE0000000;
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return EncodedValue;
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getMachineOpValue - Return binary encoding of operand. If the machine
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// operand requires relocation, record the relocation and return zero.
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetMachineOpValue(const MCInst &MI, const MCOperand &MO,
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  SmallVectorImpl<MCFixup> &Fixups) const {
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isReg()) {
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned Reg = MO.getReg();
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned RegNo = getARMRegisterNumbering(Reg);
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Q registers are encoded as 2x their register number.
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch (Reg) {
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default:
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      return RegNo;
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM::Q0:  case ARM::Q1:  case ARM::Q2:  case ARM::Q3:
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM::Q4:  case ARM::Q5:  case ARM::Q6:  case ARM::Q7:
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM::Q8:  case ARM::Q9:  case ARM::Q10: case ARM::Q11:
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      return 2 * RegNo;
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  } else if (MO.isImm()) {
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return static_cast<unsigned>(MO.getImm());
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  } else if (MO.isFPImm()) {
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return static_cast<unsigned>(APFloat(MO.getFPImm())
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     .bitcastToAPInt().getHiBits(32).getLimitedValue());
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  llvm_unreachable("Unable to encode MCOperand!");
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return 0;
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool ARMMCCodeEmitter::
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const {
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO  = MI.getOperand(OpIdx);
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Reg = getARMRegisterNumbering(MO.getReg());
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  int32_t SImm = MO1.getImm();
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isAdd = true;
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Special value for #-0
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (SImm == INT32_MIN) {
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    SImm = 0;
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    isAdd = false;
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (SImm < 0) {
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    SImm = -SImm;
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    isAdd = false;
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Imm = SImm;
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return isAdd;
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getBranchTargetOpValue - Helper function to get the branch target operand,
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// which is either an immediate or requires a fixup.
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       unsigned FixupKind,
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       SmallVectorImpl<MCFixup> &Fixups) {
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // If the destination is an immediate, we have nothing to do.
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isImm()) return MO.getImm();
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  assert(MO.isExpr() && "Unexpected branch target type!");
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCExpr *Expr = MO.getExpr();
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  MCFixupKind Kind = MCFixupKind(FixupKind);
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Fixups.push_back(MCFixup::Create(0, Expr, Kind));
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // All of the information is in the fixup.
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return 0;
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// determined by negating them and XOR'ing them with bit 23.
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int32_t encodeThumbBLOffset(int32_t offset) {
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  offset >>= 1;
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t S  = (offset & 0x800000) >> 23;
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t J1 = (offset & 0x400000) >> 22;
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t J2 = (offset & 0x200000) >> 21;
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  J1 = (~J1 & 0x1);
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  J2 = (~J2 & 0x1);
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  J1 ^= S;
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  J2 ^= S;
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  offset &= ~0x600000;
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  offset |= J1 << 22;
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  offset |= J2 << 21;
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return offset;
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getThumbBLTargetOpValue - Return encoding info for immediate branch target.
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        SmallVectorImpl<MCFixup> &Fixups) const {
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr())
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl,
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    Fixups);
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return encodeThumbBLOffset(MO.getImm());
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// BLX branch target.
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         SmallVectorImpl<MCFixup> &Fixups) const {
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr())
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx,
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    Fixups);
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return encodeThumbBLOffset(MO.getImm());
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        SmallVectorImpl<MCFixup> &Fixups) const {
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr())
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br,
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    Fixups);
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return (MO.getImm() >> 1);
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         SmallVectorImpl<MCFixup> &Fixups) const {
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr())
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc,
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    Fixups);
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return (MO.getImm() >> 1);
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        SmallVectorImpl<MCFixup> &Fixups) const {
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr())
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups);
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return (MO.getImm() >> 1);
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// Return true if this branch has a non-always predication
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic bool HasConditionalBranch(const MCInst &MI) {
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  int NumOp = MI.getNumOperands();
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (NumOp >= 2) {
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (int i = 0; i < NumOp-1; ++i) {
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      const MCOperand &MCOp1 = MI.getOperand(i);
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      const MCOperand &MCOp2 = MI.getOperand(i + 1);
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      if (MCOp1.isImm() && MCOp2.isReg() &&
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn          (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) {
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL)
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn          return true;
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      }
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return false;
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// target.
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       SmallVectorImpl<MCFixup> &Fixups) const {
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // FIXME: This really, really shouldn't use TargetMachine. We don't want
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // coupling between MC and TM anywhere we can help it.
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isThumb2())
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups);
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return getARMBranchTargetOpValue(MI, OpIdx, Fixups);
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// target.
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          SmallVectorImpl<MCFixup> &Fixups) const {
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr()) {
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (HasConditionalBranch(MI))
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      return ::getBranchTargetOpValue(MI, OpIdx,
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      ARM::fixup_arm_condbranch, Fixups);
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx,
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    ARM::fixup_arm_uncondbranch, Fixups);
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return MO.getImm() >> 2;
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          SmallVectorImpl<MCFixup> &Fixups) const {
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr()) {
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (HasConditionalBranch(MI))
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      return ::getBranchTargetOpValue(MI, OpIdx,
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      ARM::fixup_arm_condbranch, Fixups);
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx,
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    ARM::fixup_arm_uncondbranch, Fixups);
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return MO.getImm() >> 1;
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// immediate branch target.
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       SmallVectorImpl<MCFixup> &Fixups) const {
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Val =
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups);
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool I  = (Val & 0x800000);
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool J1 = (Val & 0x400000);
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool J2 = (Val & 0x200000);
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (I ^ J1)
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Val &= ~0x400000;
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  else
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Val |= 0x400000;
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (I ^ J2)
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Val &= ~0x200000;
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  else
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Val |= 0x200000;
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Val;
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// target.
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   SmallVectorImpl<MCFixup> &Fixups) const {
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr())
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12,
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    Fixups);
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  int32_t offset = MO.getImm();
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Val = 0x2000;
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (offset < 0) {
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Val = 0x1000;
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    offset *= -1;
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Val |= offset;
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Val;
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// target.
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   SmallVectorImpl<MCFixup> &Fixups) const {
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr())
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    Fixups);
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  int32_t Val = MO.getImm();
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (Val < 0) {
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Val *= -1;
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Val |= 0x1000;
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Val;
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// target.
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   SmallVectorImpl<MCFixup> &Fixups) const {
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr())
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10,
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    Fixups);
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return MO.getImm();
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg'
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// operand.
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              SmallVectorImpl<MCFixup> &) const {
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // [Rn, Rm]
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //   {5-3} = Rm
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //   {2-0} = Rn
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx);
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO2 = MI.getOperand(OpIdx + 1);
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Rn = getARMRegisterNumbering(MO1.getReg());
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Rm = getARMRegisterNumbering(MO2.getReg());
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return (Rm << 3) | Rn;
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        SmallVectorImpl<MCFixup> &Fixups) const {
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {17-13} = reg
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {12}    = (U)nsigned (add == '1', sub == '0')
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {11-0}  = imm12
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Reg, Imm12;
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isAdd = true;
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // If The first operand isn't a register, we have a label reference.
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (!MO.isReg()) {
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Imm12 = 0;
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    isAdd = false ; // 'U' bit is set as part of the fixup.
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (MO.isExpr()) {
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      const MCExpr *Expr = MO.getExpr();
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      MCFixupKind Kind;
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      if (isThumb2())
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      else
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Fixups.push_back(MCFixup::Create(0, Expr, Kind));
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      ++MCNumCPRelocations;
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    } else {
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Reg = ARM::PC;
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      int32_t Offset = MO.getImm();
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      if (Offset < 0) {
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Offset *= -1;
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        isAdd = false;
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      }
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Imm12 = Offset;
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  } else
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups);
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Binary = Imm12 & 0xfff;
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isAdd)
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary |= (1 << 12);
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Binary |= (Reg << 13);
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary;
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getT2Imm8s4OpValue - Return encoding info for
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// '+/- imm8<<2' operand.
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   SmallVectorImpl<MCFixup> &Fixups) const {
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // FIXME: The immediate operand should have already been encoded like this
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // before ever getting here. The encoder method should just need to combine
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // the MI operands for the register and the offset into a single
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // representation for the complex operand in the .td file. This isn't just
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // style, unfortunately. As-is, we can't represent the distinct encoding
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // for #-0.
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {8}    = (U)nsigned (add == '1', sub == '0')
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {7-0}  = imm8
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  int32_t Imm8 = MI.getOperand(OpIdx).getImm();
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isAdd = Imm8 >= 0;
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (Imm8 < 0)
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Imm8 = -Imm8;
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Scaled by 4.
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Imm8 /= 4;
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Binary = Imm8 & 0xff;
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isAdd)
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary |= (1 << 8);
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary;
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getT2AddrModeImm8s4OpValue - Return encoding info for
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// 'reg +/- imm8<<2' operand.
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        SmallVectorImpl<MCFixup> &Fixups) const {
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {12-9} = reg
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {8}    = (U)nsigned (add == '1', sub == '0')
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {7-0}  = imm8
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Reg, Imm8;
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isAdd = true;
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // If The first operand isn't a register, we have a label reference.
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (!MO.isReg()) {
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Imm8 = 0;
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    isAdd = false ; // 'U' bit is set as part of the fixup.
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert(MO.isExpr() && "Unexpected machine operand type!");
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const MCExpr *Expr = MO.getExpr();
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Fixups.push_back(MCFixup::Create(0, Expr, Kind));
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ++MCNumCPRelocations;
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  } else
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // FIXME: The immediate operand should have already been encoded like this
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // before ever getting here. The encoder method should just need to combine
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // the MI operands for the register and the offset into a single
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // representation for the complex operand in the .td file. This isn't just
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // style, unfortunately. As-is, we can't represent the distinct encoding
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // for #-0.
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Binary = (Imm8 >> 2) & 0xff;
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isAdd)
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary |= (1 << 8);
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Binary |= (Reg << 9);
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary;
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getT2AddrModeImm0_1020s4OpValue - Return encoding info for
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// 'reg + imm8<<2' operand.
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        SmallVectorImpl<MCFixup> &Fixups) const {
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {11-8} = reg
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {7-0}  = imm8
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Reg = getARMRegisterNumbering(MO.getReg());
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Imm8 = MO1.getImm();
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return (Reg << 8) | Imm8;
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// FIXME: This routine assumes that a binary
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// expression will always result in a PCRel expression
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In reality, its only true if one or more subexpressions
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// is itself a PCRel (i.e. "." in asm or some other pcrel construct)
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// but this is good enough for now.
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic bool EvaluateAsPCRel(const MCExpr *Expr) {
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  switch (Expr->getKind()) {
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  default: assert(0 && "Unexpected expression type");
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case MCExpr::SymbolRef: return false;
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case MCExpr::Binary: return true;
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      SmallVectorImpl<MCFixup> &Fixups) const {
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {20-16} = imm{15-12}
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {11-0}  = imm{11-0}
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isImm())
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Hi / lo 16 bits already extracted during earlier passes.
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return static_cast<unsigned>(MO.getImm());
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Handle :upper16: and :lower16: assembly prefixes.
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCExpr *E = MO.getExpr();
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (E->getKind() == MCExpr::Target) {
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E);
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    E = ARM16Expr->getSubExpr();
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    MCFixupKind Kind;
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch (ARM16Expr->getKind()) {
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default: assert(0 && "Unsupported ARMFixup");
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARMMCExpr::VK_ARM_HI16:
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      if (!isTargetDarwin() && EvaluateAsPCRel(E))
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Kind = MCFixupKind(isThumb2()
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           ? ARM::fixup_t2_movt_hi16_pcrel
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           : ARM::fixup_arm_movt_hi16_pcrel);
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      else
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Kind = MCFixupKind(isThumb2()
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           ? ARM::fixup_t2_movt_hi16
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           : ARM::fixup_arm_movt_hi16);
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      break;
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARMMCExpr::VK_ARM_LO16:
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      if (!isTargetDarwin() && EvaluateAsPCRel(E))
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Kind = MCFixupKind(isThumb2()
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           ? ARM::fixup_t2_movw_lo16_pcrel
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           : ARM::fixup_arm_movw_lo16_pcrel);
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      else
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Kind = MCFixupKind(isThumb2()
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           ? ARM::fixup_t2_movw_lo16
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           : ARM::fixup_arm_movw_lo16);
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      break;
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Fixups.push_back(MCFixup::Create(0, E, Kind));
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return 0;
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  };
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  llvm_unreachable("Unsupported MCExpr type in MCOperand!");
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return 0;
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    SmallVectorImpl<MCFixup> &Fixups) const {
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Rn = getARMRegisterNumbering(MO.getReg());
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Rm = getARMRegisterNumbering(MO1.getReg());
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned SBits = getShiftOp(ShOp);
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {16-13} = Rn
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {12}    = isAdd
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {11-0}  = shifter
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //  {3-0}  = Rm
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //  {4}    = 0
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //  {6-5}  = type
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //  {11-7} = imm
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Binary = Rm;
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Binary |= Rn << 13;
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Binary |= SBits << 5;
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Binary |= ShImm << 7;
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isAdd)
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary |= 1 << 12;
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary;
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    SmallVectorImpl<MCFixup> &Fixups) const {
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {17-14}  Rn
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {13}     1 == imm12, 0 == Rm
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {12}     isAdd
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {11-0}   imm12/Rm
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Rn = getARMRegisterNumbering(MO.getReg());
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups);
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Binary |= Rn << 14;
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary;
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          SmallVectorImpl<MCFixup> &Fixups) const {
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {13}     1 == imm12, 0 == Rm
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {12}     isAdd
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {11-0}   imm12/Rm
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Imm = MO1.getImm();
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isReg = MO.getReg() != 0;
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Binary = ARM_AM::getAM2Offset(Imm);
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isReg) {
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary <<= 7;                    // Shift amount is bits [11:7]
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary |= getARMRegisterNumbering(MO.getReg()); // Rm is bits [3:0]
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary | (isAdd << 12) | (isReg << 13);
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     SmallVectorImpl<MCFixup> &Fixups) const {
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {4}      isAdd
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {3-0}    Rm
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isAdd = MO1.getImm() != 0;
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return getARMRegisterNumbering(MO.getReg()) | (isAdd << 4);
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          SmallVectorImpl<MCFixup> &Fixups) const {
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {9}      1 == imm8, 0 == Rm
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {8}      isAdd
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {7-4}    imm7_4/zero
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {3-0}    imm3_0/Rm
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Imm = MO1.getImm();
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isImm = MO.getReg() == 0;
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (!isImm)
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Imm8 = getARMRegisterNumbering(MO.getReg());
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Imm8 | (isAdd << 8) | (isImm << 9);
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    SmallVectorImpl<MCFixup> &Fixups) const {
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {13}     1 == imm8, 0 == Rm
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {12-9}   Rn
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {8}      isAdd
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {7-4}    imm7_4/zero
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {3-0}    imm3_0/Rm
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Rn = getARMRegisterNumbering(MO.getReg());
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Imm = MO2.getImm();
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isImm = MO1.getReg() == 0;
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (!isImm)
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Imm8 = getARMRegisterNumbering(MO1.getReg());
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands.
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          SmallVectorImpl<MCFixup> &Fixups) const {
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // [SP, #imm]
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //   {7-0} = imm8
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  assert(MI.getOperand(OpIdx).getReg() == ARM::SP &&
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn         "Unexpected base register!");
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // The immediate is already shifted for the implicit zeroes, so no change
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // here.
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return MO1.getImm() & 0xff;
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     SmallVectorImpl<MCFixup> &Fixups) const {
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // [Rn, #imm]
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //   {7-3} = imm5
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //   {2-0} = Rn
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Rn = getARMRegisterNumbering(MO.getReg());
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Imm5 = MO1.getImm();
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return ((Imm5 & 0x1f) << 3) | Rn;
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     SmallVectorImpl<MCFixup> &Fixups) const {
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand MO = MI.getOperand(OpIdx);
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.isExpr())
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups);
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return (MO.getImm() >> 2);
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand.
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennuint32_t ARMMCCodeEmitter::
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    SmallVectorImpl<MCFixup> &Fixups) const {
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {12-9} = reg
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {8}    = (U)nsigned (add == '1', sub == '0')
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {7-0}  = imm8
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Reg, Imm8;
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isAdd;
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // If The first operand isn't a register, we have a label reference.
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(OpIdx);
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (!MO.isReg()) {
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Imm8 = 0;
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    isAdd = false; // 'U' bit is handled as part of the fixup.
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert(MO.isExpr() && "Unexpected machine operand type!");
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const MCExpr *Expr = MO.getExpr();
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    MCFixupKind Kind;
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (isThumb2())
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Fixups.push_back(MCFixup::Create(0, Expr, Kind));
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ++MCNumCPRelocations;
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  } else {
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isAdd)
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary |= (1 << 8);
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Binary |= (Reg << 9);
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary;
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                SmallVectorImpl<MCFixup> &Fixups) const {
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // shifted. The second is Rs, the amount to shift by, and the third specifies
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // the type of the shift.
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {3-0} = Rm.
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {4}   = 1
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {6-5} = type
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {11-8} = Rs
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {7}    = 0
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO  = MI.getOperand(OpIdx);
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encode Rm.
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Binary = getARMRegisterNumbering(MO.getReg());
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encode the shift opcode.
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned SBits = 0;
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Rs = MO1.getReg();
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (Rs) {
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // Set shift operand (bit[7:4]).
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // LSL - 0001
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // LSR - 0011
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // ASR - 0101
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // ROR - 0111
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch (SOpc) {
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default: llvm_unreachable("Unknown shift opc!");
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::lsl: SBits = 0x1; break;
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::lsr: SBits = 0x3; break;
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::asr: SBits = 0x5; break;
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case ARM_AM::ror: SBits = 0x7; break;
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Binary |= SBits << 4;
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encode the shift operation Rs.
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encode Rs bit[11:8].
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                SmallVectorImpl<MCFixup> &Fixups) const {
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // shifted. The second is the amount to shift by.
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {3-0} = Rm.
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {4}   = 0
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {6-5} = type
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {11-7} = imm
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO  = MI.getOperand(OpIdx);
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encode Rm.
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Binary = getARMRegisterNumbering(MO.getReg());
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encode the shift opcode.
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned SBits = 0;
11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Set shift operand (bit[6:4]).
11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // LSL - 000
11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // LSR - 010
11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // ASR - 100
11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // ROR - 110
11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // RRX - 110 and bit[11:8] clear.
11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  switch (SOpc) {
11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  default: llvm_unreachable("Unknown shift opc!");
11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case ARM_AM::lsl: SBits = 0x0; break;
11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case ARM_AM::lsr: SBits = 0x2; break;
11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case ARM_AM::asr: SBits = 0x4; break;
11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case ARM_AM::ror: SBits = 0x6; break;
11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case ARM_AM::rrx:
11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary |= 0x60;
11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Binary;
11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encode shift_imm bit[11:7].
11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Binary |= SBits << 4;
11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm());
11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  assert(Offset && "Offset must be in range 1-32!");
11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (Offset == 32) Offset = 0;
11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary | (Offset << 7);
11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                SmallVectorImpl<MCFixup> &Fixups) const {
11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpNum);
11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO2 = MI.getOperand(OpNum+1);
11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO3 = MI.getOperand(OpNum+2);
11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encoded as [Rn, Rm, imm].
11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // FIXME: Needs fixup support.
11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Value = getARMRegisterNumbering(MO1.getReg());
11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Value <<= 4;
11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Value |= getARMRegisterNumbering(MO2.getReg());
11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Value <<= 2;
11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Value |= MO3.getImm();
11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Value;
11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         SmallVectorImpl<MCFixup> &Fixups) const {
12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpNum);
12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO2 = MI.getOperand(OpNum+1);
12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // FIXME: Needs fixup support.
12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Value = getARMRegisterNumbering(MO1.getReg());
12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Even though the immediate is 8 bits long, we need 9 bits in order
12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // to represent the (inverse of the) sign bit.
12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Value <<= 9;
12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  int32_t tmp = (int32_t)MO2.getImm();
12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (tmp < 0)
12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tmp = abs(tmp);
12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  else
12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Value |= 256; // Set the ADD bit
12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Value |= tmp & 255;
12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Value;
12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         SmallVectorImpl<MCFixup> &Fixups) const {
12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpNum);
12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // FIXME: Needs fixup support.
12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Value = 0;
12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  int32_t tmp = (int32_t)MO1.getImm();
12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (tmp < 0)
12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tmp = abs(tmp);
12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  else
12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Value |= 256; // Set the ADD bit
12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Value |= tmp & 255;
12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Value;
12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         SmallVectorImpl<MCFixup> &Fixups) const {
12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpNum);
12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // FIXME: Needs fixup support.
12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Value = 0;
12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  int32_t tmp = (int32_t)MO1.getImm();
12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (tmp < 0)
12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tmp = abs(tmp);
12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  else
12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Value |= 4096; // Set the ADD bit
12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Value |= tmp & 4095;
12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Value;
12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                SmallVectorImpl<MCFixup> &Fixups) const {
12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // shifted. The second is the amount to shift by.
12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //
12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {3-0} = Rm.
12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {4}   = 0
12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {6-5} = type
12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // {11-7} = imm
12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO  = MI.getOperand(OpIdx);
12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encode Rm.
12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Binary = getARMRegisterNumbering(MO.getReg());
12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encode the shift opcode.
12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned SBits = 0;
12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Set shift operand (bit[6:4]).
12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // LSL - 000
12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // LSR - 010
12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // ASR - 100
12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // ROR - 110
12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  switch (SOpc) {
12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  default: llvm_unreachable("Unknown shift opc!");
12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case ARM_AM::lsl: SBits = 0x0; break;
12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case ARM_AM::lsr: SBits = 0x2; break;
12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case ARM_AM::asr: SBits = 0x4; break;
12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case ARM_AM::rrx: // FALLTHROUGH
12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case ARM_AM::ror: SBits = 0x6; break;
12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  Binary |= SBits << 4;
12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (SOpc == ARM_AM::rrx)
12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Binary;
12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Encode shift_imm bit[11:7].
12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               SmallVectorImpl<MCFixup> &Fixups) const {
12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // msb of the mask.
12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(Op);
12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t v = ~MO.getImm();
12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t lsb = CountTrailingZeros_32(v);
13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1;
13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return lsb | (msb << 5);
13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetRegisterListOpValue(const MCInst &MI, unsigned Op,
13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       SmallVectorImpl<MCFixup> &Fixups) const {
13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // VLDM/VSTM:
13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //   {12-8} = Vd
13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //   {7-0}  = Number of registers
13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //
13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // LDM/STM:
13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  //   {15-0}  = Bitfield of GPRs.
13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Reg = MI.getOperand(Op).getReg();
13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool SPRRegs = llvm::ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg);
13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool DPRRegs = llvm::ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg);
13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Binary = 0;
13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (SPRRegs || DPRRegs) {
13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // VLDM/VSTM
13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned RegNo = getARMRegisterNumbering(Reg);
13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;
13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Binary |= (RegNo & 0x1f) << 8;
13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (SPRRegs)
13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Binary |= NumRegs;
13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Binary |= NumRegs * 2;
13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  } else {
13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {
13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      unsigned RegNo = getARMRegisterNumbering(MI.getOperand(I).getReg());
13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Binary |= 1 << RegNo;
13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return Binary;
13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along
13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// with the alignment operand.
13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           SmallVectorImpl<MCFixup> &Fixups) const {
13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &Reg = MI.getOperand(Op);
13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &Imm = MI.getOperand(Op + 1);
13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Align = 0;
13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  switch (Imm.getImm()) {
13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  default: break;
13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 2:
13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 4:
13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 8:  Align = 0x01; break;
13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 16: Align = 0x02; break;
13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 32: Align = 0x03; break;
13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return RegNo | (Align << 4);
13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number
13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// along  with the alignment operand for use in VST1 and VLD1 with size 32.
13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    SmallVectorImpl<MCFixup> &Fixups) const {
13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &Reg = MI.getOperand(Op);
13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &Imm = MI.getOperand(Op + 1);
13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Align = 0;
13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  switch (Imm.getImm()) {
13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  default: break;
13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 2:
13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 4:
13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 8:
13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 16: Align = 0x00; break;
13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 32: Align = 0x03; break;
13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return RegNo | (Align << 4);
13836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and
13876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// alignment operand for use in VLD-dup instructions.  This is the same as
13886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// getAddrMode6AddressOpValue except for the alignment encoding, which is
13896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// different for VLD4-dup.
13906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
13916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
13926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              SmallVectorImpl<MCFixup> &Fixups) const {
13936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &Reg = MI.getOperand(Op);
13946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &Imm = MI.getOperand(Op + 1);
13956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
13976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned Align = 0;
13986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  switch (Imm.getImm()) {
14006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  default: break;
14016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 2:
14026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 4:
14036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 8:  Align = 0x01; break;
14046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  case 16: Align = 0x03; break;
14056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
14066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return RegNo | (Align << 4);
14086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
14116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
14126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          SmallVectorImpl<MCFixup> &Fixups) const {
14136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCOperand &MO = MI.getOperand(Op);
14146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (MO.getReg() == 0) return 0x0D;
14156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return getARMRegisterNumbering(MO.getReg());
14166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
14196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetShiftRight8Imm(const MCInst &MI, unsigned Op,
14206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  SmallVectorImpl<MCFixup> &Fixups) const {
14216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return 8 - MI.getOperand(Op).getImm();
14226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
14256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetShiftRight16Imm(const MCInst &MI, unsigned Op,
14266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   SmallVectorImpl<MCFixup> &Fixups) const {
14276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return 16 - MI.getOperand(Op).getImm();
14286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
14316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetShiftRight32Imm(const MCInst &MI, unsigned Op,
14326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   SmallVectorImpl<MCFixup> &Fixups) const {
14336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return 32 - MI.getOperand(Op).getImm();
14346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennunsigned ARMMCCodeEmitter::
14376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenngetShiftRight64Imm(const MCInst &MI, unsigned Op,
14386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   SmallVectorImpl<MCFixup> &Fixups) const {
14396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  return 64 - MI.getOperand(Op).getImm();
14406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid ARMMCCodeEmitter::
14436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennEncodeInstruction(const MCInst &MI, raw_ostream &OS,
14446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                  SmallVectorImpl<MCFixup> &Fixups) const {
14456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Pseudo instructions don't get encoded.
14466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
14476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint64_t TSFlags = Desc.TSFlags;
14486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)
14496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return;
14506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  int Size;
14526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (Desc.getSize() == 2 || Desc.getSize() == 4)
14536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Size = Desc.getSize();
14546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  else
14556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    llvm_unreachable("Unexpected instruction size!");
14566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
14586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // Thumb 32-bit wide instructions need to emit the high order halfword
14596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  // first.
14606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  if (isThumb() && Size == 4) {
14616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EmitConstant(Binary >> 16, 2, OS);
14626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EmitConstant(Binary & 0xffff, 2, OS);
14636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  } else
14646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    EmitConstant(Binary, Size, OS);
14656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ++MCNumEmitted;  // Keep track of the # of mi's emitted.
14666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "ARMGenMCCodeEmitter.inc"
14696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn