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
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/ARMMCTargetDesc.h"
15ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
16be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMBaseInfo.h"
17be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMFixupKinds.h"
18ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/APFloat.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h"
21568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCCodeEmitter.h"
22df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher#include "llvm/MC/MCContext.h"
23568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCExpr.h"
24568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/MC/MCInst.h"
2559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCInstrInfo.h"
26be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/MC/MCRegisterInfo.h"
2759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ErrorHandling.h"
29568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach#include "llvm/Support/raw_ostream.h"
3059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng
31568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachusing namespace llvm;
32568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mccodeemitter"
34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
3570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
3670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim GrosbachSTATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");
37d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach
38568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachnamespace {
39568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachclass ARMMCCodeEmitter : public MCCodeEmitter {
40ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ARMMCCodeEmitter(const ARMMCCodeEmitter &) = delete;
41ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void operator=(const ARMMCCodeEmitter &) = delete;
4259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  const MCInstrInfo &MCII;
43df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  const MCContext &CTX;
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool IsLittleEndian;
45568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
46568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachpublic:
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ARMMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool IsLittle)
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    : MCII(mcii), CTX(ctx), IsLittleEndian(IsLittle) {
49568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
50568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
512c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  ~ARMMCCodeEmitter() override {}
52568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isThumb(const MCSubtargetInfo &STI) const {
5459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
5559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  }
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isThumb2(const MCSubtargetInfo &STI) const {
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isThumb(STI) && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
5859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  }
5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isTargetMachO(const MCSubtargetInfo &STI) const {
6059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng    Triple TT(STI.getTargetTriple());
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return TT.isOSBinFormatMachO();
6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  }
6359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng
640de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach  unsigned getMachineSoImmOpValue(unsigned SoImm) const;
650de6ab3c43ed2143d661115dddf1480545236c91Jim Grosbach
669af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  // getBinaryCodeForInstr - TableGen'erated function for getting the
679af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  // binary encoding for an instruction.
684f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson  uint64_t getBinaryCodeForInstr(const MCInst &MI,
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                 SmallVectorImpl<MCFixup> &Fixups,
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                 const MCSubtargetInfo &STI) const;
719af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
729af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  /// getMachineOpValue - Return binary encoding of operand. If the machine
739af82ba42b53905f580f8c4270626946e3548654Jim Grosbach  /// operand requires relocation, record the relocation and return zero.
74806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             SmallVectorImpl<MCFixup> &Fixups,
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             const MCSubtargetInfo &STI) const;
779af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
787597212abced110723f2fee985a7d60557c092ecEvan Cheng  /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of
79971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson  /// the specified operand. This is used for operands with :lower16: and
807597212abced110723f2fee985a7d60557c092ecEvan Cheng  /// :upper16: prefixes.
817597212abced110723f2fee985a7d60557c092ecEvan Cheng  uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               SmallVectorImpl<MCFixup> &Fixups,
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               const MCSubtargetInfo &STI) const;
84837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim
8592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
86806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach                              unsigned &Reg, unsigned &Imm,
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SmallVectorImpl<MCFixup> &Fixups,
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              const MCSubtargetInfo &STI) const;
8992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
90662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate
9109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  /// BL branch target.
92662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   SmallVectorImpl<MCFixup> &Fixups,
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   const MCSubtargetInfo &STI) const;
95662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
9609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
9709aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  /// BLX branch target.
9809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling  uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    SmallVectorImpl<MCFixup> &Fixups,
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    const MCSubtargetInfo &STI) const;
10109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling
102e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach  /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
103e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach  uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   SmallVectorImpl<MCFixup> &Fixups,
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   const MCSubtargetInfo &STI) const;
106e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach
10701086451393ef33e82b6fad623989dd97dd70edfJim Grosbach  /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
10801086451393ef33e82b6fad623989dd97dd70edfJim Grosbach  uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    SmallVectorImpl<MCFixup> &Fixups,
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    const MCSubtargetInfo &STI) const;
11101086451393ef33e82b6fad623989dd97dd70edfJim Grosbach
112027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach  /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
113027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach  uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   SmallVectorImpl<MCFixup> &Fixups,
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   const MCSubtargetInfo &STI) const;
116dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling
117c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach  /// getBranchTargetOpValue - Return encoding info for 24-bit immediate
118c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach  /// branch target.
119c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach  uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  SmallVectorImpl<MCFixup> &Fixups,
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  const MCSubtargetInfo &STI) const;
122c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
123c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
124c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  /// immediate Thumb2 direct branch target.
125c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  SmallVectorImpl<MCFixup> &Fixups,
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  const MCSubtargetInfo &STI) const;
12810096dbdef22a10a6a4444437c935ab428545525Owen Anderson
129685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate
130685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  /// branch target.
131685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     SmallVectorImpl<MCFixup> &Fixups,
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     const MCSubtargetInfo &STI) const;
1347b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach  uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                 SmallVectorImpl<MCFixup> &Fixups,
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                 const MCSubtargetInfo &STI) const;
137f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  SmallVectorImpl<MCFixup> &Fixups,
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  const MCSubtargetInfo &STI) const;
140c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson
1415d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
1425d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  /// ADR label target.
1435d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach  uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SmallVectorImpl<MCFixup> &Fixups,
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              const MCSubtargetInfo &STI) const;
146d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach  uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SmallVectorImpl<MCFixup> &Fixups,
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              const MCSubtargetInfo &STI) const;
149a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson  uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SmallVectorImpl<MCFixup> &Fixups,
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              const MCSubtargetInfo &STI) const;
152971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
1535d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach
15492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
15592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// operand.
156806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   SmallVectorImpl<MCFixup> &Fixups,
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   const MCSubtargetInfo &STI) const;
15992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
160f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.
161f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                         SmallVectorImpl<MCFixup> &Fixups,
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                         const MCSubtargetInfo &STI) const;
1640f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson
1659d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
1669d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  /// operand.
1679d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   SmallVectorImpl<MCFixup> &Fixups,
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   const MCSubtargetInfo &STI) const;
170b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
171b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2'
172b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  /// operand.
173b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   SmallVectorImpl<MCFixup> &Fixups,
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   const MCSubtargetInfo &STI) const;
176b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
177a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2'
178a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  /// operand.
179a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SmallVectorImpl<MCFixup> &Fixups,
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              const MCSubtargetInfo &STI) const;
1829d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
1839d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
18454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
18554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  /// operand as needed by load/store instructions.
18654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               SmallVectorImpl<MCFixup> &Fixups,
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               const MCSubtargetInfo &STI) const;
18954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
1905d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  /// getLdStmModeOpValue - Return encoding for load/store multiple mode.
1915d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               SmallVectorImpl<MCFixup> &Fixups,
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               const MCSubtargetInfo &STI) const {
1945d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();
1955d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    switch (Mode) {
196bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Unknown addressing sub-mode!");
1975d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::da: return 0;
1985d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::ia: return 1;
1995d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::db: return 2;
2005d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    case ARM_AM::ib: return 3;
2015d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach    }
2025d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach  }
20399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
20499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  ///
20599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {
20699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    switch (ShOpc) {
20799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::no_shift:
20899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::lsl: return 0;
20999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::lsr: return 1;
21099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::asr: return 2;
21199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::ror:
21299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    case ARM_AM::rrx: return 3;
21399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    }
2144d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    llvm_unreachable("Invalid ShiftOpc!");
21599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  }
21699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
21799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getAddrMode2OpValue - Return encoding for addrmode2 operands.
21899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               SmallVectorImpl<MCFixup> &Fixups,
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               const MCSubtargetInfo &STI) const;
22199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
22299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
22399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     SmallVectorImpl<MCFixup> &Fixups,
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     const MCSubtargetInfo &STI) const;
22699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
2277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  /// getPostIdxRegOpValue - Return encoding for postidx_reg operands.
2287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                SmallVectorImpl<MCFixup> &Fixups,
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                const MCSubtargetInfo &STI) const;
2317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2327eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
2337eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     SmallVectorImpl<MCFixup> &Fixups,
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     const MCSubtargetInfo &STI) const;
2367eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach
237570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  /// getAddrMode3OpValue - Return encoding for addrmode3 operands.
238570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               SmallVectorImpl<MCFixup> &Fixups,
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               const MCSubtargetInfo &STI) const;
2415d5eb9e3817a2765297e6dd5649ecb9b8b03e334Jim Grosbach
242d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12'
243d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  /// operand.
244d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     SmallVectorImpl<MCFixup> &Fixups,
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     const MCSubtargetInfo &STI) const;
247d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach
248f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
249f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                SmallVectorImpl<MCFixup> &Fixups,
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                const MCSubtargetInfo &STI) const;
2521fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling
253b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
254b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                SmallVectorImpl<MCFixup> &Fixups,
25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                const MCSubtargetInfo &STI) const;
257b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling
25892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
259806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               SmallVectorImpl<MCFixup> &Fixups,
26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               const MCSubtargetInfo &STI) const;
2623e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach
26308bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach  /// getCCOutOpValue - Return encoding of the 's' bit.
264806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           SmallVectorImpl<MCFixup> &Fixups,
26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           const MCSubtargetInfo &STI) const {
26708bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
26808bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    // '1' respectively.
26908bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach    return MI.getOperand(Op).getReg() == ARM::CPSR;
27008bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach  }
271ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
2722a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach  /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
273806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           SmallVectorImpl<MCFixup> &Fixups,
27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           const MCSubtargetInfo &STI) const {
27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCOperand &MO = MI.getOperand(Op);
27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // We expect MO to be an immediate or an expression,
28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // if it is an immediate - that's fine, just encode the value.
28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Otherwise - create a Fixup.
28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (MO.isExpr()) {
28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const MCExpr *Expr = MO.getExpr();
28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // In instruction code this value always encoded as lowest 12 bits,
28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // so we don't have to perform any specific adjustments.
28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Due to requirements of relocatable records we have to use FK_Data_4.
28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // See ARMELFObjectWriter::ExplicitRelSym and
28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      //     ARMELFObjectWriter::GetRelocTypeInner for more details.
28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MCFixupKind Kind = MCFixupKind(FK_Data_4);
29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return 0;
29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned SoImm = MO.getImm();
2952a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    int SoImmVal = ARM_AM::getSOImmVal(SoImm);
2962a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    assert(SoImmVal != -1 && "Not a valid so_imm value!");
2972a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach
2982a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    // Encode rotate_imm.
2992a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
3002a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach      << ARMII::SoRotImmShift;
3012a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach
3022a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    // Encode immed_8.
3032a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
3042a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach    return Binary;
3052a6a93d5425b38546de2b6674719d52f565171d8Jim Grosbach  }
3067bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned getModImmOpValue(const MCInst &MI, unsigned Op,
308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                            SmallVectorImpl<MCFixup> &Fixups,
309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                            const MCSubtargetInfo &ST) const {
310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const MCOperand &MO = MI.getOperand(Op);
311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Support for fixups (MCFixup)
313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (MO.isExpr()) {
314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      const MCExpr *Expr = MO.getExpr();
315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // In instruction code this value always encoded as lowest 12 bits,
316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // so we don't have to perform any specific adjustments.
317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // Due to requirements of relocatable records we have to use FK_Data_4.
318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // See ARMELFObjectWriter::ExplicitRelSym and
319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      //     ARMELFObjectWriter::GetRelocTypeInner for more details.
320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MCFixupKind Kind = MCFixupKind(FK_Data_4);
321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return 0;
323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Immediate is already in its encoded format
326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return MO.getImm();
327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3295de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
3305de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           SmallVectorImpl<MCFixup> &Fixups,
33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           const MCSubtargetInfo &STI) const {
3335de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    unsigned SoImm = MI.getOperand(Op).getImm();
3345de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    unsigned Encoded =  ARM_AM::getT2SOImmVal(SoImm);
3355de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
3365de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    return Encoded;
3375de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  }
33808bd54987f4ae482de13436e7254ff08b23f825fJim Grosbach
33975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallVectorImpl<MCFixup> &Fixups,
34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCSubtargetInfo &STI) const;
34275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallVectorImpl<MCFixup> &Fixups,
34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCSubtargetInfo &STI) const;
3456af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallVectorImpl<MCFixup> &Fixups,
34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCSubtargetInfo &STI) const;
3480e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallVectorImpl<MCFixup> &Fixups,
35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCSubtargetInfo &STI) const;
35175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
352ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  /// getSORegOpValue - Return an encoded so_reg shifted register value.
353152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           SmallVectorImpl<MCFixup> &Fixups,
35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           const MCSubtargetInfo &STI) const;
356152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,
35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           SmallVectorImpl<MCFixup> &Fixups,
35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           const MCSubtargetInfo &STI) const;
3595de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             SmallVectorImpl<MCFixup> &Fixups,
36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             const MCSubtargetInfo &STI) const;
362ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
363806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   SmallVectorImpl<MCFixup> &Fixups,
36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   const MCSubtargetInfo &STI) const {
366498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson    return 64 - MI.getOperand(Op).getImm();
367498ec20703c89d0c2890b0967791f0f5f2b59a2fOwen Anderson  }
3688abe32af38b66bf4577526b23b6af6ec7eb6c155Jim Grosbach
369806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      SmallVectorImpl<MCFixup> &Fixups,
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      const MCSubtargetInfo &STI) const;
3723fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach
373806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  SmallVectorImpl<MCFixup> &Fixups,
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  const MCSubtargetInfo &STI) const;
376806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      SmallVectorImpl<MCFixup> &Fixups,
37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      const MCSubtargetInfo &STI) const;
379183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        SmallVectorImpl<MCFixup> &Fixups,
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        const MCSubtargetInfo &STI) const;
3828e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        SmallVectorImpl<MCFixup> &Fixups,
38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                        const MCSubtargetInfo &STI) const;
385806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach  unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     SmallVectorImpl<MCFixup> &Fixups,
38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                     const MCSubtargetInfo &STI) const;
3886b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach
3893116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op,
39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             SmallVectorImpl<MCFixup> &Fixups,
39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             const MCSubtargetInfo &STI) const;
3923116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op,
39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SmallVectorImpl<MCFixup> &Fixups,
39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              const MCSubtargetInfo &STI) const;
3953116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op,
39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SmallVectorImpl<MCFixup> &Fixups,
39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              const MCSubtargetInfo &STI) const;
3983116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op,
39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SmallVectorImpl<MCFixup> &Fixups,
40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              const MCSubtargetInfo &STI) const;
401a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
4026d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson  unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op,
40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                 SmallVectorImpl<MCFixup> &Fixups,
40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                 const MCSubtargetInfo &STI) const;
4056d74631062e4464326eb5c680a4d62d340fa42ebOwen Anderson
406c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      unsigned EncodedValue,
40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      const MCSubtargetInfo &STI) const;
40957dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,
41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                          unsigned EncodedValue,
41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                          const MCSubtargetInfo &STI) const;
4128f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    unsigned EncodedValue,
41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    const MCSubtargetInfo &STI) const;
41519c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  unsigned NEONThumb2V8PostEncoder(const MCInst &MI,
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   unsigned EncodedValue,
41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   const MCSubtargetInfo &STI) const;
418cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling
419cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  unsigned VFPThumb2PostEncoder(const MCInst &MI,
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                unsigned EncodedValue,
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                const MCSubtargetInfo &STI) const;
422c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson
42370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  void EmitByte(unsigned char C, raw_ostream &OS) const {
424568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    OS << (char)C;
425568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
426568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
42770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
428568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    // Output the constant in little endian byte order.
429568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    for (unsigned i = 0; i != Size; ++i) {
43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EmitByte((Val >> Shift) & 0xff, OS);
432568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach    }
433568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  }
434568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
435568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         SmallVectorImpl<MCFixup> &Fixups,
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         const MCSubtargetInfo &STI) const override;
438568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach};
439568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
440568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach} // end anonymous namespace
441568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII,
44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                              const MCRegisterInfo &MRI,
44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                              MCContext &Ctx) {
44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return new ARMMCCodeEmitter(MCII, Ctx, true);
44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMCCodeEmitter *llvm::createARMBEMCCodeEmitter(const MCInstrInfo &MCII,
44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                              const MCRegisterInfo &MRI,
45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                              MCContext &Ctx) {
45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return new ARMMCCodeEmitter(MCII, Ctx, false);
452568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}
453568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach
4547bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
4557bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
456c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson/// Thumb2 mode.
457c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 unsigned EncodedValue,
45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 const MCSubtargetInfo &STI) const {
46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isThumb2(STI)) {
4617bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach    // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
462c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
463c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    // set to 1111.
464c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    unsigned Bit24 = EncodedValue & 0x01000000;
465c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    unsigned Bit28 = Bit24 << 4;
466c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue &= 0xEFFFFFFF;
467c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue |= Bit28;
468c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson    EncodedValue |= 0x0F000000;
469c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  }
4707bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
471c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson  return EncodedValue;
472c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson}
473c7139a6f0d3acd198ab9eb536ea1ec52e61ff130Owen Anderson
47457dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
4757bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
47657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson/// Thumb2 mode.
47757dac88f775c1191a98cff89abd1f7ad33df5e29Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 unsigned EncodedValue,
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 const MCSubtargetInfo &STI) const {
48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isThumb2(STI)) {
48157dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson    EncodedValue &= 0xF0FFFFFF;
48257dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson    EncodedValue |= 0x09000000;
48357dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  }
4847bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
48557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson  return EncodedValue;
48657dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson}
48757dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson
4888f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
4897bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach/// instructions, and rewrite them to their Thumb2 form if we are currently in
4908f143913141991baaa535ca0da7c8a81606d6392Owen Anderson/// Thumb2 mode.
4918f143913141991baaa535ca0da7c8a81606d6392Owen Andersonunsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 unsigned EncodedValue,
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 const MCSubtargetInfo &STI) const {
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isThumb2(STI)) {
4958f143913141991baaa535ca0da7c8a81606d6392Owen Anderson    EncodedValue &= 0x00FFFFFF;
4968f143913141991baaa535ca0da7c8a81606d6392Owen Anderson    EncodedValue |= 0xEE000000;
4978f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  }
4987bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
4998f143913141991baaa535ca0da7c8a81606d6392Owen Anderson  return EncodedValue;
5008f143913141991baaa535ca0da7c8a81606d6392Owen Anderson}
5018f143913141991baaa535ca0da7c8a81606d6392Owen Anderson
50219c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly/// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form
50319c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly/// if we are in Thumb2.
50419c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Goulyunsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 unsigned EncodedValue,
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 const MCSubtargetInfo &STI) const {
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isThumb2(STI)) {
50819c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly    EncodedValue |= 0xC000000; // Set bits 27-26
50919c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  }
51019c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly
51119c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  return EncodedValue;
51219c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly}
51319c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly
514cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
515cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling/// them to their Thumb2 form if we are currently in Thumb2 mode.
516cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendlingunsigned ARMMCCodeEmitter::
51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesVFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue,
51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     const MCSubtargetInfo &STI) const {
51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isThumb2(STI)) {
520cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling    EncodedValue &= 0x0FFFFFFF;
521cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling    EncodedValue |= 0xE0000000;
522cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  }
523cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling  return EncodedValue;
524cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling}
52557dac88f775c1191a98cff89abd1f7ad33df5e29Owen Anderson
52656ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// getMachineOpValue - Return binary encoding of operand. If the machine
52756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach/// operand requires relocation, record the relocation and return zero.
528806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
529806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetMachineOpValue(const MCInst &MI, const MCOperand &MO,
53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  SmallVectorImpl<MCFixup> &Fixups,
53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  const MCSubtargetInfo &STI) const {
532bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  if (MO.isReg()) {
5330800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    unsigned Reg = MO.getReg();
53499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
535d8a11c25fa64c152628cfcf5f9d36eb60242b302Jim Grosbach
536b0708d292bbe04cfcfe0c5cb5e27d8a872c9839aJim Grosbach    // Q registers are encoded as 2x their register number.
5370800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    switch (Reg) {
5380800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    default:
5390800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling      return RegNo;
5400800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q0:  case ARM::Q1:  case ARM::Q2:  case ARM::Q3:
5410800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q4:  case ARM::Q5:  case ARM::Q6:  case ARM::Q7:
5420800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q8:  case ARM::Q9:  case ARM::Q10: case ARM::Q11:
5430800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling    case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
5440800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling      return 2 * RegNo;
54590d4cf931477b497553a9f2d0ed53377dd5dd88cOwen Anderson    }
546bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  } else if (MO.isImm()) {
54756ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach    return static_cast<unsigned>(MO.getImm());
548bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling  } else if (MO.isFPImm()) {
549bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling    return static_cast<unsigned>(APFloat(MO.getFPImm())
550bbbdcd453d22258cb4dd217eddf016668fcebf84Bill Wendling                     .bitcastToAPInt().getHiBits(32).getLimitedValue());
5510800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  }
5520800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
553817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach  llvm_unreachable("Unable to encode MCOperand!");
55456ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach}
55556ac907c57fcfddfd650238f03c856a9d55987e5Jim Grosbach
5565df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
557806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachbool ARMMCCodeEmitter::
558806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachEncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups,
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const {
5613e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  const MCOperand &MO  = MI.getOperand(OpIdx);
5623e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
5639af3d1c0dc2250793ada1ca6cfa98e9f1253f7f9Jim Grosbach
56499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
56592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
56692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  int32_t SImm = MO1.getImm();
56792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  bool isAdd = true;
5685df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
569ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  // Special value for #-0
5700da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson  if (SImm == INT32_MIN) {
57192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    SImm = 0;
5720da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    isAdd = false;
5730da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson  }
5745df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
575ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
57692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  if (SImm < 0) {
57792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    SImm = -SImm;
57892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    isAdd = false;
57992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  }
58092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
58192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Imm = SImm;
58292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  return isAdd;
58392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling}
5845df0e0a61d6ac0e8dcf1a600bdc28d3e4a8db0adBill Wendling
585dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Helper function to get the branch target operand,
586dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// which is either an immediate or requires a fixup.
587dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlingstatic uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
588dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling                                       unsigned FixupKind,
58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       SmallVectorImpl<MCFixup> &Fixups,
59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       const MCSubtargetInfo &STI) {
591662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
592662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
593662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  // If the destination is an immediate, we have nothing to do.
594662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  if (MO.isImm()) return MO.getImm();
595dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  assert(MO.isExpr() && "Unexpected branch target type!");
596662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  const MCExpr *Expr = MO.getExpr();
597dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling  MCFixupKind Kind = MCFixupKind(FixupKind);
59842e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach  Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
599662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
600662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  // All of the information is in the fixup.
601662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach  return 0;
602662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach}
603662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach
604559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// Thumb BL and BLX use a strange offset encoding where bits 22 and 21 are
605559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson// determined by negating them and XOR'ing them with bit 23.
606559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Andersonstatic int32_t encodeThumbBLOffset(int32_t offset) {
607559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset >>= 1;
608559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  uint32_t S  = (offset & 0x800000) >> 23;
609559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  uint32_t J1 = (offset & 0x400000) >> 22;
610559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  uint32_t J2 = (offset & 0x200000) >> 21;
611559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J1 = (~J1 & 0x1);
612559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J2 = (~J2 & 0x1);
613559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J1 ^= S;
614559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  J2 ^= S;
615559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson
616559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset &= ~0x600000;
617559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset |= J1 << 22;
618559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  offset |= J2 << 21;
619559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson
620559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  return offset;
621559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson}
622559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson
623dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getThumbBLTargetOpValue - Return encoding info for immediate branch target.
624c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbachuint32_t ARMMCCodeEmitter::
625dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        SmallVectorImpl<MCFixup> &Fixups,
62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        const MCSubtargetInfo &STI) const {
628559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
629559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  if (MO.isExpr())
630559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl,
63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    Fixups, STI);
632559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  return encodeThumbBLOffset(MO.getImm());
633dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling}
634c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
63509aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
63609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling/// BLX branch target.
63709aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendlinguint32_t ARMMCCodeEmitter::
63809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill WendlinggetThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
63936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         SmallVectorImpl<MCFixup> &Fixups,
64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         const MCSubtargetInfo &STI) const {
641559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
642559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  if (MO.isExpr())
643559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx,
64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    Fixups, STI);
645559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson  return encodeThumbBLOffset(MO.getImm());
64609aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling}
64709aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling
648e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
649e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbachuint32_t ARMMCCodeEmitter::
650e246717c3a36a913fd4200776ed621649bb2b624Jim GrosbachgetThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        SmallVectorImpl<MCFixup> &Fixups,
65236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        const MCSubtargetInfo &STI) const {
653391ac65377f2ad5e48a796e75120959e22430605Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
654391ac65377f2ad5e48a796e75120959e22430605Owen Anderson  if (MO.isExpr())
655559c277aa9242dd5b32d2f2ccc353d938f886ee9Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br,
65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    Fixups, STI);
657391ac65377f2ad5e48a796e75120959e22430605Owen Anderson  return (MO.getImm() >> 1);
658e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach}
659e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach
66001086451393ef33e82b6fad623989dd97dd70edfJim Grosbach/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
66101086451393ef33e82b6fad623989dd97dd70edfJim Grosbachuint32_t ARMMCCodeEmitter::
66201086451393ef33e82b6fad623989dd97dd70edfJim GrosbachgetThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
66336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         SmallVectorImpl<MCFixup> &Fixups,
66436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         const MCSubtargetInfo &STI) const {
665721cb1fde07423fd1905338d443172a8028ad634Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
666721cb1fde07423fd1905338d443172a8028ad634Owen Anderson  if (MO.isExpr())
667721cb1fde07423fd1905338d443172a8028ad634Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc,
66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    Fixups, STI);
669721cb1fde07423fd1905338d443172a8028ad634Owen Anderson  return (MO.getImm() >> 1);
67001086451393ef33e82b6fad623989dd97dd70edfJim Grosbach}
67101086451393ef33e82b6fad623989dd97dd70edfJim Grosbach
672027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
673dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter::
674027d6e8d1ca04e4096fb3a27579b861d861466c5Jim GrosbachgetThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
67536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        SmallVectorImpl<MCFixup> &Fixups,
67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        const MCSubtargetInfo &STI) const {
67721df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
67821df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson  if (MO.isExpr())
67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups, STI);
68021df36c57afc588c8073a070a47e3ba45fa87270Owen Anderson  return (MO.getImm() >> 1);
681dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling}
682c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
683685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// Return true if this branch has a non-always predication
684685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimstatic bool HasConditionalBranch(const MCInst &MI) {
685685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  int NumOp = MI.getNumOperands();
686685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  if (NumOp >= 2) {
687685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    for (int i = 0; i < NumOp-1; ++i) {
688685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      const MCOperand &MCOp1 = MI.getOperand(i);
689685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      const MCOperand &MCOp2 = MI.getOperand(i + 1);
69010096dbdef22a10a6a4444437c935ab428545525Owen Anderson      if (MCOp1.isImm() && MCOp2.isReg() &&
691685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim          (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) {
69210096dbdef22a10a6a4444437c935ab428545525Owen Anderson        if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL)
693685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim          return true;
694685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      }
695685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    }
696685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  }
697685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim  return false;
698685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim}
699685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
700dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
701dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling/// target.
702dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendlinguint32_t ARMMCCodeEmitter::
703dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill WendlinggetBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       SmallVectorImpl<MCFixup> &Fixups,
70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       const MCSubtargetInfo &STI) const {
706092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach  // FIXME: This really, really shouldn't use TargetMachine. We don't want
707092e2cd5693114a4f1d93eb5b72f3e194de27236Jim Grosbach  // coupling between MC and TM anywhere we can help it.
70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isThumb2(STI))
709c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    return
71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups, STI);
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return getARMBranchTargetOpValue(MI, OpIdx, Fixups, STI);
712685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim}
713685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
714685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
715685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim/// target.
716685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kimuint32_t ARMMCCodeEmitter::
717685c350ae76b588e1f00c01a511fe8bd57f18394Jason W KimgetARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          SmallVectorImpl<MCFixup> &Fixups,
71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          const MCSubtargetInfo &STI) const {
720d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
721d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  if (MO.isExpr()) {
72210096dbdef22a10a6a4444437c935ab428545525Owen Anderson    if (HasConditionalBranch(MI))
723d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson      return ::getBranchTargetOpValue(MI, OpIdx,
72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      ARM::fixup_arm_condbranch, Fixups, STI);
72510096dbdef22a10a6a4444437c935ab428545525Owen Anderson    return ::getBranchTargetOpValue(MI, OpIdx,
72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    ARM::fixup_arm_uncondbranch, Fixups, STI);
727d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  }
728d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson
729d7568e1c355f5e364eddafc15c6d5553559f32a5Owen Anderson  return MO.getImm() >> 2;
730c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach}
731c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach
732f1eab597b2316c6cfcabfcee98895fedb2071722Owen Andersonuint32_t ARMMCCodeEmitter::
7337b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim GrosbachgetARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          SmallVectorImpl<MCFixup> &Fixups,
73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          const MCSubtargetInfo &STI) const {
7367b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach  const MCOperand MO = MI.getOperand(OpIdx);
737cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy  if (MO.isExpr()) {
738cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy    if (HasConditionalBranch(MI))
739cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy      return ::getBranchTargetOpValue(MI, OpIdx,
74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      ARM::fixup_arm_condbl, Fixups, STI);
74136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups, STI);
742cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy  }
7437b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach
7447b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach  return MO.getImm() >> 2;
7457b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach}
7467b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach
7477b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbachuint32_t ARMMCCodeEmitter::
748f1eab597b2316c6cfcabfcee98895fedb2071722Owen AndersongetARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
74936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          SmallVectorImpl<MCFixup> &Fixups,
75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          const MCSubtargetInfo &STI) const {
751f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
7527b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach  if (MO.isExpr())
75336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups, STI);
754685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
755f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson  return MO.getImm() >> 1;
756f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson}
757685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim
758c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
759c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson/// immediate branch target.
760c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Andersonuint32_t ARMMCCodeEmitter::
761c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen AndersongetUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       SmallVectorImpl<MCFixup> &Fixups,
76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       const MCSubtargetInfo &STI) const {
764e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa  unsigned Val = 0;
765e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa  const MCOperand MO = MI.getOperand(OpIdx);
766e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa
767e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa  if(MO.isExpr())
76836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups, STI);
769e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa  else
770e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa    Val = MO.getImm() >> 1;
771e921f323533ee751b3fa34bd00d10fa72096ffd3Mihai Popa
772c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool I  = (Val & 0x800000);
773c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool J1 = (Val & 0x400000);
774c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  bool J2 = (Val & 0x200000);
775c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  if (I ^ J1)
776c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val &= ~0x400000;
777c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  else
778c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val |= 0x400000;
779971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
780c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  if (I ^ J2)
781c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val &= ~0x200000;
782c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  else
783c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    Val |= 0x200000;
784971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson
785c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson  return Val;
786c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson}
787c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson
7881fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getAdrLabelOpValue - Return encoding info for 12-bit shifted-immediate
7891fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// ADR label target.
7905d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbachuint32_t ARMMCCodeEmitter::
7915d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim GrosbachgetAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
79236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   SmallVectorImpl<MCFixup> &Fixups,
79336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   const MCSubtargetInfo &STI) const {
79496425c846494c1c20a4c931f4783571295ab170cOwen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
79596425c846494c1c20a4c931f4783571295ab170cOwen Anderson  if (MO.isExpr())
79696425c846494c1c20a4c931f4783571295ab170cOwen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12,
79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    Fixups, STI);
798ea8ddd86b1e364a799e57fc0ac468a9c4a8f8bcfMihai Popa  int64_t offset = MO.getImm();
79996425c846494c1c20a4c931f4783571295ab170cOwen Anderson  uint32_t Val = 0x2000;
8001fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
801d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover  int SoImmVal;
8021fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  if (offset == INT32_MIN) {
8031fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    Val = 0x1000;
804d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    SoImmVal = 0;
8051fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  } else if (offset < 0) {
80696425c846494c1c20a4c931f4783571295ab170cOwen Anderson    Val = 0x1000;
80796425c846494c1c20a4c931f4783571295ab170cOwen Anderson    offset *= -1;
808d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    SoImmVal = ARM_AM::getSOImmVal(offset);
809d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    if(SoImmVal == -1) {
810d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      Val = 0x2000;
811d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      offset *= -1;
812d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      SoImmVal = ARM_AM::getSOImmVal(offset);
813d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    }
814d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover  } else {
815d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    SoImmVal = ARM_AM::getSOImmVal(offset);
816d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    if(SoImmVal == -1) {
817d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      Val = 0x1000;
818d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      offset *= -1;
819d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover      SoImmVal = ARM_AM::getSOImmVal(offset);
820d65dfd83421f4d26e6dc20476718d7d9b6ba3f3bTim Northover    }
82196425c846494c1c20a4c931f4783571295ab170cOwen Anderson  }
8221fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
8231fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  assert(SoImmVal != -1 && "Not a valid so_imm value!");
8241fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
8251fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  Val |= SoImmVal;
82696425c846494c1c20a4c931f4783571295ab170cOwen Anderson  return Val;
8275d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach}
8285d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach
8291fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getT2AdrLabelOpValue - Return encoding info for 12-bit immediate ADR label
830a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson/// target.
831a838a25d59838adfa91463f6a918ae3adeb352c1Owen Andersonuint32_t ARMMCCodeEmitter::
832a838a25d59838adfa91463f6a918ae3adeb352c1Owen AndersongetT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
83336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   SmallVectorImpl<MCFixup> &Fixups,
83436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   const MCSubtargetInfo &STI) const {
83596425c846494c1c20a4c931f4783571295ab170cOwen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
83696425c846494c1c20a4c931f4783571295ab170cOwen Anderson  if (MO.isExpr())
83796425c846494c1c20a4c931f4783571295ab170cOwen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
83836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    Fixups, STI);
83908fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  int32_t Val = MO.getImm();
8401fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  if (Val == INT32_MIN)
8411fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    Val = 0x1000;
8421fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  else if (Val < 0) {
84308fef885eb39339a47e3be7f0842b1db33683003Owen Anderson    Val *= -1;
84408fef885eb39339a47e3be7f0842b1db33683003Owen Anderson    Val |= 0x1000;
84508fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  }
84608fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  return Val;
847a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson}
848a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson
8491fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu/// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
850d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach/// target.
851d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbachuint32_t ARMMCCodeEmitter::
852d40963c4065432ec7e47879d3ca665a54ee903b6Jim GrosbachgetThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
85336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   SmallVectorImpl<MCFixup> &Fixups,
85436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   const MCSubtargetInfo &STI) const {
85596425c846494c1c20a4c931f4783571295ab170cOwen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
85696425c846494c1c20a4c931f4783571295ab170cOwen Anderson  if (MO.isExpr())
85796425c846494c1c20a4c931f4783571295ab170cOwen Anderson    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10,
85836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    Fixups, STI);
85996425c846494c1c20a4c931f4783571295ab170cOwen Anderson  return MO.getImm();
860d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach}
861d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach
862f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg'
863f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// operand.
8640f4b60d43a289671082deee3bd56a3a055afb16aOwen Andersonuint32_t ARMMCCodeEmitter::
865f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
86636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SmallVectorImpl<MCFixup> &,
86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              const MCSubtargetInfo &STI) const {
868f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  // [Rn, Rm]
869f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  //   {5-3} = Rm
870f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  //   {2-0} = Rn
8710f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx);
872f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  const MCOperand &MO2 = MI.getOperand(OpIdx + 1);
87399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
87499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO2.getReg());
8750f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson  return (Rm << 3) | Rn;
8760f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson}
8770f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson
87892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
879806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter::
880806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
88136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        SmallVectorImpl<MCFixup> &Fixups,
88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        const MCSubtargetInfo &STI) const {
88392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {17-13} = reg
88492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {12}    = (U)nsigned (add == '1', sub == '0')
88592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {11-0}  = imm12
88692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  unsigned Reg, Imm12;
88770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  bool isAdd = true;
88870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  // If The first operand isn't a register, we have a label reference.
88970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
890971b83b67a9812556cdb97bb58aa96fb37af458dOwen Anderson  if (!MO.isReg()) {
89199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
89270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Imm12 = 0;
89370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
894fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson    if (MO.isExpr()) {
895fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      const MCExpr *Expr = MO.getExpr();
896beb920fce6ccc89b4735f280f94cb8c227f4ef5eAmaury de la Vieuville      isAdd = false ; // 'U' bit is set as part of the fixup.
897fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson
898fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      MCFixupKind Kind;
89936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (isThumb2(STI))
900fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
901fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      else
902fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
90342e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach      Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
904fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson
905fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      ++MCNumCPRelocations;
906fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson    } else {
907fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      Reg = ARM::PC;
908fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      int32_t Offset = MO.getImm();
909e97fc44045732de9fc4715241013f9238ec007dcMihai Popa      if (Offset == INT32_MIN) {
910e97fc44045732de9fc4715241013f9238ec007dcMihai Popa        Offset = 0;
911e97fc44045732de9fc4715241013f9238ec007dcMihai Popa        isAdd = false;
912e97fc44045732de9fc4715241013f9238ec007dcMihai Popa      } else if (Offset < 0) {
913fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        Offset *= -1;
914fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson        isAdd = false;
915fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      }
916fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson      Imm12 = Offset;
917fd92d2e106acfbf13ed29b5d15f3a690cd8699b2Owen Anderson    }
91870933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  } else
91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups, STI);
92092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
92192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  uint32_t Binary = Imm12 & 0xfff;
92292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
923ab682a2090f795d0b67f29889622da0a74cd97c3Jim Grosbach  if (isAdd)
92492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    Binary |= (1 << 12);
92592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Binary |= (Reg << 13);
92692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  return Binary;
92792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling}
92892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
929a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// getT2Imm8s4OpValue - Return encoding info for
930a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// '+/- imm8<<2' operand.
931a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachuint32_t ARMMCCodeEmitter::
932a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachgetT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
93336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   SmallVectorImpl<MCFixup> &Fixups,
93436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   const MCSubtargetInfo &STI) const {
935a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // FIXME: The immediate operand should have already been encoded like this
936a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // before ever getting here. The encoder method should just need to combine
937a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // the MI operands for the register and the offset into a single
938a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // representation for the complex operand in the .td file. This isn't just
939a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // style, unfortunately. As-is, we can't represent the distinct encoding
940a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // for #-0.
941a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
942a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // {8}    = (U)nsigned (add == '1', sub == '0')
943a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // {7-0}  = imm8
944a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  int32_t Imm8 = MI.getOperand(OpIdx).getImm();
945a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isAdd = Imm8 >= 0;
946a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
947a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
948a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (Imm8 < 0)
949aaf217953bef3b2cc0e0f26bf474616cc20cf7f0Richard Smith    Imm8 = -(uint32_t)Imm8;
950a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
951a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Scaled by 4.
952a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Imm8 /= 4;
953a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
954a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  uint32_t Binary = Imm8 & 0xff;
955a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
956a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (isAdd)
957a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Binary |= (1 << 8);
958a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return Binary;
959a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
960a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
9619d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// getT2AddrModeImm8s4OpValue - Return encoding info for
9629d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson/// 'reg +/- imm8<<2' operand.
9639d63d90de5e57ad96f467b270544443a9284eb2bOwen Andersonuint32_t ARMMCCodeEmitter::
9649d63d90de5e57ad96f467b270544443a9284eb2bOwen AndersongetT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
96536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        SmallVectorImpl<MCFixup> &Fixups,
96636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        const MCSubtargetInfo &STI) const {
96790cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {12-9} = reg
96890cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {8}    = (U)nsigned (add == '1', sub == '0')
96990cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach  // {7-0}  = imm8
9709d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  unsigned Reg, Imm8;
9719d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  bool isAdd = true;
9729d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  // If The first operand isn't a register, we have a label reference.
9739d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  const MCOperand &MO = MI.getOperand(OpIdx);
9749d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  if (!MO.isReg()) {
97599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
9769d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    Imm8 = 0;
9779d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    isAdd = false ; // 'U' bit is set as part of the fixup.
9789d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
9799d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    assert(MO.isExpr() && "Unexpected machine operand type!");
9809d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    const MCExpr *Expr = MO.getExpr();
9812f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
98242e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
9839d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
9849d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    ++MCNumCPRelocations;
9859d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  } else
98636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);
9879d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
988a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // FIXME: The immediate operand should have already been encoded like this
989a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // before ever getting here. The encoder method should just need to combine
990a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // the MI operands for the register and the offset into a single
991a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // representation for the complex operand in the .td file. This isn't just
992a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // style, unfortunately. As-is, we can't represent the distinct encoding
993a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // for #-0.
9949d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  uint32_t Binary = (Imm8 >> 2) & 0xff;
9959d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
9969d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  if (isAdd)
99790cc533fda9742f5c67203f97e69e5efd270c676Jim Grosbach    Binary |= (1 << 8);
9989d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  Binary |= (Reg << 9);
9999d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson  return Binary;
10009d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson}
10019d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson
1002b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// getT2AddrModeImm0_1020s4OpValue - Return encoding info for
1003b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach/// 'reg + imm8<<2' operand.
1004b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbachuint32_t ARMMCCodeEmitter::
1005b6aed508e310e31dcb080e761ca856127cec0773Jim GrosbachgetT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
100636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        SmallVectorImpl<MCFixup> &Fixups,
100736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        const MCSubtargetInfo &STI) const {
1008b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  // {11-8} = reg
1009b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  // {7-0}  = imm8
1010b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
1011b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
101299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Reg = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1013b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  unsigned Imm8 = MO1.getImm();
1014b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  return (Reg << 8) | Imm8;
1015b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach}
1016b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
10177597212abced110723f2fee985a7d60557c092ecEvan Chenguint32_t
10187597212abced110723f2fee985a7d60557c092ecEvan ChengARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
101936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      SmallVectorImpl<MCFixup> &Fixups,
102036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      const MCSubtargetInfo &STI) const {
1021837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim  // {20-16} = imm{15-12}
1022837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim  // {11-0}  = imm{11-0}
10237bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
10247597212abced110723f2fee985a7d60557c092ecEvan Cheng  if (MO.isImm())
10257597212abced110723f2fee985a7d60557c092ecEvan Cheng    // Hi / lo 16 bits already extracted during earlier passes.
1026837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    return static_cast<unsigned>(MO.getImm());
10277597212abced110723f2fee985a7d60557c092ecEvan Cheng
10287597212abced110723f2fee985a7d60557c092ecEvan Cheng  // Handle :upper16: and :lower16: assembly prefixes.
10297597212abced110723f2fee985a7d60557c092ecEvan Cheng  const MCExpr *E = MO.getExpr();
103094b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  MCFixupKind Kind;
10317597212abced110723f2fee985a7d60557c092ecEvan Cheng  if (E->getKind() == MCExpr::Target) {
10327597212abced110723f2fee985a7d60557c092ecEvan Cheng    const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E);
10337597212abced110723f2fee985a7d60557c092ecEvan Cheng    E = ARM16Expr->getSubExpr();
10347597212abced110723f2fee985a7d60557c092ecEvan Cheng
103536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(E)) {
103636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const int64_t Value = MCE->getValue();
103736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Value > UINT32_MAX)
103836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        report_fatal_error("constant value truncated (limited to 32-bit)");
103936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
104036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      switch (ARM16Expr->getKind()) {
104136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      case ARMMCExpr::VK_ARM_HI16:
104236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return (int32_t(Value) & 0xffff0000) >> 16;
104336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      case ARMMCExpr::VK_ARM_LO16:
104436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return (int32_t(Value) & 0x0000ffff);
104536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      default: llvm_unreachable("Unsupported ARMFixup");
104636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
104736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
104836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10497597212abced110723f2fee985a7d60557c092ecEvan Cheng    switch (ARM16Expr->getKind()) {
1050bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Unsupported ARMFixup");
10517597212abced110723f2fee985a7d60557c092ecEvan Cheng    case ARMMCExpr::VK_ARM_HI16:
105236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movt_hi16
105336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       : ARM::fixup_arm_movt_hi16);
1054837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim      break;
10557597212abced110723f2fee985a7d60557c092ecEvan Cheng    case ARMMCExpr::VK_ARM_LO16:
105636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movw_lo16
105736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       : ARM::fixup_arm_movw_lo16);
1058837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim      break;
1059837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    }
1060dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
106142e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc()));
1062837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    return 0;
106394b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  }
106494b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  // If the expression doesn't have :upper16: or :lower16: on it,
1065dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // it's just a plain immediate expression, previously those evaluated to
106694b590f8faf4dbba406f263e6a839882b0c68a94Jim Grosbach  // the lower 16 bits of the expression regardless of whether
1067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // we have a movt or a movw, but that led to misleadingly results.
1068dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // This is now disallowed in the the AsmParser in validateInstruction()
1069dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // so this should never happen.
1070c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  llvm_unreachable("expression without :upper16: or :lower16:");
1071837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim}
1072837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim
1073837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kimuint32_t ARMMCCodeEmitter::
107454fea632b161f98e96ec7275922e35102bcecc5dJim GrosbachgetLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
107536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    SmallVectorImpl<MCFixup> &Fixups,
107636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    const MCSubtargetInfo &STI) const {
107754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
107854fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
107954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
108099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
108199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rm = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
108254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
108354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
108499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
108599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned SBits = getShiftOp(ShOp);
108654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
108793c7c449a1351542fa5a275587187154dbedb8e0Tim Northover  // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift
108893c7c449a1351542fa5a275587187154dbedb8e0Tim Northover  // amount. However, it would be an easy mistake to make so check here.
108993c7c449a1351542fa5a275587187154dbedb8e0Tim Northover  assert((ShImm & ~0x1f) == 0 && "Out of range shift amount");
109093c7c449a1351542fa5a275587187154dbedb8e0Tim Northover
109154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {16-13} = Rn
109254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {12}    = isAdd
109354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  // {11-0}  = shifter
109454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {3-0}  = Rm
109554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {4}    = 0
109654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {6-5}  = type
109754fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  //  {11-7} = imm
1098570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t Binary = Rm;
109954fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= Rn << 13;
110054fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= SBits << 5;
110154fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  Binary |= ShImm << 7;
110254fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  if (isAdd)
110354fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach    Binary |= 1 << 12;
110454fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach  return Binary;
110554fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach}
110654fea632b161f98e96ec7275922e35102bcecc5dJim Grosbach
1107570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbachuint32_t ARMMCCodeEmitter::
110899f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
110936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    SmallVectorImpl<MCFixup> &Fixups,
111036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    const MCSubtargetInfo &STI) const {
111199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {17-14}  Rn
111299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {13}     1 == imm12, 0 == Rm
111399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {12}     isAdd
111499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {11-0}   imm12/Rm
111599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
111699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
111736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups, STI);
111899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  Binary |= Rn << 14;
111999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  return Binary;
112099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach}
112199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
112299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter::
112399f53d13efc259b47c93dc0d90a5db763cbe371aJim GrosbachgetAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
112436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          SmallVectorImpl<MCFixup> &Fixups,
112536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          const MCSubtargetInfo &STI) const {
112699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {13}     1 == imm12, 0 == Rm
112799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {12}     isAdd
112899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // {11-0}   imm12/Rm
112999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
113099f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
113199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  unsigned Imm = MO1.getImm();
113299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
113399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  bool isReg = MO.getReg() != 0;
113499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  uint32_t Binary = ARM_AM::getAM2Offset(Imm);
113599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
113699f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  if (isReg) {
113799f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);
113899f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    Binary <<= 7;                    // Shift amount is bits [11:7]
113999f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach    Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]
114099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Binary |= CTX.getRegisterInfo()->getEncodingValue(MO.getReg()); // Rm is bits [3:0]
114199f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  }
114299f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach  return Binary | (isAdd << 12) | (isReg << 13);
114399f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach}
114499f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbach
114599f53d13efc259b47c93dc0d90a5db763cbe371aJim Grosbachuint32_t ARMMCCodeEmitter::
11467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachgetPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
114736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     SmallVectorImpl<MCFixup> &Fixups,
114836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     const MCSubtargetInfo &STI) const {
11497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // {4}      isAdd
11507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // {3-0}    Rm
11517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
11527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
115316578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = MO1.getImm() != 0;
115499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  return CTX.getRegisterInfo()->getEncodingValue(MO.getReg()) | (isAdd << 4);
11557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
11567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
11577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachuint32_t ARMMCCodeEmitter::
11587eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim GrosbachgetAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
115936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          SmallVectorImpl<MCFixup> &Fixups,
116036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          const MCSubtargetInfo &STI) const {
11617eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {9}      1 == imm8, 0 == Rm
11627eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {8}      isAdd
11637eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {7-4}    imm7_4/zero
11647eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // {3-0}    imm3_0/Rm
11657eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
11667eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
11677eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  unsigned Imm = MO1.getImm();
11687eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
11697eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  bool isImm = MO.getReg() == 0;
11707eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
11717eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
11727eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  if (!isImm)
117399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
11747eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach  return Imm8 | (isAdd << 8) | (isImm << 9);
11757eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach}
11767eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbach
11777eab97f260ba0f56d1d4a82f3a4eb2c979452011Jim Grosbachuint32_t ARMMCCodeEmitter::
1178570a9226913ebe1af04832b8fb3273c70b4ee152Jim GrosbachgetAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
117936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    SmallVectorImpl<MCFixup> &Fixups,
118036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    const MCSubtargetInfo &STI) const {
1181570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {13}     1 == imm8, 0 == Rm
1182570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {12-9}   Rn
1183570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {8}      isAdd
1184570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {7-4}    imm7_4/zero
1185570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // {3-0}    imm3_0/Rm
1186570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
1187570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
1188570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
11892f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
11902f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach  // If The first operand isn't a register, we have a label reference.
11912f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach  if (!MO.isReg()) {
119299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
11932f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
11942f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    assert(MO.isExpr() && "Unexpected machine operand type!");
11952f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    const MCExpr *Expr = MO.getExpr();
11962f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled);
119742e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
11982f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
11992f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    ++MCNumCPRelocations;
12002f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    return (Rn << 9) | (1 << 13);
12012f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach  }
120299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1203570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  unsigned Imm = MO2.getImm();
1204570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
1205570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  bool isImm = MO1.getReg() == 0;
1206570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
1207570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
1208570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  if (!isImm)
120999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Imm8 = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
1210570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach  return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
1211570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach}
1212570a9226913ebe1af04832b8fb3273c70b4ee152Jim Grosbach
1213b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands.
1214d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbachuint32_t ARMMCCodeEmitter::
1215d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim GrosbachgetAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
121636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          SmallVectorImpl<MCFixup> &Fixups,
121736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          const MCSubtargetInfo &STI) const {
1218d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // [SP, #imm]
1219d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  //   {7-0} = imm8
1220d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1221b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling  assert(MI.getOperand(OpIdx).getReg() == ARM::SP &&
1222b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling         "Unexpected base register!");
12237a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
1224d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // The immediate is already shifted for the implicit zeroes, so no change
1225d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  // here.
1226d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach  return MO1.getImm() & 0xff;
1227d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach}
1228d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach
1229f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling/// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
1230272df516d7a9b1f0f69174276abaa759816ee456Bill Wendlinguint32_t ARMMCCodeEmitter::
1231f4caf69720d807573c50d41aa06bcec1c99bdbbdBill WendlinggetAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
123236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     SmallVectorImpl<MCFixup> &Fixups,
123336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     const MCSubtargetInfo &STI) const {
1234ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  // [Rn, #imm]
1235ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  //   {7-3} = imm5
1236ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  //   {2-0} = Rn
1237ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  const MCOperand &MO = MI.getOperand(OpIdx);
1238ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
123999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1240656b3d22f70c2d1c8a5286f7270cb380df862565Matt Beaumont-Gay  unsigned Imm5 = MO1.getImm();
1241272df516d7a9b1f0f69174276abaa759816ee456Bill Wendling  return ((Imm5 & 0x1f) << 3) | Rn;
12421fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling}
12431fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling
1244b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
1245b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendlinguint32_t ARMMCCodeEmitter::
1246b8958b031ec5163261f490f131780c5dc3d823d6Bill WendlinggetAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
124736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     SmallVectorImpl<MCFixup> &Fixups,
124836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     const MCSubtargetInfo &STI) const {
1249a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson  const MCOperand MO = MI.getOperand(OpIdx);
1250a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson  if (MO.isExpr())
125136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups, STI);
1252a7710edd98d71a81c43f8e3889cf0c790885d1b8Owen Anderson  return (MO.getImm() >> 2);
1253b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling}
1254b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling
12555177f79c378b47e38bed5ac05ba4b597f31b864eJim Grosbach/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand.
1256806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachuint32_t ARMMCCodeEmitter::
1257806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
125836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    SmallVectorImpl<MCFixup> &Fixups,
125936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    const MCSubtargetInfo &STI) const {
126092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {12-9} = reg
126192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {8}    = (U)nsigned (add == '1', sub == '0')
126292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // {7-0}  = imm8
126392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  unsigned Reg, Imm8;
126497dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  bool isAdd;
126570933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  // If The first operand isn't a register, we have a label reference.
126670933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  const MCOperand &MO = MI.getOperand(OpIdx);
126770933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach  if (!MO.isReg()) {
126899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC);   // Rn is PC.
126970933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    Imm8 = 0;
127097dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach    isAdd = false; // 'U' bit is handled as part of the fixup.
127170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
127270933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    assert(MO.isExpr() && "Unexpected machine operand type!");
127370933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    const MCExpr *Expr = MO.getExpr();
1274d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson    MCFixupKind Kind;
127536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (isThumb2(STI))
1276d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson      Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
1277d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson    else
1278d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson      Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
127942e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
128070933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach
128170933266ae73c891d9d1c2f0de72ecd1db8f86dfJim Grosbach    ++MCNumCPRelocations;
128297dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  } else {
128336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);
128497dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach    isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
128597dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  }
128692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
128792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
128892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
128997dd28fb89dc4c4caa3c60890335dc99489981a6Jim Grosbach  if (isAdd)
129092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling    Binary |= (1 << 8);
129192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling  Binary |= (Reg << 9);
12923e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  return Binary;
12933e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach}
12943e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach
1295806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1296152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
129736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                SmallVectorImpl<MCFixup> &Fixups,
129836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                const MCSubtargetInfo &STI) const {
12990800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
1300354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // shifted. The second is Rs, the amount to shift by, and the third specifies
1301354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // the type of the shift.
130235b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach  //
1303ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // {3-0} = Rm.
1304354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {4}   = 1
1305ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // {6-5} = type
1306354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {11-8} = Rs
1307354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {7}    = 0
1308ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1309ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO  = MI.getOperand(OpIdx);
1310ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1311ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
1312ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
1313ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1314ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode Rm.
131599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1316ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1317ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode the shift opcode.
1318ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned SBits = 0;
1319ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  unsigned Rs = MO1.getReg();
1320ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  if (Rs) {
1321ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // Set shift operand (bit[7:4]).
1322ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSL - 0001
1323ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // LSR - 0011
1324ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ASR - 0101
1325ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    // ROR - 0111
1326ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    switch (SOpc) {
1327ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    default: llvm_unreachable("Unknown shift opc!");
1328ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsl: SBits = 0x1; break;
1329ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::lsr: SBits = 0x3; break;
1330ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::asr: SBits = 0x5; break;
1331ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    case ARM_AM::ror: SBits = 0x7; break;
1332ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach    }
1333ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  }
13340800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
1335ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  Binary |= SBits << 4;
1336ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1337354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // Encode the shift operation Rs.
1338152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode Rs bit[11:8].
1339152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
134099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  return Binary | (CTX.getRegisterInfo()->getEncodingValue(Rs) << ARMII::RegRsShift);
1341152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson}
1342152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1343152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Andersonunsigned ARMMCCodeEmitter::
1344152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen AndersongetSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
134536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                SmallVectorImpl<MCFixup> &Fixups,
134636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                const MCSubtargetInfo &STI) const {
1347354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
1348354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // shifted. The second is the amount to shift by.
1349152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  //
1350152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // {3-0} = Rm.
1351354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {4}   = 0
1352152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // {6-5} = type
1353354712c5a506449676e6fcac6b623af4092e7100Owen Anderson  // {11-7} = imm
1354152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1355152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  const MCOperand &MO  = MI.getOperand(OpIdx);
1356152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
1357152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
1358152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1359152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode Rm.
136099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1361152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1362152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Encode the shift opcode.
1363152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  unsigned SBits = 0;
1364152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1365152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // Set shift operand (bit[6:4]).
1366152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // LSL - 000
1367152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // LSR - 010
1368152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // ASR - 100
1369152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // ROR - 110
1370152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  // RRX - 110 and bit[11:8] clear.
1371152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  switch (SOpc) {
1372152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  default: llvm_unreachable("Unknown shift opc!");
1373152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::lsl: SBits = 0x0; break;
1374152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::lsr: SBits = 0x2; break;
1375152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::asr: SBits = 0x4; break;
1376152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::ror: SBits = 0x6; break;
1377152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  case ARM_AM::rrx:
1378152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    Binary |= 0x60;
1379152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    return Binary;
1380ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  }
1381ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1382ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach  // Encode shift_imm bit[11:7].
1383152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson  Binary |= SBits << 4;
13843dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson  unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm());
1385b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton  assert(Offset < 32 && "Offset must be in range 0-31!");
13863dac0bec7e7874ffb378385b6160bd2117184ca9Owen Anderson  return Binary | (Offset << 7);
1387ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach}
1388ef324d704425a372aeba5fc91bee4d81635121f3Jim Grosbach
1389152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson
1390806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
139175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
139236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                SmallVectorImpl<MCFixup> &Fixups,
139336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                const MCSubtargetInfo &STI) const {
139475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
139575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO2 = MI.getOperand(OpNum+1);
13967bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach  const MCOperand &MO3 = MI.getOperand(OpNum+2);
13977bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
139875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // Encoded as [Rn, Rm, imm].
139975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // FIXME: Needs fixup support.
140099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
140175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 4;
140299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  Value |= CTX.getRegisterInfo()->getEncodingValue(MO2.getReg());
140375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 2;
140475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value |= MO3.getImm();
14057bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
140675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  return Value;
140775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson}
140875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
140975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter::
141075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen AndersongetT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
141136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         SmallVectorImpl<MCFixup> &Fixups,
141236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         const MCSubtargetInfo &STI) const {
141375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
141475579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  const MCOperand &MO2 = MI.getOperand(OpNum+1);
141575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
141675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // FIXME: Needs fixup support.
141799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Value = CTX.getRegisterInfo()->getEncodingValue(MO1.getReg());
14187bf4c02789f97e32225fc248dff6622b994a15eeJim Grosbach
141975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // Even though the immediate is 8 bits long, we need 9 bits in order
142075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  // to represent the (inverse of the) sign bit.
142175579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  Value <<= 9;
14226af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  int32_t tmp = (int32_t)MO2.getImm();
14236af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  if (tmp < 0)
14246af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    tmp = abs(tmp);
14256af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  else
14266af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    Value |= 256; // Set the ADD bit
14276af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  Value |= tmp & 255;
14286af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  return Value;
14296af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson}
14306af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson
14316af50f7dd12d82f0a80f3158102180eee4c921aaOwen Andersonunsigned ARMMCCodeEmitter::
14326af50f7dd12d82f0a80f3158102180eee4c921aaOwen AndersongetT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
143336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         SmallVectorImpl<MCFixup> &Fixups,
143436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         const MCSubtargetInfo &STI) const {
14356af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
14366af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson
14376af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  // FIXME: Needs fixup support.
14386af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  unsigned Value = 0;
14396af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  int32_t tmp = (int32_t)MO1.getImm();
14406af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  if (tmp < 0)
14416af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    tmp = abs(tmp);
14426af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  else
14436af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    Value |= 256; // Set the ADD bit
14446af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson  Value |= tmp & 255;
144575579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson  return Value;
144675579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson}
144775579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson
144875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Andersonunsigned ARMMCCodeEmitter::
14490e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen AndersongetT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
145036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         SmallVectorImpl<MCFixup> &Fixups,
145136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         const MCSubtargetInfo &STI) const {
14520e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  const MCOperand &MO1 = MI.getOperand(OpNum);
14530e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson
14540e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  // FIXME: Needs fixup support.
14550e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  unsigned Value = 0;
14560e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  int32_t tmp = (int32_t)MO1.getImm();
14570e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  if (tmp < 0)
14580e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    tmp = abs(tmp);
14590e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  else
14600e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    Value |= 4096; // Set the ADD bit
14610e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  Value |= tmp & 4095;
14620e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson  return Value;
14630e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson}
14640e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson
14650e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Andersonunsigned ARMMCCodeEmitter::
14665de6d841a5116152793dcab35a2e534a6a9aaa7aOwen AndersongetT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
146736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                SmallVectorImpl<MCFixup> &Fixups,
146836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                const MCSubtargetInfo &STI) const {
14695de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
14705de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // shifted. The second is the amount to shift by.
14715de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  //
14725de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {3-0} = Rm.
14735de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {4}   = 0
14745de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {6-5} = type
14755de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // {11-7} = imm
14765de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
14775de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  const MCOperand &MO  = MI.getOperand(OpIdx);
14785de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
14795de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
14805de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
14815de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode Rm.
148299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned Binary = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
14835de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
14845de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode the shift opcode.
14855de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  unsigned SBits = 0;
14865de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Set shift operand (bit[6:4]).
14875de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // LSL - 000
14885de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // LSR - 010
14895de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // ASR - 100
14905de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // ROR - 110
14915de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  switch (SOpc) {
14925de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  default: llvm_unreachable("Unknown shift opc!");
14935de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::lsl: SBits = 0x0; break;
14945de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::lsr: SBits = 0x2; break;
14955de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::asr: SBits = 0x4; break;
149612c7e90d369b4605aac0ddbd252231beacb2aabbOwen Anderson  case ARM_AM::rrx: // FALLTHROUGH
14975de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  case ARM_AM::ror: SBits = 0x6; break;
14985de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  }
14995de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
15005de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  Binary |= SBits << 4;
15015de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  if (SOpc == ARM_AM::rrx)
15025de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson    return Binary;
15035de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
15045de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  // Encode shift_imm bit[11:7].
15055de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson  return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
15065de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson}
15075de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Anderson
15085de6d841a5116152793dcab35a2e534a6a9aaa7aOwen Andersonunsigned ARMMCCodeEmitter::
1509806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
151036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               SmallVectorImpl<MCFixup> &Fixups,
151136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               const MCSubtargetInfo &STI) const {
15123fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
15133fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  // msb of the mask.
15143fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  const MCOperand &MO = MI.getOperand(Op);
15153fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  uint32_t v = ~MO.getImm();
1516c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer  uint32_t lsb = countTrailingZeros(v);
1517c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer  uint32_t msb = (32 - countLeadingZeros (v)) - 1;
15183fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
15193fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach  return lsb | (msb << 5);
15203fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach}
15213fea19105d4929ad694f0b6272de31924c9f9f09Jim Grosbach
1522806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1523806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetRegisterListOpValue(const MCInst &MI, unsigned Op,
152436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       SmallVectorImpl<MCFixup> &Fixups,
152536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       const MCSubtargetInfo &STI) const {
15266bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  // VLDM/VSTM:
15276bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {12-8} = Vd
15286bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {7-0}  = Number of registers
15296bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //
15306bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  // LDM/STM:
15316bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  //   {15-0}  = Bitfield of GPRs.
15326bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  unsigned Reg = MI.getOperand(Op).getReg();
1533c89c744b69cecac576317a98322fd295e36e9886Craig Topper  bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg);
1534c89c744b69cecac576317a98322fd295e36e9886Craig Topper  bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg);
15356bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
15365e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  unsigned Binary = 0;
15376bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
15386bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  if (SPRRegs || DPRRegs) {
15396bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    // VLDM/VSTM
154099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
15416bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;
15426bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    Binary |= (RegNo & 0x1f) << 8;
15436bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    if (SPRRegs)
15446bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= NumRegs;
15456bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    else
15466bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= NumRegs * 2;
15476bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling  } else {
15486bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {
154999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling      unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(MI.getOperand(I).getReg());
15506bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling      Binary |= 1 << RegNo;
15516bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling    }
15525e559a22c18166508a01fbd65471ec4e752726f9Bill Wendling  }
15536bc105a7b9282a0b5beb9d06267b31a3054fb3faBill Wendling
15546b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach  return Binary;
15556b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach}
15566b5252db2db5eeeadec4602329ac56beb6dea54aJim Grosbach
15578e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue - Encode an addrmode6 register number along
15588e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// with the alignment operand.
1559806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1560806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
156136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           SmallVectorImpl<MCFixup> &Fixups,
156236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           const MCSubtargetInfo &STI) const {
1563d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  const MCOperand &Reg = MI.getOperand(Op);
15640800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  const MCOperand &Imm = MI.getOperand(Op + 1);
156535b2de012d9404e3e9e4373e45f41711f752dd3aJim Grosbach
156699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
15670800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  unsigned Align = 0;
15680800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
15690800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  switch (Imm.getImm()) {
15700800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  default: break;
15710800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 2:
15720800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 4:
15730800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 8:  Align = 0x01; break;
15740800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 16: Align = 0x02; break;
15750800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  case 32: Align = 0x03; break;
1576d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  }
15770800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling
1578d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson  return RegNo | (Align << 4);
1579d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson}
1580d9aa7d30aa277fba319ee4bcdb862cd79f1aabe5Owen Anderson
1581183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// getAddrMode6OneLane32AddressOpValue - Encode an addrmode6 register number
1582183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang/// along  with the alignment operand for use in VST1 and VLD1 with size 32.
1583183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wangunsigned ARMMCCodeEmitter::
1584183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P WanggetAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
158536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    SmallVectorImpl<MCFixup> &Fixups,
158636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    const MCSubtargetInfo &STI) const {
1587183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  const MCOperand &Reg = MI.getOperand(Op);
1588183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  const MCOperand &Imm = MI.getOperand(Op + 1);
1589183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
159099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
1591183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  unsigned Align = 0;
1592183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1593183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  switch (Imm.getImm()) {
1594183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  default: break;
1595183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  case 8:
1596eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach  case 16:
1597eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach  case 32: // Default '0' value for invalid alignments of 8, 16, 32 bytes.
1598eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach  case 2: Align = 0x00; break;
1599eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach  case 4: Align = 0x03; break;
1600183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  }
1601183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1602183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang  return RegNo | (Align << 4);
1603183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang}
1604183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
1605183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang
16068e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and
16078e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// alignment operand for use in VLD-dup instructions.  This is the same as
16088e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// getAddrMode6AddressOpValue except for the alignment encoding, which is
16098e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson/// different for VLD4-dup.
16108e0c7b52877983b4838e54e233449912fc1a2325Bob Wilsonunsigned ARMMCCodeEmitter::
16118e0c7b52877983b4838e54e233449912fc1a2325Bob WilsongetAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
161236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              SmallVectorImpl<MCFixup> &Fixups,
161336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                              const MCSubtargetInfo &STI) const {
16148e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  const MCOperand &Reg = MI.getOperand(Op);
16158e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  const MCOperand &Imm = MI.getOperand(Op + 1);
16168e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
161799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg.getReg());
16188e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  unsigned Align = 0;
16198e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
16208e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  switch (Imm.getImm()) {
16218e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  default: break;
16228e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 2:
16238e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 4:
16248e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 8:  Align = 0x01; break;
16258e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  case 16: Align = 0x03; break;
16268e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  }
16278e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
16288e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson  return RegNo | (Align << 4);
16298e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson}
16308e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson
1631806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbachunsigned ARMMCCodeEmitter::
1632806e80ef42bdb416f409142a1ff1d4e8752baac8Jim GrosbachgetAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
163336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          SmallVectorImpl<MCFixup> &Fixups,
163436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          const MCSubtargetInfo &STI) const {
16350800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  const MCOperand &MO = MI.getOperand(Op);
16360800ce71896ccd7f49b37861a8cfbc21b6b10022Bill Wendling  if (MO.getReg() == 0) return 0x0D;
163799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  return CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
1638a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1639a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1640a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
16413116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight8Imm(const MCInst &MI, unsigned Op,
164236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  SmallVectorImpl<MCFixup> &Fixups,
164336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  const MCSubtargetInfo &STI) const {
1644a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 8 - MI.getOperand(Op).getImm();
1645a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1646a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1647a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
16483116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight16Imm(const MCInst &MI, unsigned Op,
164936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   SmallVectorImpl<MCFixup> &Fixups,
165036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   const MCSubtargetInfo &STI) const {
1651a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 16 - MI.getOperand(Op).getImm();
1652a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling}
1653a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
1654a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendlingunsigned ARMMCCodeEmitter::
16553116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight32Imm(const MCInst &MI, unsigned Op,
165636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   SmallVectorImpl<MCFixup> &Fixups,
165736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   const MCSubtargetInfo &STI) const {
1658a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling  return 32 - MI.getOperand(Op).getImm();
16593116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling}
16603116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling
16613116dce33840a115130c5f8ffcb9679d023496d6Bill Wendlingunsigned ARMMCCodeEmitter::
16623116dce33840a115130c5f8ffcb9679d023496d6Bill WendlinggetShiftRight64Imm(const MCInst &MI, unsigned Op,
166336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   SmallVectorImpl<MCFixup> &Fixups,
166436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   const MCSubtargetInfo &STI) const {
16653116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling  return 64 - MI.getOperand(Op).getImm();
1666cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson}
1667cf667be17b479fe276fd606b8fd72ccfa3065bb8Owen Anderson
1668568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbachvoid ARMMCCodeEmitter::
1669568eeedea72c274abbba1310c18a31eef78e14a4Jim GrosbachEncodeInstruction(const MCInst &MI, raw_ostream &OS,
167036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  SmallVectorImpl<MCFixup> &Fixups,
167136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  const MCSubtargetInfo &STI) const {
1672d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach  // Pseudo instructions don't get encoded.
167359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
1674e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  uint64_t TSFlags = Desc.TSFlags;
1675e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)
1676d6d4b42ba473657b6d30242962f0d0fb23fe126eJim Grosbach    return;
167716884415db751c75f2133bd04921393c792b1158Owen Anderson
1678e50e6bcd901ebb1cfc42fe9ca0796ae303d7f1a1Jim Grosbach  int Size;
167916884415db751c75f2133bd04921393c792b1158Owen Anderson  if (Desc.getSize() == 2 || Desc.getSize() == 4)
168016884415db751c75f2133bd04921393c792b1158Owen Anderson    Size = Desc.getSize();
168116884415db751c75f2133bd04921393c792b1158Owen Anderson  else
168216884415db751c75f2133bd04921393c792b1158Owen Anderson    llvm_unreachable("Unexpected instruction size!");
168310096dbdef22a10a6a4444437c935ab428545525Owen Anderson
168436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
16857597212abced110723f2fee985a7d60557c092ecEvan Cheng  // Thumb 32-bit wide instructions need to emit the high order halfword
16867597212abced110723f2fee985a7d60557c092ecEvan Cheng  // first.
168736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isThumb(STI) && Size == 4) {
1688d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary >> 16, 2, OS);
1689d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary & 0xffff, 2, OS);
1690d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach  } else
1691d91f4e40e6312304c60c83c3dd93f769a39a9772Jim Grosbach    EmitConstant(Binary, Size, OS);
16927292e0a6564bb24707eff1c49da9044dd5eaec78Bill Wendling  ++MCNumEmitted;  // Keep track of the # of mi's emitted.
1693568eeedea72c274abbba1310c18a31eef78e14a4Jim Grosbach}
16949af82ba42b53905f580f8c4270626946e3548654Jim Grosbach
1695806e80ef42bdb416f409142a1ff1d4e8752baac8Jim Grosbach#include "ARMGenMCCodeEmitter.inc"
1696