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