1f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===-- ARM/ARMCodeEmitter.cpp - Convert ARM code to machine code ---------===//
2f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
3f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//                     The LLVM Compiler Infrastructure
4f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
5081ce940e7351e90fff829320b7dc6738a6b3815Chris Lattner// This file is distributed under the University of Illinois Open Source
6081ce940e7351e90fff829320b7dc6738a6b3815Chris Lattner// License. See LICENSE.TXT for details.
7f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
8f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===----------------------------------------------------------------------===//
9f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
10f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// This file contains the pass that transforms the ARM machine instructions into
11f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman// relocatable machine code.
12f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//
13f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman//===----------------------------------------------------------------------===//
14f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
15f07a9b69d1c91187d73667b46aa423d4325ccf04Evan Cheng#define DEBUG_TYPE "jit"
16efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng#include "ARM.h"
17acf2077ca497980a066e8e7bb81ceec0de82d5daCraig Topper#include "ARMBaseInstrInfo.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "ARMConstantPoolValue.h"
19efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng#include "ARMRelocations.h"
20f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "ARMSubtarget.h"
21f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "ARMTargetMachine.h"
22ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h"
241ea31ff434f7966f3d8b2c158b4f20950e94e80dBruno Cardoso Lopes#include "llvm/CodeGen/JITCodeEmitter.h"
25e4c813ccdf946b232816949926386aa6bbcdfa0eEvan Cheng#include "llvm/CodeGen/MachineConstantPool.h"
26f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "llvm/CodeGen/MachineFunctionPass.h"
27f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "llvm/CodeGen/MachineInstr.h"
280f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
2998cb5536ab1aa5667bb5b602bf691631f3bbaffcDaniel Dunbar#include "llvm/CodeGen/MachineModuleInfo.h"
30f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman#include "llvm/CodeGen/Passes.h"
310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h"
320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
34d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/PassManager.h"
35efb9181429f459e5e04f1d79533bcdc3dbac2582Evan Cheng#include "llvm/Support/Debug.h"
363cb884811f68c27210391441d631146faa74f55eEdwin Török#include "llvm/Support/ErrorHandling.h"
373cb884811f68c27210391441d631146faa74f55eEdwin Török#include "llvm/Support/raw_ostream.h"
380f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng#ifndef NDEBUG
390f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng#include <iomanip>
400f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng#endif
41f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohmanusing namespace llvm;
42f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
43f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan GohmanSTATISTIC(NumEmitted, "Number of machine instructions emitted");
44f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
45f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohmannamespace {
461ea31ff434f7966f3d8b2c158b4f20950e94e80dBruno Cardoso Lopes
4711d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattner  class ARMCodeEmitter : public MachineFunctionPass {
48e4c813ccdf946b232816949926386aa6bbcdfa0eEvan Cheng    ARMJITInfo                *JTI;
49acf2077ca497980a066e8e7bb81ceec0de82d5daCraig Topper    const ARMBaseInstrInfo    *II;
503574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow    const DataLayout          *TD;
5150e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng    const ARMSubtarget        *Subtarget;
52e4c813ccdf946b232816949926386aa6bbcdfa0eEvan Cheng    TargetMachine             &TM;
5311d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattner    JITCodeEmitter            &MCE;
54e3330170d608053806e37c4dc953f15cf47b3388Chris Lattner    MachineModuleInfo *MMI;
55b562f8b205bad45d278863af6644e87c054e6bc0Evan Cheng    const std::vector<MachineConstantPoolEntry> *MCPEs;
560f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    const std::vector<MachineJumpTableEntry> *MJTEs;
570f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    bool IsPIC;
58b9103199ac28a1462150439f024e615b36bef093Bob Wilson    bool IsThumb;
59164fe923dac9b977ab0e3d923978cf0ba875d959Bob Wilson
6098cb5536ab1aa5667bb5b602bf691631f3bbaffcDaniel Dunbar    void getAnalysisUsage(AnalysisUsage &AU) const {
6198cb5536ab1aa5667bb5b602bf691631f3bbaffcDaniel Dunbar      AU.addRequired<MachineModuleInfo>();
6298cb5536ab1aa5667bb5b602bf691631f3bbaffcDaniel Dunbar      MachineFunctionPass::getAnalysisUsage(AU);
6398cb5536ab1aa5667bb5b602bf691631f3bbaffcDaniel Dunbar    }
64164fe923dac9b977ab0e3d923978cf0ba875d959Bob Wilson
65f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    static char ID;
6611d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattner  public:
6711d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattner    ARMCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
687569322765651f19eea0609fb082e6b267d5d2b5Owen Anderson      : MachineFunctionPass(ID), JTI(0),
69acf2077ca497980a066e8e7bb81ceec0de82d5daCraig Topper        II((const ARMBaseInstrInfo *)tm.getInstrInfo()),
703574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow        TD(tm.getDataLayout()), TM(tm),
71b9103199ac28a1462150439f024e615b36bef093Bob Wilson        MCE(mce), MCPEs(0), MJTEs(0),
72b9103199ac28a1462150439f024e615b36bef093Bob Wilson        IsPIC(TM.getRelocationModel() == Reloc::PIC_), IsThumb(false) {}
73164fe923dac9b977ab0e3d923978cf0ba875d959Bob Wilson
7411d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattner    /// getBinaryCodeForInstr - This function, generated by the
7511d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattner    /// CodeEmitterGenerator using TableGen, produces the binary encoding for
7611d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattner    /// machine instructions.
774f8dc7b17accf4f2ec953b80b2cc79786207492eOwen Anderson    uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const;
78f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
79f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    bool runOnMachineFunction(MachineFunction &MF);
80f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
81f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    virtual const char *getPassName() const {
82f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman      return "ARM Machine Code Emitter";
83f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    }
84f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
85f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    void emitInstruction(const MachineInstr &MI);
86efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
87efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  private:
88e4c813ccdf946b232816949926386aa6bbcdfa0eEvan Cheng
89c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    void emitWordLE(unsigned Binary);
909e280e07770715ab3814954a5ad7d88bc0a3f9d8Evan Cheng    void emitDWordLE(uint64_t Binary);
91e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    void emitConstantToMemory(unsigned CPI, const Constant *CV);
92e4c813ccdf946b232816949926386aa6bbcdfa0eEvan Cheng    void emitConstPoolInstruction(const MachineInstr &MI);
935d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang    void emitMOVi32immInstruction(const MachineInstr &MI);
947cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng    void emitMOVi2piecesInstruction(const MachineInstr &MI);
95e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    void emitLEApcrelInstruction(const MachineInstr &MI);
960f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    void emitLEApcrelJTInstruction(const MachineInstr &MI);
977f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    void emitPseudoMoveInstruction(const MachineInstr &MI);
98c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    void addPCLabel(unsigned LabelID);
99e4c813ccdf946b232816949926386aa6bbcdfa0eEvan Cheng    void emitPseudoInstruction(const MachineInstr &MI);
10000dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    unsigned getMachineSoRegOpValue(const MachineInstr &MI,
101e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                                    const MCInstrDesc &MCID,
102d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng                                    const MachineOperand &MO,
10300dc31b291ddde446299bf4b50011fb56758f211Evan Cheng                                    unsigned OpIdx);
10400dc31b291ddde446299bf4b50011fb56758f211Evan Cheng
1057cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng    unsigned getMachineSoImmOpValue(unsigned SoImm);
1061feed0434ec93100876edf72897700148b74d054Jim Grosbach    unsigned getAddrModeSBit(const MachineInstr &MI,
107e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                             const MCInstrDesc &MCID) const;
108378c3a98dc3cc70f8562e5221d41ef23c38d87f2Evan Cheng
109c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    void emitDataProcessingInstruction(const MachineInstr &MI,
110260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng                                       unsigned ImplicitRd = 0,
111c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng                                       unsigned ImplicitRn = 0);
11286a926a425286e882a7f3902a525527f17bb127fEvan Cheng
113c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    void emitLoadStoreInstruction(const MachineInstr &MI,
1140f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng                                  unsigned ImplicitRd = 0,
115c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng                                  unsigned ImplicitRn = 0);
11686a926a425286e882a7f3902a525527f17bb127fEvan Cheng
117c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    void emitMiscLoadStoreInstruction(const MachineInstr &MI,
118c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng                                      unsigned ImplicitRn = 0);
11986a926a425286e882a7f3902a525527f17bb127fEvan Cheng
12086a926a425286e882a7f3902a525527f17bb127fEvan Cheng    void emitLoadStoreMultipleInstruction(const MachineInstr &MI);
12186a926a425286e882a7f3902a525527f17bb127fEvan Cheng
122ee80fb79279be7c84e6f8a3f06403200386a6ef5Evan Cheng    void emitMulFrmInstruction(const MachineInstr &MI);
12386a926a425286e882a7f3902a525527f17bb127fEvan Cheng
12437afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    void emitExtendInstruction(const MachineInstr &MI);
12537afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
126c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng    void emitMiscArithInstruction(const MachineInstr &MI);
127c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng
128118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson    void emitSaturateInstruction(const MachineInstr &MI);
129118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson
13086a926a425286e882a7f3902a525527f17bb127fEvan Cheng    void emitBranchInstruction(const MachineInstr &MI);
13186a926a425286e882a7f3902a525527f17bb127fEvan Cheng
132260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    void emitInlineJumpTable(unsigned JTIndex);
1330f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
13486a926a425286e882a7f3902a525527f17bb127fEvan Cheng    void emitMiscBranchInstruction(const MachineInstr &MI);
135efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
136c63e15ebf517f96d2ac3a6b969791bf3f9130964Evan Cheng    void emitVFPArithInstruction(const MachineInstr &MI);
137c63e15ebf517f96d2ac3a6b969791bf3f9130964Evan Cheng
1389d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng    void emitVFPConversionInstruction(const MachineInstr &MI);
1399d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng
140bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    void emitVFPLoadStoreInstruction(const MachineInstr &MI);
141bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
142bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    void emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI);
143bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
144facbbb139d11a2c238a98a19574ff14b9069ec29jush    void emitMiscInstruction(const MachineInstr &MI);
145facbbb139d11a2c238a98a19574ff14b9069ec29jush
146bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson    void emitNEONLaneInstruction(const MachineInstr &MI);
147ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson    void emitNEONDupInstruction(const MachineInstr &MI);
148f1672483d8ff3d19e647cc959edefc853902012dBob Wilson    void emitNEON1RegModImmInstruction(const MachineInstr &MI);
149f1672483d8ff3d19e647cc959edefc853902012dBob Wilson    void emitNEON2RegInstruction(const MachineInstr &MI);
150383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson    void emitNEON3RegInstruction(const MachineInstr &MI);
15173e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson
152efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng    /// getMachineOpValue - Return binary encoding of operand. If the machine
153efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng    /// operand requires relocation, record the relocation and return zero.
1546a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach    unsigned getMachineOpValue(const MachineInstr &MI,
1556a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach                               const MachineOperand &MO) const;
1566a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach    unsigned getMachineOpValue(const MachineInstr &MI, unsigned OpIdx) const {
157efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng      return getMachineOpValue(MI, MI.getOperand(OpIdx));
158efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng    }
159efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
1602b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach    // FIXME: The legacy JIT ARMCodeEmitter doesn't rely on the the
1612b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach    //  TableGen'erated getBinaryCodeForInstr() function to encode any
1622b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach    //  operand values, instead querying getMachineOpValue() directly for
1632b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach    //  each operand it needs to encode. Thus, any of the new encoder
1642b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach    //  helper functions can simply return 0 as the values the return
1652b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach    //  are already handled elsewhere. They are placeholders to allow this
1662b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach    //  encoder to continue to function until the MC encoder is sufficiently
1672b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach    //  far along that this one can be eliminated entirely.
168aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao    unsigned NEONThumb2DataIPostEncoder(const MachineInstr &MI, unsigned Val)
16979ecaa7de5ede4475ffdd30c48093c885397ffe9Owen Anderson      const { return 0; }
170aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao    unsigned NEONThumb2LoadStorePostEncoder(const MachineInstr &MI,unsigned Val)
17142d0aa8e8035a3899bb8a652f6f7786791c86565Owen Anderson      const { return 0; }
172aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao    unsigned NEONThumb2DupPostEncoder(const MachineInstr &MI,unsigned Val)
173b2adc06c2e963ca9af94c1b0c154c599496b7a0eOwen Anderson      const { return 0; }
174cf590263cd5c24ccf1d08cef612738d99cd980d9Bill Wendling    unsigned VFPThumb2PostEncoder(const MachineInstr&MI, unsigned Val)
175f55066572ff8040747ff03a7fa71d88b85f41812Shih-wei Liao      const {
176d5f8f75e62b9564890df9599eb916ea4bf68c307Jush Lu      if (IsThumb) {
177d5f8f75e62b9564890df9599eb916ea4bf68c307Jush Lu        Val &= 0x0FFFFFFF;
178d5f8f75e62b9564890df9599eb916ea4bf68c307Jush Lu        Val |= 0xE0000000;
179d5f8f75e62b9564890df9599eb916ea4bf68c307Jush Lu      }
180d5f8f75e62b9564890df9599eb916ea4bf68c307Jush Lu      return Val;
181d5f8f75e62b9564890df9599eb916ea4bf68c307Jush Lu    }
1825d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach    unsigned getAdrLabelOpValue(const MachineInstr &MI, unsigned Op)
1835d14f9be7ba64162c7b996f36d419b11d8cdbe9aJim Grosbach      const { return 0; }
184d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach    unsigned getThumbAdrLabelOpValue(const MachineInstr &MI, unsigned Op)
185d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach      const { return 0; }
186662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach    unsigned getThumbBLTargetOpValue(const MachineInstr &MI, unsigned Op)
187662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach      const { return 0; }
18809aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling    unsigned getThumbBLXTargetOpValue(const MachineInstr &MI, unsigned Op)
18909aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling      const { return 0; }
190e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach    unsigned getThumbBRTargetOpValue(const MachineInstr &MI, unsigned Op)
191e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach      const { return 0; }
19201086451393ef33e82b6fad623989dd97dd70edfJim Grosbach    unsigned getThumbBCCTargetOpValue(const MachineInstr &MI, unsigned Op)
19301086451393ef33e82b6fad623989dd97dd70edfJim Grosbach      const { return 0; }
194027d6e8d1ca04e4096fb3a27579b861d861466c5Jim Grosbach    unsigned getThumbCBTargetOpValue(const MachineInstr &MI, unsigned Op)
195dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling      const { return 0; }
19643bcc3ab69a55bf0cf8c11f4b702092676ecca17Jim Grosbach    unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned Op)
19743bcc3ab69a55bf0cf8c11f4b702092676ecca17Jim Grosbach      const { return 0; }
198c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson    unsigned getUnconditionalBranchTargetOpValue(const MachineInstr &MI,
199c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson      unsigned Op) const { return 0; }
200685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim    unsigned getARMBranchTargetOpValue(const MachineInstr &MI, unsigned Op)
201685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim      const { return 0; }
2027b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach    unsigned getARMBLTargetOpValue(const MachineInstr &MI, unsigned Op)
2037b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach      const { return 0; }
204f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson    unsigned getARMBLXTargetOpValue(const MachineInstr &MI, unsigned Op)
205f1eab597b2316c6cfcabfcee98895fedb2071722Owen Anderson      const { return 0; }
2062b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach    unsigned getCCOutOpValue(const MachineInstr &MI, unsigned Op)
2072b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach      const { return 0; }
20824ad3be2dbdf34a342afe90a17a4ec846a2c16deJim Grosbach    unsigned getSOImmOpValue(const MachineInstr &MI, unsigned Op)
20924ad3be2dbdf34a342afe90a17a4ec846a2c16deJim Grosbach      const { return 0; }
2100d5d833eaee85389cee84daae39691c75faf728eOwen Anderson    unsigned getT2SOImmOpValue(const MachineInstr &MI, unsigned Op)
2110d5d833eaee85389cee84daae39691c75faf728eOwen Anderson      const { return 0; }
212152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    unsigned getSORegRegOpValue(const MachineInstr &MI, unsigned Op)
213152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson      const { return 0; }
214152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    unsigned getSORegImmOpValue(const MachineInstr &MI, unsigned Op)
215e631d79977c636c471178ae9a5f90a96df645dacJim Grosbach      const { return 0; }
216f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    unsigned getThumbAddrModeRegRegOpValue(const MachineInstr &MI, unsigned Op)
2170f4b60d43a289671082deee3bd56a3a055afb16aOwen Anderson      const { return 0; }
21875579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson    unsigned getT2AddrModeImm12OpValue(const MachineInstr &MI, unsigned Op)
21975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson      const { return 0; }
22075579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson    unsigned getT2AddrModeImm8OpValue(const MachineInstr &MI, unsigned Op)
2216af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson      const { return 0; }
222a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    unsigned getT2Imm8s4OpValue(const MachineInstr &MI, unsigned Op)
223a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      const { return 0; }
2249d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson    unsigned getT2AddrModeImm8s4OpValue(const MachineInstr &MI, unsigned Op)
2259d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson      const { return 0; }
226b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    unsigned getT2AddrModeImm0_1020s4OpValue(const MachineInstr &MI,unsigned Op)
227b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      const { return 0; }
2286af50f7dd12d82f0a80f3158102180eee4c921aaOwen Anderson    unsigned getT2AddrModeImm8OffsetOpValue(const MachineInstr &MI, unsigned Op)
22975579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson      const { return 0; }
2300e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson    unsigned getT2AddrModeImm12OffsetOpValue(const MachineInstr &MI,unsigned Op)
2310e1bcdf4f7547bb5f47ed5ff5f2409a8f72f3609Owen Anderson      const { return 0; }
23275579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson    unsigned getT2AddrModeSORegOpValue(const MachineInstr &MI, unsigned Op)
23375579f739fbc99a92a15f3ce75bbd7628ba00f8cOwen Anderson      const { return 0; }
2340d5d833eaee85389cee84daae39691c75faf728eOwen Anderson    unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op)
2350d5d833eaee85389cee84daae39691c75faf728eOwen Anderson      const { return 0; }
236a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson    unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op)
237a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson      const { return 0; }
238b203fb2303fc4f88a4d2fc34d12fcb6fe6f4ddbfOwen Anderson    unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op)
23992ccf4e164683b68c5dfb8b66fb619a6c571ac86Owen Anderson      const { return 0; }
240183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang    unsigned getAddrMode6OneLane32AddressOpValue(const MachineInstr &MI,
241183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang                                                 unsigned Op)
242183c627d89be5d0e8f3255ab7f6d1204c2fabedfMon P Wang      const { return 0; }
2438e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson    unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op)
2448e0c7b52877983b4838e54e233449912fc1a2325Bob Wilson      const { return 0; }
245b203fb2303fc4f88a4d2fc34d12fcb6fe6f4ddbfOwen Anderson    unsigned getAddrMode6OffsetOpValue(const MachineInstr &MI, unsigned Op)
2461ecf448d79815235fc8d5ba8838a2ced577ebd96Owen Anderson      const { return 0; }
247d6eaaca5d353ffb9936b7ed95333e5b08f095a53Jim Grosbach    unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI,
248d6eaaca5d353ffb9936b7ed95333e5b08f095a53Jim Grosbach                                            unsigned Op) const { return 0; }
249895c1e2deea3e6118b159c26b3f86d40a37e8501Bruno Cardoso Lopes    unsigned getSsatBitPosValue(const MachineInstr &MI,
250895c1e2deea3e6118b159c26b3f86d40a37e8501Bruno Cardoso Lopes                                unsigned Op) const { return 0; }
25164a300e4ac281fe84470fb10e56c4f3f7edba1f1Jim Grosbach    uint32_t getLdStmModeOpValue(const MachineInstr &MI, unsigned OpIdx)
25264a300e4ac281fe84470fb10e56c4f3f7edba1f1Jim Grosbach      const {return 0; }
25368291b0f3a96a589794b405196d237834bee4bf9Jim Grosbach    uint32_t getLdStSORegOpValue(const MachineInstr &MI, unsigned OpIdx)
25468291b0f3a96a589794b405196d237834bee4bf9Jim Grosbach      const { return 0; }
2555a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling
2565a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling    unsigned getAddrModeImm12OpValue(const MachineInstr &MI, unsigned Op)
2575a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      const {
2585a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      // {17-13} = reg
2595a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      // {12}    = (U)nsigned (add == '1', sub == '0')
2605a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      // {11-0}  = imm12
261620a4c21e78c9e6616f911b42a2af8b08f5ffa47Bill Wendling      const MachineOperand &MO  = MI.getOperand(Op);
262620a4c21e78c9e6616f911b42a2af8b08f5ffa47Bill Wendling      const MachineOperand &MO1 = MI.getOperand(Op + 1);
263620a4c21e78c9e6616f911b42a2af8b08f5ffa47Bill Wendling      if (!MO.isReg()) {
264620a4c21e78c9e6616f911b42a2af8b08f5ffa47Bill Wendling        emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry);
265620a4c21e78c9e6616f911b42a2af8b08f5ffa47Bill Wendling        return 0;
26608db1849b78a233df0b965cb723b8e81e8457d68Jim Grosbach      }
267df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher      unsigned Reg = II->getRegisterInfo().getEncodingValue(MO.getReg());
2685a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      int32_t Imm12 = MO1.getImm();
269620a4c21e78c9e6616f911b42a2af8b08f5ffa47Bill Wendling      uint32_t Binary;
2705a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      Binary = Imm12 & 0xfff;
2715a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      if (Imm12 >= 0)
2725a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling        Binary |= (1 << 12);
2735a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      Binary |= (Reg << 13);
2745a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      return Binary;
2755a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling    }
276837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim
277f55066572ff8040747ff03a7fa71d88b85f41812Shih-wei Liao    unsigned getHiLo16ImmOpValue(const MachineInstr &MI, unsigned Op)
278260b29b71916d4176b0031bf794fd093344fffe6Jush Lu      const {
279f899bd4a462884aa91b9d0c93ab2dbc605dac116Nowar Gu      const MCInstrDesc &MCID = MI.getDesc();
280260b29b71916d4176b0031bf794fd093344fffe6Jush Lu      const MachineOperand &MO = MI.getOperand(Op);
281260b29b71916d4176b0031bf794fd093344fffe6Jush Lu
282f899bd4a462884aa91b9d0c93ab2dbc605dac116Nowar Gu      unsigned Reloc = (MCID.Opcode == ARM::MOVi16 ?
283260b29b71916d4176b0031bf794fd093344fffe6Jush Lu                       ARM::reloc_arm_movw : ARM::reloc_arm_movt);
284260b29b71916d4176b0031bf794fd093344fffe6Jush Lu
285260b29b71916d4176b0031bf794fd093344fffe6Jush Lu      if (!MO.isImm()) {
286260b29b71916d4176b0031bf794fd093344fffe6Jush Lu        emitGlobalAddress(MO.getGlobal(), Reloc, true, false);
287260b29b71916d4176b0031bf794fd093344fffe6Jush Lu        return 0;
288260b29b71916d4176b0031bf794fd093344fffe6Jush Lu      }
289260b29b71916d4176b0031bf794fd093344fffe6Jush Lu      unsigned Imm16 = static_cast<unsigned>(MO.getImm());
290f55066572ff8040747ff03a7fa71d88b85f41812Shih-wei Liao      return Imm16;
291837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim    }
292837caa9313e1f9480721f232f89f5c7b1b9c9d09Jason W Kim
2931e30624e0cd61521c7d2c784c85460f6cc0c45c6Jim Grosbach    uint32_t getAddrMode2OpValue(const MachineInstr &MI, unsigned OpIdx)
2941e30624e0cd61521c7d2c784c85460f6cc0c45c6Jim Grosbach      const { return 0;}
2951e30624e0cd61521c7d2c784c85460f6cc0c45c6Jim Grosbach    uint32_t getAddrMode2OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
2961e30624e0cd61521c7d2c784c85460f6cc0c45c6Jim Grosbach      const { return 0;}
2977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    uint32_t getPostIdxRegOpValue(const MachineInstr &MI, unsigned OpIdx)
2987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const { return 0;}
299219358c134c3539f4a7cc110355633f4004dda39Jim Grosbach    uint32_t getAddrMode3OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
300219358c134c3539f4a7cc110355633f4004dda39Jim Grosbach      const { return 0;}
301ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    uint32_t getAddrMode3OpValue(const MachineInstr &MI, unsigned Op)
302ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      const { return 0; }
303d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach    uint32_t getAddrModeThumbSPOpValue(const MachineInstr &MI, unsigned Op)
304d967cd096ae87accf2f1df86b2dfac969d9c9da2Jim Grosbach      const { return 0; }
305272df516d7a9b1f0f69174276abaa759816ee456Bill Wendling    uint32_t getAddrModeSOpValue(const MachineInstr &MI, unsigned Op)
3061fd374e9c1c074c1681336bef31e65f0170b0f7eBill Wendling      const { return 0; }
307f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    uint32_t getAddrModeISOpValue(const MachineInstr &MI, unsigned Op)
308f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      const { return 0; }
309b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling    uint32_t getAddrModePCOpValue(const MachineInstr &MI, unsigned Op)
310b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling      const { return 0; }
3115a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling    uint32_t getAddrMode5OpValue(const MachineInstr &MI, unsigned Op) const {
3125a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      // {12-9}  = reg
3135a7b47f6e8f8f9ed702ad23497fa0123c722271dBill Wendling      // {8}     = (U)nsigned (add == '1', sub == '0')
31428263e86e6e8b8f3e41ed67eab48a50d07772503jush      // {7-0}   = imm8
3151d4f9a57447faa0142a1d0301e5ce550cfe60c4fNowar Gu      uint32_t Binary = 0;
31628263e86e6e8b8f3e41ed67eab48a50d07772503jush      const MachineOperand &MO  = MI.getOperand(Op);
31792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling      const MachineOperand &MO1 = MI.getOperand(Op + 1);
31892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling      if (!MO.isReg()) {
31992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling        emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry);
32092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling        return 0;
32192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling      }
322df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher      unsigned Reg = II->getRegisterInfo().getEncodingValue(MO.getReg());
32320272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling      int32_t Imm12 = MO1.getImm();
32420272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling
32520272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling      // Special value for #-0
32620272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling      if (Imm12 == INT32_MIN)
32720272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling        Imm12 = 0;
32820272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling
32920272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling      // Immediate is always encoded as positive. The 'U' bit controls add vs
33020272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling      // sub.
33120272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling      bool isAdd = true;
33220272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling      if (Imm12 < 0) {
33320272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling        Imm12 = -Imm12;
33420272a7c5a0ecb02364fb03ccde5a0d4533cb3d7Bill Wendling        isAdd = false;
33528263e86e6e8b8f3e41ed67eab48a50d07772503jush      }
33628263e86e6e8b8f3e41ed67eab48a50d07772503jush
33728263e86e6e8b8f3e41ed67eab48a50d07772503jush      // If immediate offset is omitted, default to +0.
33828263e86e6e8b8f3e41ed67eab48a50d07772503jush      Binary |= 1 << 8;
339620a4c21e78c9e6616f911b42a2af8b08f5ffa47Bill Wendling      return Binary;
340620a4c21e78c9e6616f911b42a2af8b08f5ffa47Bill Wendling    }
3414ad47e374eb0ee8e3de2fd752fb06bbcd26243f6Jim Grosbach    unsigned getNEONVcvtImm32OpValue(const MachineInstr &MI, unsigned Op)
3424ad47e374eb0ee8e3de2fd752fb06bbcd26243f6Jim Grosbach      const { return 0; }
3432b80f415f24e44b5c8859b7ddf3939bdf657a64cJim Grosbach
3448e744e3ebcd112345c2abe72a28d308bf5e55d96Jim Grosbach    unsigned getRegisterListOpValue(const MachineInstr &MI, unsigned Op)
3458e744e3ebcd112345c2abe72a28d308bf5e55d96Jim Grosbach      const { return 0; }
3468e744e3ebcd112345c2abe72a28d308bf5e55d96Jim Grosbach
3473116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling    unsigned getShiftRight8Imm(const MachineInstr &MI, unsigned Op)
348a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling      const { return 0; }
3493116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling    unsigned getShiftRight16Imm(const MachineInstr &MI, unsigned Op)
350a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling      const { return 0; }
3513116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling    unsigned getShiftRight32Imm(const MachineInstr &MI, unsigned Op)
3523116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling      const { return 0; }
3533116dce33840a115130c5f8ffcb9679d023496d6Bill Wendling    unsigned getShiftRight64Imm(const MachineInstr &MI, unsigned Op)
354a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling      const { return 0; }
355a656b63ee4d5b0e3f4d26a55dd4cc69795746684Bill Wendling
356521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao    /// getMovi32Value - Return binary encoding of operand for movw/movt. If the
3578ff4917b26a45db09087b5c994b11bd5214789cdJim Grosbach    /// machine operand requires relocation, record the relocation and return
3588ff4917b26a45db09087b5c994b11bd5214789cdJim Grosbach    /// zero.
359521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao    unsigned getMovi32Value(const MachineInstr &MI,const MachineOperand &MO,
3605d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang                            unsigned Reloc);
3615d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
362c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
363efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng    ///
364c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    unsigned getShiftOp(unsigned Imm) const ;
365efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
366efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng    /// Routines that handle operands which add machine relocations which are
367260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    /// fixed up by the relocation stage.
36836c56d0353f1a9c4e878f509aff85a62e5087dd4Dan Gohman    void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
369e63aa1f6906831c4a1b8bf2f2bc1ee23a4e3c3c6Jeffrey Yasskin                           bool MayNeedFarStub,  bool Indirect,
3706a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach                           intptr_t ACPV = 0) const;
3716a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach    void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
3726a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach    void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
3736a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach    void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
374260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
3756a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach                               intptr_t JTBase = 0) const;
376df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned encodeVFPRd(const MachineInstr &MI, unsigned OpIdx) const;
377df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned encodeVFPRn(const MachineInstr &MI, unsigned OpIdx) const;
378df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned encodeVFPRm(const MachineInstr &MI, unsigned OpIdx) const;
379df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned encodeNEONRd(const MachineInstr &MI, unsigned OpIdx) const;
380df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned encodeNEONRn(const MachineInstr &MI, unsigned OpIdx) const;
381df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned encodeNEONRm(const MachineInstr &MI, unsigned OpIdx) const;
382f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  };
383f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman}
384f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
38511d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnerchar ARMCodeEmitter::ID = 0;
38611d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattner
387164fe923dac9b977ab0e3d923978cf0ba875d959Bob Wilson/// createARMJITCodeEmitterPass - Return a pass that emits the collected ARM
388a06694d3d85c7a604ef0068b687cd5f28a903173Chris Lattner/// code to the specified MCE object.
389aabb9a5359cbb0bf9d25bfb917ecb09c086d034bBruno Cardoso LopesFunctionPass *llvm::createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
390aabb9a5359cbb0bf9d25bfb917ecb09c086d034bBruno Cardoso Lopes                                                JITCodeEmitter &JCE) {
39111d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattner  return new ARMCodeEmitter(TM, JCE);
392f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman}
3931ea31ff434f7966f3d8b2c158b4f20950e94e80dBruno Cardoso Lopes
39411d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnerbool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
3954e23ebe7665f2e03c0bb8db3ae5ab90eb0f724e5Benjamin Kramer  TargetMachine &Target = const_cast<TargetMachine&>(MF.getTarget());
3964e23ebe7665f2e03c0bb8db3ae5ab90eb0f724e5Benjamin Kramer
3974e23ebe7665f2e03c0bb8db3ae5ab90eb0f724e5Benjamin Kramer  assert((Target.getRelocationModel() != Reloc::Default ||
3984e23ebe7665f2e03c0bb8db3ae5ab90eb0f724e5Benjamin Kramer          Target.getRelocationModel() != Reloc::Static) &&
399f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman         "JIT relocation model must be set to static or default!");
4004e23ebe7665f2e03c0bb8db3ae5ab90eb0f724e5Benjamin Kramer
4014e23ebe7665f2e03c0bb8db3ae5ab90eb0f724e5Benjamin Kramer  JTI = static_cast<ARMJITInfo*>(Target.getJITInfo());
4024e23ebe7665f2e03c0bb8db3ae5ab90eb0f724e5Benjamin Kramer  II = static_cast<const ARMBaseInstrInfo*>(Target.getInstrInfo());
4034e23ebe7665f2e03c0bb8db3ae5ab90eb0f724e5Benjamin Kramer  TD = Target.getDataLayout();
4044e23ebe7665f2e03c0bb8db3ae5ab90eb0f724e5Benjamin Kramer
40550e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng  Subtarget = &TM.getSubtarget<ARMSubtarget>();
406b562f8b205bad45d278863af6644e87c054e6bc0Evan Cheng  MCPEs = &MF.getConstantPool()->getConstants();
407b10c7e2e10bb899f1f48cd33195c68b31ecc2db0Chris Lattner  MJTEs = 0;
408b10c7e2e10bb899f1f48cd33195c68b31ecc2db0Chris Lattner  if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
4090f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  IsPIC = TM.getRelocationModel() == Reloc::PIC_;
410b9103199ac28a1462150439f024e615b36bef093Bob Wilson  IsThumb = MF.getInfo<ARMFunctionInfo>()->isThumbFunction();
411ba96b1a43da968e21c217ed05a65cfbe2a845f47Evan Cheng  JTI->Initialize(MF, IsPIC);
412e3330170d608053806e37c4dc953f15cf47b3388Chris Lattner  MMI = &getAnalysis<MachineModuleInfo>();
413e3330170d608053806e37c4dc953f15cf47b3388Chris Lattner  MCE.setModuleInfo(MMI);
414f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
415f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  do {
416770d718405114860f3874871848e345873bf7cb4Jim Grosbach    DEBUG(errs() << "JITTing function '"
41796601ca332ab388754ca4673be8973396fea2dddCraig Topper          << MF.getName() << "'\n");
418f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    MCE.startFunction(MF);
419770d718405114860f3874871848e345873bf7cb4Jim Grosbach    for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
420f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman         MBB != E; ++MBB) {
421f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman      MCE.StartMachineBasicBlock(MBB);
4227c2a4a30e0e16762c75adacebd05ec9fcbccf16bEvan Cheng      for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
423f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman           I != E; ++I)
424f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman        emitInstruction(*I);
425f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman    }
426f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  } while (MCE.finishFunction(MF));
427f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
428f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman  return false;
429f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman}
430f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman
431c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
432efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng///
43311d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnerunsigned ARMCodeEmitter::getShiftOp(unsigned Imm) const {
434c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  switch (ARM_AM::getAM2ShiftOpc(Imm)) {
435bd448e3ca993226084d7f53445388fcd8e46b996Edwin Török  default: llvm_unreachable("Unknown shift opc!");
436efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  case ARM_AM::asr: return 2;
437efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  case ARM_AM::lsl: return 0;
438efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  case ARM_AM::lsr: return 1;
439a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng  case ARM_AM::ror:
440efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  case ARM_AM::rrx: return 3;
441a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng  }
442a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng}
443a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
444521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao/// getMovi32Value - Return binary encoding of operand for movw/movt. If the
4455d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang/// machine operand requires relocation, record the relocation and return zero.
4465d392dd93e023f9c14353ea84e2db717792db4bdZonr Changunsigned ARMCodeEmitter::getMovi32Value(const MachineInstr &MI,
447521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao                                        const MachineOperand &MO,
4485d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang                                        unsigned Reloc) {
449521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao  assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw))
4505d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang      && "Relocation to this function should be for movt or movw");
4515d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
4525d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  if (MO.isImm())
4535d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang    return static_cast<unsigned>(MO.getImm());
4545d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  else if (MO.isGlobal())
4555d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang    emitGlobalAddress(MO.getGlobal(), Reloc, true, false);
4565d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  else if (MO.isSymbol())
4575d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang    emitExternalSymbolAddress(MO.getSymbolName(), Reloc);
4585d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  else if (MO.isMBB())
4595d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang    emitMachineBasicBlock(MO.getMBB(), Reloc);
4605d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  else {
4615d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang#ifndef NDEBUG
4625d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang    errs() << MO;
4635d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang#endif
4645d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang    llvm_unreachable("Unsupported operand type for movw/movt");
4655d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  }
4665d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  return 0;
4675d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang}
4685d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
469efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng/// getMachineOpValue - Return binary encoding of operand. If the machine
470efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng/// operand requires relocation, record the relocation and return zero.
47111d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnerunsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
4726a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach                                           const MachineOperand &MO) const {
473b9f4fa7b400836808bc3beab96482418f418f246Dan Gohman  if (MO.isReg())
474df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    return II->getRegisterInfo().getEncodingValue(MO.getReg());
475b9f4fa7b400836808bc3beab96482418f418f246Dan Gohman  else if (MO.isImm())
476efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng    return static_cast<unsigned>(MO.getImm());
47730a4c49153cb859d72f6507ba361dd78bdfc2a01jush  else if (MO.isFPImm())
47830a4c49153cb859d72f6507ba361dd78bdfc2a01jush    return static_cast<unsigned>(MO.getFPImm()->getValueAPF()
47930a4c49153cb859d72f6507ba361dd78bdfc2a01jush                      .bitcastToAPInt().getHiBits(32).getLimitedValue());
480b9f4fa7b400836808bc3beab96482418f418f246Dan Gohman  else if (MO.isGlobal())
48150e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng    emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true, false);
482b9f4fa7b400836808bc3beab96482418f418f246Dan Gohman  else if (MO.isSymbol())
4835c454e984a39c417eae57989e54e5c44f2d85557Evan Cheng    emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_branch);
484668d0df68e2c40e4f4073535afcc5ec210d7d200Evan Cheng  else if (MO.isCPI()) {
485e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    const MCInstrDesc &MCID = MI.getDesc();
486668d0df68e2c40e4f4073535afcc5ec210d7d200Evan Cheng    // For VFP load, the immediate offset is multiplied by 4.
487e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    unsigned Reloc =  ((MCID.TSFlags & ARMII::FormMask) == ARMII::VFPLdStFrm)
488668d0df68e2c40e4f4073535afcc5ec210d7d200Evan Cheng      ? ARM::reloc_arm_vfp_cp_entry : ARM::reloc_arm_cp_entry;
489668d0df68e2c40e4f4073535afcc5ec210d7d200Evan Cheng    emitConstPoolAddress(MO.getIndex(), Reloc);
490668d0df68e2c40e4f4073535afcc5ec210d7d200Evan Cheng  } else if (MO.isJTI())
4916017d48252df62d121344138c5ba9241f7bd73b8Chris Lattner    emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative);
492b9f4fa7b400836808bc3beab96482418f418f246Dan Gohman  else if (MO.isMBB())
4930f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    emitMachineBasicBlock(MO.getMBB(), ARM::reloc_arm_branch);
494817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach  else
495817c1a6dddadb4664738777d224bc7eae6e62cf3Jim Grosbach    llvm_unreachable("Unable to encode MachineOperand!");
496efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  return 0;
497a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng}
498a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
499e4c813ccdf946b232816949926386aa6bbcdfa0eEvan Cheng/// emitGlobalAddress - Emit the specified address to the code stream.
500a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng///
50136c56d0353f1a9c4e878f509aff85a62e5087dd4Dan Gohmanvoid ARMCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
50211d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattner                                       bool MayNeedFarStub, bool Indirect,
5036a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach                                       intptr_t ACPV) const {
50450e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng  MachineRelocation MR = Indirect
50550e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng    ? MachineRelocation::getIndirectSymbol(MCE.getCurrentPCOffset(), Reloc,
50636c56d0353f1a9c4e878f509aff85a62e5087dd4Dan Gohman                                           const_cast<GlobalValue *>(GV),
50736c56d0353f1a9c4e878f509aff85a62e5087dd4Dan Gohman                                           ACPV, MayNeedFarStub)
50850e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng    : MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
50936c56d0353f1a9c4e878f509aff85a62e5087dd4Dan Gohman                               const_cast<GlobalValue *>(GV), ACPV,
51036c56d0353f1a9c4e878f509aff85a62e5087dd4Dan Gohman                               MayNeedFarStub);
51150e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng  MCE.addRelocation(MR);
512a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng}
513a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
514a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng/// emitExternalSymbolAddress - Arrange for the address of an external symbol to
515a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng/// be emitted to the current location in the function, and allow it to be PC
516a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng/// relative.
5176a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbachvoid ARMCodeEmitter::
5186a153f291b60c7afbc8ce9f96c5468476474addfJim GrosbachemitExternalSymbolAddress(const char *ES, unsigned Reloc) const {
519a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng  MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
520a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng                                                 Reloc, ES));
521a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng}
522a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
523a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng/// emitConstPoolAddress - Arrange for the address of an constant pool
524a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng/// to be emitted to the current location in the function, and allow it to be PC
525a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng/// relative.
5266a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbachvoid ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const {
527f07a9b69d1c91187d73667b46aa423d4325ccf04Evan Cheng  // Tell JIT emitter we'll resolve the address.
528a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng  MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
529260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng                                                    Reloc, CPI, 0, true));
530a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng}
531a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
532a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng/// emitJumpTableAddress - Arrange for the address of a jump table to
533a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng/// be emitted to the current location in the function, and allow it to be PC
534a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng/// relative.
5356a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbachvoid ARMCodeEmitter::
5366a153f291b60c7afbc8ce9f96c5468476474addfJim GrosbachemitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const {
537a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng  MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
538260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng                                                    Reloc, JTIndex, 0, true));
539a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng}
540a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
541d8dc8c5ffcd9d787ccdd8b48c1ebcee8870bfc01Raul Herbster/// emitMachineBasicBlock - Emit the specified address basic block.
54211d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
5436a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach                                           unsigned Reloc,
5446a153f291b60c7afbc8ce9f96c5468476474addfJim Grosbach                                           intptr_t JTBase) const {
545d8dc8c5ffcd9d787ccdd8b48c1ebcee8870bfc01Raul Herbster  MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
546260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng                                             Reloc, BB, JTBase));
547d8dc8c5ffcd9d787ccdd8b48c1ebcee8870bfc01Raul Herbster}
548a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
54911d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitWordLE(unsigned Binary) {
5502c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << "  0x";
5512c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner        errs().write_hex(Binary) << "\n");
552c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  MCE.emitWordLE(Binary);
553c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng}
554c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng
55511d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitDWordLE(uint64_t Binary) {
5562c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << "  0x";
5572c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner        errs().write_hex(Binary) << "\n");
5589e280e07770715ab3814954a5ad7d88bc0a3f9d8Evan Cheng  MCE.emitDWordLE(Binary);
5599e280e07770715ab3814954a5ad7d88bc0a3f9d8Evan Cheng}
5609e280e07770715ab3814954a5ad7d88bc0a3f9d8Evan Cheng
56111d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
562d71b0b0bc402d151d7ea364cad32ad44ac7fbee2Chris Lattner  DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);
563efb9181429f459e5e04f1d79533bcdc3dbac2582Evan Cheng
5645450fc15cb5de674d4e5203ab9ace59d3d6c38e5Devang Patel  MCE.processDebugLoc(MI.getDebugLoc(), true);
5656628b5ba0e383904260935a46fe39d61d3e3bd52Jeffrey Yasskin
566559d513348a11936bc90b64aad75e2540b26c6a4Dan Gohman  ++NumEmitted;  // Keep track of the # of mi's emitted
56786a926a425286e882a7f3902a525527f17bb127fEvan Cheng  switch (MI.getDesc().TSFlags & ARMII::FormMask) {
5689d2c9231ced48ab86dd4707431be7405deeff3bcEvan Cheng  default: {
569bd448e3ca993226084d7f53445388fcd8e46b996Edwin Török    llvm_unreachable("Unhandled instruction encoding format!");
5709d2c9231ced48ab86dd4707431be7405deeff3bcEvan Cheng  }
57185eb54cf0cfb0f328669080c45cf8cc298aa2868Jim Grosbach  case ARMII::MiscFrm:
57285eb54cf0cfb0f328669080c45cf8cc298aa2868Jim Grosbach    if (MI.getOpcode() == ARM::LEApcrelJT) {
57385eb54cf0cfb0f328669080c45cf8cc298aa2868Jim Grosbach      // Materialize jumptable address.
57485eb54cf0cfb0f328669080c45cf8cc298aa2868Jim Grosbach      emitLEApcrelJTInstruction(MI);
57585eb54cf0cfb0f328669080c45cf8cc298aa2868Jim Grosbach      break;
57685eb54cf0cfb0f328669080c45cf8cc298aa2868Jim Grosbach    }
57785eb54cf0cfb0f328669080c45cf8cc298aa2868Jim Grosbach    llvm_unreachable("Unhandled instruction encoding!");
57886a926a425286e882a7f3902a525527f17bb127fEvan Cheng  case ARMII::Pseudo:
579e4c813ccdf946b232816949926386aa6bbcdfa0eEvan Cheng    emitPseudoInstruction(MI);
58086a926a425286e882a7f3902a525527f17bb127fEvan Cheng    break;
58186a926a425286e882a7f3902a525527f17bb127fEvan Cheng  case ARMII::DPFrm:
58286a926a425286e882a7f3902a525527f17bb127fEvan Cheng  case ARMII::DPSoRegFrm:
58386a926a425286e882a7f3902a525527f17bb127fEvan Cheng    emitDataProcessingInstruction(MI);
58486a926a425286e882a7f3902a525527f17bb127fEvan Cheng    break;
58581794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  case ARMII::LdFrm:
58681794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  case ARMII::StFrm:
58786a926a425286e882a7f3902a525527f17bb127fEvan Cheng    emitLoadStoreInstruction(MI);
58886a926a425286e882a7f3902a525527f17bb127fEvan Cheng    break;
58981794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  case ARMII::LdMiscFrm:
59081794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  case ARMII::StMiscFrm:
59186a926a425286e882a7f3902a525527f17bb127fEvan Cheng    emitMiscLoadStoreInstruction(MI);
59286a926a425286e882a7f3902a525527f17bb127fEvan Cheng    break;
59311838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  case ARMII::LdStMulFrm:
59486a926a425286e882a7f3902a525527f17bb127fEvan Cheng    emitLoadStoreMultipleInstruction(MI);
59586a926a425286e882a7f3902a525527f17bb127fEvan Cheng    break;
596ee80fb79279be7c84e6f8a3f06403200386a6ef5Evan Cheng  case ARMII::MulFrm:
597ee80fb79279be7c84e6f8a3f06403200386a6ef5Evan Cheng    emitMulFrmInstruction(MI);
59886a926a425286e882a7f3902a525527f17bb127fEvan Cheng    break;
59937afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  case ARMII::ExtFrm:
60037afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    emitExtendInstruction(MI);
60137afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    break;
602c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  case ARMII::ArithMiscFrm:
603c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng    emitMiscArithInstruction(MI);
604c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng    break;
605118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  case ARMII::SatFrm:
606118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson    emitSaturateInstruction(MI);
607118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson    break;
608f8e8b6224f80c48736ae4387901bd5f84c2781d5Evan Cheng  case ARMII::BrFrm:
60986a926a425286e882a7f3902a525527f17bb127fEvan Cheng    emitBranchInstruction(MI);
61086a926a425286e882a7f3902a525527f17bb127fEvan Cheng    break;
611f8e8b6224f80c48736ae4387901bd5f84c2781d5Evan Cheng  case ARMII::BrMiscFrm:
61286a926a425286e882a7f3902a525527f17bb127fEvan Cheng    emitMiscBranchInstruction(MI);
61386a926a425286e882a7f3902a525527f17bb127fEvan Cheng    break;
614c63e15ebf517f96d2ac3a6b969791bf3f9130964Evan Cheng  // VFP instructions.
615c63e15ebf517f96d2ac3a6b969791bf3f9130964Evan Cheng  case ARMII::VFPUnaryFrm:
616c63e15ebf517f96d2ac3a6b969791bf3f9130964Evan Cheng  case ARMII::VFPBinaryFrm:
617c63e15ebf517f96d2ac3a6b969791bf3f9130964Evan Cheng    emitVFPArithInstruction(MI);
618c63e15ebf517f96d2ac3a6b969791bf3f9130964Evan Cheng    break;
6199d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng  case ARMII::VFPConv1Frm:
6209d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng  case ARMII::VFPConv2Frm:
621828ccdc0ffc967ba75d96e1f3c55230047c5a13cEvan Cheng  case ARMII::VFPConv3Frm:
6227427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv4Frm:
6237427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv5Frm:
6249d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng    emitVFPConversionInstruction(MI);
6259d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng    break;
626bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  case ARMII::VFPLdStFrm:
627bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    emitVFPLoadStoreInstruction(MI);
628bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    break;
629bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  case ARMII::VFPLdStMulFrm:
630bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    emitVFPLoadStoreMultipleInstruction(MI);
631bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    break;
632facbbb139d11a2c238a98a19574ff14b9069ec29jush  case ARMII::VFPMiscFrm:
633facbbb139d11a2c238a98a19574ff14b9069ec29jush    emitMiscInstruction(MI);
634facbbb139d11a2c238a98a19574ff14b9069ec29jush    break;
63573e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  // NEON instructions.
6364c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  case ARMII::NGetLnFrm:
637bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson  case ARMII::NSetLnFrm:
638bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson    emitNEONLaneInstruction(MI);
6394c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson    break;
640ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson  case ARMII::NDupFrm:
641ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson    emitNEONDupInstruction(MI);
642ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson    break;
64373e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  case ARMII::N1RegModImmFrm:
644f1672483d8ff3d19e647cc959edefc853902012dBob Wilson    emitNEON1RegModImmInstruction(MI);
645f1672483d8ff3d19e647cc959edefc853902012dBob Wilson    break;
646f1672483d8ff3d19e647cc959edefc853902012dBob Wilson  case ARMII::N2RegFrm:
647f1672483d8ff3d19e647cc959edefc853902012dBob Wilson    emitNEON2RegInstruction(MI);
64873e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson    break;
649383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  case ARMII::N3RegFrm:
650383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson    emitNEON3RegInstruction(MI);
651383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson    break;
65286a926a425286e882a7f3902a525527f17bb127fEvan Cheng  }
6535450fc15cb5de674d4e5203ab9ace59d3d6c38e5Devang Patel  MCE.processDebugLoc(MI.getDebugLoc(), false);
654a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng}
655a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
656e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liaovoid ARMCodeEmitter::emitConstantToMemory(unsigned CPI, const Constant *C) {
657e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  DEBUG({
658e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao      errs() << "  ** Constant pool #" << CPI << " @ "
659e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao             << (void*)MCE.getCurrentPCValue() << " ";
660e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao      if (const Function *F = dyn_cast<Function>(C))
661e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao        errs() << F->getName();
662e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao      else
663e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao        errs() << *C;
664e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao      errs() << '\n';
665e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    });
666e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
667e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  switch (C->getValueID()) {
668e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  default: {
669e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    llvm_unreachable("Unable to handle this constantpool entry!");
670e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    break;
671e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  }
672e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  case Value::GlobalVariableVal: {
673e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    emitGlobalAddress(static_cast<const GlobalValue*>(C),
674e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao                      ARM::reloc_arm_absolute, isa<Function>(C), false);
675e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    emitWordLE(0);
676e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    break;
677e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  }
678e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  case Value::ConstantIntVal: {
679e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    const ConstantInt *CI = static_cast<const ConstantInt*>(C);
680e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
681e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    emitWordLE(Val);
682e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    break;
683e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  }
684e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  case Value::ConstantFPVal: {
685e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    const ConstantFP *CFP = static_cast<const ConstantFP*>(C);
686e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    if (CFP->getType()->isFloatTy())
687e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao      emitWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
688e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    else if (CFP->getType()->isDoubleTy())
689e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao      emitDWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
690e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    else {
691e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao      llvm_unreachable("Unable to handle this constantpool entry!");
692e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    }
693e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    break;
694e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  }
695e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  case Value::ConstantArrayVal: {
696e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    const ConstantArray *CA = static_cast<const ConstantArray*>(C);
697e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
698e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao      emitConstantToMemory(CPI, CA->getOperand(i));
699e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    break;
700e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  }
701e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  }
702e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
703e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  return;
704e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao}
705e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
70611d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
707260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng  unsigned CPI = MI.getOperand(0).getImm();       // CP instruction index.
708260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng  unsigned CPIndex = MI.getOperand(1).getIndex(); // Actual cp entry index.
709b562f8b205bad45d278863af6644e87c054e6bc0Evan Cheng  const MachineConstantPoolEntry &MCPE = (*MCPEs)[CPIndex];
710770d718405114860f3874871848e345873bf7cb4Jim Grosbach
711d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  // Remember the CONSTPOOL_ENTRY address for later relocation.
712d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  JTI->addConstantPoolEntryAddr(CPI, MCE.getCurrentPCValue());
713d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng
714d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  // Emit constpool island entry. In most cases, the actual values will be
715d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  // resolved and relocated after code emission.
716d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  if (MCPE.isMachineConstantPoolEntry()) {
717d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng    ARMConstantPoolValue *ACPV =
718d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng      static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
719d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng
720d71b0b0bc402d151d7ea364cad32ad44ac7fbee2Chris Lattner    DEBUG(errs() << "  ** ARM constant pool #" << CPI << " @ "
721d71b0b0bc402d151d7ea364cad32ad44ac7fbee2Chris Lattner          << (void*)MCE.getCurrentPCValue() << " " << *ACPV << '\n');
722d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng
72362acbf19235b3b20a24958b973538e35ec6f2d67Bob Wilson    assert(ACPV->isGlobalValue() && "unsupported constant pool value");
7245bb779976a7d8e48408051ec2289fe69206dc072Bill Wendling    const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
725d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng    if (GV) {
72650e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng      Reloc::Model RelocM = TM.getRelocationModel();
727c299914a58baed2d7cf594494dbba60880d476cdEvan Cheng      emitGlobalAddress(GV, ARM::reloc_arm_machine_cp_entry,
72850e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng                        isa<Function>(GV),
72950e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng                        Subtarget->GVIsIndirectSymbol(GV, RelocM),
73050e503fc4a90ecd8e98266c4a68c566e5f3e315fEvan Cheng                        (intptr_t)ACPV);
731fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling    } else  {
732fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling      const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
733fe31e673506ef9a1080eaa684b43b34178c6f447Bill Wendling      emitExternalSymbolAddress(Sym, ARM::reloc_arm_absolute);
734d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng    }
735c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    emitWordLE(0);
736d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  } else {
737e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    emitConstantToMemory(CPI, MCPE.Val.ConstVal);
738d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  }
739d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng}
740d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng
7415d392dd93e023f9c14353ea84e2db717792db4bdZonr Changvoid ARMCodeEmitter::emitMOVi32immInstruction(const MachineInstr &MI) {
7425d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  const MachineOperand &MO0 = MI.getOperand(0);
7435d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  const MachineOperand &MO1 = MI.getOperand(1);
7445d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
7455d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  // Emit the 'movw' instruction.
7465d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  unsigned Binary = 0x30 << 20;  // mov: Insts{27-20} = 0b00110000
7475d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
7485d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  unsigned Lo16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movw) & 0xFFFF;
7495d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
7505d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  // Set the conditional execution predicate.
7515d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
7525d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
7535d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  // Encode Rd.
7545d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
7555d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
7565d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  // Encode imm16 as imm4:imm12
7575d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  Binary |= Lo16 & 0xFFF; // Insts{11-0} = imm12
7585d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  Binary |= ((Lo16 >> 12) & 0xF) << 16; // Insts{19-16} = imm4
7595d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  emitWordLE(Binary);
7605d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
7615d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  unsigned Hi16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movt) >> 16;
7625d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  // Emit the 'movt' instruction.
7635d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  Binary = 0x34 << 20; // movt: Insts{27-20} = 0b00110100
7645d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
7655d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  // Set the conditional execution predicate.
7665d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
7675d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
7685d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  // Encode Rd.
7695d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
7705d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
7715d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  // Encode imm16 as imm4:imm1, same as movw above.
7725d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  Binary |= Hi16 & 0xFFF;
7735d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  Binary |= ((Hi16 >> 12) & 0xF) << 16;
7745d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  emitWordLE(Binary);
7755d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang}
7765d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
77711d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
7787cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  const MachineOperand &MO0 = MI.getOperand(0);
7797cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  const MachineOperand &MO1 = MI.getOperand(1);
7807bd90eea10c84a2dbc72f84dd702346ac472a465Bob Wilson  assert(MO1.isImm() && ARM_AM::isSOImmTwoPartVal(MO1.getImm()) &&
7817bd90eea10c84a2dbc72f84dd702346ac472a465Bob Wilson                                                  "Not a valid so_imm value!");
7827cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO1.getImm());
7837cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO1.getImm());
7847cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng
7857cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Emit the 'mov' instruction.
7867cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  unsigned Binary = 0xd << 21;  // mov: Insts{24-21} = 0b1101
7877cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng
7887cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Set the conditional execution predicate.
78937afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
7907cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng
7917cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Encode Rd.
7927cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
7937cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng
7947cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Encode so_imm.
7957cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Set bit I(25) to identify this is the immediate form of <shifter_op>
7967cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  Binary |= 1 << ARMII::I_BitShift;
7978be2a5bd2b7a7296f150053c0a8d8767a810b78cEvan Cheng  Binary |= getMachineSoImmOpValue(V1);
7987cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  emitWordLE(Binary);
7997cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng
8007cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Now the 'orr' instruction.
8017cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  Binary = 0xc << 21;  // orr: Insts{24-21} = 0b1100
8027cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng
8037cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Set the conditional execution predicate.
80437afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
8057cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng
8067cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Encode Rd.
8077cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;
8087cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng
8097cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Encode Rn.
8107cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRnShift;
8117cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng
8127cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Encode so_imm.
8137cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  // Set bit I(25) to identify this is the immediate form of <shifter_op>
8147cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  Binary |= 1 << ARMII::I_BitShift;
8158be2a5bd2b7a7296f150053c0a8d8767a810b78cEvan Cheng  Binary |= getMachineSoImmOpValue(V2);
8167cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng  emitWordLE(Binary);
8177cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng}
8187cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng
819e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liaovoid ARMCodeEmitter::emitLEApcrelInstruction(const MachineInstr &MI) {
820e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  // It's basically add r, pc, (LCPI - $+8)
821f899bd4a462884aa91b9d0c93ab2dbc605dac116Nowar Gu  const MCInstrDesc &MCID = MI.getDesc();
822e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
823e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  unsigned Binary = 0;
824e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
825e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  // Set the conditional execution predicate
826e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
827e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
828e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  // Encode S bit if MI modifies CPSR.
829f899bd4a462884aa91b9d0c93ab2dbc605dac116Nowar Gu  Binary |= getAddrModeSBit(MI, MCID);
830e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
831e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  // Encode Rd.
832e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
833e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
834e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  // Encode Rn which is PC.
83531675153bd2d7617db8cb6aeb58054934c7b9f73Stephen Hines  Binary |= II->getRegisterInfo().getEncodingValue(ARM::PC) << ARMII::RegRnShift;
836e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
837e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  // Encode the displacement which is a so_imm.
838e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  // Set bit I(25) to identify this is the immediate form of <shifter_op>
839e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  Binary |= 1 << ARMII::I_BitShift;
840e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  emitConstPoolAddress(MI.getOperand(1).getIndex(), ARM::reloc_arm_so_imm_cp_entry);
841e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
842e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  emitWordLE(Binary);
843e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao}
844e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao
84511d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitLEApcrelJTInstruction(const MachineInstr &MI) {
8460f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  // It's basically add r, pc, (LJTI - $+8)
847770d718405114860f3874871848e345873bf7cb4Jim Grosbach
848e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
8490f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
8500f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  // Emit the 'add' instruction.
8510129be281eea2c22a925873f2e1cd5cc978ae87cJim Grosbach  unsigned Binary = 0x4 << 21;  // add: Insts{24-21} = 0b0100
8520f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
8530f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  // Set the conditional execution predicate
8540f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
8550f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
8560f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  // Encode S bit if MI modifies CPSR.
857e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  Binary |= getAddrModeSBit(MI, MCID);
8580f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
8590f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  // Encode Rd.
8600f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
8610f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
8620f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  // Encode Rn which is PC.
863df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  Binary |= II->getRegisterInfo().getEncodingValue(ARM::PC) << ARMII::RegRnShift;
8640f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
8650f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  // Encode the displacement.
8660f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  Binary |= 1 << ARMII::I_BitShift;
8670f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  emitJumpTableAddress(MI.getOperand(1).getIndex(), ARM::reloc_arm_jt_base);
8680f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
8690f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  emitWordLE(Binary);
8700f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng}
8710f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
87211d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitPseudoMoveInstruction(const MachineInstr &MI) {
8737f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  unsigned Opcode = MI.getDesc().Opcode;
8747f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng
8757f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  // Part of binary is determined by TableGn.
8767f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
8777f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng
8787f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  // Set the conditional execution predicate
8797f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
8807f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng
8817f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  // Encode S bit if MI modifies CPSR.
8827f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  if (Opcode == ARM::MOVsrl_flag || Opcode == ARM::MOVsra_flag)
8837f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    Binary |= 1 << ARMII::S_BitShift;
8847f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng
8857f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  // Encode register def if there is one.
8867f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
8877f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng
8887f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  // Encode the shift operation.
8897f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  switch (Opcode) {
8907f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  default: break;
8917c165e244d6747a51f74568588240dc8eaef5542Jim Grosbach  case ARM::RRX:
8927f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    // rrx
8937f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    Binary |= 0x6 << 4;
8947f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    break;
8957f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  case ARM::MOVsrl_flag:
8967f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    // lsr #1
8977f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    Binary |= (0x2 << 4) | (1 << 7);
8987f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    break;
8997f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  case ARM::MOVsra_flag:
9007f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    // asr #1
9017f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    Binary |= (0x4 << 4) | (1 << 7);
9027f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    break;
9037f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  }
9047f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng
9057f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  // Encode register Rm.
9067f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  Binary |= getMachineOpValue(MI, 1);
9077f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng
9087f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  emitWordLE(Binary);
9097f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng}
9107f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng
91111d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::addPCLabel(unsigned LabelID) {
9122c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << "  ** LPC" << LabelID << " @ "
9132c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner        << (void*)MCE.getCurrentPCValue() << '\n');
914c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  JTI->addPCLabelAddr(LabelID, MCE.getCurrentPCValue());
915c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng}
916c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng
91711d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
918d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  unsigned Opcode = MI.getDesc().Opcode;
919d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  switch (Opcode) {
920d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  default:
92116c012d9a28fe4db3ee081192a587ad7f30d4cc2Evan Cheng    llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
9223a5b41d8f8aae9ca8c9ebf95f49de1c46224ec0aJush Lu  case ARM::B:
9233a5b41d8f8aae9ca8c9ebf95f49de1c46224ec0aJush Lu    emitBranchInstruction(MI);
9243a5b41d8f8aae9ca8c9ebf95f49de1c46224ec0aJush Lu    break;
925e6fd111ddf8f32b7d63405e83678887292c34223Jush Lu  case ARM::BR_JTr:
926e6fd111ddf8f32b7d63405e83678887292c34223Jush Lu  case ARM::BR_JTm:
927e6fd111ddf8f32b7d63405e83678887292c34223Jush Lu  case ARM::BR_JTadd:
928e6fd111ddf8f32b7d63405e83678887292c34223Jush Lu    emitMiscBranchInstruction(MI);
929e6fd111ddf8f32b7d63405e83678887292c34223Jush Lu    break;
930532c2f1d503a42c5e8e0c5c9a513c459fed73d25Jim Grosbach  case ARM::BX_CALL:
931f16936e5923156863906c915de657b134db4fb16Jakob Stoklund Olesen  case ARM::BMOVPCRX_CALL: {
932ab4095eeebd2d0ed2f1c3baccaae7674700d9995Xerxes Ranby    // First emit mov lr, pc
933ab4095eeebd2d0ed2f1c3baccaae7674700d9995Xerxes Ranby    unsigned Binary = 0x01a0e00f;
934ab4095eeebd2d0ed2f1c3baccaae7674700d9995Xerxes Ranby    Binary |= II->getPredicate(&MI) << ARMII::CondShift;
935ab4095eeebd2d0ed2f1c3baccaae7674700d9995Xerxes Ranby    emitWordLE(Binary);
936ab4095eeebd2d0ed2f1c3baccaae7674700d9995Xerxes Ranby
937ab4095eeebd2d0ed2f1c3baccaae7674700d9995Xerxes Ranby    // and then emit the branch.
938ab4095eeebd2d0ed2f1c3baccaae7674700d9995Xerxes Ranby    emitMiscBranchInstruction(MI);
939ab4095eeebd2d0ed2f1c3baccaae7674700d9995Xerxes Ranby    break;
940ab4095eeebd2d0ed2f1c3baccaae7674700d9995Xerxes Ranby  }
9414052b296030e3523b9a4a8d1e4a9af9091a8d7e8Chris Lattner  case TargetOpcode::INLINEASM: {
9420f6a5612ac72664b641b39ffd17ae3df07ef432aEvan Cheng    // We allow inline assembler nodes with empty bodies - they can
9430f6a5612ac72664b641b39ffd17ae3df07ef432aEvan Cheng    // implicitly define registers, which is ok for JIT.
9440f6a5612ac72664b641b39ffd17ae3df07ef432aEvan Cheng    if (MI.getOperand(0).getSymbolName()[0]) {
9458316f2d3810dd37bae0f847bc3efd495432b5893Chris Lattner      report_fatal_error("JIT does not support inline asm!");
9460f6a5612ac72664b641b39ffd17ae3df07ef432aEvan Cheng    }
9479d2c9231ced48ab86dd4707431be7405deeff3bcEvan Cheng    break;
9489d2c9231ced48ab86dd4707431be7405deeff3bcEvan Cheng  }
949a02effc0bdeef3db3c148485564cab5ab6a7294aBill Wendling  case TargetOpcode::PROLOG_LABEL:
9508574dddd63edcb47af66df3ea309ff03a6b04549Chris Lattner  case TargetOpcode::EH_LABEL:
9518574dddd63edcb47af66df3ea309ff03a6b04549Chris Lattner    MCE.emitLabel(MI.getOperand(0).getMCSymbol());
9528574dddd63edcb47af66df3ea309ff03a6b04549Chris Lattner    break;
9534052b296030e3523b9a4a8d1e4a9af9091a8d7e8Chris Lattner  case TargetOpcode::IMPLICIT_DEF:
9544052b296030e3523b9a4a8d1e4a9af9091a8d7e8Chris Lattner  case TargetOpcode::KILL:
9559d2c9231ced48ab86dd4707431be7405deeff3bcEvan Cheng    // Do nothing.
9569d2c9231ced48ab86dd4707431be7405deeff3bcEvan Cheng    break;
957d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  case ARM::CONSTPOOL_ENTRY:
958d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng    emitConstPoolInstruction(MI);
959d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng    break;
960eeb84081f389b99547082b9867830ad4c46cb39aJush Lu  case ARM::LDMIA_RET:
961eeb84081f389b99547082b9867830ad4c46cb39aJush Lu    emitLoadStoreMultipleInstruction(MI);
962eeb84081f389b99547082b9867830ad4c46cb39aJush Lu    break;
963d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  case ARM::PICADD: {
9645a033a6c9c08d06f316e42b111cc79756c672733Evan Cheng    // Remember of the address of the PC label for relocation later.
965c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    addPCLabel(MI.getOperand(2).getImm());
966d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng    // PICADD is just an add instruction that implicitly read pc.
967260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    emitDataProcessingInstruction(MI, 0, ARM::PC);
968c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    break;
969c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  }
970c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  case ARM::PICLDR:
971c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  case ARM::PICLDRB:
972c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  case ARM::PICSTR:
973c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  case ARM::PICSTRB: {
974c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    // Remember of the address of the PC label for relocation later.
975c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    addPCLabel(MI.getOperand(2).getImm());
976c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    // These are just load / store instructions that implicitly read pc.
9770f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    emitLoadStoreInstruction(MI, 0, ARM::PC);
978c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    break;
979c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  }
980c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  case ARM::PICLDRH:
981c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  case ARM::PICLDRSH:
982c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  case ARM::PICLDRSB:
983c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  case ARM::PICSTRH: {
984c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    // Remember of the address of the PC label for relocation later.
985c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    addPCLabel(MI.getOperand(2).getImm());
986c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    // These are just load / store instructions that implicitly read pc.
987c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    emitMiscLoadStoreInstruction(MI, ARM::PC);
988d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng    break;
989d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  }
9905d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
9915d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  case ARM::MOVi32imm:
9927cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng    // Two instructions to materialize a constant.
9937bda3adcb509f837b10f418d94707498a388ff9bEvan Cheng    if (Subtarget->hasV6T2Ops())
9947bda3adcb509f837b10f418d94707498a388ff9bEvan Cheng      emitMOVi32immInstruction(MI);
9957bda3adcb509f837b10f418d94707498a388ff9bEvan Cheng    else
9967bda3adcb509f837b10f418d94707498a388ff9bEvan Cheng      emitMOVi2piecesInstruction(MI);
9977cd4acb355755ff9c52e60095fa7444fff7269afEvan Cheng    break;
998e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao  case ARM::LEApcrel:
999e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    // Materialize constantpool index address.
1000e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    emitLEApcrelInstruction(MI);
1001e8ec223e344c3c4db95dcee42c46a829d04f8ceeShih-wei Liao    break;
10020f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  case ARM::LEApcrelJT:
10030f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    // Materialize jumptable address.
10040f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    emitLEApcrelJTInstruction(MI);
10050f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    break;
10067c165e244d6747a51f74568588240dc8eaef5542Jim Grosbach  case ARM::RRX:
10077f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  case ARM::MOVsrl_flag:
10087f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng  case ARM::MOVsra_flag:
10097f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    emitPseudoMoveInstruction(MI);
10107f240d2720ad13acf5da2a8219f1848c02ff4c26Evan Cheng    break;
1011d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  }
1012d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng}
1013d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng
1014164fe923dac9b977ab0e3d923978cf0ba875d959Bob Wilsonunsigned ARMCodeEmitter::getMachineSoRegOpValue(const MachineInstr &MI,
1015e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                                                const MCInstrDesc &MCID,
1016d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng                                                const MachineOperand &MO,
101700dc31b291ddde446299bf4b50011fb56758f211Evan Cheng                                                unsigned OpIdx) {
1018d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  unsigned Binary = getMachineOpValue(MI, MO);
101900dc31b291ddde446299bf4b50011fb56758f211Evan Cheng
102000dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  const MachineOperand &MO1 = MI.getOperand(OpIdx + 1);
102100dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  const MachineOperand &MO2 = MI.getOperand(OpIdx + 2);
102200dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
102300dc31b291ddde446299bf4b50011fb56758f211Evan Cheng
102400dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  // Encode the shift opcode.
102500dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  unsigned SBits = 0;
102600dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  unsigned Rs = MO1.getReg();
102700dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  if (Rs) {
102800dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // Set shift operand (bit[7:4]).
102900dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // LSL - 0001
103000dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // LSR - 0011
103100dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // ASR - 0101
103200dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // ROR - 0111
103300dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // RRX - 0110 and bit[11:8] clear.
103400dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    switch (SOpc) {
1035bd448e3ca993226084d7f53445388fcd8e46b996Edwin Török    default: llvm_unreachable("Unknown shift opc!");
103600dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    case ARM_AM::lsl: SBits = 0x1; break;
103700dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    case ARM_AM::lsr: SBits = 0x3; break;
103800dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    case ARM_AM::asr: SBits = 0x5; break;
103900dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    case ARM_AM::ror: SBits = 0x7; break;
104000dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    case ARM_AM::rrx: SBits = 0x6; break;
104100dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    }
104200dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  } else {
104300dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // Set shift operand (bit[6:4]).
104400dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // LSL - 000
104500dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // LSR - 010
104600dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // ASR - 100
104700dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // ROR - 110
104800dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    switch (SOpc) {
1049bd448e3ca993226084d7f53445388fcd8e46b996Edwin Török    default: llvm_unreachable("Unknown shift opc!");
105000dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    case ARM_AM::lsl: SBits = 0x0; break;
105100dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    case ARM_AM::lsr: SBits = 0x2; break;
105200dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    case ARM_AM::asr: SBits = 0x4; break;
105300dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    case ARM_AM::ror: SBits = 0x6; break;
1054a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng    }
1055a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng  }
105600dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  Binary |= SBits << 4;
105700dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  if (SOpc == ARM_AM::rrx)
105800dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    return Binary;
1059a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
106000dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  // Encode the shift operation Rs or shift_imm (except rrx).
106100dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  if (Rs) {
106200dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // Encode Rs bit[11:8].
106300dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
1064df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    return Binary | (II->getRegisterInfo().getEncodingValue(Rs) << ARMII::RegRsShift);
1065efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  }
1066a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
106700dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  // Encode shift_imm bit[11:7].
106800dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
106900dc31b291ddde446299bf4b50011fb56758f211Evan Cheng}
1070efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
107111d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnerunsigned ARMCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) {
10728be2a5bd2b7a7296f150053c0a8d8767a810b78cEvan Cheng  int SoImmVal = ARM_AM::getSOImmVal(SoImm);
10738be2a5bd2b7a7296f150053c0a8d8767a810b78cEvan Cheng  assert(SoImmVal != -1 && "Not a valid so_imm value!");
10748be2a5bd2b7a7296f150053c0a8d8767a810b78cEvan Cheng
1075d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  // Encode rotate_imm.
10768be2a5bd2b7a7296f150053c0a8d8767a810b78cEvan Cheng  unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
107737afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    << ARMII::SoRotImmShift;
107837afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
1079d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  // Encode immed_8.
10808be2a5bd2b7a7296f150053c0a8d8767a810b78cEvan Cheng  Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
1081d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  return Binary;
1082d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng}
1083d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng
108411d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnerunsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI,
1085e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                                         const MCInstrDesc &MCID) const {
10868e0c7697fd9b9354856074efc06eea9f6d80015cJim Grosbach  for (unsigned i = MI.getNumOperands(), e = MCID.getNumOperands(); i >= e;--i){
1087378c3a98dc3cc70f8562e5221d41ef23c38d87f2Evan Cheng    const MachineOperand &MO = MI.getOperand(i-1);
1088b9f4fa7b400836808bc3beab96482418f418f246Dan Gohman    if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR)
1089378c3a98dc3cc70f8562e5221d41ef23c38d87f2Evan Cheng      return 1 << ARMII::S_BitShift;
1090378c3a98dc3cc70f8562e5221d41ef23c38d87f2Evan Cheng  }
1091378c3a98dc3cc70f8562e5221d41ef23c38d87f2Evan Cheng  return 0;
1092378c3a98dc3cc70f8562e5221d41ef23c38d87f2Evan Cheng}
1093378c3a98dc3cc70f8562e5221d41ef23c38d87f2Evan Cheng
1094164fe923dac9b977ab0e3d923978cf0ba875d959Bob Wilsonvoid ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI,
1095260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng                                                   unsigned ImplicitRd,
1096c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng                                                   unsigned ImplicitRn) {
1097e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
109886a926a425286e882a7f3902a525527f17bb127fEvan Cheng
109986a926a425286e882a7f3902a525527f17bb127fEvan Cheng  // Part of binary is determined by TableGn.
110086a926a425286e882a7f3902a525527f17bb127fEvan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
110186a926a425286e882a7f3902a525527f17bb127fEvan Cheng
1102f899bd4a462884aa91b9d0c93ab2dbc605dac116Nowar Gu  if (MCID.Opcode == ARM::MOVi16 || MCID.Opcode == ARM::MOVTi16) {
1103260b29b71916d4176b0031bf794fd093344fffe6Jush Lu      emitWordLE(Binary);
1104260b29b71916d4176b0031bf794fd093344fffe6Jush Lu      return;
1105260b29b71916d4176b0031bf794fd093344fffe6Jush Lu  }
1106260b29b71916d4176b0031bf794fd093344fffe6Jush Lu
1107320c148375723e6e2f850f5e9909da26391a0119Jim Grosbach  // Set the conditional execution predicate
110837afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
1109a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
1110378c3a98dc3cc70f8562e5221d41ef23c38d87f2Evan Cheng  // Encode S bit if MI modifies CPSR.
1111e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  Binary |= getAddrModeSBit(MI, MCID);
1112378c3a98dc3cc70f8562e5221d41ef23c38d87f2Evan Cheng
111300dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  // Encode register def if there is one.
1114e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  unsigned NumDefs = MCID.getNumDefs();
11153eb25b3e793196ac12d225fd3fe37c5dc1365a2fEvan Cheng  unsigned OpIdx = 0;
1116260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng  if (NumDefs)
1117260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;
1118260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng  else if (ImplicitRd)
1119260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    // Special handling for implicit use (e.g. PC).
1120df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    Binary |= (II->getRegisterInfo().getEncodingValue(ImplicitRd) << ARMII::RegRdShift);
112100dc31b291ddde446299bf4b50011fb56758f211Evan Cheng
1122e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.Opcode == ARM::MOVi16) {
1123f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang      // Get immediate from MI.
1124f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang      unsigned Lo16 = getMovi32Value(MI, MI.getOperand(OpIdx),
1125f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang                      ARM::reloc_arm_movw);
1126f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang      // Encode imm which is the same as in emitMOVi32immInstruction().
1127f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang      Binary |= Lo16 & 0xFFF;
1128f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang      Binary |= ((Lo16 >> 12) & 0xF) << 16;
1129f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang      emitWordLE(Binary);
1130f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang      return;
1131e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  } else if(MCID.Opcode == ARM::MOVTi16) {
1132f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang      unsigned Hi16 = (getMovi32Value(MI, MI.getOperand(OpIdx),
1133f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang                       ARM::reloc_arm_movt) >> 16);
1134f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang      Binary |= Hi16 & 0xFFF;
1135f86399be0c2cd095ebaa80dcc0180dab45ec263cZonr Chang      Binary |= ((Hi16 >> 12) & 0xF) << 16;
11366d37a29588e9a48d81480501f895ac627bf60201Shih-wei Liao      emitWordLE(Binary);
11376d37a29588e9a48d81480501f895ac627bf60201Shih-wei Liao      return;
1138e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  } else if ((MCID.Opcode == ARM::BFC) || (MCID.Opcode == ARM::BFI)) {
1139ac79ed164b7f70ab2f16557c7d4eed7e9db3063aShih-wei Liao      uint32_t v = ~MI.getOperand(2).getImm();
1140ac79ed164b7f70ab2f16557c7d4eed7e9db3063aShih-wei Liao      int32_t lsb = CountTrailingZeros_32(v);
1141ac79ed164b7f70ab2f16557c7d4eed7e9db3063aShih-wei Liao      int32_t msb = (32 - CountLeadingZeros_32(v)) - 1;
114263ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao      // Instr{20-16} = msb, Instr{11-7} = lsb
1143ac79ed164b7f70ab2f16557c7d4eed7e9db3063aShih-wei Liao      Binary |= (msb & 0x1F) << 16;
1144ac79ed164b7f70ab2f16557c7d4eed7e9db3063aShih-wei Liao      Binary |= (lsb & 0x1F) << 7;
114563ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao      emitWordLE(Binary);
114663ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao      return;
1147e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  } else if ((MCID.Opcode == ARM::UBFX) || (MCID.Opcode == ARM::SBFX)) {
114863ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao      // Encode Rn in Instr{0-3}
114963ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao      Binary |= getMachineOpValue(MI, OpIdx++);
115063ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao
115163ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao      uint32_t lsb = MI.getOperand(OpIdx++).getImm();
115263ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao      uint32_t widthm1 = MI.getOperand(OpIdx++).getImm() - 1;
115363ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao
115463ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao      // Instr{20-16} = widthm1, Instr{11-7} = lsb
115563ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao      Binary |= (widthm1 & 0x1F) << 16;
115663ff440fd17c797cebb3c64c7198dad46ef7c90aShih-wei Liao      Binary |= (lsb & 0x1F) << 7;
11575d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang      emitWordLE(Binary);
11585d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang      return;
11595d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang  }
11605d392dd93e023f9c14353ea84e2db717792db4bdZonr Chang
1161be9982437e064b956575c7e9fb32465309b08cb2Evan Cheng  // If this is a two-address operand, skip it. e.g. MOVCCr operand 1.
1162e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
1163be9982437e064b956575c7e9fb32465309b08cb2Evan Cheng    ++OpIdx;
1164be9982437e064b956575c7e9fb32465309b08cb2Evan Cheng
1165b98d7197d674a5435545acc691236f46eb2ee97bJim Grosbach  // Encode first non-shifter register operand if there is one.
1166e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  bool isUnary = MCID.TSFlags & ARMII::UnaryDP;
116786a926a425286e882a7f3902a525527f17bb127fEvan Cheng  if (!isUnary) {
1168c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    if (ImplicitRn)
1169c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng      // Special handling for implicit use (e.g. PC).
1170df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher      Binary |= (II->getRegisterInfo().getEncodingValue(ImplicitRn) << ARMII::RegRnShift);
1171d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng    else {
1172d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng      Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift;
1173d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng      ++OpIdx;
1174d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng    }
1175efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  }
1176a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
117700dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  // Encode shifter operand.
1178d6dcbe2281bb989bf4b96f4783b5163d68802c87Evan Cheng  const MachineOperand &MO = MI.getOperand(OpIdx);
1179e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if ((MCID.TSFlags & ARMII::FormMask) == ARMII::DPSoRegFrm) {
118000dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // Encode SoReg.
1181e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    emitWordLE(Binary | getMachineSoRegOpValue(MI, MCID, MO, OpIdx));
118286a926a425286e882a7f3902a525527f17bb127fEvan Cheng    return;
118386a926a425286e882a7f3902a525527f17bb127fEvan Cheng  }
118400dc31b291ddde446299bf4b50011fb56758f211Evan Cheng
118586a926a425286e882a7f3902a525527f17bb127fEvan Cheng  if (MO.isReg()) {
118600dc31b291ddde446299bf4b50011fb56758f211Evan Cheng    // Encode register Rm.
1187df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    emitWordLE(Binary | II->getRegisterInfo().getEncodingValue(MO.getReg()));
118886a926a425286e882a7f3902a525527f17bb127fEvan Cheng    return;
118986a926a425286e882a7f3902a525527f17bb127fEvan Cheng  }
119000dc31b291ddde446299bf4b50011fb56758f211Evan Cheng
119100dc31b291ddde446299bf4b50011fb56758f211Evan Cheng  // Encode so_imm.
11928be2a5bd2b7a7296f150053c0a8d8767a810b78cEvan Cheng  Binary |= getMachineSoImmOpValue((unsigned)MO.getImm());
119386a926a425286e882a7f3902a525527f17bb127fEvan Cheng
1194c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  emitWordLE(Binary);
1195efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng}
1196a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
1197164fe923dac9b977ab0e3d923978cf0ba875d959Bob Wilsonvoid ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
11980f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng                                              unsigned ImplicitRd,
1199c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng                                              unsigned ImplicitRn) {
1200e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
1201e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  unsigned Form = MCID.TSFlags & ARMII::FormMask;
1202e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  bool IsPrePost = (MCID.TSFlags & ARMII::IndexModeMask) != 0;
12032929cc0f51dd998bc00547377f00386758dc962fEvan Cheng
120486a926a425286e882a7f3902a525527f17bb127fEvan Cheng  // Part of binary is determined by TableGn.
120586a926a425286e882a7f3902a525527f17bb127fEvan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
120686a926a425286e882a7f3902a525527f17bb127fEvan Cheng
1207f9ea7dde3e92919ea1716e38c1ad3aac7bb7a9bbJim Grosbach  // If this is an LDRi12, STRi12 or LDRcp, nothing more needs be done.
1208f9ea7dde3e92919ea1716e38c1ad3aac7bb7a9bbJim Grosbach  if (MI.getOpcode() == ARM::LDRi12 || MI.getOpcode() == ARM::LDRcp ||
12094485fa16ecd3a16ab2b670691fcbfd24cf0656e2jush      MI.getOpcode() == ARM::STRi12 || MI.getOpcode() == ARM::LDRBi12 ||
12104485fa16ecd3a16ab2b670691fcbfd24cf0656e2jush      MI.getOpcode() == ARM::STRBi12) {
12114dcf14aadbfaa68953607b11dc5008f7a0cce1aeJim Grosbach    emitWordLE(Binary);
12124dcf14aadbfaa68953607b11dc5008f7a0cce1aeJim Grosbach    return;
12134dcf14aadbfaa68953607b11dc5008f7a0cce1aeJim Grosbach  }
12144dcf14aadbfaa68953607b11dc5008f7a0cce1aeJim Grosbach
1215e6fd111ddf8f32b7d63405e83678887292c34223Jush Lu  if (MI.getOpcode() == ARM::BR_JTm)
1216e6fd111ddf8f32b7d63405e83678887292c34223Jush Lu    Binary = 0x710F000;
1217e6fd111ddf8f32b7d63405e83678887292c34223Jush Lu  else if (MI.getOpcode() == ARM::BR_JTr)
1218e6fd111ddf8f32b7d63405e83678887292c34223Jush Lu    Binary = 0x1A0F000;
1219e6fd111ddf8f32b7d63405e83678887292c34223Jush Lu
1220320c148375723e6e2f850f5e9909da26391a0119Jim Grosbach  // Set the conditional execution predicate
122137afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
1222e4c813ccdf946b232816949926386aa6bbcdfa0eEvan Cheng
12230f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  unsigned OpIdx = 0;
122481794bb21ef0b38886835eed1995d495e47be42aEvan Cheng
122581794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  // Operand 0 of a pre- and post-indexed store is the address base
122681794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  // writeback. Skip it.
122781794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  bool Skipped = false;
122881794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  if (IsPrePost && Form == ARMII::StFrm) {
122981794bb21ef0b38886835eed1995d495e47be42aEvan Cheng    ++OpIdx;
123081794bb21ef0b38886835eed1995d495e47be42aEvan Cheng    Skipped = true;
123181794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  }
123281794bb21ef0b38886835eed1995d495e47be42aEvan Cheng
123381794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  // Set first operand
12340f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  if (ImplicitRd)
12350f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    // Special handling for implicit use (e.g. PC).
1236df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    Binary |= (II->getRegisterInfo().getEncodingValue(ImplicitRd) << ARMII::RegRdShift);
12370f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  else
12380f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;
1239efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
1240efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // Set second operand
1241c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  if (ImplicitRn)
1242c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    // Special handling for implicit use (e.g. PC).
1243df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    Binary |= (II->getRegisterInfo().getEncodingValue(ImplicitRn) << ARMII::RegRnShift);
12440f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  else
12450f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
1246efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
12472929cc0f51dd998bc00547377f00386758dc962fEvan Cheng  // If this is a two-address operand, skip it. e.g. LDR_PRE.
1248e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (!Skipped && MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
12492929cc0f51dd998bc00547377f00386758dc962fEvan Cheng    ++OpIdx;
12502929cc0f51dd998bc00547377f00386758dc962fEvan Cheng
1251c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  const MachineOperand &MO2 = MI.getOperand(OpIdx);
1252be9982437e064b956575c7e9fb32465309b08cb2Evan Cheng  unsigned AM2Opc = (ImplicitRn == ARM::PC)
1253c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    ? 0 : MI.getOperand(OpIdx+1).getImm();
1254efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
125500330db76463b811bc5908306a1c7248a1eeaf2bEvan Cheng  // Set bit U(23) according to sign of immed value (positive or negative).
1256c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  Binary |= ((ARM_AM::getAM2Op(AM2Opc) == ARM_AM::add ? 1 : 0) <<
125700330db76463b811bc5908306a1c7248a1eeaf2bEvan Cheng             ARMII::U_BitShift);
1258efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  if (!MO2.getReg()) { // is immediate
1259c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    if (ARM_AM::getAM2Offset(AM2Opc))
1260efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng      // Set the value of offset_12 field
1261c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng      Binary |= ARM_AM::getAM2Offset(AM2Opc);
1262c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    emitWordLE(Binary);
126386a926a425286e882a7f3902a525527f17bb127fEvan Cheng    return;
1264a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng  }
1265a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
12662f37e157aafd3c7495d74e6081e598bc3a19db9eBill Wendling  // Set bit I(25), because this is not in immediate encoding.
1267efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  Binary |= 1 << ARMII::I_BitShift;
1268efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg()));
1269efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // Set bit[3:0] to the corresponding Rm register
1270df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  Binary |= II->getRegisterInfo().getEncodingValue(MO2.getReg());
1271efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
12729eba91165910dcb37d5751bf43b2e90b83a381d1Evan Cheng  // If this instr is in scaled register offset/index instruction, set
1273efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // shift_immed(bit[11:7]) and shift(bit[6:5]) fields.
1274c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(AM2Opc)) {
12759eba91165910dcb37d5751bf43b2e90b83a381d1Evan Cheng    Binary |= getShiftOp(AM2Opc) << ARMII::ShiftImmShift;  // shift
12769eba91165910dcb37d5751bf43b2e90b83a381d1Evan Cheng    Binary |= ShImm              << ARMII::ShiftShift;     // shift_immed
1277efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  }
1278a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
1279c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  emitWordLE(Binary);
1280efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng}
1281efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
128211d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
1283164fe923dac9b977ab0e3d923978cf0ba875d959Bob Wilson                                                  unsigned ImplicitRn) {
1284e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
1285e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  unsigned Form = MCID.TSFlags & ARMII::FormMask;
1286e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  bool IsPrePost = (MCID.TSFlags & ARMII::IndexModeMask) != 0;
12872929cc0f51dd998bc00547377f00386758dc962fEvan Cheng
128886a926a425286e882a7f3902a525527f17bb127fEvan Cheng  // Part of binary is determined by TableGn.
128986a926a425286e882a7f3902a525527f17bb127fEvan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
129086a926a425286e882a7f3902a525527f17bb127fEvan Cheng
1291320c148375723e6e2f850f5e9909da26391a0119Jim Grosbach  // Set the conditional execution predicate
129237afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
1293e4c813ccdf946b232816949926386aa6bbcdfa0eEvan Cheng
129481794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  unsigned OpIdx = 0;
129581794bb21ef0b38886835eed1995d495e47be42aEvan Cheng
129681794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  // Operand 0 of a pre- and post-indexed store is the address base
129781794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  // writeback. Skip it.
129881794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  bool Skipped = false;
129981794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  if (IsPrePost && Form == ARMII::StMiscFrm) {
130081794bb21ef0b38886835eed1995d495e47be42aEvan Cheng    ++OpIdx;
130181794bb21ef0b38886835eed1995d495e47be42aEvan Cheng    Skipped = true;
130281794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  }
130381794bb21ef0b38886835eed1995d495e47be42aEvan Cheng
1304efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // Set first operand
130581794bb21ef0b38886835eed1995d495e47be42aEvan Cheng  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;
1306efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
130741169551d59e9aee3d9dcd043013d65ee6e33759Evan Cheng  // Skip LDRD and STRD's second operand.
1308e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.Opcode == ARM::LDRD || MCID.Opcode == ARM::STRD)
130941169551d59e9aee3d9dcd043013d65ee6e33759Evan Cheng    ++OpIdx;
131041169551d59e9aee3d9dcd043013d65ee6e33759Evan Cheng
1311efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // Set second operand
1312c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  if (ImplicitRn)
1313c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    // Special handling for implicit use (e.g. PC).
1314df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    Binary |= (II->getRegisterInfo().getEncodingValue(ImplicitRn) << ARMII::RegRnShift);
13150f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  else
13160f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
1317efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
13182929cc0f51dd998bc00547377f00386758dc962fEvan Cheng  // If this is a two-address operand, skip it. e.g. LDRH_POST.
1319e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (!Skipped && MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
13202929cc0f51dd998bc00547377f00386758dc962fEvan Cheng    ++OpIdx;
13212929cc0f51dd998bc00547377f00386758dc962fEvan Cheng
1322c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  const MachineOperand &MO2 = MI.getOperand(OpIdx);
1323be9982437e064b956575c7e9fb32465309b08cb2Evan Cheng  unsigned AM3Opc = (ImplicitRn == ARM::PC)
1324c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    ? 0 : MI.getOperand(OpIdx+1).getImm();
1325efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
132600330db76463b811bc5908306a1c7248a1eeaf2bEvan Cheng  // Set bit U(23) according to sign of immed value (positive or negative)
1327c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  Binary |= ((ARM_AM::getAM3Op(AM3Opc) == ARM_AM::add ? 1 : 0) <<
1328efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng             ARMII::U_BitShift);
1329efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
1330efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // If this instr is in register offset/index encoding, set bit[3:0]
1331efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // to the corresponding Rm register.
1332efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  if (MO2.getReg()) {
1333df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    Binary |= II->getRegisterInfo().getEncodingValue(MO2.getReg());
1334c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng    emitWordLE(Binary);
133586a926a425286e882a7f3902a525527f17bb127fEvan Cheng    return;
1336a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng  }
1337a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
1338be9982437e064b956575c7e9fb32465309b08cb2Evan Cheng  // This instr is in immediate offset/index encoding, set bit 22 to 1.
133937afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= 1 << ARMII::AM3_I_BitShift;
1340c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  if (unsigned ImmOffs = ARM_AM::getAM3Offset(AM3Opc)) {
1341efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng    // Set operands
13429eba91165910dcb37d5751bf43b2e90b83a381d1Evan Cheng    Binary |= (ImmOffs >> 4) << ARMII::ImmHiShift;  // immedH
13439eba91165910dcb37d5751bf43b2e90b83a381d1Evan Cheng    Binary |= (ImmOffs & 0xF);                      // immedL
1344efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  }
1345a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng
1346c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  emitWordLE(Binary);
1347efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng}
1348efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
1349bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Chengstatic unsigned getAddrModeUPBits(unsigned Mode) {
1350bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  unsigned Binary = 0;
1351efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
1352efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // Set addressing mode by modifying bits U(23) and P(24)
1353efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // IA - Increment after  - bit U = 1 and bit P = 0
1354efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // IB - Increment before - bit U = 1 and bit P = 1
1355efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // DA - Decrement after  - bit U = 0 and bit P = 0
1356efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // DB - Decrement before - bit U = 0 and bit P = 1
1357efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  switch (Mode) {
1358bd448e3ca993226084d7f53445388fcd8e46b996Edwin Török  default: llvm_unreachable("Unknown addressing sub-mode!");
135971429f87316fc88ebe54b904c4b1326a71fbc3ecEvan Cheng  case ARM_AM::da:                                     break;
136037afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  case ARM_AM::db: Binary |= 0x1 << ARMII::P_BitShift; break;
136137afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  case ARM_AM::ia: Binary |= 0x1 << ARMII::U_BitShift; break;
136237afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  case ARM_AM::ib: Binary |= 0x3 << ARMII::U_BitShift; break;
1363a7b3e7c33f1ef7be844fde18dcd9e24afdc97748Evan Cheng  }
1364efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
1365bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  return Binary;
1366bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng}
1367bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1368b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilsonvoid ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
1369e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
1370e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  bool IsUpdating = (MCID.TSFlags & ARMII::IndexModeMask) != 0;
1371b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson
1372bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Part of binary is determined by TableGn.
1373bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
1374bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1375f899bd4a462884aa91b9d0c93ab2dbc605dac116Nowar Gu  if (MCID.getOpcode() == ARM::LDMIA_RET) {
1376eeb84081f389b99547082b9867830ad4c46cb39aJush Lu    IsUpdating = true;
1377eeb84081f389b99547082b9867830ad4c46cb39aJush Lu    Binary |= 0x8B00000;
1378eeb84081f389b99547082b9867830ad4c46cb39aJush Lu  }
1379eeb84081f389b99547082b9867830ad4c46cb39aJush Lu
1380bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Set the conditional execution predicate
1381bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
1382bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1383b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  // Skip operand 0 of an instruction with base register update.
1384b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  unsigned OpIdx = 0;
1385b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  if (IsUpdating)
1386b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson    ++OpIdx;
1387b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson
1388bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Set base address operand
1389b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
1390bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1391bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Set addressing mode by modifying bits U(23) and P(24)
13922567eec4233d58a2a0cbdcafca9420452689b395Bill Wendling  ARM_AM::AMSubMode Mode = ARM_AM::getLoadStoreMultipleSubMode(MI.getOpcode());
13932567eec4233d58a2a0cbdcafca9420452689b395Bill Wendling  Binary |= getAddrModeUPBits(ARM_AM::getAM4SubMode(Mode));
1394bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1395efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // Set bit W(21)
1396dfa5da942162f3e44b08d27e4df9e7d94f17e13dBob Wilson  if (IsUpdating)
139737afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    Binary |= 0x1 << ARMII::W_BitShift;
1398efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
1399efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // Set registers
1400b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  for (unsigned i = OpIdx+2, e = MI.getNumOperands(); i != e; ++i) {
1401efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng    const MachineOperand &MO = MI.getOperand(i);
1402bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    if (!MO.isReg() || MO.isImplicit())
1403bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng      break;
1404df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned RegNum = II->getRegisterInfo().getEncodingValue(MO.getReg());
1405efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng    assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
1406efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng           RegNum < 16);
1407efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng    Binary |= 0x1 << RegNum;
1408efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  }
1409efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
1410c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  emitWordLE(Binary);
1411efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng}
1412efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
141311d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitMulFrmInstruction(const MachineInstr &MI) {
1414e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
141586a926a425286e882a7f3902a525527f17bb127fEvan Cheng
141686a926a425286e882a7f3902a525527f17bb127fEvan Cheng  // Part of binary is determined by TableGn.
141786a926a425286e882a7f3902a525527f17bb127fEvan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
141886a926a425286e882a7f3902a525527f17bb127fEvan Cheng
14191feed0434ec93100876edf72897700148b74d054Jim Grosbach  // Set the conditional execution predicate
142037afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
14211feed0434ec93100876edf72897700148b74d054Jim Grosbach
14221feed0434ec93100876edf72897700148b74d054Jim Grosbach  // Encode S bit if MI modifies CPSR.
1423e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  Binary |= getAddrModeSBit(MI, MCID);
14241feed0434ec93100876edf72897700148b74d054Jim Grosbach
14251feed0434ec93100876edf72897700148b74d054Jim Grosbach  // 32x32->64bit operations have two destination registers. The number
14261feed0434ec93100876edf72897700148b74d054Jim Grosbach  // of register definitions will tell us if that's what we're dealing with.
142737afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  unsigned OpIdx = 0;
1428e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.getNumDefs() == 2)
14291feed0434ec93100876edf72897700148b74d054Jim Grosbach    Binary |= getMachineOpValue (MI, OpIdx++) << ARMII::RegRdLoShift;
14301feed0434ec93100876edf72897700148b74d054Jim Grosbach
14311feed0434ec93100876edf72897700148b74d054Jim Grosbach  // Encode Rd
14321feed0434ec93100876edf72897700148b74d054Jim Grosbach  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdHiShift;
14331feed0434ec93100876edf72897700148b74d054Jim Grosbach
14341feed0434ec93100876edf72897700148b74d054Jim Grosbach  // Encode Rm
14351feed0434ec93100876edf72897700148b74d054Jim Grosbach  Binary |= getMachineOpValue(MI, OpIdx++);
14361feed0434ec93100876edf72897700148b74d054Jim Grosbach
14371feed0434ec93100876edf72897700148b74d054Jim Grosbach  // Encode Rs
14381feed0434ec93100876edf72897700148b74d054Jim Grosbach  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRsShift;
14391feed0434ec93100876edf72897700148b74d054Jim Grosbach
1440ee80fb79279be7c84e6f8a3f06403200386a6ef5Evan Cheng  // Many multiple instructions (e.g. MLA) have three src operands. Encode
1441ee80fb79279be7c84e6f8a3f06403200386a6ef5Evan Cheng  // it as Rn (for multiply, that's in the same offset as RdLo.
1442e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.getNumOperands() > OpIdx &&
1443e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      !MCID.OpInfo[OpIdx].isPredicate() &&
1444e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      !MCID.OpInfo[OpIdx].isOptionalDef())
144537afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRdLoShift;
144637afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
144737afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  emitWordLE(Binary);
144837afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng}
144937afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
145011d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitExtendInstruction(const MachineInstr &MI) {
1451e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
145237afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
145337afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  // Part of binary is determined by TableGn.
145437afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
145537afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
145637afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  // Set the conditional execution predicate
145737afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
145837afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
145937afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  unsigned OpIdx = 0;
146037afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
146137afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  // Encode Rd
146237afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;
146337afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
146437afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  const MachineOperand &MO1 = MI.getOperand(OpIdx++);
146537afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  const MachineOperand &MO2 = MI.getOperand(OpIdx);
146637afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  if (MO2.isReg()) {
146737afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    // Two register operand form.
146837afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    // Encode Rn.
146937afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    Binary |= getMachineOpValue(MI, MO1) << ARMII::RegRnShift;
147037afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
147137afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    // Encode Rm.
147237afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    Binary |= getMachineOpValue(MI, MO2);
147337afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    ++OpIdx;
147437afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  } else {
147537afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    Binary |= getMachineOpValue(MI, MO1);
147637afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  }
147737afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng
147837afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  // Encode rot imm (0, 8, 16, or 24) if it has a rotate immediate operand.
147937afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  if (MI.getOperand(OpIdx).isImm() &&
1480e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      !MCID.OpInfo[OpIdx].isPredicate() &&
1481e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      !MCID.OpInfo[OpIdx].isOptionalDef())
148237afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng    Binary |= (getMachineOpValue(MI, OpIdx) / 8) << ARMII::ExtRotImmShift;
1483ee80fb79279be7c84e6f8a3f06403200386a6ef5Evan Cheng
1484c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  emitWordLE(Binary);
14851feed0434ec93100876edf72897700148b74d054Jim Grosbach}
14861feed0434ec93100876edf72897700148b74d054Jim Grosbach
148711d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitMiscArithInstruction(const MachineInstr &MI) {
1488e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
1489c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng
1490c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  // Part of binary is determined by TableGn.
1491c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
1492c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng
14933983d243ad2386d7c2c835c798db141b176ef4e7Stephen Hines  // Set the conditional execution predicate
14943983d243ad2386d7c2c835c798db141b176ef4e7Stephen Hines  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
14953983d243ad2386d7c2c835c798db141b176ef4e7Stephen Hines
149633c110e602bbdfee23cfb58fddef246a262647abEric Christopher  // PKH instructions are finished at this point
1497e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.Opcode == ARM::PKHBT || MCID.Opcode == ARM::PKHTB) {
1498f55066572ff8040747ff03a7fa71d88b85f41812Shih-wei Liao    emitWordLE(Binary);
1499f55066572ff8040747ff03a7fa71d88b85f41812Shih-wei Liao    return;
1500f55066572ff8040747ff03a7fa71d88b85f41812Shih-wei Liao  }
1501f55066572ff8040747ff03a7fa71d88b85f41812Shih-wei Liao
1502c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  unsigned OpIdx = 0;
1503c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng
1504c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  // Encode Rd
1505c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;
1506c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng
1507c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  const MachineOperand &MO = MI.getOperand(OpIdx++);
1508e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (OpIdx == MCID.getNumOperands() ||
1509e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      MCID.OpInfo[OpIdx].isPredicate() ||
1510e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      MCID.OpInfo[OpIdx].isOptionalDef()) {
1511c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng    // Encode Rm and it's done.
1512c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng    Binary |= getMachineOpValue(MI, MO);
1513c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng    emitWordLE(Binary);
1514c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng    return;
1515c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  }
1516c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng
1517c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  // Encode Rn.
1518c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  Binary |= getMachineOpValue(MI, MO) << ARMII::RegRnShift;
1519c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng
1520c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  // Encode Rm.
1521c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  Binary |= getMachineOpValue(MI, OpIdx++);
1522c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng
1523c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  // Encode shift_imm.
1524c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  unsigned ShiftAmt = MI.getOperand(OpIdx).getImm();
1525e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.Opcode == ARM::PKHTB) {
1526fec03d6365fe3d8a86bd9bb82e6274bbf567b914Bob Wilson    assert(ShiftAmt != 0 && "PKHTB shift_imm is 0!");
1527fec03d6365fe3d8a86bd9bb82e6274bbf567b914Bob Wilson    if (ShiftAmt == 32)
1528fec03d6365fe3d8a86bd9bb82e6274bbf567b914Bob Wilson      ShiftAmt = 0;
1529fec03d6365fe3d8a86bd9bb82e6274bbf567b914Bob Wilson  }
1530c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
1531c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  Binary |= ShiftAmt << ARMII::ShiftShift;
1532770d718405114860f3874871848e345873bf7cb4Jim Grosbach
1533c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng  emitWordLE(Binary);
1534c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng}
1535c2121a25f17c99f2f1b0235bf425842962535ae6Evan Cheng
1536118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilsonvoid ARMCodeEmitter::emitSaturateInstruction(const MachineInstr &MI) {
1537e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
1538118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson
1539118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  // Part of binary is determined by TableGen.
1540118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  unsigned Binary = getBinaryCodeForInstr(MI);
1541118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson
1542118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  // Set the conditional execution predicate
1543118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
1544118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson
1545118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  // Encode Rd
1546118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;
1547118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson
1548118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  // Encode saturate bit position.
1549118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  unsigned Pos = MI.getOperand(1).getImm();
1550e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.Opcode == ARM::SSAT || MCID.Opcode == ARM::SSAT16)
1551118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson    Pos -= 1;
1552118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  assert((Pos < 16 || (Pos < 32 &&
1553e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                       MCID.Opcode != ARM::SSAT16 &&
1554e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng                       MCID.Opcode != ARM::USAT16)) &&
1555118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson         "saturate bit position out of range");
1556118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  Binary |= Pos << 16;
1557118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson
1558118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  // Encode Rm
1559118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  Binary |= getMachineOpValue(MI, 2);
1560118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson
1561118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  // Encode shift_imm.
1562e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.getNumOperands() == 4) {
15636aed5ee28d0ef1b624ea5367409c497b4ab4a36aBob Wilson    unsigned ShiftOp = MI.getOperand(3).getImm();
15646aed5ee28d0ef1b624ea5367409c497b4ab4a36aBob Wilson    ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
15656aed5ee28d0ef1b624ea5367409c497b4ab4a36aBob Wilson    if (Opc == ARM_AM::asr)
15666aed5ee28d0ef1b624ea5367409c497b4ab4a36aBob Wilson      Binary |= (1 << 6);
1567118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson    unsigned ShiftAmt = MI.getOperand(3).getImm();
15686aed5ee28d0ef1b624ea5367409c497b4ab4a36aBob Wilson    if (ShiftAmt == 32 && Opc == ARM_AM::asr)
1569118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson      ShiftAmt = 0;
1570118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson    assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
1571118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson    Binary |= ShiftAmt << ARMII::ShiftShift;
1572118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  }
1573118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson
1574118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson  emitWordLE(Binary);
1575118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson}
1576118b4dea46da0da74c3ef4a1c6e7581b404d59bcBob Wilson
157711d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
1578e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
157986a926a425286e882a7f3902a525527f17bb127fEvan Cheng
1580e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.Opcode == ARM::TPsoft) {
1581bd448e3ca993226084d7f53445388fcd8e46b996Edwin Török    llvm_unreachable("ARM::TPsoft FIXME"); // FIXME
15824d9756a9843862edb9daddfaa0d8c78ac1c52b32Edwin Török  }
1583f8e8b6224f80c48736ae4387901bd5f84c2781d5Evan Cheng
1584efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  // Part of binary is determined by TableGn.
1585efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
1586efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
1587f899bd4a462884aa91b9d0c93ab2dbc605dac116Nowar Gu  if (MCID.Opcode == ARM::B) {
15883a5b41d8f8aae9ca8c9ebf95f49de1c46224ec0aJush Lu    Binary = 0xEA000000;
15893a5b41d8f8aae9ca8c9ebf95f49de1c46224ec0aJush Lu  }
15903a5b41d8f8aae9ca8c9ebf95f49de1c46224ec0aJush Lu
159186a926a425286e882a7f3902a525527f17bb127fEvan Cheng  // Set the conditional execution predicate
159237afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
159386a926a425286e882a7f3902a525527f17bb127fEvan Cheng
159486a926a425286e882a7f3902a525527f17bb127fEvan Cheng  // Set signed_immed_24 field
159586a926a425286e882a7f3902a525527f17bb127fEvan Cheng  Binary |= getMachineOpValue(MI, 0);
159686a926a425286e882a7f3902a525527f17bb127fEvan Cheng
1597c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  emitWordLE(Binary);
159886a926a425286e882a7f3902a525527f17bb127fEvan Cheng}
159986a926a425286e882a7f3902a525527f17bb127fEvan Cheng
160011d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitInlineJumpTable(unsigned JTIndex) {
16010f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  // Remember the base address of the inline jump table.
16026e561c71f74571ff2a448e7e07cb74047edef776Evan Cheng  uintptr_t JTBase = MCE.getCurrentPCValue();
1603260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng  JTI->addJumpTableBaseAddr(JTIndex, JTBase);
16042c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << "  ** Jump Table #" << JTIndex << " @ " << (void*)JTBase
16052c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner               << '\n');
16060f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
16070f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  // Now emit the jump table entries.
16080f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  const std::vector<MachineBasicBlock*> &MBBs = (*MJTEs)[JTIndex].MBBs;
16090f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  for (unsigned i = 0, e = MBBs.size(); i != e; ++i) {
16100f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    if (IsPIC)
16110f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng      // DestBB address - JT base.
1612260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng      emitMachineBasicBlock(MBBs[i], ARM::reloc_arm_pic_jt, JTBase);
16130f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    else
16140f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng      // Absolute DestBB address.
16150f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng      emitMachineBasicBlock(MBBs[i], ARM::reloc_arm_absolute);
16160f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    emitWordLE(0);
16170f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  }
16180f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng}
16190f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
162011d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
1621e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
162286a926a425286e882a7f3902a525527f17bb127fEvan Cheng
1623260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng  // Handle jump tables.
1624e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.Opcode == ARM::BR_JTr || MCID.Opcode == ARM::BR_JTadd) {
1625260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    // First emit a ldr pc, [] instruction.
1626260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    emitDataProcessingInstruction(MI, ARM::PC);
1627260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng
1628260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    // Then emit the inline jump table.
1629ec6e592736ba478f7ec001eae1d68a436fec6dd0Evan Cheng    unsigned JTIndex =
1630e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      (MCID.Opcode == ARM::BR_JTr)
1631260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng      ? MI.getOperand(1).getIndex() : MI.getOperand(2).getIndex();
1632260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    emitInlineJumpTable(JTIndex);
1633260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    return;
1634e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  } else if (MCID.Opcode == ARM::BR_JTm) {
16350f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    // First emit a ldr pc, [] instruction.
16360f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    emitLoadStoreInstruction(MI, ARM::PC);
16370f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
16380f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    // Then emit the inline jump table.
1639260ae19f81f574a4ec2c4cc648a63bd4278e4615Evan Cheng    emitInlineJumpTable(MI.getOperand(3).getIndex());
16400f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng    return;
16410f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng  }
16420f63ae111d5a509911fc61246c1acc62f8c58f18Evan Cheng
164386a926a425286e882a7f3902a525527f17bb127fEvan Cheng  // Part of binary is determined by TableGn.
164486a926a425286e882a7f3902a525527f17bb127fEvan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
164586a926a425286e882a7f3902a525527f17bb127fEvan Cheng
164686a926a425286e882a7f3902a525527f17bb127fEvan Cheng  // Set the conditional execution predicate
164737afa438c83f6c25ae29ba269b67240def64fc68Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
164886a926a425286e882a7f3902a525527f17bb127fEvan Cheng
1649e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.Opcode == ARM::BX_RET || MCID.Opcode == ARM::MOVPCLR)
165086a926a425286e882a7f3902a525527f17bb127fEvan Cheng    // The return register is LR.
1651df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    Binary |= II->getRegisterInfo().getEncodingValue(ARM::LR);
1652770d718405114860f3874871848e345873bf7cb4Jim Grosbach  else
165386a926a425286e882a7f3902a525527f17bb127fEvan Cheng    // otherwise, set the return register
165486a926a425286e882a7f3902a525527f17bb127fEvan Cheng    Binary |= getMachineOpValue(MI, 0);
165586a926a425286e882a7f3902a525527f17bb127fEvan Cheng
1656c41fb3151784f7fccb4731ef594c4ea3dc685d5fEvan Cheng  emitWordLE(Binary);
1657f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cDan Gohman}
1658efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng
1659df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopherunsigned ARMCodeEmitter::encodeVFPRd(const MachineInstr &MI,
1660df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher                                     unsigned OpIdx) const {
16618a0454bb13f2db05517e70aae31e0f15f5d252feEvan Cheng  unsigned RegD = MI.getOperand(OpIdx).getReg();
16627427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  unsigned Binary = 0;
1663420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  bool isSPVFP = ARM::SPRRegClass.contains(RegD);
1664df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  RegD = II->getRegisterInfo().getEncodingValue(RegD);
1665098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang  if (!isSPVFP) {
1666098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang    Binary |=  (RegD & 0x0F)       << ARMII::RegRdShift;
1667098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang    Binary |= ((RegD & 0x10) >> 4) << ARMII::D_BitShift;
1668098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang  } else {
16698a0454bb13f2db05517e70aae31e0f15f5d252feEvan Cheng    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
16708a0454bb13f2db05517e70aae31e0f15f5d252feEvan Cheng    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
16718a0454bb13f2db05517e70aae31e0f15f5d252feEvan Cheng  }
16727427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  return Binary;
16737427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng}
16748a0454bb13f2db05517e70aae31e0f15f5d252feEvan Cheng
1675df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopherunsigned ARMCodeEmitter::encodeVFPRn(const MachineInstr &MI,
1676df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher                                     unsigned OpIdx) const {
16778a0454bb13f2db05517e70aae31e0f15f5d252feEvan Cheng  unsigned RegN = MI.getOperand(OpIdx).getReg();
16787427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  unsigned Binary = 0;
1679420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  bool isSPVFP = ARM::SPRRegClass.contains(RegN);
1680df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  RegN = II->getRegisterInfo().getEncodingValue(RegN);
1681098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang  if (!isSPVFP) {
1682098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang    Binary |=  (RegN & 0x0F)       << ARMII::RegRnShift;
1683098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang    Binary |= ((RegN & 0x10) >> 4) << ARMII::N_BitShift;
1684098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang  } else {
16858a0454bb13f2db05517e70aae31e0f15f5d252feEvan Cheng    Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
16868a0454bb13f2db05517e70aae31e0f15f5d252feEvan Cheng    Binary |=  (RegN & 0x01)       << ARMII::N_BitShift;
16878a0454bb13f2db05517e70aae31e0f15f5d252feEvan Cheng  }
16887427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  return Binary;
16897427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng}
16909d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng
1691df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopherunsigned ARMCodeEmitter::encodeVFPRm(const MachineInstr &MI,
1692df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher                                     unsigned OpIdx) const {
16937427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  unsigned RegM = MI.getOperand(OpIdx).getReg();
16947427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  unsigned Binary = 0;
1695420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  bool isSPVFP = ARM::SPRRegClass.contains(RegM);
1696df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  RegM = II->getRegisterInfo().getEncodingValue(RegM);
1697098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang  if (!isSPVFP) {
1698098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang    Binary |=  (RegM & 0x0F);
1699098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang    Binary |= ((RegM & 0x10) >> 4) << ARMII::M_BitShift;
1700098ca99ad1de07ef2117d8fe0f4bfad3cb9d4301Zonr Chang  } else {
17017427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    Binary |= ((RegM & 0x1E) >> 1);
17027427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
17039d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng  }
17047427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  return Binary;
17057427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng}
17067427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng
170711d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
1708e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
170911838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng
171011838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  // Part of binary is determined by TableGn.
171111838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
171211838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng
171311838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  // Set the conditional execution predicate
171411838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
171511838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng
171611838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  unsigned OpIdx = 0;
171711838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng
171811838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  // Encode Dd / Sd.
171911838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  Binary |= encodeVFPRd(MI, OpIdx++);
172011838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng
172111838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  // If this is a two-address operand, skip it, e.g. FMACD.
1722e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
172311838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng    ++OpIdx;
172411838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng
172511838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  // Encode Dn / Sn.
1726e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if ((MCID.TSFlags & ARMII::FormMask) == ARMII::VFPBinaryFrm)
1727db60806dfc019724a37f8a5d2e997ea38d205f8fEvan Cheng    Binary |= encodeVFPRn(MI, OpIdx++);
172811838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng
1729e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (OpIdx == MCID.getNumOperands() ||
1730e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      MCID.OpInfo[OpIdx].isPredicate() ||
1731e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      MCID.OpInfo[OpIdx].isOptionalDef()) {
173211838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng    // FCMPEZD etc. has only one operand.
173311838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng    emitWordLE(Binary);
173411838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng    return;
173511838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  }
173611838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng
173711838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  // Encode Dm / Sm.
173811838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  Binary |= encodeVFPRm(MI, OpIdx);
1739770d718405114860f3874871848e345873bf7cb4Jim Grosbach
174011838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  emitWordLE(Binary);
174111838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng}
174211838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng
1743164fe923dac9b977ab0e3d923978cf0ba875d959Bob Wilsonvoid ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) {
1744e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
1745e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  unsigned Form = MCID.TSFlags & ARMII::FormMask;
17467427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng
17477427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  // Part of binary is determined by TableGn.
17487427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
17497427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng
17507427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  // Set the conditional execution predicate
17517427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
17527427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng
17537427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  switch (Form) {
17547427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  default: break;
17557427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv1Frm:
17567427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv2Frm:
17577427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv3Frm:
17587427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    // Encode Dd / Sd.
17597427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    Binary |= encodeVFPRd(MI, 0);
17607427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    break;
17617427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv4Frm:
17627427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    // Encode Dn / Sn.
17637427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    Binary |= encodeVFPRn(MI, 0);
17647427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    break;
17657427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv5Frm:
17667427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    // Encode Dm / Sm.
17677427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    Binary |= encodeVFPRm(MI, 0);
17687427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    break;
17697427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  }
17707427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng
17717427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  switch (Form) {
17727427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  default: break;
17737427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv1Frm:
17747427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    // Encode Dm / Sm.
17757427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    Binary |= encodeVFPRm(MI, 1);
17763d89598f1f77b6592f04671cc5d356eb285b746fEvan Cheng    break;
17777427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv2Frm:
17787427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv3Frm:
17797427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    // Encode Dn / Sn.
17807427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    Binary |= encodeVFPRn(MI, 1);
17817427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    break;
17827427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv4Frm:
17837427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  case ARMII::VFPConv5Frm:
17847427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    // Encode Dd / Sd.
17857427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    Binary |= encodeVFPRd(MI, 1);
17867427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    break;
17877427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  }
17887427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng
17897427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  if (Form == ARMII::VFPConv5Frm)
17907427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    // Encode Dn / Sn.
17917427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    Binary |= encodeVFPRn(MI, 2);
17927427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng  else if (Form == ARMII::VFPConv3Frm)
17937427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    // Encode Dm / Sm.
17947427338c3da0cf35ecd0ea845ea41e3939eab608Evan Cheng    Binary |= encodeVFPRm(MI, 2);
17959d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng
17969d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng  emitWordLE(Binary);
17979d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng}
17989d3cc18099051234d17dedbd15dfd486b89b9a25Evan Cheng
179911d88be3b07e41ef0eec781cd2fff01d25039c89Chris Lattnervoid ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
1800bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Part of binary is determined by TableGn.
1801bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
1802bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1803bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Set the conditional execution predicate
1804bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
1805bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
180628263e86e6e8b8f3e41ed67eab48a50d07772503jush  if (MI.getOpcode() == ARM::VLDRS || MI.getOpcode() == ARM::VLDRD ||
180728263e86e6e8b8f3e41ed67eab48a50d07772503jush      MI.getOpcode() == ARM::VSTRS || MI.getOpcode() == ARM::VSTRD){
180828263e86e6e8b8f3e41ed67eab48a50d07772503jush    emitWordLE(Binary);
180928263e86e6e8b8f3e41ed67eab48a50d07772503jush    return;
181028263e86e6e8b8f3e41ed67eab48a50d07772503jush  }
181128263e86e6e8b8f3e41ed67eab48a50d07772503jush
1812bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  unsigned OpIdx = 0;
1813bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1814bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Encode Dd / Sd.
181511838a81de997021b6b914cd725eb4d65c3183e5Evan Cheng  Binary |= encodeVFPRd(MI, OpIdx++);
1816bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1817bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Encode address base.
1818bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  const MachineOperand &Base = MI.getOperand(OpIdx++);
1819bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  Binary |= getMachineOpValue(MI, Base) << ARMII::RegRnShift;
1820bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1821bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // If there is a non-zero immediate offset, encode it.
1822bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  if (Base.isReg()) {
1823bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    const MachineOperand &Offset = MI.getOperand(OpIdx);
1824bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    if (unsigned ImmOffs = ARM_AM::getAM5Offset(Offset.getImm())) {
1825bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng      if (ARM_AM::getAM5Op(Offset.getImm()) == ARM_AM::add)
1826bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng        Binary |= 1 << ARMII::U_BitShift;
1827517b3e868e9ad48ac2905dbb52d731962abcbca9Evan Cheng      Binary |= ImmOffs;
1828bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng      emitWordLE(Binary);
1829bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng      return;
1830bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    }
1831bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  }
1832bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1833bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // If immediate offset is omitted, default to +0.
1834bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  Binary |= 1 << ARMII::U_BitShift;
1835bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1836bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  emitWordLE(Binary);
1837bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng}
1838bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1839164fe923dac9b977ab0e3d923978cf0ba875d959Bob Wilsonvoid
1840164fe923dac9b977ab0e3d923978cf0ba875d959Bob WilsonARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI) {
1841e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
1842e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  bool IsUpdating = (MCID.TSFlags & ARMII::IndexModeMask) != 0;
1843b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson
1844bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Part of binary is determined by TableGn.
1845bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  unsigned Binary = getBinaryCodeForInstr(MI);
1846bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1847bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Set the conditional execution predicate
1848bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
1849bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1850b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  // Skip operand 0 of an instruction with base register update.
1851b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  unsigned OpIdx = 0;
1852b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  if (IsUpdating)
1853b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson    ++OpIdx;
1854b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson
1855bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Set base address operand
1856b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
1857bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1858bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Set addressing mode by modifying bits U(23) and P(24)
18592567eec4233d58a2a0cbdcafca9420452689b395Bill Wendling  ARM_AM::AMSubMode Mode = ARM_AM::getLoadStoreMultipleSubMode(MI.getOpcode());
18602567eec4233d58a2a0cbdcafca9420452689b395Bill Wendling  Binary |= getAddrModeUPBits(ARM_AM::getAM4SubMode(Mode));
1861bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1862bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // Set bit W(21)
1863a256a75c0333dcbac0e119dad233782527db513cBob Wilson  if (IsUpdating)
1864bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    Binary |= 0x1 << ARMII::W_BitShift;
1865bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1866bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  // First register is encoded in Dd.
1867b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  Binary |= encodeVFPRd(MI, OpIdx+2);
1868bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
18691e68cc1f1f9540f01e2aad5eb0c2a8710ca4a054Bob Wilson  // Count the number of registers.
1870bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  unsigned NumRegs = 1;
1871b9ee99d999a51b1d9869853cba4b69e0b5b95e54Bob Wilson  for (unsigned i = OpIdx+3, e = MI.getNumOperands(); i != e; ++i) {
1872bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    const MachineOperand &MO = MI.getOperand(i);
1873bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    if (!MO.isReg() || MO.isImplicit())
1874bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng      break;
1875bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng    ++NumRegs;
1876bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  }
1877521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao  // Bit 8 will be set if <list> is consecutive 64-bit registers (e.g., D0)
1878521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao  // Otherwise, it will be 0, in the case of 32-bit registers.
1879521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao  if(Binary & 0x100)
1880521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao    Binary |= NumRegs * 2;
1881521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao  else
1882521a8d4fa73593c22976fc4ad509d46840ef512bShih-wei Liao    Binary |= NumRegs;
1883bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1884bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng  emitWordLE(Binary);
1885bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng}
1886bb786b31491ed3cf69247d29cd2d42afa75dc54aEvan Cheng
1887facbbb139d11a2c238a98a19574ff14b9069ec29jushvoid ARMCodeEmitter::emitMiscInstruction(const MachineInstr &MI) {
1888facbbb139d11a2c238a98a19574ff14b9069ec29jush  unsigned Opcode = MI.getDesc().Opcode;
1889facbbb139d11a2c238a98a19574ff14b9069ec29jush  // Part of binary is determined by TableGn.
1890facbbb139d11a2c238a98a19574ff14b9069ec29jush  unsigned Binary = getBinaryCodeForInstr(MI);
1891facbbb139d11a2c238a98a19574ff14b9069ec29jush
1892aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao  if (Opcode == ARM::FCONSTS) {
1893aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao    unsigned Imm = getMachineOpValue(MI, 1);
1894aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao    Binary &= ~(0x780000 >> 19);
1895aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao    Binary |= (Imm & 0x780000) >> 19;
1896aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao    Binary &= ~(0x3800000 >> 7);
1897aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao    Binary |= (Imm & 0x3800000) >> 7;
1898aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao    Binary = VFPThumb2PostEncoder(MI, Binary);
1899aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao  }
1900aa9bc19930f66ade30857fa50617f1e70952f8dbShih-wei Liao
1901facbbb139d11a2c238a98a19574ff14b9069ec29jush  // Set the conditional execution predicate
1902facbbb139d11a2c238a98a19574ff14b9069ec29jush  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
1903facbbb139d11a2c238a98a19574ff14b9069ec29jush
1904facbbb139d11a2c238a98a19574ff14b9069ec29jush  emitWordLE(Binary);
1905facbbb139d11a2c238a98a19574ff14b9069ec29jush}
1906facbbb139d11a2c238a98a19574ff14b9069ec29jush
1907df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopherunsigned ARMCodeEmitter::encodeNEONRd(const MachineInstr &MI,
1908df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher                                      unsigned OpIdx) const {
190973e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  unsigned RegD = MI.getOperand(OpIdx).getReg();
191073e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  unsigned Binary = 0;
1911df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  RegD = II->getRegisterInfo().getEncodingValue(RegD);
191273e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  Binary |= (RegD & 0xf) << ARMII::RegRdShift;
191373e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  Binary |= ((RegD >> 4) & 1) << ARMII::D_BitShift;
191473e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  return Binary;
191573e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson}
191673e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson
1917df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopherunsigned ARMCodeEmitter::encodeNEONRn(const MachineInstr &MI,
1918df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher                                      unsigned OpIdx) const {
1919383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  unsigned RegN = MI.getOperand(OpIdx).getReg();
1920383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  unsigned Binary = 0;
1921df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  RegN = II->getRegisterInfo().getEncodingValue(RegN);
1922383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  Binary |= (RegN & 0xf) << ARMII::RegRnShift;
1923383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  Binary |= ((RegN >> 4) & 1) << ARMII::N_BitShift;
1924383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  return Binary;
1925383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson}
1926383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson
1927df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopherunsigned ARMCodeEmitter::encodeNEONRm(const MachineInstr &MI,
1928df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher                                      unsigned OpIdx) const {
1929f1672483d8ff3d19e647cc959edefc853902012dBob Wilson  unsigned RegM = MI.getOperand(OpIdx).getReg();
1930f1672483d8ff3d19e647cc959edefc853902012dBob Wilson  unsigned Binary = 0;
1931df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  RegM = II->getRegisterInfo().getEncodingValue(RegM);
1932f1672483d8ff3d19e647cc959edefc853902012dBob Wilson  Binary |= (RegM & 0xf);
1933f1672483d8ff3d19e647cc959edefc853902012dBob Wilson  Binary |= ((RegM >> 4) & 1) << ARMII::M_BitShift;
1934f1672483d8ff3d19e647cc959edefc853902012dBob Wilson  return Binary;
1935f1672483d8ff3d19e647cc959edefc853902012dBob Wilson}
1936f1672483d8ff3d19e647cc959edefc853902012dBob Wilson
193786bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson/// convertNEONDataProcToThumb - Convert the ARM mode encoding for a NEON
193886bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson/// data-processing instruction to the corresponding Thumb encoding.
193986bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilsonstatic unsigned convertNEONDataProcToThumb(unsigned Binary) {
194086bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson  assert((Binary & 0xfe000000) == 0xf2000000 &&
194186bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson         "not an ARM NEON data-processing instruction");
194286bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson  unsigned UBit = (Binary >> 24) & 1;
194386bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson  return 0xef000000 | (UBit << 28) | (Binary & 0xffffff);
194486bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson}
194586bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson
1946bdd93b262fd7700fa141f937925842b901e8d382Bob Wilsonvoid ARMCodeEmitter::emitNEONLaneInstruction(const MachineInstr &MI) {
19474c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  unsigned Binary = getBinaryCodeForInstr(MI);
19484c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson
1949bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson  unsigned RegTOpIdx, RegNOpIdx, LnOpIdx;
1950e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
1951e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if ((MCID.TSFlags & ARMII::FormMask) == ARMII::NGetLnFrm) {
1952bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson    RegTOpIdx = 0;
1953bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson    RegNOpIdx = 1;
1954bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson    LnOpIdx = 2;
1955bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson  } else { // ARMII::NSetLnFrm
1956bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson    RegTOpIdx = 2;
1957bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson    RegNOpIdx = 0;
1958bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson    LnOpIdx = 3;
1959bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson  }
1960bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson
19614c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  // Set the conditional execution predicate
1962113efc8485d586656ff7c7966e35dc34ea982dabBob Wilson  Binary |= (IsThumb ? ARMCC::AL : II->getPredicate(&MI)) << ARMII::CondShift;
19634c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson
1964bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson  unsigned RegT = MI.getOperand(RegTOpIdx).getReg();
1965df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  RegT = II->getRegisterInfo().getEncodingValue(RegT);
19664c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  Binary |= (RegT << ARMII::RegRdShift);
1967bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson  Binary |= encodeNEONRn(MI, RegNOpIdx);
19684c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson
19694c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  unsigned LaneShift;
19704c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  if ((Binary & (1 << 22)) != 0)
19714c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson    LaneShift = 0; // 8-bit elements
19724c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  else if ((Binary & (1 << 5)) != 0)
19734c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson    LaneShift = 1; // 16-bit elements
19744c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  else
19754c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson    LaneShift = 2; // 32-bit elements
19764c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson
1977bdd93b262fd7700fa141f937925842b901e8d382Bob Wilson  unsigned Lane = MI.getOperand(LnOpIdx).getImm() << LaneShift;
19784c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  unsigned Opc1 = Lane >> 2;
19794c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  unsigned Opc2 = Lane & 3;
19804c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  assert((Opc1 & 3) == 0 && "out-of-range lane number operand");
19814c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  Binary |= (Opc1 << 21);
19824c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  Binary |= (Opc2 << 5);
19834c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson
19844c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson  emitWordLE(Binary);
19854c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson}
19864c5c79d288a17ed7be2d8e9155188a3d26a8515dBob Wilson
1987ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilsonvoid ARMCodeEmitter::emitNEONDupInstruction(const MachineInstr &MI) {
1988ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson  unsigned Binary = getBinaryCodeForInstr(MI);
1989ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson
1990ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson  // Set the conditional execution predicate
1991ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson  Binary |= (IsThumb ? ARMCC::AL : II->getPredicate(&MI)) << ARMII::CondShift;
1992ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson
1993ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson  unsigned RegT = MI.getOperand(1).getReg();
1994df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher  RegT = II->getRegisterInfo().getEncodingValue(RegT);
1995ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson  Binary |= (RegT << ARMII::RegRdShift);
1996ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson  Binary |= encodeNEONRn(MI, 0);
1997ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson  emitWordLE(Binary);
1998ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson}
1999ffdc17bec626bae590717b8af59e4ba1de216bb4Bob Wilson
2000f1672483d8ff3d19e647cc959edefc853902012dBob Wilsonvoid ARMCodeEmitter::emitNEON1RegModImmInstruction(const MachineInstr &MI) {
200173e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  unsigned Binary = getBinaryCodeForInstr(MI);
200273e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  // Destination register is encoded in Dd.
200373e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  Binary |= encodeNEONRd(MI, 0);
200473e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  // Immediate fields: Op, Cmode, I, Imm3, Imm4
200573e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  unsigned Imm = MI.getOperand(1).getImm();
200673e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  unsigned Op = (Imm >> 12) & 1;
200773e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  unsigned Cmode = (Imm >> 8) & 0xf;
200873e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  unsigned I = (Imm >> 7) & 1;
200973e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  unsigned Imm3 = (Imm >> 4) & 0x7;
201073e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  unsigned Imm4 = Imm & 0xf;
2011f48bd3b93d62085766f1ec01e8a2243f68ebe0ceBob Wilson  Binary |= (I << 24) | (Imm3 << 16) | (Cmode << 8) | (Op << 5) | Imm4;
2012b9103199ac28a1462150439f024e615b36bef093Bob Wilson  if (IsThumb)
201386bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson    Binary = convertNEONDataProcToThumb(Binary);
201473e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson  emitWordLE(Binary);
201573e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson}
201673e9f2e91b86c25a1b908e7dc9a65c2d84339e81Bob Wilson
2017f1672483d8ff3d19e647cc959edefc853902012dBob Wilsonvoid ARMCodeEmitter::emitNEON2RegInstruction(const MachineInstr &MI) {
2018e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
2019f1672483d8ff3d19e647cc959edefc853902012dBob Wilson  unsigned Binary = getBinaryCodeForInstr(MI);
2020383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  // Destination register is encoded in Dd; source register in Dm.
2021383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  unsigned OpIdx = 0;
2022383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  Binary |= encodeNEONRd(MI, OpIdx++);
2023e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
2024383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson    ++OpIdx;
2025383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  Binary |= encodeNEONRm(MI, OpIdx);
2026b9103199ac28a1462150439f024e615b36bef093Bob Wilson  if (IsThumb)
202786bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson    Binary = convertNEONDataProcToThumb(Binary);
2028f1672483d8ff3d19e647cc959edefc853902012dBob Wilson  // FIXME: This does not handle VDUPfdf or VDUPfqf.
2029f1672483d8ff3d19e647cc959edefc853902012dBob Wilson  emitWordLE(Binary);
2030f1672483d8ff3d19e647cc959edefc853902012dBob Wilson}
2031f1672483d8ff3d19e647cc959edefc853902012dBob Wilson
2032383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilsonvoid ARMCodeEmitter::emitNEON3RegInstruction(const MachineInstr &MI) {
2033e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI.getDesc();
2034383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  unsigned Binary = getBinaryCodeForInstr(MI);
2035383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  // Destination register is encoded in Dd; source registers in Dn and Dm.
2036383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  unsigned OpIdx = 0;
2037383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  Binary |= encodeNEONRd(MI, OpIdx++);
2038e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
2039383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson    ++OpIdx;
2040383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  Binary |= encodeNEONRn(MI, OpIdx++);
2041e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
2042383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson    ++OpIdx;
2043383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  Binary |= encodeNEONRm(MI, OpIdx);
2044b9103199ac28a1462150439f024e615b36bef093Bob Wilson  if (IsThumb)
204586bd22b53945cda14f934591a587a2dd80dfcbe7Bob Wilson    Binary = convertNEONDataProcToThumb(Binary);
2046383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  // FIXME: This does not handle VMOVDneon or VMOVQ.
2047383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson  emitWordLE(Binary);
2048383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson}
2049383e846e3abbfb4e09bd7e020a9d46c424755e34Bob Wilson
2050efc43652ace14e19983914ef145d205e1fd45e00Evan Cheng#include "ARMGenCodeEmitter.inc"
2051