1568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM code to machine code -------===//
2568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//
3568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//                     The LLVM Compiler Infrastructure
4568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//
5568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// This file is distributed under the University of Illinois Open Source
6568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// License. See LICENSE.TXT for details.
7568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//
8568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//===----------------------------------------------------------------------===//
9568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//
10568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach// This file implements the ARMMCCodeEmitter class.
11568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//
12568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach//===----------------------------------------------------------------------===//
13568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
142ac190238e88b21e716e2853900b5076c9013410Chris Lattner#define DEBUG_TYPE "mccodeemitter"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/ARMMCTargetDesc.h"
16ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
17be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMBaseInfo.h"
18be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMFixupKinds.h"
19ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/APFloat.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h"
22568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCCodeEmitter.h"
23df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher#include "llvm/MC/MCContext.h"
24568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCExpr.h"
25568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCInst.h"
2659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCInstrInfo.h"
27be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/MC/MCRegisterInfo.h"
2859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
29568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/Support/raw_ostream.h"
3059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng
31568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachusing namespace llvm;
32568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
3370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
3470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");
35d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach
36568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachnamespace {
37568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachclass ARMMCCodeEmitter : public MCCodeEmitter {
3886a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  ARMMCCodeEmitter(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION;
3986a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper  void operator=(const ARMMCCodeEmitter &) LLVM_DELETED_FUNCTION;
4059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  const MCInstrInfo &MCII;
4159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  const MCSubtargetInfo &STI;
42df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  const MCContext &CTX;
43568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
44568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachpublic:
4559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  ARMMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
4659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                   MCContext &ctx)
47df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    : MCII(mcii), STI(sti), CTX(ctx) {
48568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
49568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
50568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  ~ARMMCCodeEmitter() {}
51568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
5259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  bool isThumb() const {
5359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    // FIXME: Can tablegen auto-generate this?
5459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
5559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  }
5659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  bool isThumb2() const {
5759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
5859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  }
5959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  bool isTargetDarwin() const {
6059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    Triple TT(STI.getTargetTriple());
6159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    Triple::OSType OS = TT.getOS();
6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    return OS == Triple::Darwin || OS == Triple::MacOSX || OS == Triple::IOS;
6359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  }
6459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng
650de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach  unsigned getMachineSoImmOpValue(unsigned SoImm) const;
660de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach
679af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  // getBinaryCodeForInstr - TableGen'erated function for getting the
689af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  // binary encoding for an instruction.
694f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson  uint64_t getBinaryCodeForInstr(const MCInst &MI,
70806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                 SmallVectorImpl<MCFixup> &Fixups) const;
719af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
729af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  /// getMachineOpValue - Return binary encoding of operand. If the machine
739af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  /// operand requires relocation, record the relocation and return zero.
74806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
75806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                             SmallVectorImpl<MCFixup> &Fixups) const;
769af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
777597212abced110723f2fee985a7d60557c092ecEvan Cheng  /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of
78971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson  /// the specified operand. This is used for operands with :lower16: and
797597212abced110723f2fee985a7d60557c092ecEvan Cheng  /// :upper16: prefixes.
807597212abced110723f2fee985a7d60557c092ecEvan Cheng  uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
817597212abced110723f2fee985a7d60557c092ecEvan Cheng                               SmallVectorImpl<MCFixup> &Fixups) const;
82837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim
8392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
84806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                              unsigned &Reg, unsigned &Imm,
85806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
8692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
87662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate
8809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  /// BL branch target.
89662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
90662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const;
91662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
9209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
9309aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  /// BLX branch target.
9409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
9509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling                                    SmallVectorImpl<MCFixup> &Fixups) const;
9609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling
97e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach  /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
98e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach  uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
99e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const;
100e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach
10101086451393ef33e82b6fad623989dd97dd70edfJim Grosbach  /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
10201086451393ef33e82b6fad623989dd97dd70edfJim Grosbach  uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
10301086451393ef33e82b6fad623989dd97dd70edfJim Grosbach                                    SmallVectorImpl<MCFixup> &Fixups) const;
10401086451393ef33e82b6fad623989dd97dd70edfJim Grosbach
105027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach  /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
106027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach  uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
107dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                                   SmallVectorImpl<MCFixup> &Fixups) const;
108dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling
109c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach  /// getBranchTargetOpValue - Return encoding info for 24-bit immediate
110c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach  /// branch target.
111c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach  uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
112c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach                                  SmallVectorImpl<MCFixup> &Fixups) const;
113c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
114c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
115c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  /// immediate Thumb2 direct branch target.
116c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
117c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson                                  SmallVectorImpl<MCFixup> &Fixups) const;
11810096dbdef22a10a6a4444437c935ab428545525Owen Anderson
119685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate
120685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  /// branch target.
121685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
122685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim                                     SmallVectorImpl<MCFixup> &Fixups) const;
1237b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach  uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
1247b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach                                 SmallVectorImpl<MCFixup> &Fixups) const;
125f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
1267b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach                                  SmallVectorImpl<MCFixup> &Fixups) const;
127c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson
1285d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
1295d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  /// ADR label target.
1305d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
1315d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
132d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
133d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
134a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson  uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
135a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson                              SmallVectorImpl<MCFixup> &Fixups) const;
136971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
1375d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach
13892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
13992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// operand.
140806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
141806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const;
14292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
143f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.
144f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
145f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling                                         SmallVectorImpl<MCFixup> &Fixups)const;
1460f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson
1479d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
1489d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  /// operand.
1499d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
1509d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson                                   SmallVectorImpl<MCFixup> &Fixups) const;
151b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
152b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2'
153b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  /// operand.
154b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
155b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const;
156b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
157a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2'
158a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  /// operand.
159a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
160a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
1619d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
1629d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
16354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
16454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  /// operand as needed by load/store instructions.
16554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
16654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
16754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
1685d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  /// getLdStmModeOpValue - Return encoding for load/store multiple mode.
1695d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,
1705d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const {
1715d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();
1725d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    switch (Mode) {
173bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Unknown addressing sub-mode!");
1745d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::da: return 0;
1755d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::ia: return 1;
1765d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::db: return 2;
1775d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::ib: return 3;
1785d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    }
1795d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  }
18099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
18199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  ///
18299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {
18399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    switch (ShOpc) {
18499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::no_shift:
18599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::lsl: return 0;
18699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::lsr: return 1;
18799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::asr: return 2;
18899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::ror:
18999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::rrx: return 3;
19099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    }
1914d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    llvm_unreachable("Invalid ShiftOpc!");
19299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  }
19399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
19499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getAddrMode2OpValue - Return encoding for addrmode2 operands.
19599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
19699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
19799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
19899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
19999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
20099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
20199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
2027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  /// getPostIdxRegOpValue - Return encoding for postidx_reg operands.
2037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
2047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                SmallVectorImpl<MCFixup> &Fixups) const;
2057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2067eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
2077eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
2087eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
2097eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach
210570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  /// getAddrMode3OpValue - Return encoding for addrmode3 operands.
211570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
212570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
2135d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach
214d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12'
215d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  /// operand.
216d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
217d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
218d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach
219f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
220f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
22122447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling                                SmallVectorImpl<MCFixup> &Fixups) const;
2221fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling
223b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
224b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
225b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling                                SmallVectorImpl<MCFixup> &Fixups) const;
226b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling
22792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
228806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
229806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
2303e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach
23108bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach  /// getCCOutOpValue - Return encoding of the 's' bit.
232806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
233806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
23408bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
23508bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    // '1' respectively.
23608bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    return MI.getOperand(Op).getReg() == ARM::CPSR;
23708bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach  }
238ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
2392a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach  /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
240806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
241806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
2422a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    unsigned SoImm = MI.getOperand(Op).getImm();
2432a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    int SoImmVal = ARM_AM::getSOImmVal(SoImm);
2442a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    assert(SoImmVal != -1 && "Not a valid so_imm value!");
2452a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach
2462a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    // Encode rotate_imm.
2472a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
2482a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach      << ARMII::SoRotImmShift;
2492a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach
2502a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    // Encode immed_8.
2512a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
2522a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    return Binary;
2532a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach  }
2547bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
2555de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
2565de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
2575de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson                           SmallVectorImpl<MCFixup> &Fixups) const {
2585de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    unsigned SoImm = MI.getOperand(Op).getImm();
2595de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    unsigned Encoded =  ARM_AM::getT2SOImmVal(SoImm);
2605de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
2615de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    return Encoded;
2625de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  }
26308bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach
26475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
26575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
26675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
26775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
2686af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
2696af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
2700e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
2710e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
27275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
273ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  /// getSORegOpValue - Return an encoded so_reg shifted register value.
274152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,
275152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson                           SmallVectorImpl<MCFixup> &Fixups) const;
276152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,
277806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const;
2785de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
2795de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson                             SmallVectorImpl<MCFixup> &Fixups) const;
280ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
281806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
282806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const {
283498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson    return 64 - MI.getOperand(Op).getImm();
284498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson  }
2858abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach
286806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
287806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                      SmallVectorImpl<MCFixup> &Fixups) const;
2883fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach
289806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
290806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                  SmallVectorImpl<MCFixup> &Fixups) const;
291806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
292806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                      SmallVectorImpl<MCFixup> &Fixups) const;
293183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
294183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang                                        SmallVectorImpl<MCFixup> &Fixups) const;
2958e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
2968e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson                                        SmallVectorImpl<MCFixup> &Fixups) const;
297806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
298806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
2996b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach
3003116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op,
3013116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                             SmallVectorImpl<MCFixup> &Fixups) const;
3023116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op,
3033116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                              SmallVectorImpl<MCFixup> &Fixups) const;
3043116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op,
3053116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                              SmallVectorImpl<MCFixup> &Fixups) const;
3063116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op,
3073116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                              SmallVectorImpl<MCFixup> &Fixups) const;
308a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
3096d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson  unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op,
3106d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson                                 SmallVectorImpl<MCFixup> &Fixups) const;
3116d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson
312c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
313c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson                                      unsigned EncodedValue) const;
31457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,
315cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling                                          unsigned EncodedValue) const;
3168f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
317cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling                                    unsigned EncodedValue) const;
31819c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  unsigned NEONThumb2V8PostEncoder(const MCInst &MI,
31919c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly                                   unsigned EncodedValue) const;
320cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling
321cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  unsigned VFPThumb2PostEncoder(const MCInst &MI,
322cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling                                unsigned EncodedValue) const;
323c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson
32470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  void EmitByte(unsigned char C, raw_ostream &OS) const {
325568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    OS << (char)C;
326568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
327568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
32870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
329568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    // Output the constant in little endian byte order.
330568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    for (unsigned i = 0; i != Size; ++i) {
33170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach      EmitByte(Val & 255, OS);
332568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach      Val >>= 8;
333568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    }
334568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
335568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
336568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
337568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach                         SmallVectorImpl<MCFixup> &Fixups) const;
338568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach};
339568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
340568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} // end anonymous namespace
341568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
34259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan ChengMCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII,
343918f55fe239f00651e396be841f2b3b6e242f98dJim Grosbach                                            const MCRegisterInfo &MRI,
34459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                            const MCSubtargetInfo &STI,
3450800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling                                            MCContext &Ctx) {
34659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  return new ARMMCCodeEmitter(MCII, STI, Ctx);
347568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}
348568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
3497bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
3507bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
351c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson/// Thumb2 mode.
352c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
353c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson                                                 unsigned EncodedValue) const {
35459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
3557bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach    // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
356c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
357c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    // set to 1111.
358c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    unsigned Bit24 = EncodedValue & 0x01000000;
359c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    unsigned Bit28 = Bit24 << 4;
360c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue &= 0xEFFFFFFF;
361c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue |= Bit28;
362c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue |= 0x0F000000;
363c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  }
3647bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
365c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  return EncodedValue;
366c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson}
367c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson
36857dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
3697bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
37057dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// Thumb2 mode.
37157dac88f775c1191a98cff89abd1f7ad33df5e29Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
37257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson                                                 unsigned EncodedValue) const {
37359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
37457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson    EncodedValue &= 0xF0FFFFFF;
37557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson    EncodedValue |= 0x09000000;
37657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  }
3777bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
37857dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  return EncodedValue;
37957dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson}
38057dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson
3818f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
3827bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
3838f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// Thumb2 mode.
3848f143913141991baaa535ca0da7c8a81606d6392Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
3858f143913141991baaa535ca0da7c8a81606d6392Owen Anderson                                                 unsigned EncodedValue) const {
38659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
3878f143913141991baaa535ca0da7c8a81606d6392Owen Anderson    EncodedValue &= 0x00FFFFFF;
3888f143913141991baaa535ca0da7c8a81606d6392Owen Anderson    EncodedValue |= 0xEE000000;
3898f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  }
3907bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
3918f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  return EncodedValue;
3928f143913141991baaa535ca0da7c8a81606d6392Owen Anderson}
3938f143913141991baaa535ca0da7c8a81606d6392Owen Anderson
39419c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly/// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form
39519c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly/// if we are in Thumb2.
39619c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Goulyunsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,
39719c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly                                                 unsigned EncodedValue) const {
39819c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  if (isThumb2()) {
39919c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly    EncodedValue |= 0xC000000; // Set bits 27-26
40019c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  }
40119c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly
40219c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  return EncodedValue;
40319c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly}
40419c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly
405cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
406cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// them to their Thumb2 form if we are currently in Thumb2 mode.
407cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendlingunsigned ARMMCCodeEmitter::
408cf590263cd5c24ccf1d08cef612738d99cd980d9Bill WendlingVFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const {
40959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
410cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling    EncodedValue &= 0x0FFFFFFF;
411cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling    EncodedValue |= 0xE0000000;
412cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  }
413cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  return EncodedValue;
414cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling}
41557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson
41656ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// getMachineOpValue - Return binary encoding of operand. If the machine
41756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// operand requires relocation, record the relocation and return zero.
418806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
419806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetMachineOpValue(const MCInst &MI, const MCOperand &MO,
420806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                  SmallVectorImpl<MCFixup> &Fixups) const {
421bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  if (MO.isReg()) {
4220800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    unsigned Reg = MO.getReg();
42399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
424d8a11c25fa64c152628cfcf5f9d36eb60242b302Jim Grosbach
425b0708d292bbe04cfcfe0c5cb5e27d8a872c9839aJim Grosbach    // Q registers are encoded as 2x their register number.
4260800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    switch (Reg) {
4270800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    default:
4280800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling      return RegNo;
4290800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q0:  case ARM::Q1:  case ARM::Q2:  case ARM::Q3:
4300800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q4:  case ARM::Q5:  case ARM::Q6:  case ARM::Q7:
4310800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q8:  case ARM::Q9:  case ARM::Q10: case ARM::Q11:
4320800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
4330800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling      return 2 * RegNo;
43490d4cf931477b497553a9f2d0ed53377dd5dd88cOwen Anderson    }
435bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  } else if (MO.isImm()) {
43656ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach    return static_cast<unsigned>(MO.getImm());
437bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  } else if (MO.isFPImm()) {
438bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling    return static_cast<unsigned>(APFloat(MO.getFPImm())
439bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling                     .bitcastToAPInt().getHiBits(32).getLimitedValue());
4400800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  }
4410800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
442817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach  llvm_unreachable("Unable to encode MCOperand!");
44356ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach}
44456ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach
4455df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
446806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachbool ARMMCCodeEmitter::
447806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
448806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                       unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const {
4493e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  const MCOperand &MO  = MI.getOperand(OpIdx);
4503e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
4519af3d1c0dc2250793ada1ca6cfa98e9f1253f7f9Jim Grosbach
45299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
45392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
45492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  int32_t SImm = MO1.getImm();
45592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  bool isAdd = true;
4565df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
457ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  // Special value for #-0
4580da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson  if (SImm == INT32_MIN) {
45992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    SImm = 0;
4600da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    isAdd = false;
4610da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson  }
4625df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
463ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
46492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  if (SImm < 0) {
46592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    SImm = -SImm;
46692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    isAdd = false;
46792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  }
46892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
46992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Imm = SImm;
47092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  return isAdd;
47192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling}
4725df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
473dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Helper function to get the branch target operand,
474dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// which is either an immediate or requires a fixup.
475dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlingstatic uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
476dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                                       unsigned FixupKind,
477dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                                       SmallVectorImpl<MCFixup> &Fixups) {
478662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
479662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
480662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  // If the destination is an immediate, we have nothing to do.
481662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  if (MO.isImm()) return MO.getImm();
482dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  assert(MO.isExpr() && "Unexpected branch target type!");
483662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  const MCExpr *Expr = MO.getExpr();
484dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  MCFixupKind Kind = MCFixupKind(FixupKind);
48542e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach  Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
486662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
487662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  // All of the information is in the fixup.
488662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  return 0;
489662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach}
490662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
491559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are
492559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// determined by negating them and XOR'ing them with bit 23.
493559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Andersonstatic int32_t encodeThumbBLOffset(int32_t offset) {
494559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset >>= 1;
495559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  uint32_t S  = (offset & 0x800000) >> 23;
496559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  uint32_t J1 = (offset & 0x400000) >> 22;
497559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  uint32_t J2 = (offset & 0x200000) >> 21;
498559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J1 = (~J1 & 0x1);
499559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J2 = (~J2 & 0x1);
500559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J1 ^= S;
501559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J2 ^= S;
502559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson
503559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset &= ~0x600000;
504559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset |= J1 << 22;
505559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset |= J2 << 21;
506559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson
507559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  return offset;
508559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson}
509559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson
510dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getThumbBLTargetOpValue - Return encoding info for immediate branch target.
511c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbachuint32_t ARMMCCodeEmitter::
512dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
513c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
514559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
515559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  if (MO.isExpr())
516559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl,
517559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson                                    Fixups);
518559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  return encodeThumbBLOffset(MO.getImm());
519dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling}
520c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
52109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
52209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// BLX branch target.
52309aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendlinguint32_t ARMMCCodeEmitter::
52409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill WendlinggetThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
52509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling                         SmallVectorImpl<MCFixup> &Fixups) const {
526559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
527559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  if (MO.isExpr())
528559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx,
529559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson                                    Fixups);
530559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  return encodeThumbBLOffset(MO.getImm());
53109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling}
53209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling
533e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
534e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbachuint32_t ARMMCCodeEmitter::
535e246717c3a36a913fd4200776ed621649bb2b624Jim GrosbachgetThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
536e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
537391ac65377f2ad5e48a796e75120959e22430605Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
538391ac65377f2ad5e48a796e75120959e22430605Owen Anderson  if (MO.isExpr())
539559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br,
540559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson                                    Fixups);
541391ac65377f2ad5e48a796e75120959e22430605Owen Anderson  return (MO.getImm() >> 1);
542e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach}
543e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach
54401086451393ef33e82b6fad623989dd97dd70edfJim Grosbach/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
54501086451393ef33e82b6fad623989dd97dd70edfJim Grosbachuint32_t ARMMCCodeEmitter::
54601086451393ef33e82b6fad623989dd97dd70edfJim GrosbachgetThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
547e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach                         SmallVectorImpl<MCFixup> &Fixups) const {
548721cb1fde07423fd1905338d443172a8028ad634Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
549721cb1fde07423fd1905338d443172a8028ad634Owen Anderson  if (MO.isExpr())
550721cb1fde07423fd1905338d443172a8028ad634Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc,
551721cb1fde07423fd1905338d443172a8028ad634Owen Anderson                                    Fixups);
552721cb1fde07423fd1905338d443172a8028ad634Owen Anderson  return (MO.getImm() >> 1);
55301086451393ef33e82b6fad623989dd97dd70edfJim Grosbach}
55401086451393ef33e82b6fad623989dd97dd70edfJim Grosbach
555027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
556dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter::
557027d6e8d1ca04e4096fb3a27579b861d861466c5Jim GrosbachgetThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
558dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                        SmallVectorImpl<MCFixup> &Fixups) const {
55921df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
56021df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson  if (MO.isExpr())
56121df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups);
56221df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson  return (MO.getImm() >> 1);
563dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling}
564c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
565685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// Return true if this branch has a non-always predication
566685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimstatic bool HasConditionalBranch(const MCInst &MI) {
567685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  int NumOp = MI.getNumOperands();
568685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  if (NumOp >= 2) {
569685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    for (int i = 0; i < NumOp-1; ++i) {
570685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      const MCOperand &MCOp1 = MI.getOperand(i);
571685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      const MCOperand &MCOp2 = MI.getOperand(i + 1);
57210096dbdef22a10a6a4444437c935ab428545525Owen Anderson      if (MCOp1.isImm() && MCOp2.isReg() &&
573685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim          (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) {
57410096dbdef22a10a6a4444437c935ab428545525Owen Anderson        if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL)
575685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim          return true;
576685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      }
577685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    }
578685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  }
579685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  return false;
580685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim}
581685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
582dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
583dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target.
584dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter::
585dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
586dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                       SmallVectorImpl<MCFixup> &Fixups) const {
587092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach  // FIXME: This really, really shouldn't use TargetMachine. We don't want
588092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach  // coupling between MC and TM anywhere we can help it.
58959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2())
590c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    return
591c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson      ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups);
592685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  return getARMBranchTargetOpValue(MI, OpIdx, Fixups);
593685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim}
594685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
595685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
596685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// target.
597685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimuint32_t ARMMCCodeEmitter::
598685c350ae76b588e1f00c01a511fe8bd57f18394Jason W KimgetARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
599685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim                          SmallVectorImpl<MCFixup> &Fixups) const {
600d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
601d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  if (MO.isExpr()) {
60210096dbdef22a10a6a4444437c935ab428545525Owen Anderson    if (HasConditionalBranch(MI))
603d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson      return ::getBranchTargetOpValue(MI, OpIdx,
604d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson                                      ARM::fixup_arm_condbranch, Fixups);
60510096dbdef22a10a6a4444437c935ab428545525Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx,
606d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson                                    ARM::fixup_arm_uncondbranch, Fixups);
607d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  }
608d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson
609d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  return MO.getImm() >> 2;
610c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach}
611c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
612f1eab597b2316c6cfcabfcee98895fedb2071722Owen Andersonuint32_t ARMMCCodeEmitter::
6137b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim GrosbachgetARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
6147b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
6157b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach  const MCOperand MO = MI.getOperand(OpIdx);
616cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy  if (MO.isExpr()) {
617cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy    if (HasConditionalBranch(MI))
618cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy      return ::getBranchTargetOpValue(MI, OpIdx,
619cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy                                      ARM::fixup_arm_condbl, Fixups);
620cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups);
621cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy  }
6227b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach
6237b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach  return MO.getImm() >> 2;
6247b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach}
6257b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach
6267b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbachuint32_t ARMMCCodeEmitter::
627f1eab597b2316c6cfcabfcee98895fedb2071722Owen AndersongetARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
628f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson                          SmallVectorImpl<MCFixup> &Fixups) const {
629f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
6307b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach  if (MO.isExpr())
6317b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups);
632685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
633f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  return MO.getImm() >> 1;
634f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson}
635685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
636c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
637c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// immediate branch target.
638c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Andersonuint32_t ARMMCCodeEmitter::
639c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen AndersongetUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
640c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson                       SmallVectorImpl<MCFixup> &Fixups) const {
641c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  unsigned Val =
642c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups);
643c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool I  = (Val & 0x800000);
644c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool J1 = (Val & 0x400000);
645c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool J2 = (Val & 0x200000);
646c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  if (I ^ J1)
647c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val &= ~0x400000;
648c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  else
649c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val |= 0x400000;
650971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
651c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  if (I ^ J2)
652c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val &= ~0x200000;
653c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  else
654c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val |= 0x200000;
655971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
656c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  return Val;
657c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson}
658c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson
6591fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate
6601fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// ADR label target.
6615d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbachuint32_t ARMMCCodeEmitter::
6625d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim GrosbachgetAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
6635d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach                   SmallVectorImpl<MCFixup> &Fixups) const {
66496425c846494c1c20a4c931f4783571295ab170cOwen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
66596425c846494c1c20a4c931f4783571295ab170cOwen Anderson  if (MO.isExpr())
66696425c846494c1c20a4c931f4783571295ab170cOwen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12,
66796425c846494c1c20a4c931f4783571295ab170cOwen Anderson                                    Fixups);
66896425c846494c1c20a4c931f4783571295ab170cOwen Anderson  int32_t offset = MO.getImm();
66996425c846494c1c20a4c931f4783571295ab170cOwen Anderson  uint32_t Val = 0x2000;
6701fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
671d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover  int SoImmVal;
6721fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  if (offset == INT32_MIN) {
6731fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    Val = 0x1000;
674d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    SoImmVal = 0;
6751fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  } else if (offset < 0) {
67696425c846494c1c20a4c931f4783571295ab170cOwen Anderson    Val = 0x1000;
67796425c846494c1c20a4c931f4783571295ab170cOwen Anderson    offset *= -1;
678d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    SoImmVal = ARM_AM::getSOImmVal(offset);
679d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    if(SoImmVal == -1) {
680d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      Val = 0x2000;
681d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      offset *= -1;
682d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      SoImmVal = ARM_AM::getSOImmVal(offset);
683d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    }
684d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover  } else {
685d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    SoImmVal = ARM_AM::getSOImmVal(offset);
686d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    if(SoImmVal == -1) {
687d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      Val = 0x1000;
688d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      offset *= -1;
689d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      SoImmVal = ARM_AM::getSOImmVal(offset);
690d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    }
69196425c846494c1c20a4c931f4783571295ab170cOwen Anderson  }
6921fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
6931fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  assert(SoImmVal != -1 && "Not a valid so_imm value!");
6941fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
6951fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  Val |= SoImmVal;
69696425c846494c1c20a4c931f4783571295ab170cOwen Anderson  return Val;
6975d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach}
6985d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach
6991fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
700a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// target.
701a838a25d59838adfa91463f6a918ae3adeb352c1Owen Andersonuint32_t ARMMCCodeEmitter::
702a838a25d59838adfa91463f6a918ae3adeb352c1Owen AndersongetT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
703a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson                   SmallVectorImpl<MCFixup> &Fixups) const {
70496425c846494c1c20a4c931f4783571295ab170cOwen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
70596425c846494c1c20a4c931f4783571295ab170cOwen Anderson  if (MO.isExpr())
70696425c846494c1c20a4c931f4783571295ab170cOwen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
70796425c846494c1c20a4c931f4783571295ab170cOwen Anderson                                    Fixups);
70808fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  int32_t Val = MO.getImm();
7091fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  if (Val == INT32_MIN)
7101fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    Val = 0x1000;
7111fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  else if (Val < 0) {
71208fef885eb39339a47e3be7f0842b1db33683003Owen Anderson    Val *= -1;
71308fef885eb39339a47e3be7f0842b1db33683003Owen Anderson    Val |= 0x1000;
71408fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  }
71508fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  return Val;
716a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson}
717a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson
7181fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
719d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// target.
720d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbachuint32_t ARMMCCodeEmitter::
721d40963c4065432ec7e47879d3ca665a54ee903b6Jim GrosbachgetThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
722d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                   SmallVectorImpl<MCFixup> &Fixups) const {
72396425c846494c1c20a4c931f4783571295ab170cOwen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
72496425c846494c1c20a4c931f4783571295ab170cOwen Anderson  if (MO.isExpr())
72596425c846494c1c20a4c931f4783571295ab170cOwen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10,
72696425c846494c1c20a4c931f4783571295ab170cOwen Anderson                                    Fixups);
72796425c846494c1c20a4c931f4783571295ab170cOwen Anderson  return MO.getImm();
728d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach}
729d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach
730f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg'
731f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// operand.
7320f4b60d43a289671082deee3bd56a3a055afb16aOwen Andersonuint32_t ARMMCCodeEmitter::
733f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
734f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling                              SmallVectorImpl<MCFixup> &) const {
735f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  // [Rn, Rm]
736f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  //   {5-3} = Rm
737f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  //   {2-0} = Rn
7380f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx);
739f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  const MCOperand &MO2 = MI.getOperand(OpIdx + 1);
74099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
74199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO2.getReg());
7420f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  return (Rm << 3) | Rn;
7430f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson}
7440f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson
74592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
746806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter::
747806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
748806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
74992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {17-13} = reg
75092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {12}    = (U)nsigned (add == '1', sub == '0')
75192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {11-0}  = imm12
75292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  unsigned Reg, Imm12;
75370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  bool isAdd = true;
75470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  // If The first operand isn't a register, we have a label reference.
75570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
756971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson  if (!MO.isReg()) {
75799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
75870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Imm12 = 0;
75970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
760fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson    if (MO.isExpr()) {
761fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      const MCExpr *Expr = MO.getExpr();
762beb920fce6ccc89b4735f280f94cb8c227f4ef5eAmaury de la Vieuville      isAdd = false ; // 'U' bit is set as part of the fixup.
763fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson
764fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      MCFixupKind Kind;
765fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      if (isThumb2())
766fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
767fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      else
768fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
76942e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach      Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
770fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson
771fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      ++MCNumCPRelocations;
772fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson    } else {
773fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      Reg = ARM::PC;
774fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      int32_t Offset = MO.getImm();
7750b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      // FIXME: Handle #-0.
776fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      if (Offset < 0) {
777fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        Offset *= -1;
778fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        isAdd = false;
779fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      }
780fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      Imm12 = Offset;
781fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson    }
78270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  } else
78370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups);
78492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
78592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  uint32_t Binary = Imm12 & 0xfff;
78692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
787ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  if (isAdd)
78892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    Binary |= (1 << 12);
78992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Binary |= (Reg << 13);
79092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  return Binary;
79192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling}
79292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
793a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// getT2Imm8s4OpValue - Return encoding info for
794a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// '+/- imm8<<2' operand.
795a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachuint32_t ARMMCCodeEmitter::
796a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachgetT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
797a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                   SmallVectorImpl<MCFixup> &Fixups) const {
798a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // FIXME: The immediate operand should have already been encoded like this
799a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // before ever getting here. The encoder method should just need to combine
800a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // the MI operands for the register and the offset into a single
801a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // representation for the complex operand in the .td file. This isn't just
802a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // style, unfortunately. As-is, we can't represent the distinct encoding
803a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // for #-0.
804a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
805a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // {8}    = (U)nsigned (add == '1', sub == '0')
806a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // {7-0}  = imm8
807a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  int32_t Imm8 = MI.getOperand(OpIdx).getImm();
808a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isAdd = Imm8 >= 0;
809a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
810a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
811a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (Imm8 < 0)
812aaf217953bef3b2cc0e0f26bf474616cc20cf7f0Richard Smith    Imm8 = -(uint32_t)Imm8;
813a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
814a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Scaled by 4.
815a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Imm8 /= 4;
816a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
817a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  uint32_t Binary = Imm8 & 0xff;
818a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
819a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (isAdd)
820a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Binary |= (1 << 8);
821a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return Binary;
822a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
823a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
8249d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// getT2AddrModeImm8s4OpValue - Return encoding info for
8259d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// 'reg +/- imm8<<2' operand.
8269d63d90de5e57ad96f467b270544443a9284eb2bOwen Andersonuint32_t ARMMCCodeEmitter::
8279d63d90de5e57ad96f467b270544443a9284eb2bOwen AndersongetT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
8289d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson                        SmallVectorImpl<MCFixup> &Fixups) const {
82990cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {12-9} = reg
83090cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {8}    = (U)nsigned (add == '1', sub == '0')
83190cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {7-0}  = imm8
8329d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  unsigned Reg, Imm8;
8339d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  bool isAdd = true;
8349d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  // If The first operand isn't a register, we have a label reference.
8359d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  const MCOperand &MO = MI.getOperand(OpIdx);
8369d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  if (!MO.isReg()) {
83799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
8389d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    Imm8 = 0;
8399d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    isAdd = false ; // 'U' bit is set as part of the fixup.
8409d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
8419d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    assert(MO.isExpr() && "Unexpected machine operand type!");
8429d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    const MCExpr *Expr = MO.getExpr();
8432f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
84442e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
8459d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
8469d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    ++MCNumCPRelocations;
8479d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  } else
8489d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
8499d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
850a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // FIXME: The immediate operand should have already been encoded like this
851a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // before ever getting here. The encoder method should just need to combine
852a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // the MI operands for the register and the offset into a single
853a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // representation for the complex operand in the .td file. This isn't just
854a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // style, unfortunately. As-is, we can't represent the distinct encoding
855a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // for #-0.
8569d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  uint32_t Binary = (Imm8 >> 2) & 0xff;
8579d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
8589d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  if (isAdd)
85990cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach    Binary |= (1 << 8);
8609d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  Binary |= (Reg << 9);
8619d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  return Binary;
8629d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson}
8639d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
864b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// getT2AddrModeImm0_1020s4OpValue - Return encoding info for
865b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// 'reg + imm8<<2' operand.
866b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbachuint32_t ARMMCCodeEmitter::
867b6aed508e310e31dcb080e761ca856127cec0773Jim GrosbachgetT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
868b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
869b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  // {11-8} = reg
870b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  // {7-0}  = imm8
871b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
872b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
87399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
874b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  unsigned Imm8 = MO1.getImm();
875b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  return (Reg << 8) | Imm8;
876b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach}
877b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
87886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// FIXME: This routine assumes that a binary
87986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// expression will always result in a PCRel expression
88086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// In reality, its only true if one or more subexpressions
88186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// is itself a PCRel (i.e. "." in asm or some other pcrel construct)
88286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// but this is good enough for now.
88386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kimstatic bool EvaluateAsPCRel(const MCExpr *Expr) {
88486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  switch (Expr->getKind()) {
885bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Unexpected expression type");
88686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case MCExpr::SymbolRef: return false;
88786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case MCExpr::Binary: return true;
88886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  }
88986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim}
89086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim
8917597212abced110723f2fee985a7d60557c092ecEvan Chenguint32_t
8927597212abced110723f2fee985a7d60557c092ecEvan ChengARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
8937597212abced110723f2fee985a7d60557c092ecEvan Cheng                                      SmallVectorImpl<MCFixup> &Fixups) const {
894837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim  // {20-16} = imm{15-12}
895837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim  // {11-0}  = imm{11-0}
8967bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
8977597212abced110723f2fee985a7d60557c092ecEvan Cheng  if (MO.isImm())
8987597212abced110723f2fee985a7d60557c092ecEvan Cheng    // Hi / lo 16 bits already extracted during earlier passes.
899837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    return static_cast<unsigned>(MO.getImm());
9007597212abced110723f2fee985a7d60557c092ecEvan Cheng
9017597212abced110723f2fee985a7d60557c092ecEvan Cheng  // Handle :upper16: and :lower16: assembly prefixes.
9027597212abced110723f2fee985a7d60557c092ecEvan Cheng  const MCExpr *E = MO.getExpr();
90394b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  MCFixupKind Kind;
9047597212abced110723f2fee985a7d60557c092ecEvan Cheng  if (E->getKind() == MCExpr::Target) {
9057597212abced110723f2fee985a7d60557c092ecEvan Cheng    const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E);
9067597212abced110723f2fee985a7d60557c092ecEvan Cheng    E = ARM16Expr->getSubExpr();
9077597212abced110723f2fee985a7d60557c092ecEvan Cheng
9087597212abced110723f2fee985a7d60557c092ecEvan Cheng    switch (ARM16Expr->getKind()) {
909bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Unsupported ARMFixup");
9107597212abced110723f2fee985a7d60557c092ecEvan Cheng    case ARMMCExpr::VK_ARM_HI16:
91159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng      if (!isTargetDarwin() && EvaluateAsPCRel(E))
91259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
913f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movt_hi16_pcrel
914f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movt_hi16_pcrel);
915f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      else
91659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
917f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movt_hi16
918f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movt_hi16);
919837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim      break;
9207597212abced110723f2fee985a7d60557c092ecEvan Cheng    case ARMMCExpr::VK_ARM_LO16:
92159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng      if (!isTargetDarwin() && EvaluateAsPCRel(E))
92259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
923f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movw_lo16_pcrel
924f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movw_lo16_pcrel);
925f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      else
92659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
927f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movw_lo16
928f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movw_lo16);
929837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim      break;
930837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    }
93142e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc()));
932837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    return 0;
93394b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  }
93494b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  // If the expression doesn't have :upper16: or :lower16: on it,
93594b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  // it's just a plain immediate expression, and those evaluate to
93694b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  // the lower 16 bits of the expression regardless of whether
93794b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  // we have a movt or a movw.
93894b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  if (!isTargetDarwin() && EvaluateAsPCRel(E))
93994b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach    Kind = MCFixupKind(isThumb2()
94094b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach                       ? ARM::fixup_t2_movw_lo16_pcrel
94194b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach                       : ARM::fixup_arm_movw_lo16_pcrel);
94294b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  else
94394b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach    Kind = MCFixupKind(isThumb2()
94494b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach                       ? ARM::fixup_t2_movw_lo16
94594b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach                       : ARM::fixup_arm_movw_lo16);
94694b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc()));
94794b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  return 0;
948837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim}
949837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim
950837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kimuint32_t ARMMCCodeEmitter::
95154fea632b161f98e96ec7275922e35102bcecc5dJim GrosbachgetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
95254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
95354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
95454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
95554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
95699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
95799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
95854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
95954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
96099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
96199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned SBits = getShiftOp(ShOp);
96254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
96393c7c449a1351542fa5a275587187154dbedb8e0Tim Northover  // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift
96493c7c449a1351542fa5a275587187154dbedb8e0Tim Northover  // amount. However, it would be an easy mistake to make so check here.
96593c7c449a1351542fa5a275587187154dbedb8e0Tim Northover  assert((ShImm & ~0x1f) == 0 && "Out of range shift amount");
96693c7c449a1351542fa5a275587187154dbedb8e0Tim Northover
96754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {16-13} = Rn
96854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {12}    = isAdd
96954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {11-0}  = shifter
97054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {3-0}  = Rm
97154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {4}    = 0
97254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {6-5}  = type
97354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {11-7} = imm
974570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t Binary = Rm;
97554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= Rn << 13;
97654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= SBits << 5;
97754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= ShImm << 7;
97854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  if (isAdd)
97954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach    Binary |= 1 << 12;
98054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  return Binary;
98154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach}
98254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
983570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbachuint32_t ARMMCCodeEmitter::
98499f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
98599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
98699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {17-14}  Rn
98799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {13}     1 == imm12, 0 == Rm
98899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {12}     isAdd
98999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {11-0}   imm12/Rm
99099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
99199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
99299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups);
99399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  Binary |= Rn << 14;
99499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  return Binary;
99599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach}
99699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
99799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter::
99899f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
99999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
100099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {13}     1 == imm12, 0 == Rm
100199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {12}     isAdd
100299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {11-0}   imm12/Rm
100399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
100499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
100599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned Imm = MO1.getImm();
100699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
100799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  bool isReg = MO.getReg() != 0;
100899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t Binary = ARM_AM::getAM2Offset(Imm);
100999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
101099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  if (isReg) {
101199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);
101299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    Binary <<= 7;                    // Shift amount is bits [11:7]
101399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]
101499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Binary |= CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); // Rm is bits [3:0]
101599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  }
101699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  return Binary | (isAdd << 12) | (isReg << 13);
101799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach}
101899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
101999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter::
10207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachgetPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
10217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                     SmallVectorImpl<MCFixup> &Fixups) const {
10227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // {4}      isAdd
10237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // {3-0}    Rm
10247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
10257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
102616578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = MO1.getImm() != 0;
102799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()) | (isAdd << 4);
10287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
10297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
10307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachuint32_t ARMMCCodeEmitter::
10317eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim GrosbachgetAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
10327eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
10337eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {9}      1 == imm8, 0 == Rm
10347eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {8}      isAdd
10357eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {7-4}    imm7_4/zero
10367eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {3-0}    imm3_0/Rm
10377eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
10387eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
10397eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  unsigned Imm = MO1.getImm();
10407eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
10417eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  bool isImm = MO.getReg() == 0;
10427eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
10437eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
10447eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  if (!isImm)
104599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
10467eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  return Imm8 | (isAdd << 8) | (isImm << 9);
10477eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach}
10487eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach
10497eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbachuint32_t ARMMCCodeEmitter::
1050570a9226913ebe1af04832b8fb3273c70b4ee152Jim GrosbachgetAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
1051570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
1052570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {13}     1 == imm8, 0 == Rm
1053570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {12-9}   Rn
1054570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {8}      isAdd
1055570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {7-4}    imm7_4/zero
1056570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {3-0}    imm3_0/Rm
1057570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
1058570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
1059570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
10602f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
10612f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach  // If The first operand isn't a register, we have a label reference.
10622f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach  if (!MO.isReg()) {
106399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
10642f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
10652f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    assert(MO.isExpr() && "Unexpected machine operand type!");
10662f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    const MCExpr *Expr = MO.getExpr();
10672f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled);
106842e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
10692f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
10702f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    ++MCNumCPRelocations;
10712f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    return (Rn << 9) | (1 << 13);
10722f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach  }
107399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1074570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  unsigned Imm = MO2.getImm();
1075570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
1076570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  bool isImm = MO1.getReg() == 0;
1077570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
1078570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
1079570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  if (!isImm)
108099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
1081570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
1082570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach}
1083570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach
1084b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands.
1085d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbachuint32_t ARMMCCodeEmitter::
1086d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim GrosbachgetAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
1087d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
1088d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // [SP, #imm]
1089d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  //   {7-0} = imm8
1090d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1091b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  assert(MI.getOperand(OpIdx).getReg() == ARM::SP &&
1092b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling         "Unexpected base register!");
10937a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
1094d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // The immediate is already shifted for the implicit zeroes, so no change
1095d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // here.
1096d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  return MO1.getImm() & 0xff;
1097d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach}
1098d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach
1099f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
1100272df516d7a9b1f0f69174276abaa759816ee456Bill Wendlinguint32_t ARMMCCodeEmitter::
1101f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
110222447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling                     SmallVectorImpl<MCFixup> &Fixups) const {
1103ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  // [Rn, #imm]
1104ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  //   {7-3} = imm5
1105ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  //   {2-0} = Rn
1106ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  const MCOperand &MO = MI.getOperand(OpIdx);
1107ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
110899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1109656b3d22f70c2d1c8a5286f7270cb380df862565Matt Beaumont-Gay  unsigned Imm5 = MO1.getImm();
1110272df516d7a9b1f0f69174276abaa759816ee456Bill Wendling  return ((Imm5 & 0x1f) << 3) | Rn;
11111fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling}
11121fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling
1113b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
1114b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendlinguint32_t ARMMCCodeEmitter::
1115b8958b031ec5163261f490f131780c5dc3d823d6Bill WendlinggetAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
1116b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling                     SmallVectorImpl<MCFixup> &Fixups) const {
1117a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
1118a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson  if (MO.isExpr())
1119a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups);
1120a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson  return (MO.getImm() >> 2);
1121b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling}
1122b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling
11235177f79c378b47e38bed5ac05ba4b597f31b864eJim Grosbach/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand.
1124806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter::
1125806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
1126806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
112792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {12-9} = reg
112892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {8}    = (U)nsigned (add == '1', sub == '0')
112992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {7-0}  = imm8
113092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  unsigned Reg, Imm8;
113197dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  bool isAdd;
113270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  // If The first operand isn't a register, we have a label reference.
113370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
113470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  if (!MO.isReg()) {
113599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
113670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Imm8 = 0;
113797dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach    isAdd = false; // 'U' bit is handled as part of the fixup.
113870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
113970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    assert(MO.isExpr() && "Unexpected machine operand type!");
114070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    const MCExpr *Expr = MO.getExpr();
1141d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson    MCFixupKind Kind;
114259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    if (isThumb2())
1143d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson      Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
1144d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson    else
1145d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson      Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
114642e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
114770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
114870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    ++MCNumCPRelocations;
114997dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  } else {
115070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
115197dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach    isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
115297dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  }
115392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
115492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
115592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
115697dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  if (isAdd)
115792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    Binary |= (1 << 8);
115892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Binary |= (Reg << 9);
11593e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  return Binary;
11603e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach}
11613e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach
1162806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1163152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
1164806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                SmallVectorImpl<MCFixup> &Fixups) const {
11650800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
1166354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // shifted. The second is Rs, the amount to shift by, and the third specifies
1167354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // the type of the shift.
116835b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach  //
1169ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // {3-0} = Rm.
1170354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {4}   = 1
1171ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // {6-5} = type
1172354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {11-8} = Rs
1173354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {7}    = 0
1174ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1175ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO  = MI.getOperand(OpIdx);
1176ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1177ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
1178ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
1179ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1180ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode Rm.
118199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1182ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1183ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode the shift opcode.
1184ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned SBits = 0;
1185ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned Rs = MO1.getReg();
1186ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  if (Rs) {
1187ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // Set shift operand (bit[7:4]).
1188ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSL - 0001
1189ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSR - 0011
1190ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ASR - 0101
1191ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ROR - 0111
1192ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    switch (SOpc) {
1193ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    default: llvm_unreachable("Unknown shift opc!");
1194ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsl: SBits = 0x1; break;
1195ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsr: SBits = 0x3; break;
1196ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::asr: SBits = 0x5; break;
1197ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::ror: SBits = 0x7; break;
1198ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    }
1199ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  }
12000800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
1201ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  Binary |= SBits << 4;
1202ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1203354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // Encode the shift operation Rs.
1204152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode Rs bit[11:8].
1205152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
120699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  return Binary | (CTX.getRegisterInfo()->getEncodingValue(Rs) << ARMII::RegRsShift);
1207152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson}
1208152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1209152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Andersonunsigned ARMMCCodeEmitter::
1210152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
1211152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson                SmallVectorImpl<MCFixup> &Fixups) const {
1212354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
1213354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // shifted. The second is the amount to shift by.
1214152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  //
1215152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // {3-0} = Rm.
1216354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {4}   = 0
1217152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // {6-5} = type
1218354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {11-7} = imm
1219152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1220152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  const MCOperand &MO  = MI.getOperand(OpIdx);
1221152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1222152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
1223152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1224152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode Rm.
122599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1226152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1227152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode the shift opcode.
1228152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned SBits = 0;
1229152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1230152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Set shift operand (bit[6:4]).
1231152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // LSL - 000
1232152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // LSR - 010
1233152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // ASR - 100
1234152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // ROR - 110
1235152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // RRX - 110 and bit[11:8] clear.
1236152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  switch (SOpc) {
1237152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  default: llvm_unreachable("Unknown shift opc!");
1238152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::lsl: SBits = 0x0; break;
1239152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::lsr: SBits = 0x2; break;
1240152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::asr: SBits = 0x4; break;
1241152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::ror: SBits = 0x6; break;
1242152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::rrx:
1243152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    Binary |= 0x60;
1244152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    return Binary;
1245ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  }
1246ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1247ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode shift_imm bit[11:7].
1248152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  Binary |= SBits << 4;
12493dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson  unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm());
1250b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton  assert(Offset < 32 && "Offset must be in range 0-31!");
12513dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson  return Binary | (Offset << 7);
1252ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach}
1253ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1254152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1255806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
125675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
125775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson                SmallVectorImpl<MCFixup> &Fixups) const {
125875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
125975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO2 = MI.getOperand(OpNum+1);
12607bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach  const MCOperand &MO3 = MI.getOperand(OpNum+2);
12617bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
126275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // Encoded as [Rn, Rm, imm].
126375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // FIXME: Needs fixup support.
126499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
126575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 4;
126699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  Value |= CTX.getRegisterInfo()->getEncodingValue(MO2.getReg());
126775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 2;
126875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value |= MO3.getImm();
12697bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
127075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  return Value;
127175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson}
127275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
127375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter::
127475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
127575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson                         SmallVectorImpl<MCFixup> &Fixups) const {
127675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
127775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO2 = MI.getOperand(OpNum+1);
127875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
127975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // FIXME: Needs fixup support.
128099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
12817bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
128275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // Even though the immediate is 8 bits long, we need 9 bits in order
128375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // to represent the (inverse of the) sign bit.
128475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 9;
12856af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  int32_t tmp = (int32_t)MO2.getImm();
12866af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  if (tmp < 0)
12876af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    tmp = abs(tmp);
12886af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  else
12896af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    Value |= 256; // Set the ADD bit
12906af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  Value |= tmp & 255;
12916af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  return Value;
12926af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson}
12936af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson
12946af50f7dd12d82f0a80f3158102180eee4c921aaOwen Andersonunsigned ARMMCCodeEmitter::
12956af50f7dd12d82f0a80f3158102180eee4c921aaOwen AndersongetT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
12966af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson                         SmallVectorImpl<MCFixup> &Fixups) const {
12976af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
12986af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson
12996af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  // FIXME: Needs fixup support.
13006af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  unsigned Value = 0;
13016af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  int32_t tmp = (int32_t)MO1.getImm();
13026af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  if (tmp < 0)
13036af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    tmp = abs(tmp);
13046af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  else
13056af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    Value |= 256; // Set the ADD bit
13066af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  Value |= tmp & 255;
130775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  return Value;
130875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson}
130975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
131075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter::
13110e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen AndersongetT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
13120e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson                         SmallVectorImpl<MCFixup> &Fixups) const {
13130e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
13140e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson
13150e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  // FIXME: Needs fixup support.
13160e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  unsigned Value = 0;
13170e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  int32_t tmp = (int32_t)MO1.getImm();
13180e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  if (tmp < 0)
13190e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    tmp = abs(tmp);
13200e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  else
13210e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    Value |= 4096; // Set the ADD bit
13220e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  Value |= tmp & 4095;
13230e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  return Value;
13240e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson}
13250e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson
13260e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Andersonunsigned ARMMCCodeEmitter::
13275de6d841a5116152793dcab35a2e534a6a9aaa7aOwen AndersongetT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
13285de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson                SmallVectorImpl<MCFixup> &Fixups) const {
13295de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
13305de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // shifted. The second is the amount to shift by.
13315de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  //
13325de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {3-0} = Rm.
13335de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {4}   = 0
13345de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {6-5} = type
13355de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {11-7} = imm
13365de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
13375de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  const MCOperand &MO  = MI.getOperand(OpIdx);
13385de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
13395de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
13405de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
13415de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode Rm.
134299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
13435de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
13445de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode the shift opcode.
13455de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned SBits = 0;
13465de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Set shift operand (bit[6:4]).
13475de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // LSL - 000
13485de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // LSR - 010
13495de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // ASR - 100
13505de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // ROR - 110
13515de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  switch (SOpc) {
13525de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  default: llvm_unreachable("Unknown shift opc!");
13535de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::lsl: SBits = 0x0; break;
13545de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::lsr: SBits = 0x2; break;
13555de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::asr: SBits = 0x4; break;
135612c7e90d369b4605aac0ddbd252231beacb2aabbOwen Anderson  case ARM_AM::rrx: // FALLTHROUGH
13575de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::ror: SBits = 0x6; break;
13585de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  }
13595de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
13605de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  Binary |= SBits << 4;
13615de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  if (SOpc == ARM_AM::rrx)
13625de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    return Binary;
13635de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
13645de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode shift_imm bit[11:7].
13655de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
13665de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson}
13675de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
13685de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Andersonunsigned ARMMCCodeEmitter::
1369806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
1370806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const {
13713fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
13723fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  // msb of the mask.
13733fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  const MCOperand &MO = MI.getOperand(Op);
13743fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t v = ~MO.getImm();
1375c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer  uint32_t lsb = countTrailingZeros(v);
1376c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer  uint32_t msb = (32 - countLeadingZeros (v)) - 1;
13773fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
13783fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  return lsb | (msb << 5);
13793fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach}
13803fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach
1381806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1382806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetRegisterListOpValue(const MCInst &MI, unsigned Op,
13835e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling                       SmallVectorImpl<MCFixup> &Fixups) const {
13846bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  // VLDM/VSTM:
13856bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {12-8} = Vd
13866bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {7-0}  = Number of registers
13876bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //
13886bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  // LDM/STM:
13896bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {15-0}  = Bitfield of GPRs.
13906bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  unsigned Reg = MI.getOperand(Op).getReg();
1391c89c744b69cecac576317a98322fd295e36e9886Craig Topper  bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg);
1392c89c744b69cecac576317a98322fd295e36e9886Craig Topper  bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg);
13936bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
13945e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  unsigned Binary = 0;
13956bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
13966bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  if (SPRRegs || DPRRegs) {
13976bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    // VLDM/VSTM
139899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
13996bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;
14006bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    Binary |= (RegNo & 0x1f) << 8;
14016bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    if (SPRRegs)
14026bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= NumRegs;
14036bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    else
14046bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= NumRegs * 2;
14056bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  } else {
14066bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {
140799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling      unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(MI.getOperand(I).getReg());
14086bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= 1 << RegNo;
14096bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    }
14105e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  }
14116bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
14126b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach  return Binary;
14136b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach}
14146b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach
14158e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along
14168e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// with the alignment operand.
1417806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1418806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
1419806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
1420d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  const MCOperand &Reg = MI.getOperand(Op);
14210800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  const MCOperand &Imm = MI.getOperand(Op + 1);
142235b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach
142399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
14240800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  unsigned Align = 0;
14250800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
14260800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  switch (Imm.getImm()) {
14270800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  default: break;
14280800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 2:
14290800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 4:
14300800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 8:  Align = 0x01; break;
14310800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 16: Align = 0x02; break;
14320800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 32: Align = 0x03; break;
1433d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  }
14340800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
1435d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  return RegNo | (Align << 4);
1436d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson}
1437d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson
1438183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number
1439183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// along  with the alignment operand for use in VST1 and VLD1 with size 32.
1440183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wangunsigned ARMMCCodeEmitter::
1441183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P WanggetAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
1442183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang                                    SmallVectorImpl<MCFixup> &Fixups) const {
1443183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  const MCOperand &Reg = MI.getOperand(Op);
1444183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  const MCOperand &Imm = MI.getOperand(Op + 1);
1445183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
144699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
1447183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  unsigned Align = 0;
1448183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1449183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  switch (Imm.getImm()) {
1450183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  default: break;
1451183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 8:
1452eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach  case 16:
1453eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach  case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes.
1454eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach  case 2: Align = 0x00; break;
1455eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach  case 4: Align = 0x03; break;
1456183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  }
1457183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1458183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  return RegNo | (Align << 4);
1459183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang}
1460183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1461183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
14628e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and
14638e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// alignment operand for use in VLD-dup instructions.  This is the same as
14648e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue except for the alignment encoding, which is
14658e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// different for VLD4-dup.
14668e0c7b52877983b4838e54e233449912fc1a2325Bob Wilsonunsigned ARMMCCodeEmitter::
14678e0c7b52877983b4838e54e233449912fc1a2325Bob WilsongetAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
14688e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson                              SmallVectorImpl<MCFixup> &Fixups) const {
14698e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  const MCOperand &Reg = MI.getOperand(Op);
14708e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  const MCOperand &Imm = MI.getOperand(Op + 1);
14718e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
147299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
14738e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  unsigned Align = 0;
14748e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
14758e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  switch (Imm.getImm()) {
14768e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  default: break;
14778e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 2:
14788e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 4:
14798e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 8:  Align = 0x01; break;
14808e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 16: Align = 0x03; break;
14818e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  }
14828e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
14838e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  return RegNo | (Align << 4);
14848e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson}
14858e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
1486806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1487806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
1488806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
14890800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  const MCOperand &MO = MI.getOperand(Op);
14900800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  if (MO.getReg() == 0) return 0x0D;
149199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  return CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1492a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1493a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1494a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
14953116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight8Imm(const MCInst &MI, unsigned Op,
14963116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                  SmallVectorImpl<MCFixup> &Fixups) const {
1497a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 8 - MI.getOperand(Op).getImm();
1498a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1499a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1500a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
15013116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight16Imm(const MCInst &MI, unsigned Op,
15023116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                   SmallVectorImpl<MCFixup> &Fixups) const {
1503a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 16 - MI.getOperand(Op).getImm();
1504a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1505a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1506a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
15073116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight32Imm(const MCInst &MI, unsigned Op,
15083116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                   SmallVectorImpl<MCFixup> &Fixups) const {
1509a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 32 - MI.getOperand(Op).getImm();
15103116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling}
15113116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling
15123116dce33840a115130c5f8ffcb9679d023496d6Bill Wendlingunsigned ARMMCCodeEmitter::
15133116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight64Imm(const MCInst &MI, unsigned Op,
15143116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                   SmallVectorImpl<MCFixup> &Fixups) const {
15153116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  return 64 - MI.getOperand(Op).getImm();
1516cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson}
1517cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson
1518568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachvoid ARMMCCodeEmitter::
1519568eeedea72c274abbba1310c18a31eef78e14a4Jim GrosbachEncodeInstruction(const MCInst &MI, raw_ostream &OS,
1520806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                  SmallVectorImpl<MCFixup> &Fixups) const {
1521d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach  // Pseudo instructions don't get encoded.
152259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
1523e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  uint64_t TSFlags = Desc.TSFlags;
1524e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)
1525d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach    return;
152616884415db751c75f2133bd04921393c792b1158Owen Anderson
1527e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  int Size;
152816884415db751c75f2133bd04921393c792b1158Owen Anderson  if (Desc.getSize() == 2 || Desc.getSize() == 4)
152916884415db751c75f2133bd04921393c792b1158Owen Anderson    Size = Desc.getSize();
153016884415db751c75f2133bd04921393c792b1158Owen Anderson  else
153116884415db751c75f2133bd04921393c792b1158Owen Anderson    llvm_unreachable("Unexpected instruction size!");
153210096dbdef22a10a6a4444437c935ab428545525Owen Anderson
1533d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
15347597212abced110723f2fee985a7d60557c092ecEvan Cheng  // Thumb 32-bit wide instructions need to emit the high order halfword
15357597212abced110723f2fee985a7d60557c092ecEvan Cheng  // first.
153659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb() && Size == 4) {
1537d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary >> 16, 2, OS);
1538d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary & 0xffff, 2, OS);
1539d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach  } else
1540d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary, Size, OS);
15417292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling  ++MCNumEmitted;  // Keep track of the # of mi's emitted.
1542568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}
15439af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
1544806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach#include "ARMGenMCCodeEmitter.inc"
1545