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"
15ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
16be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMBaseInfo.h"
17be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMFixupKinds.h"
18ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
19be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMMCTargetDesc.h"
20568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCCodeEmitter.h"
21568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCExpr.h"
22568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCInst.h"
2359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCInstrInfo.h"
24be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/MC/MCRegisterInfo.h"
2559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
26ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "llvm/ADT/APFloat.h"
27d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach#include "llvm/ADT/Statistic.h"
28568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/Support/raw_ostream.h"
2959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng
30568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachusing namespace llvm;
31568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
3270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
3370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");
34d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach
35568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachnamespace {
36568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachclass ARMMCCodeEmitter : public MCCodeEmitter {
37568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  ARMMCCodeEmitter(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
38568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  void operator=(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
3959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  const MCInstrInfo &MCII;
4059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  const MCSubtargetInfo &STI;
41568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
42568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachpublic:
4359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  ARMMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
4459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                   MCContext &ctx)
45af0a2e6730ffb59405352269e1500b6e83e42d6aEvan Cheng    : MCII(mcii), STI(sti) {
46568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
47568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
48568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  ~ARMMCCodeEmitter() {}
49568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
5059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  bool isThumb() const {
5159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    // FIXME: Can tablegen auto-generate this?
5259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
5359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  }
5459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  bool isThumb2() const {
5559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
5659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  }
5759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  bool isTargetDarwin() const {
5859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    Triple TT(STI.getTargetTriple());
5959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    Triple::OSType OS = TT.getOS();
6059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    return OS == Triple::Darwin || OS == Triple::MacOSX || OS == Triple::IOS;
6159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  }
6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng
630de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach  unsigned getMachineSoImmOpValue(unsigned SoImm) const;
640de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach
659af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  // getBinaryCodeForInstr - TableGen'erated function for getting the
669af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  // binary encoding for an instruction.
67806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getBinaryCodeForInstr(const MCInst &MI,
68806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                 SmallVectorImpl<MCFixup> &Fixups) const;
699af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
709af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  /// getMachineOpValue - Return binary encoding of operand. If the machine
719af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  /// operand requires relocation, record the relocation and return zero.
72806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
73806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                             SmallVectorImpl<MCFixup> &Fixups) const;
749af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
757597212abced110723f2fee985a7d60557c092ecEvan Cheng  /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of
76971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson  /// the specified operand. This is used for operands with :lower16: and
777597212abced110723f2fee985a7d60557c092ecEvan Cheng  /// :upper16: prefixes.
787597212abced110723f2fee985a7d60557c092ecEvan Cheng  uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
797597212abced110723f2fee985a7d60557c092ecEvan Cheng                               SmallVectorImpl<MCFixup> &Fixups) const;
80837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim
8192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
82806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                              unsigned &Reg, unsigned &Imm,
83806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
8492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
85662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate
8609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  /// BL branch target.
87662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
88662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const;
89662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
9009aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
9109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  /// BLX branch target.
9209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
9309aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling                                    SmallVectorImpl<MCFixup> &Fixups) const;
9409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling
95e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach  /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
96e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach  uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
97e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const;
98e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach
9901086451393ef33e82b6fad623989dd97dd70edfJim Grosbach  /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
10001086451393ef33e82b6fad623989dd97dd70edfJim Grosbach  uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
10101086451393ef33e82b6fad623989dd97dd70edfJim Grosbach                                    SmallVectorImpl<MCFixup> &Fixups) const;
10201086451393ef33e82b6fad623989dd97dd70edfJim Grosbach
103027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach  /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
104027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach  uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
105dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                                   SmallVectorImpl<MCFixup> &Fixups) const;
106dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling
107c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach  /// getBranchTargetOpValue - Return encoding info for 24-bit immediate
108c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach  /// branch target.
109c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach  uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
110c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach                                  SmallVectorImpl<MCFixup> &Fixups) const;
111c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
112c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
113c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  /// immediate Thumb2 direct branch target.
114c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
115c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson                                  SmallVectorImpl<MCFixup> &Fixups) const;
11610096dbdef22a10a6a4444437c935ab428545525Owen Anderson
117685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate
118685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  /// branch target.
119685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
120685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim                                     SmallVectorImpl<MCFixup> &Fixups) const;
121f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
122f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson                                     SmallVectorImpl<MCFixup> &Fixups) const;
123c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson
1245d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
1255d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  /// ADR label target.
1265d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
1275d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
128d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
129d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
130a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson  uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
131a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson                              SmallVectorImpl<MCFixup> &Fixups) const;
132971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
1335d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach
13492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
13592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// operand.
136806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
137806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const;
13892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
139f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.
140f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
141f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling                                         SmallVectorImpl<MCFixup> &Fixups)const;
1420f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson
1439d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
1449d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  /// operand.
1459d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
1469d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson                                   SmallVectorImpl<MCFixup> &Fixups) const;
147b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
148b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2'
149b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  /// operand.
150b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
151b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const;
152b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
153a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2'
154a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  /// operand.
155a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
156a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
1579d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
1589d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
15954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
16054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  /// operand as needed by load/store instructions.
16154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
16254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
16354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
1645d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  /// getLdStmModeOpValue - Return encoding for load/store multiple mode.
1655d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,
1665d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const {
1675d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();
1685d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    switch (Mode) {
1695f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay    default: assert(0 && "Unknown addressing sub-mode!");
1705d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::da: return 0;
1715d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::ia: return 1;
1725d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::db: return 2;
1735d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::ib: return 3;
1745d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    }
1755d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  }
17699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
17799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  ///
17899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {
17999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    switch (ShOpc) {
18099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    default: llvm_unreachable("Unknown shift opc!");
18199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::no_shift:
18299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::lsl: return 0;
18399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::lsr: return 1;
18499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::asr: return 2;
18599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::ror:
18699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::rrx: return 3;
18799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    }
18899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    return 0;
18999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  }
19099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
19199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getAddrMode2OpValue - Return encoding for addrmode2 operands.
19299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
19399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
19499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
19599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
19699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
19799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
19899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
1997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  /// getPostIdxRegOpValue - Return encoding for postidx_reg operands.
2007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
2017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                SmallVectorImpl<MCFixup> &Fixups) const;
2027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2037eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
2047eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
2057eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
2067eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach
207570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  /// getAddrMode3OpValue - Return encoding for addrmode3 operands.
208570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
209570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
2105d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach
211d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12'
212d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  /// operand.
213d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
214d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
215d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach
216f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
217f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
21822447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling                                SmallVectorImpl<MCFixup> &Fixups) const;
2191fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling
220b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
221b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
222b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling                                SmallVectorImpl<MCFixup> &Fixups) const;
223b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling
22492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
225806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
226806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
2273e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach
22808bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach  /// getCCOutOpValue - Return encoding of the 's' bit.
229806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
230806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
23108bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
23208bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    // '1' respectively.
23308bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    return MI.getOperand(Op).getReg() == ARM::CPSR;
23408bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach  }
235ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
2362a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach  /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
237806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
238806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
2392a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    unsigned SoImm = MI.getOperand(Op).getImm();
2402a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    int SoImmVal = ARM_AM::getSOImmVal(SoImm);
2412a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    assert(SoImmVal != -1 && "Not a valid so_imm value!");
2422a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach
2432a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    // Encode rotate_imm.
2442a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
2452a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach      << ARMII::SoRotImmShift;
2462a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach
2472a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    // Encode immed_8.
2482a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
2492a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    return Binary;
2502a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach  }
2517bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
2525de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
2535de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
2545de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson                           SmallVectorImpl<MCFixup> &Fixups) const {
2555de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    unsigned SoImm = MI.getOperand(Op).getImm();
2565de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    unsigned Encoded =  ARM_AM::getT2SOImmVal(SoImm);
2575de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
2585de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    return Encoded;
2595de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  }
26008bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach
26175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
26275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
26375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
26475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
2656af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
2666af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
2670e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
2680e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
26975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
270ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  /// getSORegOpValue - Return an encoded so_reg shifted register value.
271152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,
272152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson                           SmallVectorImpl<MCFixup> &Fixups) const;
273152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,
274806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const;
2755de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
2765de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson                             SmallVectorImpl<MCFixup> &Fixups) const;
277ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
278806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
279806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const {
280498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson    return 64 - MI.getOperand(Op).getImm();
281498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson  }
2828abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach
283806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
284806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                      SmallVectorImpl<MCFixup> &Fixups) const;
2853fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach
286806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
287806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                  SmallVectorImpl<MCFixup> &Fixups) const;
288806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
289806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                      SmallVectorImpl<MCFixup> &Fixups) const;
290183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
291183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang                                        SmallVectorImpl<MCFixup> &Fixups) const;
2928e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
2938e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson                                        SmallVectorImpl<MCFixup> &Fixups) const;
294806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
295806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
2966b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach
2973116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op,
2983116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                             SmallVectorImpl<MCFixup> &Fixups) const;
2993116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op,
3003116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                              SmallVectorImpl<MCFixup> &Fixups) const;
3013116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op,
3023116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                              SmallVectorImpl<MCFixup> &Fixups) const;
3033116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op,
3043116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                              SmallVectorImpl<MCFixup> &Fixups) const;
305a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
3066d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson  unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op,
3076d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson                                 SmallVectorImpl<MCFixup> &Fixups) const;
3086d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson
309c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
310c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson                                      unsigned EncodedValue) const;
31157dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,
312cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling                                          unsigned EncodedValue) const;
3138f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
314cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling                                    unsigned EncodedValue) const;
315cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling
316cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  unsigned VFPThumb2PostEncoder(const MCInst &MI,
317cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling                                unsigned EncodedValue) const;
318c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson
31970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  void EmitByte(unsigned char C, raw_ostream &OS) const {
320568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    OS << (char)C;
321568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
322568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
32370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
324568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    // Output the constant in little endian byte order.
325568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    for (unsigned i = 0; i != Size; ++i) {
32670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach      EmitByte(Val & 255, OS);
327568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach      Val >>= 8;
328568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    }
329568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
330568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
331568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
332568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach                         SmallVectorImpl<MCFixup> &Fixups) const;
333568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach};
334568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
335568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} // end anonymous namespace
336568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
33759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan ChengMCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII,
33859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                            const MCSubtargetInfo &STI,
3390800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling                                            MCContext &Ctx) {
34059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  return new ARMMCCodeEmitter(MCII, STI, Ctx);
341568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}
342568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
3437bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
3447bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
345c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson/// Thumb2 mode.
346c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
347c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson                                                 unsigned EncodedValue) const {
34859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
3497bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach    // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
350c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
351c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    // set to 1111.
352c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    unsigned Bit24 = EncodedValue & 0x01000000;
353c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    unsigned Bit28 = Bit24 << 4;
354c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue &= 0xEFFFFFFF;
355c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue |= Bit28;
356c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue |= 0x0F000000;
357c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  }
3587bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
359c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  return EncodedValue;
360c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson}
361c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson
36257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
3637bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
36457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// Thumb2 mode.
36557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
36657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson                                                 unsigned EncodedValue) const {
36759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
36857dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson    EncodedValue &= 0xF0FFFFFF;
36957dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson    EncodedValue |= 0x09000000;
37057dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  }
3717bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
37257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  return EncodedValue;
37357dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson}
37457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson
3758f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
3767bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
3778f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// Thumb2 mode.
3788f143913141991baaa535ca0da7c8a81606d6392Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
3798f143913141991baaa535ca0da7c8a81606d6392Owen Anderson                                                 unsigned EncodedValue) const {
38059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
3818f143913141991baaa535ca0da7c8a81606d6392Owen Anderson    EncodedValue &= 0x00FFFFFF;
3828f143913141991baaa535ca0da7c8a81606d6392Owen Anderson    EncodedValue |= 0xEE000000;
3838f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  }
3847bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
3858f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  return EncodedValue;
3868f143913141991baaa535ca0da7c8a81606d6392Owen Anderson}
3878f143913141991baaa535ca0da7c8a81606d6392Owen Anderson
388cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
389cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// them to their Thumb2 form if we are currently in Thumb2 mode.
390cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendlingunsigned ARMMCCodeEmitter::
391cf590263cd5c24ccf1d08cef612738d99cd980d9Bill WendlingVFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const {
39259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
393cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling    EncodedValue &= 0x0FFFFFFF;
394cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling    EncodedValue |= 0xE0000000;
395cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  }
396cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  return EncodedValue;
397cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling}
39857dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson
39956ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// getMachineOpValue - Return binary encoding of operand. If the machine
40056ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// operand requires relocation, record the relocation and return zero.
401806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
402806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetMachineOpValue(const MCInst &MI, const MCOperand &MO,
403806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                  SmallVectorImpl<MCFixup> &Fixups) const {
404bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  if (MO.isReg()) {
4050800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    unsigned Reg = MO.getReg();
4060800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    unsigned RegNo = getARMRegisterNumbering(Reg);
407d8a11c25fa64c152628cfcf5f9d36eb60242b302Jim Grosbach
408b0708d292bbe04cfcfe0c5cb5e27d8a872c9839aJim Grosbach    // Q registers are encoded as 2x their register number.
4090800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    switch (Reg) {
4100800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    default:
4110800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling      return RegNo;
4120800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q0:  case ARM::Q1:  case ARM::Q2:  case ARM::Q3:
4130800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q4:  case ARM::Q5:  case ARM::Q6:  case ARM::Q7:
4140800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q8:  case ARM::Q9:  case ARM::Q10: case ARM::Q11:
4150800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
4160800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling      return 2 * RegNo;
41790d4cf931477b497553a9f2d0ed53377dd5dd88cOwen Anderson    }
418bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  } else if (MO.isImm()) {
41956ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach    return static_cast<unsigned>(MO.getImm());
420bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  } else if (MO.isFPImm()) {
421bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling    return static_cast<unsigned>(APFloat(MO.getFPImm())
422bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling                     .bitcastToAPInt().getHiBits(32).getLimitedValue());
4230800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  }
4240800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
425817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach  llvm_unreachable("Unable to encode MCOperand!");
42656ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach  return 0;
42756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach}
42856ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach
4295df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
430806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachbool ARMMCCodeEmitter::
431806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
432806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                       unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const {
4333e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  const MCOperand &MO  = MI.getOperand(OpIdx);
4343e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
4359af3d1c0dc2250793ada1ca6cfa98e9f1253f7f9Jim Grosbach
43692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Reg = getARMRegisterNumbering(MO.getReg());
43792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
43892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  int32_t SImm = MO1.getImm();
43992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  bool isAdd = true;
4405df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
441ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  // Special value for #-0
4420da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson  if (SImm == INT32_MIN) {
44392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    SImm = 0;
4440da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    isAdd = false;
4450da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson  }
4465df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
447ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
44892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  if (SImm < 0) {
44992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    SImm = -SImm;
45092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    isAdd = false;
45192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  }
45292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
45392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Imm = SImm;
45492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  return isAdd;
45592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling}
4565df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
457dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Helper function to get the branch target operand,
458dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// which is either an immediate or requires a fixup.
459dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlingstatic uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
460dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                                       unsigned FixupKind,
461dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                                       SmallVectorImpl<MCFixup> &Fixups) {
462662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
463662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
464662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  // If the destination is an immediate, we have nothing to do.
465662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  if (MO.isImm()) return MO.getImm();
466dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  assert(MO.isExpr() && "Unexpected branch target type!");
467662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  const MCExpr *Expr = MO.getExpr();
468dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  MCFixupKind Kind = MCFixupKind(FixupKind);
469662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  Fixups.push_back(MCFixup::Create(0, Expr, Kind));
470662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
471662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  // All of the information is in the fixup.
472662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  return 0;
473662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach}
474662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
475559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are
476559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// determined by negating them and XOR'ing them with bit 23.
477559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Andersonstatic int32_t encodeThumbBLOffset(int32_t offset) {
478559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset >>= 1;
479559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  uint32_t S  = (offset & 0x800000) >> 23;
480559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  uint32_t J1 = (offset & 0x400000) >> 22;
481559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  uint32_t J2 = (offset & 0x200000) >> 21;
482559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J1 = (~J1 & 0x1);
483559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J2 = (~J2 & 0x1);
484559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J1 ^= S;
485559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J2 ^= S;
486559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson
487559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset &= ~0x600000;
488559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset |= J1 << 22;
489559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset |= J2 << 21;
490559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson
491559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  return offset;
492559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson}
493559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson
494dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getThumbBLTargetOpValue - Return encoding info for immediate branch target.
495c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbachuint32_t ARMMCCodeEmitter::
496dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
497c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
498559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
499559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  if (MO.isExpr())
500559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl,
501559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson                                    Fixups);
502559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  return encodeThumbBLOffset(MO.getImm());
503dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling}
504c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
50509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
50609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// BLX branch target.
50709aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendlinguint32_t ARMMCCodeEmitter::
50809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill WendlinggetThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
50909aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling                         SmallVectorImpl<MCFixup> &Fixups) const {
510559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
511559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  if (MO.isExpr())
512559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx,
513559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson                                    Fixups);
514559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  return encodeThumbBLOffset(MO.getImm());
51509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling}
51609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling
517e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
518e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbachuint32_t ARMMCCodeEmitter::
519e246717c3a36a913fd4200776ed621649bb2b624Jim GrosbachgetThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
520e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
521391ac65377f2ad5e48a796e75120959e22430605Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
522391ac65377f2ad5e48a796e75120959e22430605Owen Anderson  if (MO.isExpr())
523559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br,
524559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson                                    Fixups);
525391ac65377f2ad5e48a796e75120959e22430605Owen Anderson  return (MO.getImm() >> 1);
526e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach}
527e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach
52801086451393ef33e82b6fad623989dd97dd70edfJim Grosbach/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
52901086451393ef33e82b6fad623989dd97dd70edfJim Grosbachuint32_t ARMMCCodeEmitter::
53001086451393ef33e82b6fad623989dd97dd70edfJim GrosbachgetThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
531e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach                         SmallVectorImpl<MCFixup> &Fixups) const {
532721cb1fde07423fd1905338d443172a8028ad634Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
533721cb1fde07423fd1905338d443172a8028ad634Owen Anderson  if (MO.isExpr())
534721cb1fde07423fd1905338d443172a8028ad634Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc,
535721cb1fde07423fd1905338d443172a8028ad634Owen Anderson                                    Fixups);
536721cb1fde07423fd1905338d443172a8028ad634Owen Anderson  return (MO.getImm() >> 1);
53701086451393ef33e82b6fad623989dd97dd70edfJim Grosbach}
53801086451393ef33e82b6fad623989dd97dd70edfJim Grosbach
539027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
540dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter::
541027d6e8d1ca04e4096fb3a27579b861d861466c5Jim GrosbachgetThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
542dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                        SmallVectorImpl<MCFixup> &Fixups) const {
54321df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
54421df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson  if (MO.isExpr())
54521df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups);
54621df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson  return (MO.getImm() >> 1);
547dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling}
548c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
549685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// Return true if this branch has a non-always predication
550685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimstatic bool HasConditionalBranch(const MCInst &MI) {
551685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  int NumOp = MI.getNumOperands();
552685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  if (NumOp >= 2) {
553685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    for (int i = 0; i < NumOp-1; ++i) {
554685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      const MCOperand &MCOp1 = MI.getOperand(i);
555685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      const MCOperand &MCOp2 = MI.getOperand(i + 1);
55610096dbdef22a10a6a4444437c935ab428545525Owen Anderson      if (MCOp1.isImm() && MCOp2.isReg() &&
557685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim          (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) {
55810096dbdef22a10a6a4444437c935ab428545525Owen Anderson        if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL)
559685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim          return true;
560685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      }
561685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    }
562685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  }
563685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  return false;
564685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim}
565685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
566dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
567dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target.
568dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter::
569dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
570dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                       SmallVectorImpl<MCFixup> &Fixups) const {
571092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach  // FIXME: This really, really shouldn't use TargetMachine. We don't want
572092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach  // coupling between MC and TM anywhere we can help it.
57359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2())
574c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    return
575c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson      ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups);
576685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  return getARMBranchTargetOpValue(MI, OpIdx, Fixups);
577685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim}
578685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
579685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
580685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// target.
581685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimuint32_t ARMMCCodeEmitter::
582685c350ae76b588e1f00c01a511fe8bd57f18394Jason W KimgetARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
583685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim                          SmallVectorImpl<MCFixup> &Fixups) const {
584d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
585d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  if (MO.isExpr()) {
58610096dbdef22a10a6a4444437c935ab428545525Owen Anderson    if (HasConditionalBranch(MI))
587d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson      return ::getBranchTargetOpValue(MI, OpIdx,
588d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson                                      ARM::fixup_arm_condbranch, Fixups);
58910096dbdef22a10a6a4444437c935ab428545525Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx,
590d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson                                    ARM::fixup_arm_uncondbranch, Fixups);
591d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  }
592d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson
593d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  return MO.getImm() >> 2;
594c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach}
595c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
596f1eab597b2316c6cfcabfcee98895fedb2071722Owen Andersonuint32_t ARMMCCodeEmitter::
597f1eab597b2316c6cfcabfcee98895fedb2071722Owen AndersongetARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
598f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson                          SmallVectorImpl<MCFixup> &Fixups) const {
599f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
600f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  if (MO.isExpr()) {
60110096dbdef22a10a6a4444437c935ab428545525Owen Anderson    if (HasConditionalBranch(MI))
602f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson      return ::getBranchTargetOpValue(MI, OpIdx,
603f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson                                      ARM::fixup_arm_condbranch, Fixups);
60410096dbdef22a10a6a4444437c935ab428545525Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx,
605f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson                                    ARM::fixup_arm_uncondbranch, Fixups);
606f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  }
607685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
608f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  return MO.getImm() >> 1;
609f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson}
610685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
611c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
612c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// immediate branch target.
613c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Andersonuint32_t ARMMCCodeEmitter::
614c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen AndersongetUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
615c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson                       SmallVectorImpl<MCFixup> &Fixups) const {
616c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  unsigned Val =
617c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups);
618c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool I  = (Val & 0x800000);
619c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool J1 = (Val & 0x400000);
620c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool J2 = (Val & 0x200000);
621c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  if (I ^ J1)
622c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val &= ~0x400000;
623c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  else
624c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val |= 0x400000;
625971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
626c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  if (I ^ J2)
627c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val &= ~0x200000;
628c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  else
629c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val |= 0x200000;
630971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
631c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  return Val;
632c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson}
633c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson
634dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
635dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target.
6365d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbachuint32_t ARMMCCodeEmitter::
6375d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim GrosbachgetAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
6385d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach                   SmallVectorImpl<MCFixup> &Fixups) const {
63996425c846494c1c20a4c931f4783571295ab170cOwen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
64096425c846494c1c20a4c931f4783571295ab170cOwen Anderson  if (MO.isExpr())
64196425c846494c1c20a4c931f4783571295ab170cOwen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12,
64296425c846494c1c20a4c931f4783571295ab170cOwen Anderson                                    Fixups);
64396425c846494c1c20a4c931f4783571295ab170cOwen Anderson  int32_t offset = MO.getImm();
64496425c846494c1c20a4c931f4783571295ab170cOwen Anderson  uint32_t Val = 0x2000;
64596425c846494c1c20a4c931f4783571295ab170cOwen Anderson  if (offset < 0) {
64696425c846494c1c20a4c931f4783571295ab170cOwen Anderson    Val = 0x1000;
64796425c846494c1c20a4c931f4783571295ab170cOwen Anderson    offset *= -1;
64896425c846494c1c20a4c931f4783571295ab170cOwen Anderson  }
64996425c846494c1c20a4c931f4783571295ab170cOwen Anderson  Val |= offset;
65096425c846494c1c20a4c931f4783571295ab170cOwen Anderson  return Val;
6515d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach}
6525d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach
653a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
654a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// target.
655a838a25d59838adfa91463f6a918ae3adeb352c1Owen Andersonuint32_t ARMMCCodeEmitter::
656a838a25d59838adfa91463f6a918ae3adeb352c1Owen AndersongetT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
657a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson                   SmallVectorImpl<MCFixup> &Fixups) const {
65896425c846494c1c20a4c931f4783571295ab170cOwen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
65996425c846494c1c20a4c931f4783571295ab170cOwen Anderson  if (MO.isExpr())
66096425c846494c1c20a4c931f4783571295ab170cOwen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
66196425c846494c1c20a4c931f4783571295ab170cOwen Anderson                                    Fixups);
66208fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  int32_t Val = MO.getImm();
66308fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  if (Val < 0) {
66408fef885eb39339a47e3be7f0842b1db33683003Owen Anderson    Val *= -1;
66508fef885eb39339a47e3be7f0842b1db33683003Owen Anderson    Val |= 0x1000;
66608fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  }
66708fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  return Val;
668a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson}
669a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson
670d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// getAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
671d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// target.
672d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbachuint32_t ARMMCCodeEmitter::
673d40963c4065432ec7e47879d3ca665a54ee903b6Jim GrosbachgetThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
674d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                   SmallVectorImpl<MCFixup> &Fixups) const {
67596425c846494c1c20a4c931f4783571295ab170cOwen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
67696425c846494c1c20a4c931f4783571295ab170cOwen Anderson  if (MO.isExpr())
67796425c846494c1c20a4c931f4783571295ab170cOwen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10,
67896425c846494c1c20a4c931f4783571295ab170cOwen Anderson                                    Fixups);
67996425c846494c1c20a4c931f4783571295ab170cOwen Anderson  return MO.getImm();
680d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach}
681d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach
682f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg'
683f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// operand.
6840f4b60d43a289671082deee3bd56a3a055afb16aOwen Andersonuint32_t ARMMCCodeEmitter::
685f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
686f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling                              SmallVectorImpl<MCFixup> &) const {
687f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  // [Rn, Rm]
688f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  //   {5-3} = Rm
689f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  //   {2-0} = Rn
6900f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx);
691f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  const MCOperand &MO2 = MI.getOperand(OpIdx + 1);
6920f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  unsigned Rn = getARMRegisterNumbering(MO1.getReg());
6930f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  unsigned Rm = getARMRegisterNumbering(MO2.getReg());
6940f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  return (Rm << 3) | Rn;
6950f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson}
6960f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson
69792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
698806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter::
699806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
700806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
70192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {17-13} = reg
70292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {12}    = (U)nsigned (add == '1', sub == '0')
70392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {11-0}  = imm12
70492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  unsigned Reg, Imm12;
70570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  bool isAdd = true;
70670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  // If The first operand isn't a register, we have a label reference.
70770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
708971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson  if (!MO.isReg()) {
709679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
71070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Imm12 = 0;
71197dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach    isAdd = false ; // 'U' bit is set as part of the fixup.
71270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
713fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson    if (MO.isExpr()) {
714fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      const MCExpr *Expr = MO.getExpr();
715fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson
716fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      MCFixupKind Kind;
717fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      if (isThumb2())
718fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
719fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      else
720fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
721fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      Fixups.push_back(MCFixup::Create(0, Expr, Kind));
722fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson
723fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      ++MCNumCPRelocations;
724fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson    } else {
725fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      Reg = ARM::PC;
726fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      int32_t Offset = MO.getImm();
727fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      if (Offset < 0) {
728fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        Offset *= -1;
729fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        isAdd = false;
730fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      }
731fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      Imm12 = Offset;
732fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson    }
73370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  } else
73470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups);
73592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
73692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  uint32_t Binary = Imm12 & 0xfff;
73792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
738ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  if (isAdd)
73992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    Binary |= (1 << 12);
74092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Binary |= (Reg << 13);
74192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  return Binary;
74292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling}
74392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
744a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// getT2Imm8s4OpValue - Return encoding info for
745a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// '+/- imm8<<2' operand.
746a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachuint32_t ARMMCCodeEmitter::
747a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachgetT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
748a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                   SmallVectorImpl<MCFixup> &Fixups) const {
749a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // FIXME: The immediate operand should have already been encoded like this
750a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // before ever getting here. The encoder method should just need to combine
751a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // the MI operands for the register and the offset into a single
752a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // representation for the complex operand in the .td file. This isn't just
753a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // style, unfortunately. As-is, we can't represent the distinct encoding
754a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // for #-0.
755a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
756a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // {8}    = (U)nsigned (add == '1', sub == '0')
757a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // {7-0}  = imm8
758a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  int32_t Imm8 = MI.getOperand(OpIdx).getImm();
759a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isAdd = Imm8 >= 0;
760a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
761a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
762a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (Imm8 < 0)
763a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Imm8 = -Imm8;
764a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
765a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Scaled by 4.
766a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Imm8 /= 4;
767a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
768a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  uint32_t Binary = Imm8 & 0xff;
769a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
770a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (isAdd)
771a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Binary |= (1 << 8);
772a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return Binary;
773a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
774a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
7759d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// getT2AddrModeImm8s4OpValue - Return encoding info for
7769d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// 'reg +/- imm8<<2' operand.
7779d63d90de5e57ad96f467b270544443a9284eb2bOwen Andersonuint32_t ARMMCCodeEmitter::
7789d63d90de5e57ad96f467b270544443a9284eb2bOwen AndersongetT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
7799d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson                        SmallVectorImpl<MCFixup> &Fixups) const {
78090cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {12-9} = reg
78190cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {8}    = (U)nsigned (add == '1', sub == '0')
78290cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {7-0}  = imm8
7839d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  unsigned Reg, Imm8;
7849d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  bool isAdd = true;
7859d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  // If The first operand isn't a register, we have a label reference.
7869d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  const MCOperand &MO = MI.getOperand(OpIdx);
7879d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  if (!MO.isReg()) {
7889d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
7899d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    Imm8 = 0;
7909d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    isAdd = false ; // 'U' bit is set as part of the fixup.
7919d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
7929d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    assert(MO.isExpr() && "Unexpected machine operand type!");
7939d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    const MCExpr *Expr = MO.getExpr();
7949d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
7959d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    Fixups.push_back(MCFixup::Create(0, Expr, Kind));
7969d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
7979d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    ++MCNumCPRelocations;
7989d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  } else
7999d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
8009d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
801a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // FIXME: The immediate operand should have already been encoded like this
802a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // before ever getting here. The encoder method should just need to combine
803a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // the MI operands for the register and the offset into a single
804a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // representation for the complex operand in the .td file. This isn't just
805a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // style, unfortunately. As-is, we can't represent the distinct encoding
806a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // for #-0.
8079d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  uint32_t Binary = (Imm8 >> 2) & 0xff;
8089d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
8099d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  if (isAdd)
81090cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach    Binary |= (1 << 8);
8119d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  Binary |= (Reg << 9);
8129d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  return Binary;
8139d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson}
8149d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
815b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// getT2AddrModeImm0_1020s4OpValue - Return encoding info for
816b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// 'reg + imm8<<2' operand.
817b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbachuint32_t ARMMCCodeEmitter::
818b6aed508e310e31dcb080e761ca856127cec0773Jim GrosbachgetT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
819b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
820b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  // {11-8} = reg
821b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  // {7-0}  = imm8
822b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
823b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
824b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  unsigned Reg = getARMRegisterNumbering(MO.getReg());
825b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  unsigned Imm8 = MO1.getImm();
826b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  return (Reg << 8) | Imm8;
827b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach}
828b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
82986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// FIXME: This routine assumes that a binary
83086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// expression will always result in a PCRel expression
83186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// In reality, its only true if one or more subexpressions
83286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// is itself a PCRel (i.e. "." in asm or some other pcrel construct)
83386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// but this is good enough for now.
83486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kimstatic bool EvaluateAsPCRel(const MCExpr *Expr) {
83586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  switch (Expr->getKind()) {
8365f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay  default: assert(0 && "Unexpected expression type");
83786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case MCExpr::SymbolRef: return false;
83886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case MCExpr::Binary: return true;
83986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  }
84086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim}
84186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim
8427597212abced110723f2fee985a7d60557c092ecEvan Chenguint32_t
8437597212abced110723f2fee985a7d60557c092ecEvan ChengARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
8447597212abced110723f2fee985a7d60557c092ecEvan Cheng                                      SmallVectorImpl<MCFixup> &Fixups) const {
845837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim  // {20-16} = imm{15-12}
846837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim  // {11-0}  = imm{11-0}
8477bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
8487597212abced110723f2fee985a7d60557c092ecEvan Cheng  if (MO.isImm())
8497597212abced110723f2fee985a7d60557c092ecEvan Cheng    // Hi / lo 16 bits already extracted during earlier passes.
850837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    return static_cast<unsigned>(MO.getImm());
8517597212abced110723f2fee985a7d60557c092ecEvan Cheng
8527597212abced110723f2fee985a7d60557c092ecEvan Cheng  // Handle :upper16: and :lower16: assembly prefixes.
8537597212abced110723f2fee985a7d60557c092ecEvan Cheng  const MCExpr *E = MO.getExpr();
8547597212abced110723f2fee985a7d60557c092ecEvan Cheng  if (E->getKind() == MCExpr::Target) {
8557597212abced110723f2fee985a7d60557c092ecEvan Cheng    const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E);
8567597212abced110723f2fee985a7d60557c092ecEvan Cheng    E = ARM16Expr->getSubExpr();
8577597212abced110723f2fee985a7d60557c092ecEvan Cheng
858837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    MCFixupKind Kind;
8597597212abced110723f2fee985a7d60557c092ecEvan Cheng    switch (ARM16Expr->getKind()) {
8605f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay    default: assert(0 && "Unsupported ARMFixup");
8617597212abced110723f2fee985a7d60557c092ecEvan Cheng    case ARMMCExpr::VK_ARM_HI16:
86259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng      if (!isTargetDarwin() && EvaluateAsPCRel(E))
86359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
864f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movt_hi16_pcrel
865f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movt_hi16_pcrel);
866f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      else
86759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
868f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movt_hi16
869f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movt_hi16);
870837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim      break;
8717597212abced110723f2fee985a7d60557c092ecEvan Cheng    case ARMMCExpr::VK_ARM_LO16:
87259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng      if (!isTargetDarwin() && EvaluateAsPCRel(E))
87359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
874f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movw_lo16_pcrel
875f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movw_lo16_pcrel);
876f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      else
87759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
878f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movw_lo16
879f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movw_lo16);
880837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim      break;
881837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    }
8827597212abced110723f2fee985a7d60557c092ecEvan Cheng    Fixups.push_back(MCFixup::Create(0, E, Kind));
883837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    return 0;
884817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach  };
8857597212abced110723f2fee985a7d60557c092ecEvan Cheng
886817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach  llvm_unreachable("Unsupported MCExpr type in MCOperand!");
887837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim  return 0;
888837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim}
889837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim
890837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kimuint32_t ARMMCCodeEmitter::
89154fea632b161f98e96ec7275922e35102bcecc5dJim GrosbachgetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
89254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
89354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
89454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
89554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
89654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned Rn = getARMRegisterNumbering(MO.getReg());
89754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned Rm = getARMRegisterNumbering(MO1.getReg());
89854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
89954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
90099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
90199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned SBits = getShiftOp(ShOp);
90254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
90354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {16-13} = Rn
90454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {12}    = isAdd
90554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {11-0}  = shifter
90654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {3-0}  = Rm
90754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {4}    = 0
90854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {6-5}  = type
90954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {11-7} = imm
910570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t Binary = Rm;
91154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= Rn << 13;
91254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= SBits << 5;
91354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= ShImm << 7;
91454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  if (isAdd)
91554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach    Binary |= 1 << 12;
91654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  return Binary;
91754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach}
91854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
919570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbachuint32_t ARMMCCodeEmitter::
92099f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
92199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
92299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {17-14}  Rn
92399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {13}     1 == imm12, 0 == Rm
92499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {12}     isAdd
92599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {11-0}   imm12/Rm
92699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
92799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned Rn = getARMRegisterNumbering(MO.getReg());
92899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups);
92999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  Binary |= Rn << 14;
93099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  return Binary;
93199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach}
93299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
93399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter::
93499f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
93599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
93699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {13}     1 == imm12, 0 == Rm
93799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {12}     isAdd
93899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {11-0}   imm12/Rm
93999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
94099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
94199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned Imm = MO1.getImm();
94299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
94399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  bool isReg = MO.getReg() != 0;
94499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t Binary = ARM_AM::getAM2Offset(Imm);
94599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
94699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  if (isReg) {
94799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);
94899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    Binary <<= 7;                    // Shift amount is bits [11:7]
94999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]
95099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    Binary |= getARMRegisterNumbering(MO.getReg()); // Rm is bits [3:0]
95199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  }
95299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  return Binary | (isAdd << 12) | (isReg << 13);
95399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach}
95499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
95599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter::
9567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachgetPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
9577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                     SmallVectorImpl<MCFixup> &Fixups) const {
9587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // {4}      isAdd
9597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // {3-0}    Rm
9607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
9617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
96216578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = MO1.getImm() != 0;
9637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return getARMRegisterNumbering(MO.getReg()) | (isAdd << 4);
9647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
9657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
9667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachuint32_t ARMMCCodeEmitter::
9677eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim GrosbachgetAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
9687eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
9697eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {9}      1 == imm8, 0 == Rm
9707eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {8}      isAdd
9717eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {7-4}    imm7_4/zero
9727eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {3-0}    imm3_0/Rm
9737eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
9747eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
9757eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  unsigned Imm = MO1.getImm();
9767eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
9777eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  bool isImm = MO.getReg() == 0;
9787eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
9797eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
9807eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  if (!isImm)
9817eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach    Imm8 = getARMRegisterNumbering(MO.getReg());
9827eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  return Imm8 | (isAdd << 8) | (isImm << 9);
9837eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach}
9847eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach
9857eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbachuint32_t ARMMCCodeEmitter::
986570a9226913ebe1af04832b8fb3273c70b4ee152Jim GrosbachgetAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
987570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
988570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {13}     1 == imm8, 0 == Rm
989570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {12-9}   Rn
990570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {8}      isAdd
991570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {7-4}    imm7_4/zero
992570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {3-0}    imm3_0/Rm
993570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
994570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
995570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
996570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  unsigned Rn = getARMRegisterNumbering(MO.getReg());
997570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  unsigned Imm = MO2.getImm();
998570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
999570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  bool isImm = MO1.getReg() == 0;
1000570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
1001570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
1002570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  if (!isImm)
1003570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach    Imm8 = getARMRegisterNumbering(MO1.getReg());
1004570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
1005570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach}
1006570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach
1007b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands.
1008d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbachuint32_t ARMMCCodeEmitter::
1009d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim GrosbachgetAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
1010d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
1011d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // [SP, #imm]
1012d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  //   {7-0} = imm8
1013d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1014b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  assert(MI.getOperand(OpIdx).getReg() == ARM::SP &&
1015b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling         "Unexpected base register!");
10167a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
1017d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // The immediate is already shifted for the implicit zeroes, so no change
1018d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // here.
1019d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  return MO1.getImm() & 0xff;
1020d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach}
1021d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach
1022f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
1023272df516d7a9b1f0f69174276abaa759816ee456Bill Wendlinguint32_t ARMMCCodeEmitter::
1024f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
102522447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling                     SmallVectorImpl<MCFixup> &Fixups) const {
1026ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  // [Rn, #imm]
1027ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  //   {7-3} = imm5
1028ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  //   {2-0} = Rn
1029ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  const MCOperand &MO = MI.getOperand(OpIdx);
1030ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1031ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  unsigned Rn = getARMRegisterNumbering(MO.getReg());
1032656b3d22f70c2d1c8a5286f7270cb380df862565Matt Beaumont-Gay  unsigned Imm5 = MO1.getImm();
1033272df516d7a9b1f0f69174276abaa759816ee456Bill Wendling  return ((Imm5 & 0x1f) << 3) | Rn;
10341fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling}
10351fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling
1036b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
1037b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendlinguint32_t ARMMCCodeEmitter::
1038b8958b031ec5163261f490f131780c5dc3d823d6Bill WendlinggetAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
1039b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling                     SmallVectorImpl<MCFixup> &Fixups) const {
1040a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
1041a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson  if (MO.isExpr())
1042a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups);
1043a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson  return (MO.getImm() >> 2);
1044b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling}
1045b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling
10465177f79c378b47e38bed5ac05ba4b597f31b864eJim Grosbach/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand.
1047806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter::
1048806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
1049806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
105092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {12-9} = reg
105192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {8}    = (U)nsigned (add == '1', sub == '0')
105292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {7-0}  = imm8
105392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  unsigned Reg, Imm8;
105497dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  bool isAdd;
105570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  // If The first operand isn't a register, we have a label reference.
105670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
105770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  if (!MO.isReg()) {
1058679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
105970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Imm8 = 0;
106097dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach    isAdd = false; // 'U' bit is handled as part of the fixup.
106170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
106270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    assert(MO.isExpr() && "Unexpected machine operand type!");
106370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    const MCExpr *Expr = MO.getExpr();
1064d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson    MCFixupKind Kind;
106559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    if (isThumb2())
1066d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson      Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
1067d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson    else
1068d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson      Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
106970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind));
107070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
107170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    ++MCNumCPRelocations;
107297dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  } else {
107370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
107497dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach    isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
107597dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  }
107692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
107792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
107892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
107997dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  if (isAdd)
108092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    Binary |= (1 << 8);
108192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Binary |= (Reg << 9);
10823e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  return Binary;
10833e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach}
10843e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach
1085806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1086152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
1087806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                SmallVectorImpl<MCFixup> &Fixups) const {
10880800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
1089354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // shifted. The second is Rs, the amount to shift by, and the third specifies
1090354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // the type of the shift.
109135b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach  //
1092ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // {3-0} = Rm.
1093354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {4}   = 1
1094ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // {6-5} = type
1095354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {11-8} = Rs
1096354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {7}    = 0
1097ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1098ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO  = MI.getOperand(OpIdx);
1099ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1100ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
1101ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
1102ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1103ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode Rm.
1104ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned Binary = getARMRegisterNumbering(MO.getReg());
1105ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1106ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode the shift opcode.
1107ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned SBits = 0;
1108ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned Rs = MO1.getReg();
1109ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  if (Rs) {
1110ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // Set shift operand (bit[7:4]).
1111ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSL - 0001
1112ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSR - 0011
1113ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ASR - 0101
1114ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ROR - 0111
1115ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    switch (SOpc) {
1116ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    default: llvm_unreachable("Unknown shift opc!");
1117ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsl: SBits = 0x1; break;
1118ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsr: SBits = 0x3; break;
1119ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::asr: SBits = 0x5; break;
1120ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::ror: SBits = 0x7; break;
1121ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    }
1122ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  }
11230800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
1124ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  Binary |= SBits << 4;
1125ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1126354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // Encode the shift operation Rs.
1127152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode Rs bit[11:8].
1128152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
1129152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
1130152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson}
1131152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1132152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Andersonunsigned ARMMCCodeEmitter::
1133152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
1134152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson                SmallVectorImpl<MCFixup> &Fixups) const {
1135354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
1136354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // shifted. The second is the amount to shift by.
1137152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  //
1138152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // {3-0} = Rm.
1139354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {4}   = 0
1140152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // {6-5} = type
1141354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {11-7} = imm
1142152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1143152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  const MCOperand &MO  = MI.getOperand(OpIdx);
1144152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1145152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
1146152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1147152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode Rm.
1148152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned Binary = getARMRegisterNumbering(MO.getReg());
1149152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1150152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode the shift opcode.
1151152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned SBits = 0;
1152152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1153152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Set shift operand (bit[6:4]).
1154152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // LSL - 000
1155152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // LSR - 010
1156152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // ASR - 100
1157152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // ROR - 110
1158152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // RRX - 110 and bit[11:8] clear.
1159152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  switch (SOpc) {
1160152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  default: llvm_unreachable("Unknown shift opc!");
1161152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::lsl: SBits = 0x0; break;
1162152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::lsr: SBits = 0x2; break;
1163152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::asr: SBits = 0x4; break;
1164152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::ror: SBits = 0x6; break;
1165152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::rrx:
1166152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    Binary |= 0x60;
1167152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    return Binary;
1168ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  }
1169ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1170ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode shift_imm bit[11:7].
1171152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  Binary |= SBits << 4;
11723dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson  unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm());
11733dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson  assert(Offset && "Offset must be in range 1-32!");
11743dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson  if (Offset == 32) Offset = 0;
11753dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson  return Binary | (Offset << 7);
1176ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach}
1177ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1178152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1179806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
118075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
118175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson                SmallVectorImpl<MCFixup> &Fixups) const {
118275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
118375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO2 = MI.getOperand(OpNum+1);
11847bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach  const MCOperand &MO3 = MI.getOperand(OpNum+2);
11857bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
118675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // Encoded as [Rn, Rm, imm].
118775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // FIXME: Needs fixup support.
118875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned Value = getARMRegisterNumbering(MO1.getReg());
118975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 4;
119075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value |= getARMRegisterNumbering(MO2.getReg());
119175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 2;
119275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value |= MO3.getImm();
11937bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
119475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  return Value;
119575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson}
119675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
119775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter::
119875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
119975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson                         SmallVectorImpl<MCFixup> &Fixups) const {
120075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
120175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO2 = MI.getOperand(OpNum+1);
120275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
120375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // FIXME: Needs fixup support.
120475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned Value = getARMRegisterNumbering(MO1.getReg());
12057bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
120675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // Even though the immediate is 8 bits long, we need 9 bits in order
120775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // to represent the (inverse of the) sign bit.
120875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 9;
12096af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  int32_t tmp = (int32_t)MO2.getImm();
12106af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  if (tmp < 0)
12116af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    tmp = abs(tmp);
12126af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  else
12136af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    Value |= 256; // Set the ADD bit
12146af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  Value |= tmp & 255;
12156af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  return Value;
12166af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson}
12176af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson
12186af50f7dd12d82f0a80f3158102180eee4c921aaOwen Andersonunsigned ARMMCCodeEmitter::
12196af50f7dd12d82f0a80f3158102180eee4c921aaOwen AndersongetT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
12206af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson                         SmallVectorImpl<MCFixup> &Fixups) const {
12216af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
12226af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson
12236af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  // FIXME: Needs fixup support.
12246af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  unsigned Value = 0;
12256af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  int32_t tmp = (int32_t)MO1.getImm();
12266af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  if (tmp < 0)
12276af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    tmp = abs(tmp);
12286af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  else
12296af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    Value |= 256; // Set the ADD bit
12306af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  Value |= tmp & 255;
123175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  return Value;
123275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson}
123375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
123475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter::
12350e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen AndersongetT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
12360e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson                         SmallVectorImpl<MCFixup> &Fixups) const {
12370e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
12380e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson
12390e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  // FIXME: Needs fixup support.
12400e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  unsigned Value = 0;
12410e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  int32_t tmp = (int32_t)MO1.getImm();
12420e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  if (tmp < 0)
12430e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    tmp = abs(tmp);
12440e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  else
12450e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    Value |= 4096; // Set the ADD bit
12460e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  Value |= tmp & 4095;
12470e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  return Value;
12480e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson}
12490e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson
12500e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Andersonunsigned ARMMCCodeEmitter::
12515de6d841a5116152793dcab35a2e534a6a9aaa7aOwen AndersongetT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
12525de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson                SmallVectorImpl<MCFixup> &Fixups) const {
12535de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
12545de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // shifted. The second is the amount to shift by.
12555de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  //
12565de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {3-0} = Rm.
12575de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {4}   = 0
12585de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {6-5} = type
12595de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {11-7} = imm
12605de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
12615de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  const MCOperand &MO  = MI.getOperand(OpIdx);
12625de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
12635de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
12645de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
12655de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode Rm.
12665de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned Binary = getARMRegisterNumbering(MO.getReg());
12675de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
12685de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode the shift opcode.
12695de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned SBits = 0;
12705de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Set shift operand (bit[6:4]).
12715de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // LSL - 000
12725de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // LSR - 010
12735de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // ASR - 100
12745de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // ROR - 110
12755de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  switch (SOpc) {
12765de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  default: llvm_unreachable("Unknown shift opc!");
12775de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::lsl: SBits = 0x0; break;
12785de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::lsr: SBits = 0x2; break;
12795de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::asr: SBits = 0x4; break;
128012c7e90d369b4605aac0ddbd252231beacb2aabbOwen Anderson  case ARM_AM::rrx: // FALLTHROUGH
12815de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::ror: SBits = 0x6; break;
12825de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  }
12835de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
12845de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  Binary |= SBits << 4;
12855de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  if (SOpc == ARM_AM::rrx)
12865de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    return Binary;
12875de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
12885de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode shift_imm bit[11:7].
12895de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
12905de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson}
12915de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
12925de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Andersonunsigned ARMMCCodeEmitter::
1293806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
1294806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const {
12953fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
12963fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  // msb of the mask.
12973fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  const MCOperand &MO = MI.getOperand(Op);
12983fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t v = ~MO.getImm();
12993fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t lsb = CountTrailingZeros_32(v);
13003fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1;
13013fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
13023fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  return lsb | (msb << 5);
13033fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach}
13043fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach
1305806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1306806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetRegisterListOpValue(const MCInst &MI, unsigned Op,
13075e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling                       SmallVectorImpl<MCFixup> &Fixups) const {
13086bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  // VLDM/VSTM:
13096bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {12-8} = Vd
13106bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {7-0}  = Number of registers
13116bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //
13126bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  // LDM/STM:
13136bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {15-0}  = Bitfield of GPRs.
13146bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  unsigned Reg = MI.getOperand(Op).getReg();
1315be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng  bool SPRRegs = llvm::ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg);
1316be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng  bool DPRRegs = llvm::ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg);
13176bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
13185e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  unsigned Binary = 0;
13196bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
13206bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  if (SPRRegs || DPRRegs) {
13216bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    // VLDM/VSTM
13226bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    unsigned RegNo = getARMRegisterNumbering(Reg);
13236bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;
13246bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    Binary |= (RegNo & 0x1f) << 8;
13256bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    if (SPRRegs)
13266bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= NumRegs;
13276bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    else
13286bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= NumRegs * 2;
13296bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  } else {
13306bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {
13316bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      unsigned RegNo = getARMRegisterNumbering(MI.getOperand(I).getReg());
13326bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= 1 << RegNo;
13336bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    }
13345e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  }
13356bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
13366b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach  return Binary;
13376b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach}
13386b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach
13398e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along
13408e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// with the alignment operand.
1341806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1342806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
1343806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
1344d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  const MCOperand &Reg = MI.getOperand(Op);
13450800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  const MCOperand &Imm = MI.getOperand(Op + 1);
134635b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach
1347d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
13480800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  unsigned Align = 0;
13490800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
13500800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  switch (Imm.getImm()) {
13510800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  default: break;
13520800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 2:
13530800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 4:
13540800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 8:  Align = 0x01; break;
13550800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 16: Align = 0x02; break;
13560800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 32: Align = 0x03; break;
1357d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  }
13580800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
1359d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  return RegNo | (Align << 4);
1360d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson}
1361d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson
1362183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number
1363183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// along  with the alignment operand for use in VST1 and VLD1 with size 32.
1364183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wangunsigned ARMMCCodeEmitter::
1365183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P WanggetAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
1366183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang                                    SmallVectorImpl<MCFixup> &Fixups) const {
1367183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  const MCOperand &Reg = MI.getOperand(Op);
1368183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  const MCOperand &Imm = MI.getOperand(Op + 1);
1369183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1370183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
1371183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  unsigned Align = 0;
1372183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1373183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  switch (Imm.getImm()) {
1374183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  default: break;
1375183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 2:
1376183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 4:
1377183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 8:
1378183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 16: Align = 0x00; break;
1379183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 32: Align = 0x03; break;
1380183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  }
1381183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1382183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  return RegNo | (Align << 4);
1383183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang}
1384183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1385183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
13868e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and
13878e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// alignment operand for use in VLD-dup instructions.  This is the same as
13888e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue except for the alignment encoding, which is
13898e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// different for VLD4-dup.
13908e0c7b52877983b4838e54e233449912fc1a2325Bob Wilsonunsigned ARMMCCodeEmitter::
13918e0c7b52877983b4838e54e233449912fc1a2325Bob WilsongetAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
13928e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson                              SmallVectorImpl<MCFixup> &Fixups) const {
13938e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  const MCOperand &Reg = MI.getOperand(Op);
13948e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  const MCOperand &Imm = MI.getOperand(Op + 1);
13958e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
13968e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
13978e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  unsigned Align = 0;
13988e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
13998e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  switch (Imm.getImm()) {
14008e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  default: break;
14018e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 2:
14028e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 4:
14038e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 8:  Align = 0x01; break;
14048e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 16: Align = 0x03; break;
14058e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  }
14068e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
14078e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  return RegNo | (Align << 4);
14088e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson}
14098e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
1410806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1411806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
1412806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
14130800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  const MCOperand &MO = MI.getOperand(Op);
14140800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  if (MO.getReg() == 0) return 0x0D;
14150800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  return MO.getReg();
1416a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1417a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1418a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
14193116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight8Imm(const MCInst &MI, unsigned Op,
14203116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                  SmallVectorImpl<MCFixup> &Fixups) const {
1421a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 8 - MI.getOperand(Op).getImm();
1422a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1423a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1424a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
14253116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight16Imm(const MCInst &MI, unsigned Op,
14263116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                   SmallVectorImpl<MCFixup> &Fixups) const {
1427a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 16 - MI.getOperand(Op).getImm();
1428a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1429a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1430a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
14313116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight32Imm(const MCInst &MI, unsigned Op,
14323116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                   SmallVectorImpl<MCFixup> &Fixups) const {
1433a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 32 - MI.getOperand(Op).getImm();
14343116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling}
14353116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling
14363116dce33840a115130c5f8ffcb9679d023496d6Bill Wendlingunsigned ARMMCCodeEmitter::
14373116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight64Imm(const MCInst &MI, unsigned Op,
14383116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                   SmallVectorImpl<MCFixup> &Fixups) const {
14393116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  return 64 - MI.getOperand(Op).getImm();
1440cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson}
1441cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson
1442568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachvoid ARMMCCodeEmitter::
1443568eeedea72c274abbba1310c18a31eef78e14a4Jim GrosbachEncodeInstruction(const MCInst &MI, raw_ostream &OS,
1444806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                  SmallVectorImpl<MCFixup> &Fixups) const {
1445d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach  // Pseudo instructions don't get encoded.
144659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
1447e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  uint64_t TSFlags = Desc.TSFlags;
1448e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)
1449d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach    return;
145016884415db751c75f2133bd04921393c792b1158Owen Anderson
1451e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  int Size;
145216884415db751c75f2133bd04921393c792b1158Owen Anderson  if (Desc.getSize() == 2 || Desc.getSize() == 4)
145316884415db751c75f2133bd04921393c792b1158Owen Anderson    Size = Desc.getSize();
145416884415db751c75f2133bd04921393c792b1158Owen Anderson  else
145516884415db751c75f2133bd04921393c792b1158Owen Anderson    llvm_unreachable("Unexpected instruction size!");
145610096dbdef22a10a6a4444437c935ab428545525Owen Anderson
1457d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
14587597212abced110723f2fee985a7d60557c092ecEvan Cheng  // Thumb 32-bit wide instructions need to emit the high order halfword
14597597212abced110723f2fee985a7d60557c092ecEvan Cheng  // first.
146059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb() && Size == 4) {
1461d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary >> 16, 2, OS);
1462d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary & 0xffff, 2, OS);
1463d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach  } else
1464d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary, Size, OS);
14657292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling  ++MCNumEmitted;  // Keep track of the # of mi's emitted.
1466568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}
14679af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
1468806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach#include "ARMGenMCCodeEmitter.inc"
1469