ARMMCCodeEmitter.cpp revision 7ce057983ea7b8ad42d5cca1bb5d3f6941662269
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;
116c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen 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;
121c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson
1225d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
1235d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  /// ADR label target.
1245d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
1255d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
126d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
127d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                              SmallVectorImpl<MCFixup> &Fixups) const;
128a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson  uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
129a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson                              SmallVectorImpl<MCFixup> &Fixups) const;
130971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
1315d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach
13292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
13392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// operand.
134806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
135806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const;
13692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
137f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.
138f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
139f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling                                         SmallVectorImpl<MCFixup> &Fixups)const;
1400f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson
1419d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
1429d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  /// operand.
1439d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
1449d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson                                   SmallVectorImpl<MCFixup> &Fixups) const;
1459d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
1469d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
14754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
14854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  /// operand as needed by load/store instructions.
14954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
15054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
15154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
1525d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  /// getLdStmModeOpValue - Return encoding for load/store multiple mode.
1535d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,
1545d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const {
1555d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();
1565d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    switch (Mode) {
1575f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay    default: assert(0 && "Unknown addressing sub-mode!");
1585d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::da: return 0;
1595d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::ia: return 1;
1605d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::db: return 2;
1615d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::ib: return 3;
1625d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    }
1635d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  }
16499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
16599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  ///
16699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {
16799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    switch (ShOpc) {
16899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    default: llvm_unreachable("Unknown shift opc!");
16999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::no_shift:
17099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::lsl: return 0;
17199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::lsr: return 1;
17299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::asr: return 2;
17399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::ror:
17499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::rrx: return 3;
17599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    }
17699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    return 0;
17799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  }
17899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
17999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getAddrMode2OpValue - Return encoding for addrmode2 operands.
18099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
18199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
18299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
18399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
18499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
18599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
18699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
1877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  /// getPostIdxRegOpValue - Return encoding for postidx_reg operands.
1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                SmallVectorImpl<MCFixup> &Fixups) const;
1907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1917eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
1927eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
1937eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
1947eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach
195570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  /// getAddrMode3OpValue - Return encoding for addrmode3 operands.
196570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
197570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
1985d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach
199d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12'
200d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  /// operand.
201d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
202d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
203d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach
204f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
205f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
20622447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling                                SmallVectorImpl<MCFixup> &Fixups) const;
2071fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling
208b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
209b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
210b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling                                SmallVectorImpl<MCFixup> &Fixups) const;
211b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling
21292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
213806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
214806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const;
2153e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach
21608bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach  /// getCCOutOpValue - Return encoding of the 's' bit.
217806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
218806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
21908bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
22008bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    // '1' respectively.
22108bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    return MI.getOperand(Op).getReg() == ARM::CPSR;
22208bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach  }
223ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
2242a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach  /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
225806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
226806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
2272a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    unsigned SoImm = MI.getOperand(Op).getImm();
2282a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    int SoImmVal = ARM_AM::getSOImmVal(SoImm);
2292a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    assert(SoImmVal != -1 && "Not a valid so_imm value!");
2302a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach
2312a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    // Encode rotate_imm.
2322a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
2332a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach      << ARMII::SoRotImmShift;
2342a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach
2352a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    // Encode immed_8.
2362a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
2372a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    return Binary;
2382a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach  }
2397bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
2405de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
2415de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
2425de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson                           SmallVectorImpl<MCFixup> &Fixups) const {
2435de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    unsigned SoImm = MI.getOperand(Op).getImm();
2445de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    unsigned Encoded =  ARM_AM::getT2SOImmVal(SoImm);
2455de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
2465de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    return Encoded;
2475de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  }
24808bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach
24975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
25075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
25175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
25275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
2536af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
2546af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
2550e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
2560e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    SmallVectorImpl<MCFixup> &Fixups) const;
25775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
258ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  /// getSORegOpValue - Return an encoded so_reg shifted register value.
259152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,
260152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson                           SmallVectorImpl<MCFixup> &Fixups) const;
261152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,
262806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const;
2635de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
2645de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson                             SmallVectorImpl<MCFixup> &Fixups) const;
265ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
266806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
267806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                   SmallVectorImpl<MCFixup> &Fixups) const {
268498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson    return 64 - MI.getOperand(Op).getImm();
269498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson  }
2708abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach
271806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
272806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                      SmallVectorImpl<MCFixup> &Fixups) const;
2733fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach
274a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes  unsigned getMsbOpValue(const MCInst &MI, unsigned Op,
275a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes                         SmallVectorImpl<MCFixup> &Fixups) const;
276a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes
277806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
278806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                  SmallVectorImpl<MCFixup> &Fixups) const;
279806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
280806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                      SmallVectorImpl<MCFixup> &Fixups) const;
281183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
282183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang                                        SmallVectorImpl<MCFixup> &Fixups) const;
2838e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
2848e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson                                        SmallVectorImpl<MCFixup> &Fixups) const;
285806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
286806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                                     SmallVectorImpl<MCFixup> &Fixups) const;
2876b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach
2883116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op,
2893116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                             SmallVectorImpl<MCFixup> &Fixups) const;
2903116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op,
2913116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                              SmallVectorImpl<MCFixup> &Fixups) const;
2923116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op,
2933116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                              SmallVectorImpl<MCFixup> &Fixups) const;
2943116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op,
2953116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                              SmallVectorImpl<MCFixup> &Fixups) const;
296a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
297c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
298c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson                                      unsigned EncodedValue) const;
29957dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,
300cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling                                          unsigned EncodedValue) const;
3018f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
302cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling                                    unsigned EncodedValue) const;
303cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling
304cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  unsigned VFPThumb2PostEncoder(const MCInst &MI,
305cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling                                unsigned EncodedValue) const;
306c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson
30770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  void EmitByte(unsigned char C, raw_ostream &OS) const {
308568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    OS << (char)C;
309568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
310568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
31170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
312568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    // Output the constant in little endian byte order.
313568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    for (unsigned i = 0; i != Size; ++i) {
31470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach      EmitByte(Val & 255, OS);
315568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach      Val >>= 8;
316568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    }
317568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
318568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
319568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
320568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach                         SmallVectorImpl<MCFixup> &Fixups) const;
321568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach};
322568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
323568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} // end anonymous namespace
324568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
32559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan ChengMCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII,
32659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng                                            const MCSubtargetInfo &STI,
3270800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling                                            MCContext &Ctx) {
32859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  return new ARMMCCodeEmitter(MCII, STI, Ctx);
329568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}
330568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
3317bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
3327bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
333c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson/// Thumb2 mode.
334c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
335c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson                                                 unsigned EncodedValue) const {
33659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
3377bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach    // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
338c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
339c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    // set to 1111.
340c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    unsigned Bit24 = EncodedValue & 0x01000000;
341c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    unsigned Bit28 = Bit24 << 4;
342c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue &= 0xEFFFFFFF;
343c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue |= Bit28;
344c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue |= 0x0F000000;
345c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  }
3467bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
347c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  return EncodedValue;
348c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson}
349c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson
35057dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
3517bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
35257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// Thumb2 mode.
35357dac88f775c1191a98cff89abd1f7ad33df5e29Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
35457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson                                                 unsigned EncodedValue) const {
35559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
35657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson    EncodedValue &= 0xF0FFFFFF;
35757dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson    EncodedValue |= 0x09000000;
35857dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  }
3597bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
36057dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  return EncodedValue;
36157dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson}
36257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson
3638f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
3647bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
3658f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// Thumb2 mode.
3668f143913141991baaa535ca0da7c8a81606d6392Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
3678f143913141991baaa535ca0da7c8a81606d6392Owen Anderson                                                 unsigned EncodedValue) const {
36859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
3698f143913141991baaa535ca0da7c8a81606d6392Owen Anderson    EncodedValue &= 0x00FFFFFF;
3708f143913141991baaa535ca0da7c8a81606d6392Owen Anderson    EncodedValue |= 0xEE000000;
3718f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  }
3727bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
3738f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  return EncodedValue;
3748f143913141991baaa535ca0da7c8a81606d6392Owen Anderson}
3758f143913141991baaa535ca0da7c8a81606d6392Owen Anderson
376cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
377cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// them to their Thumb2 form if we are currently in Thumb2 mode.
378cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendlingunsigned ARMMCCodeEmitter::
379cf590263cd5c24ccf1d08cef612738d99cd980d9Bill WendlingVFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const {
38059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2()) {
381cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling    EncodedValue &= 0x0FFFFFFF;
382cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling    EncodedValue |= 0xE0000000;
383cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  }
384cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  return EncodedValue;
385cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling}
38657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson
38756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// getMachineOpValue - Return binary encoding of operand. If the machine
38856ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// operand requires relocation, record the relocation and return zero.
389806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
390806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetMachineOpValue(const MCInst &MI, const MCOperand &MO,
391806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                  SmallVectorImpl<MCFixup> &Fixups) const {
392bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  if (MO.isReg()) {
3930800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    unsigned Reg = MO.getReg();
3940800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    unsigned RegNo = getARMRegisterNumbering(Reg);
395d8a11c25fa64c152628cfcf5f9d36eb60242b302Jim Grosbach
396b0708d292bbe04cfcfe0c5cb5e27d8a872c9839aJim Grosbach    // Q registers are encoded as 2x their register number.
3970800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    switch (Reg) {
3980800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    default:
3990800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling      return RegNo;
4000800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q0:  case ARM::Q1:  case ARM::Q2:  case ARM::Q3:
4010800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q4:  case ARM::Q5:  case ARM::Q6:  case ARM::Q7:
4020800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q8:  case ARM::Q9:  case ARM::Q10: case ARM::Q11:
4030800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
4040800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling      return 2 * RegNo;
40590d4cf931477b497553a9f2d0ed53377dd5dd88cOwen Anderson    }
406bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  } else if (MO.isImm()) {
40756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach    return static_cast<unsigned>(MO.getImm());
408bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  } else if (MO.isFPImm()) {
409bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling    return static_cast<unsigned>(APFloat(MO.getFPImm())
410bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling                     .bitcastToAPInt().getHiBits(32).getLimitedValue());
4110800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  }
4120800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
413817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach  llvm_unreachable("Unable to encode MCOperand!");
41456ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach  return 0;
41556ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach}
41656ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach
4175df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
418806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachbool ARMMCCodeEmitter::
419806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
420806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                       unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const {
4213e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  const MCOperand &MO  = MI.getOperand(OpIdx);
4223e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
4239af3d1c0dc2250793ada1ca6cfa98e9f1253f7f9Jim Grosbach
42492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Reg = getARMRegisterNumbering(MO.getReg());
42592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
42692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  int32_t SImm = MO1.getImm();
42792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  bool isAdd = true;
4285df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
429ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  // Special value for #-0
43092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  if (SImm == INT32_MIN)
43192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    SImm = 0;
4325df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
433ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
43492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  if (SImm < 0) {
43592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    SImm = -SImm;
43692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    isAdd = false;
43792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  }
43892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
43992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Imm = SImm;
44092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  return isAdd;
44192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling}
4425df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
443dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Helper function to get the branch target operand,
444dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// which is either an immediate or requires a fixup.
445dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlingstatic uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
446dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                                       unsigned FixupKind,
447dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                                       SmallVectorImpl<MCFixup> &Fixups) {
448662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
449662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
450662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  // If the destination is an immediate, we have nothing to do.
451662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  if (MO.isImm()) return MO.getImm();
452dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  assert(MO.isExpr() && "Unexpected branch target type!");
453662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  const MCExpr *Expr = MO.getExpr();
454dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  MCFixupKind Kind = MCFixupKind(FixupKind);
455662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  Fixups.push_back(MCFixup::Create(0, Expr, Kind));
456662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
457662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  // All of the information is in the fixup.
458662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  return 0;
459662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach}
460662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
461dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getThumbBLTargetOpValue - Return encoding info for immediate branch target.
462c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbachuint32_t ARMMCCodeEmitter::
463dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
464c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
465dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl, Fixups);
466dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling}
467c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
46809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
46909aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// BLX branch target.
47009aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendlinguint32_t ARMMCCodeEmitter::
47109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill WendlinggetThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
47209aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling                         SmallVectorImpl<MCFixup> &Fixups) const {
47309aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, Fixups);
47409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling}
47509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling
476e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
477e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbachuint32_t ARMMCCodeEmitter::
478e246717c3a36a913fd4200776ed621649bb2b624Jim GrosbachgetThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
479e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
480e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, Fixups);
481e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach}
482e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach
48301086451393ef33e82b6fad623989dd97dd70edfJim Grosbach/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
48401086451393ef33e82b6fad623989dd97dd70edfJim Grosbachuint32_t ARMMCCodeEmitter::
48501086451393ef33e82b6fad623989dd97dd70edfJim GrosbachgetThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
486e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach                         SmallVectorImpl<MCFixup> &Fixups) const {
48701086451393ef33e82b6fad623989dd97dd70edfJim Grosbach  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc, Fixups);
48801086451393ef33e82b6fad623989dd97dd70edfJim Grosbach}
48901086451393ef33e82b6fad623989dd97dd70edfJim Grosbach
490027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
491dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter::
492027d6e8d1ca04e4096fb3a27579b861d861466c5Jim GrosbachgetThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
493dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                        SmallVectorImpl<MCFixup> &Fixups) const {
494b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups);
495dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling}
496c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
497685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// Return true if this branch has a non-always predication
498685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimstatic bool HasConditionalBranch(const MCInst &MI) {
499685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  int NumOp = MI.getNumOperands();
500685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  if (NumOp >= 2) {
501685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    for (int i = 0; i < NumOp-1; ++i) {
502685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      const MCOperand &MCOp1 = MI.getOperand(i);
503685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      const MCOperand &MCOp2 = MI.getOperand(i + 1);
504685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      if (MCOp1.isImm() && MCOp2.isReg() &&
505685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim          (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) {
506685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim        if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL)
507685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim          return true;
508685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      }
509685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    }
510685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  }
511685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  return false;
512685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim}
513685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
514dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
515dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target.
516dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter::
517dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
518dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                       SmallVectorImpl<MCFixup> &Fixups) const {
519092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach  // FIXME: This really, really shouldn't use TargetMachine. We don't want
520092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach  // coupling between MC and TM anywhere we can help it.
52159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb2())
522c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    return
523c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson      ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups);
524685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  return getARMBranchTargetOpValue(MI, OpIdx, Fixups);
525685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim}
526685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
527685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
528685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// target.
529685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimuint32_t ARMMCCodeEmitter::
530685c350ae76b588e1f00c01a511fe8bd57f18394Jason W KimgetARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
531685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim                          SmallVectorImpl<MCFixup> &Fixups) const {
532685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  if (HasConditionalBranch(MI))
533685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    return ::getBranchTargetOpValue(MI, OpIdx,
534685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim                                    ARM::fixup_arm_condbranch, Fixups);
535685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  return ::getBranchTargetOpValue(MI, OpIdx,
536685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim                                  ARM::fixup_arm_uncondbranch, Fixups);
537c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach}
538c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
539685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
540685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
541685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
542c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
543c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// immediate branch target.
544c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Andersonuint32_t ARMMCCodeEmitter::
545c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen AndersongetUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
546c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson                       SmallVectorImpl<MCFixup> &Fixups) const {
547c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  unsigned Val =
548c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups);
549c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool I  = (Val & 0x800000);
550c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool J1 = (Val & 0x400000);
551c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool J2 = (Val & 0x200000);
552c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  if (I ^ J1)
553c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val &= ~0x400000;
554c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  else
555c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val |= 0x400000;
556971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
557c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  if (I ^ J2)
558c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val &= ~0x200000;
559c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  else
560c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val |= 0x200000;
561971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
562c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  return Val;
563c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson}
564c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson
565dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
566dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target.
5675d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbachuint32_t ARMMCCodeEmitter::
5685d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim GrosbachgetAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
5695d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach                   SmallVectorImpl<MCFixup> &Fixups) const {
570dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!");
571dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12,
572dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                                  Fixups);
5735d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach}
5745d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach
575a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
576a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// target.
577a838a25d59838adfa91463f6a918ae3adeb352c1Owen Andersonuint32_t ARMMCCodeEmitter::
578a838a25d59838adfa91463f6a918ae3adeb352c1Owen AndersongetT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
579a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson                   SmallVectorImpl<MCFixup> &Fixups) const {
580a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson  assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!");
581a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
582a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson                                  Fixups);
583a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson}
584a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson
585d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// getAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
586d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// target.
587d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbachuint32_t ARMMCCodeEmitter::
588d40963c4065432ec7e47879d3ca665a54ee903b6Jim GrosbachgetThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
589d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                   SmallVectorImpl<MCFixup> &Fixups) const {
590d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!");
591d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10,
592d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach                                  Fixups);
593d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach}
594d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach
595f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg'
596f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// operand.
5970f4b60d43a289671082deee3bd56a3a055afb16aOwen Andersonuint32_t ARMMCCodeEmitter::
598f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
599f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling                              SmallVectorImpl<MCFixup> &) const {
600f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  // [Rn, Rm]
601f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  //   {5-3} = Rm
602f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  //   {2-0} = Rn
6030f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx);
604f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  const MCOperand &MO2 = MI.getOperand(OpIdx + 1);
6050f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  unsigned Rn = getARMRegisterNumbering(MO1.getReg());
6060f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  unsigned Rm = getARMRegisterNumbering(MO2.getReg());
6070f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  return (Rm << 3) | Rn;
6080f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson}
6090f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson
61092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
611806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter::
612806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
613806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                        SmallVectorImpl<MCFixup> &Fixups) const {
61492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {17-13} = reg
61592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {12}    = (U)nsigned (add == '1', sub == '0')
61692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {11-0}  = imm12
61792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  unsigned Reg, Imm12;
61870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  bool isAdd = true;
61970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  // If The first operand isn't a register, we have a label reference.
62070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
621971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson  if (!MO.isReg()) {
622679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
62370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Imm12 = 0;
62497dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach    isAdd = false ; // 'U' bit is set as part of the fixup.
62570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
626971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson    assert(MO.isExpr() && "Unexpected machine operand type!");
627971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson    const MCExpr *Expr = MO.getExpr();
6287bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
629d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson    MCFixupKind Kind;
63059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    if (isThumb2())
631d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson      Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
632d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson    else
633d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson      Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
63470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind));
63570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
63670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    ++MCNumCPRelocations;
63770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  } else
63870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups);
63992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
64092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  uint32_t Binary = Imm12 & 0xfff;
64192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
642ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  if (isAdd)
64392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    Binary |= (1 << 12);
64492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Binary |= (Reg << 13);
64592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  return Binary;
64692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling}
64792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
6489d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// getT2AddrModeImm8s4OpValue - Return encoding info for
6499d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// 'reg +/- imm8<<2' operand.
6509d63d90de5e57ad96f467b270544443a9284eb2bOwen Andersonuint32_t ARMMCCodeEmitter::
6519d63d90de5e57ad96f467b270544443a9284eb2bOwen AndersongetT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
6529d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson                        SmallVectorImpl<MCFixup> &Fixups) const {
65390cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {12-9} = reg
65490cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {8}    = (U)nsigned (add == '1', sub == '0')
65590cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {7-0}  = imm8
6569d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  unsigned Reg, Imm8;
6579d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  bool isAdd = true;
6589d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  // If The first operand isn't a register, we have a label reference.
6599d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  const MCOperand &MO = MI.getOperand(OpIdx);
6609d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  if (!MO.isReg()) {
6619d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
6629d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    Imm8 = 0;
6639d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    isAdd = false ; // 'U' bit is set as part of the fixup.
6649d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
6659d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    assert(MO.isExpr() && "Unexpected machine operand type!");
6669d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    const MCExpr *Expr = MO.getExpr();
6679d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
6689d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    Fixups.push_back(MCFixup::Create(0, Expr, Kind));
6699d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
6709d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    ++MCNumCPRelocations;
6719d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  } else
6729d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
6739d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
6749d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  uint32_t Binary = (Imm8 >> 2) & 0xff;
6759d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
6769d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  if (isAdd)
67790cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach    Binary |= (1 << 8);
6789d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  Binary |= (Reg << 9);
6799d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  return Binary;
6809d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson}
6819d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
68286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// FIXME: This routine assumes that a binary
68386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// expression will always result in a PCRel expression
68486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// In reality, its only true if one or more subexpressions
68586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// is itself a PCRel (i.e. "." in asm or some other pcrel construct)
68686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim// but this is good enough for now.
68786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kimstatic bool EvaluateAsPCRel(const MCExpr *Expr) {
68886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  switch (Expr->getKind()) {
6895f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay  default: assert(0 && "Unexpected expression type");
69086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case MCExpr::SymbolRef: return false;
69186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  case MCExpr::Binary: return true;
69286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim  }
69386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim}
69486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim
6957597212abced110723f2fee985a7d60557c092ecEvan Chenguint32_t
6967597212abced110723f2fee985a7d60557c092ecEvan ChengARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
6977597212abced110723f2fee985a7d60557c092ecEvan Cheng                                      SmallVectorImpl<MCFixup> &Fixups) const {
698837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim  // {20-16} = imm{15-12}
699837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim  // {11-0}  = imm{11-0}
7007bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
7017597212abced110723f2fee985a7d60557c092ecEvan Cheng  if (MO.isImm())
7027597212abced110723f2fee985a7d60557c092ecEvan Cheng    // Hi / lo 16 bits already extracted during earlier passes.
703837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    return static_cast<unsigned>(MO.getImm());
7047597212abced110723f2fee985a7d60557c092ecEvan Cheng
7057597212abced110723f2fee985a7d60557c092ecEvan Cheng  // Handle :upper16: and :lower16: assembly prefixes.
7067597212abced110723f2fee985a7d60557c092ecEvan Cheng  const MCExpr *E = MO.getExpr();
7077597212abced110723f2fee985a7d60557c092ecEvan Cheng  if (E->getKind() == MCExpr::Target) {
7087597212abced110723f2fee985a7d60557c092ecEvan Cheng    const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E);
7097597212abced110723f2fee985a7d60557c092ecEvan Cheng    E = ARM16Expr->getSubExpr();
7107597212abced110723f2fee985a7d60557c092ecEvan Cheng
711837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    MCFixupKind Kind;
7127597212abced110723f2fee985a7d60557c092ecEvan Cheng    switch (ARM16Expr->getKind()) {
7135f8a917b6558f8fdf31b4a6fa591b396e16b9ff2Matt Beaumont-Gay    default: assert(0 && "Unsupported ARMFixup");
7147597212abced110723f2fee985a7d60557c092ecEvan Cheng    case ARMMCExpr::VK_ARM_HI16:
71559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng      if (!isTargetDarwin() && EvaluateAsPCRel(E))
71659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
717f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movt_hi16_pcrel
718f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movt_hi16_pcrel);
719f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      else
72059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
721f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movt_hi16
722f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movt_hi16);
723837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim      break;
7247597212abced110723f2fee985a7d60557c092ecEvan Cheng    case ARMMCExpr::VK_ARM_LO16:
72559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng      if (!isTargetDarwin() && EvaluateAsPCRel(E))
72659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
727f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movw_lo16_pcrel
728f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movw_lo16_pcrel);
729f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng      else
73059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng        Kind = MCFixupKind(isThumb2()
731f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           ? ARM::fixup_t2_movw_lo16
732f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng                           : ARM::fixup_arm_movw_lo16);
733837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim      break;
734837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    }
7357597212abced110723f2fee985a7d60557c092ecEvan Cheng    Fixups.push_back(MCFixup::Create(0, E, Kind));
736837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    return 0;
737817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach  };
7387597212abced110723f2fee985a7d60557c092ecEvan Cheng
739817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach  llvm_unreachable("Unsupported MCExpr type in MCOperand!");
740837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim  return 0;
741837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim}
742837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim
743837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kimuint32_t ARMMCCodeEmitter::
74454fea632b161f98e96ec7275922e35102bcecc5dJim GrosbachgetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
74554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
74654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
74754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
74854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
74954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned Rn = getARMRegisterNumbering(MO.getReg());
75054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned Rm = getARMRegisterNumbering(MO1.getReg());
75154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
75254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
75399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
75499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned SBits = getShiftOp(ShOp);
75554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
75654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {16-13} = Rn
75754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {12}    = isAdd
75854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {11-0}  = shifter
75954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {3-0}  = Rm
76054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {4}    = 0
76154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {6-5}  = type
76254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {11-7} = imm
763570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t Binary = Rm;
76454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= Rn << 13;
76554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= SBits << 5;
76654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= ShImm << 7;
76754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  if (isAdd)
76854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach    Binary |= 1 << 12;
76954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  return Binary;
77054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach}
77154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
772570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbachuint32_t ARMMCCodeEmitter::
77399f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
77499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
77599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {17-14}  Rn
77699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {13}     1 == imm12, 0 == Rm
77799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {12}     isAdd
77899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {11-0}   imm12/Rm
77999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
78099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned Rn = getARMRegisterNumbering(MO.getReg());
78199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups);
78299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  Binary |= Rn << 14;
78399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  return Binary;
78499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach}
78599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
78699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter::
78799f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
78899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
78999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {13}     1 == imm12, 0 == Rm
79099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {12}     isAdd
79199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {11-0}   imm12/Rm
79299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
79399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
79499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned Imm = MO1.getImm();
79599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
79699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  bool isReg = MO.getReg() != 0;
79799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t Binary = ARM_AM::getAM2Offset(Imm);
79899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
79999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  if (isReg) {
80099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);
80199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    Binary <<= 7;                    // Shift amount is bits [11:7]
80299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]
80399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    Binary |= getARMRegisterNumbering(MO.getReg()); // Rm is bits [3:0]
80499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  }
80599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  return Binary | (isAdd << 12) | (isReg << 13);
80699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach}
80799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
80899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter::
8097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachgetPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
8107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                     SmallVectorImpl<MCFixup> &Fixups) const {
8117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // {4}      isAdd
8127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // {3-0}    Rm
8137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
8147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
8157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  unsigned Imm = MO1.getImm();
8167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
8177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return getARMRegisterNumbering(MO.getReg()) | (isAdd << 4);
8187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
8197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
8207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachuint32_t ARMMCCodeEmitter::
8217eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim GrosbachgetAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
8227eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
8237eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {9}      1 == imm8, 0 == Rm
8247eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {8}      isAdd
8257eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {7-4}    imm7_4/zero
8267eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {3-0}    imm3_0/Rm
8277eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
8287eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
8297eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  unsigned Imm = MO1.getImm();
8307eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
8317eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  bool isImm = MO.getReg() == 0;
8327eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
8337eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
8347eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  if (!isImm)
8357eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach    Imm8 = getARMRegisterNumbering(MO.getReg());
8367eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  return Imm8 | (isAdd << 8) | (isImm << 9);
8377eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach}
8387eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach
8397eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbachuint32_t ARMMCCodeEmitter::
840570a9226913ebe1af04832b8fb3273c70b4ee152Jim GrosbachgetAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
841570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
842570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {13}     1 == imm8, 0 == Rm
843570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {12-9}   Rn
844570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {8}      isAdd
845570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {7-4}    imm7_4/zero
846570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {3-0}    imm3_0/Rm
847570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
848570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
849570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
850570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  unsigned Rn = getARMRegisterNumbering(MO.getReg());
851570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  unsigned Imm = MO2.getImm();
852570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
853570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  bool isImm = MO1.getReg() == 0;
854570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
855570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
856570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  if (!isImm)
857570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach    Imm8 = getARMRegisterNumbering(MO1.getReg());
858570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
859570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach}
860570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach
861b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands.
862d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbachuint32_t ARMMCCodeEmitter::
863d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim GrosbachgetAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
864d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
865d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // [SP, #imm]
866d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  //   {7-0} = imm8
867d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
868b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  assert(MI.getOperand(OpIdx).getReg() == ARM::SP &&
869b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling         "Unexpected base register!");
8707a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
871d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // The immediate is already shifted for the implicit zeroes, so no change
872d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // here.
873d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  return MO1.getImm() & 0xff;
874d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach}
875d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach
876f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
877272df516d7a9b1f0f69174276abaa759816ee456Bill Wendlinguint32_t ARMMCCodeEmitter::
878f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
87922447ae54bcb8ca94ed994cad103074a24e66781Bill Wendling                     SmallVectorImpl<MCFixup> &Fixups) const {
880ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  // [Rn, #imm]
881ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  //   {7-3} = imm5
882ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  //   {2-0} = Rn
883ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  const MCOperand &MO = MI.getOperand(OpIdx);
884ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
885ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  unsigned Rn = getARMRegisterNumbering(MO.getReg());
886656b3d22f70c2d1c8a5286f7270cb380df862565Matt Beaumont-Gay  unsigned Imm5 = MO1.getImm();
887272df516d7a9b1f0f69174276abaa759816ee456Bill Wendling  return ((Imm5 & 0x1f) << 3) | Rn;
8881fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling}
8891fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling
890b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
891b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendlinguint32_t ARMMCCodeEmitter::
892b8958b031ec5163261f490f131780c5dc3d823d6Bill WendlinggetAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
893b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling                     SmallVectorImpl<MCFixup> &Fixups) const {
89409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups);
895b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling}
896b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling
8975177f79c378b47e38bed5ac05ba4b597f31b864eJim Grosbach/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand.
898806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter::
899806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
900806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                    SmallVectorImpl<MCFixup> &Fixups) const {
90192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {12-9} = reg
90292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {8}    = (U)nsigned (add == '1', sub == '0')
90392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {7-0}  = imm8
90492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  unsigned Reg, Imm8;
90597dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  bool isAdd;
90670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  // If The first operand isn't a register, we have a label reference.
90770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
90870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  if (!MO.isReg()) {
909679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach    Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
91070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Imm8 = 0;
91197dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach    isAdd = false; // 'U' bit is handled as part of the fixup.
91270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
91370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    assert(MO.isExpr() && "Unexpected machine operand type!");
91470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    const MCExpr *Expr = MO.getExpr();
915d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson    MCFixupKind Kind;
91659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    if (isThumb2())
917d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson      Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
918d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson    else
919d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson      Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
92070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind));
92170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
92270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    ++MCNumCPRelocations;
92397dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  } else {
92470933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
92597dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach    isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
92697dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  }
92792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
92892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
92992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
93097dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  if (isAdd)
93192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    Binary |= (1 << 8);
93292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Binary |= (Reg << 9);
9333e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  return Binary;
9343e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach}
9353e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach
936806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
937152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
938806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                SmallVectorImpl<MCFixup> &Fixups) const {
9390800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
940354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // shifted. The second is Rs, the amount to shift by, and the third specifies
941354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // the type of the shift.
94235b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach  //
943ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // {3-0} = Rm.
944354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {4}   = 1
945ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // {6-5} = type
946354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {11-8} = Rs
947354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {7}    = 0
948ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
949ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO  = MI.getOperand(OpIdx);
950ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
951ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
952ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
953ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
954ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode Rm.
955ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned Binary = getARMRegisterNumbering(MO.getReg());
956ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
957ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode the shift opcode.
958ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned SBits = 0;
959ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned Rs = MO1.getReg();
960ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  if (Rs) {
961ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // Set shift operand (bit[7:4]).
962ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSL - 0001
963ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSR - 0011
964ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ASR - 0101
965ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ROR - 0111
966ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    switch (SOpc) {
967ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    default: llvm_unreachable("Unknown shift opc!");
968ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsl: SBits = 0x1; break;
969ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsr: SBits = 0x3; break;
970ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::asr: SBits = 0x5; break;
971ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::ror: SBits = 0x7; break;
972ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    }
973ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  }
9740800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
975ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  Binary |= SBits << 4;
976ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
977354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // Encode the shift operation Rs.
978152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode Rs bit[11:8].
979152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
980152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
981152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson}
982152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
983152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Andersonunsigned ARMMCCodeEmitter::
984152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
985152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson                SmallVectorImpl<MCFixup> &Fixups) const {
986354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
987354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // shifted. The second is the amount to shift by.
988152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  //
989152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // {3-0} = Rm.
990354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {4}   = 0
991152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // {6-5} = type
992354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {11-7} = imm
993152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
994152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  const MCOperand &MO  = MI.getOperand(OpIdx);
995152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
996152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
997152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
998152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode Rm.
999152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned Binary = getARMRegisterNumbering(MO.getReg());
1000152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1001152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode the shift opcode.
1002152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned SBits = 0;
1003152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1004152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Set shift operand (bit[6:4]).
1005152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // LSL - 000
1006152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // LSR - 010
1007152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // ASR - 100
1008152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // ROR - 110
1009152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // RRX - 110 and bit[11:8] clear.
1010152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  switch (SOpc) {
1011152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  default: llvm_unreachable("Unknown shift opc!");
1012152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::lsl: SBits = 0x0; break;
1013152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::lsr: SBits = 0x2; break;
1014152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::asr: SBits = 0x4; break;
1015152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::ror: SBits = 0x6; break;
1016152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::rrx:
1017152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    Binary |= 0x60;
1018152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    return Binary;
1019ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  }
1020ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1021ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode shift_imm bit[11:7].
1022152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  Binary |= SBits << 4;
1023152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
1024ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach}
1025ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1026152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1027806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
102875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
102975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson                SmallVectorImpl<MCFixup> &Fixups) const {
103075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
103175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO2 = MI.getOperand(OpNum+1);
10327bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach  const MCOperand &MO3 = MI.getOperand(OpNum+2);
10337bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
103475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // Encoded as [Rn, Rm, imm].
103575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // FIXME: Needs fixup support.
103675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned Value = getARMRegisterNumbering(MO1.getReg());
103775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 4;
103875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value |= getARMRegisterNumbering(MO2.getReg());
103975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 2;
104075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value |= MO3.getImm();
10417bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
104275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  return Value;
104375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson}
104475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
104575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter::
104675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
104775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson                         SmallVectorImpl<MCFixup> &Fixups) const {
104875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
104975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO2 = MI.getOperand(OpNum+1);
105075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
105175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // FIXME: Needs fixup support.
105275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned Value = getARMRegisterNumbering(MO1.getReg());
10537bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
105475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // Even though the immediate is 8 bits long, we need 9 bits in order
105575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // to represent the (inverse of the) sign bit.
105675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 9;
10576af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  int32_t tmp = (int32_t)MO2.getImm();
10586af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  if (tmp < 0)
10596af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    tmp = abs(tmp);
10606af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  else
10616af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    Value |= 256; // Set the ADD bit
10626af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  Value |= tmp & 255;
10636af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  return Value;
10646af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson}
10656af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson
10666af50f7dd12d82f0a80f3158102180eee4c921aaOwen Andersonunsigned ARMMCCodeEmitter::
10676af50f7dd12d82f0a80f3158102180eee4c921aaOwen AndersongetT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
10686af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson                         SmallVectorImpl<MCFixup> &Fixups) const {
10696af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
10706af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson
10716af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  // FIXME: Needs fixup support.
10726af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  unsigned Value = 0;
10736af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  int32_t tmp = (int32_t)MO1.getImm();
10746af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  if (tmp < 0)
10756af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    tmp = abs(tmp);
10766af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  else
10776af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    Value |= 256; // Set the ADD bit
10786af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  Value |= tmp & 255;
107975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  return Value;
108075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson}
108175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
108275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter::
10830e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen AndersongetT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
10840e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson                         SmallVectorImpl<MCFixup> &Fixups) const {
10850e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
10860e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson
10870e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  // FIXME: Needs fixup support.
10880e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  unsigned Value = 0;
10890e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  int32_t tmp = (int32_t)MO1.getImm();
10900e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  if (tmp < 0)
10910e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    tmp = abs(tmp);
10920e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  else
10930e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    Value |= 4096; // Set the ADD bit
10940e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  Value |= tmp & 4095;
10950e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  return Value;
10960e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson}
10970e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson
10980e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Andersonunsigned ARMMCCodeEmitter::
10995de6d841a5116152793dcab35a2e534a6a9aaa7aOwen AndersongetT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
11005de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson                SmallVectorImpl<MCFixup> &Fixups) const {
11015de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
11025de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // shifted. The second is the amount to shift by.
11035de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  //
11045de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {3-0} = Rm.
11055de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {4}   = 0
11065de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {6-5} = type
11075de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {11-7} = imm
11085de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
11095de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  const MCOperand &MO  = MI.getOperand(OpIdx);
11105de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
11115de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
11125de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
11135de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode Rm.
11145de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned Binary = getARMRegisterNumbering(MO.getReg());
11155de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
11165de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode the shift opcode.
11175de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned SBits = 0;
11185de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Set shift operand (bit[6:4]).
11195de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // LSL - 000
11205de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // LSR - 010
11215de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // ASR - 100
11225de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // ROR - 110
11235de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  switch (SOpc) {
11245de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  default: llvm_unreachable("Unknown shift opc!");
11255de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::lsl: SBits = 0x0; break;
11265de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::lsr: SBits = 0x2; break;
11275de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::asr: SBits = 0x4; break;
11285de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::ror: SBits = 0x6; break;
11295de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  }
11305de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
11315de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  Binary |= SBits << 4;
11325de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  if (SOpc == ARM_AM::rrx)
11335de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    return Binary;
11345de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
11355de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode shift_imm bit[11:7].
11365de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
11375de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson}
11385de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
11395de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Andersonunsigned ARMMCCodeEmitter::
1140806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
1141806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                               SmallVectorImpl<MCFixup> &Fixups) const {
11423fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
11433fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  // msb of the mask.
11443fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  const MCOperand &MO = MI.getOperand(Op);
11453fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t v = ~MO.getImm();
11463fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t lsb = CountTrailingZeros_32(v);
11473fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1;
11483fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
11493fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  return lsb | (msb << 5);
11503fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach}
11513fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach
1152806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1153a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso LopesgetMsbOpValue(const MCInst &MI, unsigned Op,
1154a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes              SmallVectorImpl<MCFixup> &Fixups) const {
1155a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes  // MSB - 5 bits.
1156a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes  uint32_t lsb = MI.getOperand(Op-1).getImm();
1157a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes  uint32_t width = MI.getOperand(Op).getImm();
1158a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes  uint32_t msb = lsb+width-1;
1159a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes  assert (width != 0 && msb < 32 && "Illegal bit width!");
1160a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes  return msb;
1161a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes}
1162a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopes
1163a461d4222877f43588da38c466145f38dd74e229Bruno Cardoso Lopesunsigned ARMMCCodeEmitter::
1164806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetRegisterListOpValue(const MCInst &MI, unsigned Op,
11655e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling                       SmallVectorImpl<MCFixup> &Fixups) const {
11666bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  // VLDM/VSTM:
11676bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {12-8} = Vd
11686bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {7-0}  = Number of registers
11696bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //
11706bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  // LDM/STM:
11716bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {15-0}  = Bitfield of GPRs.
11726bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  unsigned Reg = MI.getOperand(Op).getReg();
1173be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng  bool SPRRegs = llvm::ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg);
1174be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng  bool DPRRegs = llvm::ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg);
11756bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
11765e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  unsigned Binary = 0;
11776bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
11786bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  if (SPRRegs || DPRRegs) {
11796bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    // VLDM/VSTM
11806bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    unsigned RegNo = getARMRegisterNumbering(Reg);
11816bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;
11826bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    Binary |= (RegNo & 0x1f) << 8;
11836bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    if (SPRRegs)
11846bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= NumRegs;
11856bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    else
11866bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= NumRegs * 2;
11876bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  } else {
11886bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {
11896bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      unsigned RegNo = getARMRegisterNumbering(MI.getOperand(I).getReg());
11906bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= 1 << RegNo;
11916bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    }
11925e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  }
11936bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
11946b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach  return Binary;
11956b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach}
11966b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach
11978e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along
11988e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// with the alignment operand.
1199806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1200806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
1201806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                           SmallVectorImpl<MCFixup> &Fixups) const {
1202d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  const MCOperand &Reg = MI.getOperand(Op);
12030800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  const MCOperand &Imm = MI.getOperand(Op + 1);
120435b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach
1205d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
12060800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  unsigned Align = 0;
12070800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
12080800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  switch (Imm.getImm()) {
12090800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  default: break;
12100800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 2:
12110800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 4:
12120800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 8:  Align = 0x01; break;
12130800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 16: Align = 0x02; break;
12140800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 32: Align = 0x03; break;
1215d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  }
12160800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
1217d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  return RegNo | (Align << 4);
1218d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson}
1219d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson
1220183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number
1221183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// along  with the alignment operand for use in VST1 and VLD1 with size 32.
1222183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wangunsigned ARMMCCodeEmitter::
1223183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P WanggetAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
1224183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang                                    SmallVectorImpl<MCFixup> &Fixups) const {
1225183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  const MCOperand &Reg = MI.getOperand(Op);
1226183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  const MCOperand &Imm = MI.getOperand(Op + 1);
1227183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1228183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
1229183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  unsigned Align = 0;
1230183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1231183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  switch (Imm.getImm()) {
1232183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  default: break;
1233183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 2:
1234183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 4:
1235183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 8:
1236183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 16: Align = 0x00; break;
1237183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 32: Align = 0x03; break;
1238183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  }
1239183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1240183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  return RegNo | (Align << 4);
1241183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang}
1242183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1243183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
12448e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and
12458e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// alignment operand for use in VLD-dup instructions.  This is the same as
12468e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue except for the alignment encoding, which is
12478e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// different for VLD4-dup.
12488e0c7b52877983b4838e54e233449912fc1a2325Bob Wilsonunsigned ARMMCCodeEmitter::
12498e0c7b52877983b4838e54e233449912fc1a2325Bob WilsongetAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
12508e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson                              SmallVectorImpl<MCFixup> &Fixups) const {
12518e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  const MCOperand &Reg = MI.getOperand(Op);
12528e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  const MCOperand &Imm = MI.getOperand(Op + 1);
12538e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
12548e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
12558e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  unsigned Align = 0;
12568e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
12578e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  switch (Imm.getImm()) {
12588e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  default: break;
12598e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 2:
12608e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 4:
12618e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 8:  Align = 0x01; break;
12628e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 16: Align = 0x03; break;
12638e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  }
12648e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
12658e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  return RegNo | (Align << 4);
12668e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson}
12678e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
1268806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1269806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
1270806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                          SmallVectorImpl<MCFixup> &Fixups) const {
12710800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  const MCOperand &MO = MI.getOperand(Op);
12720800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  if (MO.getReg() == 0) return 0x0D;
12730800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  return MO.getReg();
1274a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1275a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1276a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
12773116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight8Imm(const MCInst &MI, unsigned Op,
12783116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                  SmallVectorImpl<MCFixup> &Fixups) const {
1279a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 8 - MI.getOperand(Op).getImm();
1280a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1281a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1282a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
12833116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight16Imm(const MCInst &MI, unsigned Op,
12843116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                   SmallVectorImpl<MCFixup> &Fixups) const {
1285a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 16 - MI.getOperand(Op).getImm();
1286a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1287a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1288a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
12893116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight32Imm(const MCInst &MI, unsigned Op,
12903116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                   SmallVectorImpl<MCFixup> &Fixups) const {
1291a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 32 - MI.getOperand(Op).getImm();
12923116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling}
12933116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling
12943116dce33840a115130c5f8ffcb9679d023496d6Bill Wendlingunsigned ARMMCCodeEmitter::
12953116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight64Imm(const MCInst &MI, unsigned Op,
12963116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling                   SmallVectorImpl<MCFixup> &Fixups) const {
12973116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  return 64 - MI.getOperand(Op).getImm();
1298cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson}
1299cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson
1300568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachvoid ARMMCCodeEmitter::
1301568eeedea72c274abbba1310c18a31eef78e14a4Jim GrosbachEncodeInstruction(const MCInst &MI, raw_ostream &OS,
1302806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                  SmallVectorImpl<MCFixup> &Fixups) const {
1303d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach  // Pseudo instructions don't get encoded.
130459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
1305e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  uint64_t TSFlags = Desc.TSFlags;
1306e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)
1307d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach    return;
130816884415db751c75f2133bd04921393c792b1158Owen Anderson
1309e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  int Size;
131016884415db751c75f2133bd04921393c792b1158Owen Anderson  if (Desc.getSize() == 2 || Desc.getSize() == 4)
131116884415db751c75f2133bd04921393c792b1158Owen Anderson    Size = Desc.getSize();
131216884415db751c75f2133bd04921393c792b1158Owen Anderson  else
131316884415db751c75f2133bd04921393c792b1158Owen Anderson    llvm_unreachable("Unexpected instruction size!");
131416884415db751c75f2133bd04921393c792b1158Owen Anderson
1315d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
13167597212abced110723f2fee985a7d60557c092ecEvan Cheng  // Thumb 32-bit wide instructions need to emit the high order halfword
13177597212abced110723f2fee985a7d60557c092ecEvan Cheng  // first.
131859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (isThumb() && Size == 4) {
1319d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary >> 16, 2, OS);
1320d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary & 0xffff, 2, OS);
1321d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach  } else
1322d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary, Size, OS);
13237292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling  ++MCNumEmitted;  // Keep track of the # of mi's emitted.
1324568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}
13259af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
1326806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach#include "ARMGenMCCodeEmitter.inc"
1327