ARMCodeEmitter.cpp revision 2c6014b7beb12b2eb1f2487d3b52ebea13b7f58e
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===-- ARM/ARMCodeEmitter.cpp - Convert ARM code to machine code ---------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file contains the pass that transforms the ARM machine instructions into 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// relocatable machine code. 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define DEBUG_TYPE "jit" 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "ARM.h" 172e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor#include "ARMAddressingModes.h" 18e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek#include "ARMConstantPoolValue.h" 19ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#include "ARMInstrInfo.h" 20fe6b2d481d91140923f4541f273b253291884214Douglas Gregor#include "ARMRelocations.h" 21ad75653f81dece1c806e9c28dd7e7582c9929a27Ted Kremenek#include "ARMSubtarget.h" 22ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor#include "ARMTargetMachine.h" 23d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor#include "llvm/Constants.h" 247532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor#include "llvm/DerivedTypes.h" 25464175bba1318bef7905122e9fda20cff926df78Chris Lattner#include "llvm/Function.h" 2650d62d1b4a98adbc83de8f8cd1379ea1c25656f7Douglas Gregor#include "llvm/PassManager.h" 27046861b912ed72bdc364d7905180ee63e5b08870Anders Carlsson#include "llvm/CodeGen/MachineCodeEmitter.h" 28464175bba1318bef7905122e9fda20cff926df78Chris Lattner#include "llvm/CodeGen/JITCodeEmitter.h" 2968d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff#include "llvm/CodeGen/ObjectCodeEmitter.h" 302cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "llvm/CodeGen/MachineConstantPool.h" 31432a8893f7e30d141d7f279bd00b741a3cdac81fFariborz Jahanian#include "llvm/CodeGen/MachineFunctionPass.h" 326c2b6eb8d836da19007f7540709e16d5e39a1cbaChris Lattner#include "llvm/CodeGen/MachineInstr.h" 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/CodeGen/MachineJumpTableInfo.h" 345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/CodeGen/Passes.h" 35b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner#include "llvm/ADT/Statistic.h" 36b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner#include "llvm/Support/Compiler.h" 37bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/Support/Debug.h" 38b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner#include "llvm/Support/ErrorHandling.h" 39b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner#include "llvm/Support/raw_ostream.h" 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef NDEBUG 41a9376d470ccb0eac74fe09a6b2a18a890f1d17c4Chris Lattner#include <iomanip> 42e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar#endif 435e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnallusing namespace llvm; 44bdc601b196c48d4cd56a5ceb45d41ae4e87371abKen Dyck 45aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas GregorSTATISTIC(NumEmitted, "Number of machine instructions emitted"); 46e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar 472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregornamespace { 487b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis 49c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner class ARMCodeEmitter { 50e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar public: 51e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar /// getBinaryCodeForInstr - This function, generated by the 52d934112e6170b0fd940d8e40db6936cea2cdcf62Douglas Gregor /// CodeEmitterGenerator using TableGen, produces the binary encoding for 53071cc7deffad608165b1ddd5263e8bf181861520Charles Davis /// machine instructions. 54e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar unsigned getBinaryCodeForInstr(const MachineInstr &MI); 553478eb6872d836600caf45b0f81c2065d685d6e0Ted Kremenek }; 56f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 57f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson template<class CodeEmitter> 58e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar class VISIBILITY_HIDDEN Emitter : public MachineFunctionPass, 590d8df780aef1acda5962347a32591efc629b6748Anders Carlsson public ARMCodeEmitter { 6014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne ARMJITInfo *JTI; 610d8df780aef1acda5962347a32591efc629b6748Anders Carlsson const ARMInstrInfo *II; 620d8df780aef1acda5962347a32591efc629b6748Anders Carlsson const TargetData *TD; 63c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar TargetMachine &TM; 64e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar CodeEmitter &MCE; 650c01d18094100db92d38daa923c95661512db203John McCall const std::vector<MachineConstantPoolEntry> *MCPEs; 66e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar const std::vector<MachineJumpTableEntry> *MJTEs; 673e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor bool IsPIC; 680d8df780aef1acda5962347a32591efc629b6748Anders Carlsson 69e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar public: 70e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar static char ID; 71e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar explicit Emitter(TargetMachine &tm, CodeEmitter &mce) 720d8df780aef1acda5962347a32591efc629b6748Anders Carlsson : MachineFunctionPass(&ID), JTI(0), II(0), TD(0), TM(tm), 73ed97649e9574b9d854fa4d6109c9333ae0993554John McCall MCE(mce), MCPEs(0), MJTEs(0), 74eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall IsPIC(TM.getRelocationModel() == Reloc::PIC_) {} 751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Emitter(TargetMachine &tm, CodeEmitter &mce, 761b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner const ARMInstrInfo &ii, const TargetData &td) 771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump : MachineFunctionPass(&ID), JTI(0), II(&ii), TD(&td), TM(tm), 785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer MCE(mce), MCPEs(0), MJTEs(0), 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IsPIC(TM.getRelocationModel() == Reloc::PIC_) {} 801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 81ef99001908e799c388f1363b1e607dad5f5b57d3John McCall bool runOnMachineFunction(MachineFunction &MF); 82ef99001908e799c388f1363b1e607dad5f5b57d3John McCall 834ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad virtual const char *getPassName() const { 844ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad return "ARM Machine Code Emitter"; 854ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad } 864ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 874ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitInstruction(const MachineInstr &MI); 884ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 894ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad private: 904ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 914ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitWordLE(unsigned Binary); 924ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 934ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitDWordLE(uint64_t Binary); 944ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 954ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitConstPoolInstruction(const MachineInstr &MI); 964ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 974ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitMOVi2piecesInstruction(const MachineInstr &MI); 984ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 994ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitLEApcrelJTInstruction(const MachineInstr &MI); 1004ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1014ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitPseudoMoveInstruction(const MachineInstr &MI); 1024ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1034ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void addPCLabel(unsigned LabelID); 1044ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 105c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor void emitPseudoInstruction(const MachineInstr &MI); 106c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor 1074ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned getMachineSoRegOpValue(const MachineInstr &MI, 108ef99001908e799c388f1363b1e607dad5f5b57d3John McCall const TargetInstrDesc &TID, 1094ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const MachineOperand &MO, 1104ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned OpIdx); 1114ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1124ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned getMachineSoImmOpValue(unsigned SoImm); 1134ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 11433500955d731c73717af52088b7fc0e7a85681e7John McCall unsigned getAddrModeSBit(const MachineInstr &MI, 1157536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor const TargetInstrDesc &TID) const; 1164ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1174ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitDataProcessingInstruction(const MachineInstr &MI, 1189d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall unsigned ImplicitRd = 0, 1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned ImplicitRn = 0); 1204ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1214ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitLoadStoreInstruction(const MachineInstr &MI, 1221aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor unsigned ImplicitRd = 0, 1231aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor unsigned ImplicitRn = 0); 1241aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor 125ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor void emitMiscLoadStoreInstruction(const MachineInstr &MI, 126ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor unsigned ImplicitRn = 0); 127ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor 1284ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitLoadStoreMultipleInstruction(const MachineInstr &MI); 1294ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 130ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor void emitMulFrmInstruction(const MachineInstr &MI); 131ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor 13288a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel void emitExtendInstruction(const MachineInstr &MI); 133a9a4a24592a2164114a8a36717650e6341eb67a4Ted Kremenek 1344ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitMiscArithInstruction(const MachineInstr &MI); 1354ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1364ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitBranchInstruction(const MachineInstr &MI); 1374ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 138f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman void emitInlineJumpTable(unsigned JTIndex); 139f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 140f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson void emitMiscBranchInstruction(const MachineInstr &MI); 141f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 1428a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis void emitVFPArithInstruction(const MachineInstr &MI); 1438a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis 1448a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis void emitVFPConversionInstruction(const MachineInstr &MI); 1451ceee5c42d5c410217f67d384eecc6ea4a2bba9bFariborz Jahanian 146830937bc1100fba7682f7c32c40512085870f50cFariborz Jahanian void emitVFPLoadStoreInstruction(const MachineInstr &MI); 1471ceee5c42d5c410217f67d384eecc6ea4a2bba9bFariborz Jahanian 1483e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor void emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI); 1493e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor 1503e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor void emitMiscInstruction(const MachineInstr &MI); 1513e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor 1523e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor /// getMachineOpValue - Return binary encoding of operand. If the machine 1533e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor /// operand requires relocation, record the relocation and return zero. 1543e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor unsigned getMachineOpValue(const MachineInstr &MI,const MachineOperand &MO); 1553e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor unsigned getMachineOpValue(const MachineInstr &MI, unsigned OpIdx) { 1563e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor return getMachineOpValue(MI, MI.getOperand(OpIdx)); 1573e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor } 1583e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor 1593e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. 1603e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor /// 1613e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor unsigned getShiftOp(unsigned Imm) const ; 1623e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor 1633e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor /// Routines that handle operands which add machine relocations which are 1644ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad /// fixed up by the relocation stage. 1654ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitGlobalAddress(GlobalValue *GV, unsigned Reloc, 1663e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor bool NeedStub, intptr_t ACPV = 0); 1674ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitExternalSymbolAddress(const char *ES, unsigned Reloc); 1684ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void emitConstPoolAddress(unsigned CPI, unsigned Reloc); 169006113841bdae1edb77aef75ba1ffdf2e55a3094Argyrios Kyrtzidis void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc); 170006113841bdae1edb77aef75ba1ffdf2e55a3094Argyrios Kyrtzidis void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc, 171006113841bdae1edb77aef75ba1ffdf2e55a3094Argyrios Kyrtzidis intptr_t JTBase = 0); 172006113841bdae1edb77aef75ba1ffdf2e55a3094Argyrios Kyrtzidis }; 173b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson template <class CodeEmitter> 174b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson char Emitter<CodeEmitter>::ID = 0; 175b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson} 176b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson 177d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff/// createARMCodeEmitterPass - Return a pass that emits the collected ARM code 1786083ea3723ec3996ae3bdf8d1b352b0c3b3922c8Ted Kremenek/// to the specified MCE object. 179de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff 1801eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpFunctionPass *llvm::createARMCodeEmitterPass(ARMBaseTargetMachine &TM, 1816083ea3723ec3996ae3bdf8d1b352b0c3b3922c8Ted Kremenek MachineCodeEmitter &MCE) { 18213dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian return new Emitter<MachineCodeEmitter>(TM, MCE); 1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 1846083ea3723ec3996ae3bdf8d1b352b0c3b3922c8Ted KremenekFunctionPass *llvm::createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM, 185a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek JITCodeEmitter &JCE) { 186390d50a725497e99247dc104a7d2c2a255d3af14Fariborz Jahanian return new Emitter<JITCodeEmitter>(TM, JCE); 1878baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson} 1886083ea3723ec3996ae3bdf8d1b352b0c3b3922c8Ted KremenekFunctionPass *llvm::createARMObjectCodeEmitterPass(ARMBaseTargetMachine &TM, 189de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff ObjectCodeEmitter &OCE) { 1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return new Emitter<ObjectCodeEmitter>(TM, OCE); 191a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek} 1924ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1937a9d49fd2bfac00e905b361ba76d26ab5b6c3b09Ted Kremenektemplate<class CodeEmitter> 1944ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) { 1952bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian assert((MF.getTarget().getRelocationModel() != Reloc::Default || 1964ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad MF.getTarget().getRelocationModel() != Reloc::Static) && 1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump "JIT relocation model must be set to static or default!"); 198c29f77b769bcc5b6dc85e72c8e3cc2e348e5cf25Douglas Gregor II = ((ARMTargetMachine&)MF.getTarget()).getInstrInfo(); 199c29f77b769bcc5b6dc85e72c8e3cc2e348e5cf25Douglas Gregor TD = ((ARMTargetMachine&)MF.getTarget()).getTargetData(); 2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump JTI = ((ARMTargetMachine&)MF.getTarget()).getJITInfo(); 2018fad9941a635a42ee644e7396ca84cbaaa5c1b6eMike Stump MCPEs = &MF.getConstantPool()->getConstants(); 202782fa308a765aeac2acb39c4e697c937ec21185bMike Stump MJTEs = &MF.getJumpTableInfo()->getJumpTables(); 2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IsPIC = TM.getRelocationModel() == Reloc::PIC_; 2048fad9941a635a42ee644e7396ca84cbaaa5c1b6eMike Stump JTI->Initialize(MF, IsPIC); 205782fa308a765aeac2acb39c4e697c937ec21185bMike Stump 2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump do { 207adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump DEBUG(errs() << "JITTing function '" 2084ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad << MF.getFunction()->getName() << "'\n"); 209adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump MCE.startFunction(MF); 210083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 2114ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad MBB != E; ++MBB) { 212083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump MCE.StartMachineBasicBlock(MBB); 213bf1a028246d884a540aeafa38e89be59a269b072John McCall for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); 214bf1a028246d884a540aeafa38e89be59a269b072John McCall I != E; ++I) 2151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump emitInstruction(*I); 21668584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor } 21768584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor } while (MCE.finishFunction(MF)); 21868584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor 2196320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor return false; 2202455636163fdd18581d7fdae816433f886d88213Mike Stump} 2217caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor 2227caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value. 2237caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor/// 2247caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregortemplate<class CodeEmitter> 2257caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregorunsigned Emitter<CodeEmitter>::getShiftOp(unsigned Imm) const { 226251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor switch (ARM_AM::getAM2ShiftOpc(Imm)) { 227251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor default: llvm_unreachable("Unknown shift opc!"); 2287caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor case ARM_AM::asr: return 2; 2297caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor case ARM_AM::lsl: return 0; 2307caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor case ARM_AM::lsr: return 1; 2317caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor case ARM_AM::ror: 2327caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor case ARM_AM::rrx: return 3; 2337caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor } 2347caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor return 0; 2357caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor} 2367caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor 2377caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor/// getMachineOpValue - Return binary encoding of operand. If the machine 2387caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor/// operand requires relocation, record the relocation and return zero. 2397caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregortemplate<class CodeEmitter> 2407caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregorunsigned Emitter<CodeEmitter>::getMachineOpValue(const MachineInstr &MI, 2417caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor const MachineOperand &MO) { 2427caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor if (MO.isReg()) 2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return ARMRegisterInfo::getRegisterNumbering(MO.getReg()); 2447caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor else if (MO.isImm()) 245251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor return static_cast<unsigned>(MO.getImm()); 246663b5a0be7261c29bc4c526a71cffcfa02d4153eDouglas Gregor else if (MO.isGlobal()) 247251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true); 2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump else if (MO.isSymbol()) 249ed97649e9574b9d854fa4d6109c9333ae0993554John McCall emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_branch); 250ed97649e9574b9d854fa4d6109c9333ae0993554John McCall else if (MO.isCPI()) { 251ed97649e9574b9d854fa4d6109c9333ae0993554John McCall const TargetInstrDesc &TID = MI.getDesc(); 252ed97649e9574b9d854fa4d6109c9333ae0993554John McCall // For VFP load, the immediate offset is multiplied by 4. 2530d8df780aef1acda5962347a32591efc629b6748Anders Carlsson unsigned Reloc = ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPLdStFrm) 2540d8df780aef1acda5962347a32591efc629b6748Anders Carlsson ? ARM::reloc_arm_vfp_cp_entry : ARM::reloc_arm_cp_entry; 2550d8df780aef1acda5962347a32591efc629b6748Anders Carlsson emitConstPoolAddress(MO.getIndex(), Reloc); 2560d8df780aef1acda5962347a32591efc629b6748Anders Carlsson } else if (MO.isJTI()) 2570d8df780aef1acda5962347a32591efc629b6748Anders Carlsson emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative); 2580d8df780aef1acda5962347a32591efc629b6748Anders Carlsson else if (MO.isMBB()) 2590d8df780aef1acda5962347a32591efc629b6748Anders Carlsson emitMachineBasicBlock(MO.getMBB(), ARM::reloc_arm_branch); 2600d8df780aef1acda5962347a32591efc629b6748Anders Carlsson else { 2610d8df780aef1acda5962347a32591efc629b6748Anders Carlsson#ifndef NDEBUG 2620d8df780aef1acda5962347a32591efc629b6748Anders Carlsson errs() << MO; 2630d8df780aef1acda5962347a32591efc629b6748Anders Carlsson#endif 2640d8df780aef1acda5962347a32591efc629b6748Anders Carlsson llvm_unreachable(0); 2650d8df780aef1acda5962347a32591efc629b6748Anders Carlsson } 2660d8df780aef1acda5962347a32591efc629b6748Anders Carlsson return 0; 2670d8df780aef1acda5962347a32591efc629b6748Anders Carlsson} 2680d8df780aef1acda5962347a32591efc629b6748Anders Carlsson 2690d8df780aef1acda5962347a32591efc629b6748Anders Carlsson/// emitGlobalAddress - Emit the specified address to the code stream. 2700d8df780aef1acda5962347a32591efc629b6748Anders Carlsson/// 271ed97649e9574b9d854fa4d6109c9333ae0993554John McCalltemplate<class CodeEmitter> 272ed97649e9574b9d854fa4d6109c9333ae0993554John McCallvoid Emitter<CodeEmitter>::emitGlobalAddress(GlobalValue *GV, unsigned Reloc, 273ed97649e9574b9d854fa4d6109c9333ae0993554John McCall bool NeedStub, intptr_t ACPV) { 274ed97649e9574b9d854fa4d6109c9333ae0993554John McCall MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, 2751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump GV, ACPV, NeedStub)); 276d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson} 2771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2787d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor/// emitExternalSymbolAddress - Arrange for the address of an external symbol to 2797d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor/// be emitted to the current location in the function, and allow it to be PC 2807d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor/// relative. 2817d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregortemplate<class CodeEmitter> 2827d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregorvoid Emitter<CodeEmitter>::emitExternalSymbolAddress(const char *ES, 2837d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor unsigned Reloc) { 284046861b912ed72bdc364d7905180ee63e5b08870Anders Carlsson MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 2857d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor Reloc, ES)); 2867d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor} 287ef177820100ab583b08fd3056e2a5a52ee4b1629Argyrios Kyrtzidis 288ef177820100ab583b08fd3056e2a5a52ee4b1629Argyrios Kyrtzidis/// emitConstPoolAddress - Arrange for the address of an constant pool 289e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek/// to be emitted to the current location in the function, and allow it to be PC 290b800dc2d5e27ec60f567567b623cdc61152b8fb8Chris Lattner/// relative. 2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate<class CodeEmitter> 292e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenekvoid Emitter<CodeEmitter>::emitConstPoolAddress(unsigned CPI, 293e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek unsigned Reloc) { 294e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek // Tell JIT emitter we'll resolve the address. 295e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 29663fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor Reloc, CPI, 0, true)); 29763fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor} 29863fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor 29963fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor/// emitJumpTableAddress - Arrange for the address of a jump table to 3004ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad/// be emitted to the current location in the function, and allow it to be PC 3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// relative. 302fe6b2d481d91140923f4541f273b253291884214Douglas Gregortemplate<class CodeEmitter> 303fe6b2d481d91140923f4541f273b253291884214Douglas Gregorvoid Emitter<CodeEmitter>::emitJumpTableAddress(unsigned JTIndex, 304071cc7deffad608165b1ddd5263e8bf181861520Charles Davis unsigned Reloc) { 305071cc7deffad608165b1ddd5263e8bf181861520Charles Davis MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), 306ff75dfde6a351c57f41366d309c0bd11aba69bceArgyrios Kyrtzidis Reloc, JTIndex, 0, true)); 307071cc7deffad608165b1ddd5263e8bf181861520Charles Davis} 30836d2fd44bfeec417bbd7465218353abb8bf7e95dArgyrios Kyrtzidis 30936d2fd44bfeec417bbd7465218353abb8bf7e95dArgyrios Kyrtzidis/// emitMachineBasicBlock - Emit the specified address basic block. 31036d2fd44bfeec417bbd7465218353abb8bf7e95dArgyrios Kyrtzidistemplate<class CodeEmitter> 3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Emitter<CodeEmitter>::emitMachineBasicBlock(MachineBasicBlock *BB, 312444be7366d0a1e172c0290a1ea54c1cb16b5947cDaniel Dunbar unsigned Reloc, intptr_t JTBase) { 31371993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), 31429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff Reloc, BB, JTBase)); 3151b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner} 3164ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 3172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregortemplate<class CodeEmitter> 3187b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidisvoid Emitter<CodeEmitter>::emitWordLE(unsigned Binary) { 319d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor DEBUG(errs() << " 0x"; 3202e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor errs().write_hex(Binary) << "\n"); 3210f436560640a1cff5b6d96f80f540770f139453fDavid Chisnall MCE.emitWordLE(Binary); 3220f436560640a1cff5b6d96f80f540770f139453fDavid Chisnall} 3230f436560640a1cff5b6d96f80f540770f139453fDavid Chisnall 3240f436560640a1cff5b6d96f80f540770f139453fDavid Chisnalltemplate<class CodeEmitter> 325369a3bd9979cf529eed529aa037de713c213e47dFariborz Jahanianvoid Emitter<CodeEmitter>::emitDWordLE(uint64_t Binary) { 3260f436560640a1cff5b6d96f80f540770f139453fDavid Chisnall DEBUG(errs() << " 0x"; 3277a9d49fd2bfac00e905b361ba76d26ab5b6c3b09Ted Kremenek errs().write_hex(Binary) << "\n"); 328a9376d470ccb0eac74fe09a6b2a18a890f1d17c4Chris Lattner MCE.emitDWordLE(Binary); 3294ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad} 33063fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor 331c0ac4923f08b25ae973a8ee7942cf3eb89da57b7Steve Narofftemplate<class CodeEmitter> 3324ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadvoid Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI) { 333fe6b2d481d91140923f4541f273b253291884214Douglas Gregor DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI); 334fe6b2d481d91140923f4541f273b253291884214Douglas Gregor 335fe6b2d481d91140923f4541f273b253291884214Douglas Gregor MCE.processDebugLoc(MI.getDebugLoc()); 336fe6b2d481d91140923f4541f273b253291884214Douglas Gregor 337fe6b2d481d91140923f4541f273b253291884214Douglas Gregor NumEmitted++; // Keep track of the # of mi's emitted 338e7d07d113677a39026ff5119b8b67f6fe8ca9793Ted Kremenek switch (MI.getDesc().TSFlags & ARMII::FormMask) { 3391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump default: { 34078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis llvm_unreachable("Unhandled instruction encoding format!"); 34178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis break; 3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 3439c728dc4d8da89c73fcae74c9e72d7a83ffd7b6dTed Kremenek case ARMII::Pseudo: 3449c728dc4d8da89c73fcae74c9e72d7a83ffd7b6dTed Kremenek emitPseudoInstruction(MI); 345ef177820100ab583b08fd3056e2a5a52ee4b1629Argyrios Kyrtzidis break; 34668584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor case ARMII::DPFrm: 3476320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor case ARMII::DPSoRegFrm: 3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump emitDataProcessingInstruction(MI); 34968584ed35ad819a1668e3f527ba7f5dd4ae6a333Douglas Gregor break; 3506320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor case ARMII::LdFrm: 3512455636163fdd18581d7fdae816433f886d88213Mike Stump case ARMII::StFrm: 3527caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor emitLoadStoreInstruction(MI); 3531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 3547caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor case ARMII::LdMiscFrm: 355663b5a0be7261c29bc4c526a71cffcfa02d4153eDouglas Gregor case ARMII::StMiscFrm: 356663b5a0be7261c29bc4c526a71cffcfa02d4153eDouglas Gregor emitMiscLoadStoreInstruction(MI); 3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 3587caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor case ARMII::LdStMulFrm: 3597caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor emitLoadStoreMultipleInstruction(MI); 360251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor break; 3619421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis case ARMII::MulFrm: 3629421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis emitMulFrmInstruction(MI); 3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 364ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case ARMII::ExtFrm: 365ed97649e9574b9d854fa4d6109c9333ae0993554John McCall emitExtendInstruction(MI); 366d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson break; 367ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case ARMII::ArithMiscFrm: 368d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson emitMiscArithInstruction(MI); 369ed97649e9574b9d854fa4d6109c9333ae0993554John McCall break; 370ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case ARMII::BrFrm: 371ed97649e9574b9d854fa4d6109c9333ae0993554John McCall emitBranchInstruction(MI); 3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 373ed97649e9574b9d854fa4d6109c9333ae0993554John McCall case ARMII::BrMiscFrm: 374ed97649e9574b9d854fa4d6109c9333ae0993554John McCall emitMiscBranchInstruction(MI); 375ed97649e9574b9d854fa4d6109c9333ae0993554John McCall break; 3761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // VFP instructions. 377d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson case ARMII::VFPUnaryFrm: 3781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case ARMII::VFPBinaryFrm: 379d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson emitVFPArithInstruction(MI); 3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 3817d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor case ARMII::VFPConv1Frm: 3827d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor case ARMII::VFPConv2Frm: 3837d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor case ARMII::VFPConv3Frm: 3847d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor case ARMII::VFPConv4Frm: 3857d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor case ARMII::VFPConv5Frm: 3867d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor emitVFPConversionInstruction(MI); 3877d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor break; 3887d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor case ARMII::VFPLdStFrm: 389c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis emitVFPLoadStoreInstruction(MI); 390c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis break; 3917d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor case ARMII::VFPLdStMulFrm: 3927d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor emitVFPLoadStoreMultipleInstruction(MI); 3937d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor break; 3947d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor case ARMII::VFPMiscFrm: 3957d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor emitMiscInstruction(MI); 396ef177820100ab583b08fd3056e2a5a52ee4b1629Argyrios Kyrtzidis break; 397ef177820100ab583b08fd3056e2a5a52ee4b1629Argyrios Kyrtzidis } 3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 3995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 400e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCalltemplate<class CodeEmitter> 401e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCallvoid Emitter<CodeEmitter>::emitConstPoolInstruction(const MachineInstr &MI) { 402e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall unsigned CPI = MI.getOperand(0).getImm(); // CP instruction index. 403e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall unsigned CPIndex = MI.getOperand(1).getIndex(); // Actual cp entry index. 404e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall const MachineConstantPoolEntry &MCPE = (*MCPEs)[CPIndex]; 405e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall 406e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall // Remember the CONSTPOOL_ENTRY address for later relocation. 407e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall JTI->addConstantPoolEntryAddr(CPI, MCE.getCurrentPCValue()); 408e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall 409e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall // Emit constpool island entry. In most cases, the actual values will be 410e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall // resolved and relocated after code emission. 411e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall if (MCPE.isMachineConstantPoolEntry()) { 4122a984cad5ac3fdceeff2bd99daa7b90979313475John McCall ARMConstantPoolValue *ACPV = 413e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal); 41413dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian 4158e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor DEBUG(errs() << " ** ARM constant pool #" << CPI << " @ " 416444be7366d0a1e172c0290a1ea54c1cb16b5947cDaniel Dunbar << (void*)MCE.getCurrentPCValue() << " " << *ACPV << '\n'); 4171b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner 4181b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner GlobalValue *GV = ACPV->getGV(); 41963fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor if (GV) { 420fee0452973f28691a61aab0fb074468ce3e34b9bTed Kremenek assert(!ACPV->isStub() && "Don't know how to deal this yet!"); 4215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ACPV->isNonLazyPointer()) 4226ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor MCE.addRelocation(MachineRelocation::getIndirectSymbol( 4232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor MCE.getCurrentPCOffset(), ARM::reloc_arm_machine_cp_entry, GV, 4242cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor (intptr_t)ACPV, false)); 4252cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor else 4262cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor emitGlobalAddress(GV, ARM::reloc_arm_machine_cp_entry, 4272cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor ACPV->isStub() || isa<Function>(GV), (intptr_t)ACPV); 4282cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else { 4292cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!"); 4302cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute); 4312cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 4322cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor emitWordLE(0); 4332cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } else { 4347b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis Constant *CV = MCPE.Val.ConstVal; 4357b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis 4367b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis DEBUG({ 4377b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis errs() << " ** Constant pool #" << CPI << " @ " 4387b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis << (void*)MCE.getCurrentPCValue() << " "; 4397b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis if (const Function *F = dyn_cast<Function>(CV)) 4407b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis errs() << F->getName(); 4417b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis else 4427b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis errs() << *CV; 4437b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis errs() << '\n'; 4447b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis }); 4457b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis 4467b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis if (GlobalValue *GV = dyn_cast<GlobalValue>(CV)) { 4475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer emitGlobalAddress(GV, ARM::reloc_arm_absolute, isa<Function>(GV)); 44803ed44061df258e74a40383bda849e14b892a8c6Ted Kremenek emitWordLE(0); 449d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { 450464175bba1318bef7905122e9fda20cff926df78Chris Lattner uint32_t Val = *(uint32_t*)CI->getValue().getRawData(); 451464175bba1318bef7905122e9fda20cff926df78Chris Lattner emitWordLE(Val); 452464175bba1318bef7905122e9fda20cff926df78Chris Lattner } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { 4531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (CFP->getType() == Type::getFloatTy(CFP->getContext())) 4540953e767ff7817f97b3ab20896b229891eeff45bJohn McCall emitWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue()); 4550953e767ff7817f97b3ab20896b229891eeff45bJohn McCall else if (CFP->getType() == Type::getDoubleTy(CFP->getContext())) 4564ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad emitDWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue()); 4570953e767ff7817f97b3ab20896b229891eeff45bJohn McCall else { 4584ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad llvm_unreachable("Unable to handle this constantpool entry!"); 459becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall } 4600953e767ff7817f97b3ab20896b229891eeff45bJohn McCall } else { 4611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm_unreachable("Unable to handle this constantpool entry!"); 4621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 4641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 465f11284ac87daa613bc7b30db9f54bd716d123222Fariborz Jahanian 4664ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadtemplate<class CodeEmitter> 4671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Emitter<CodeEmitter>::emitMOVi2piecesInstruction(const MachineInstr &MI) { 468d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian const MachineOperand &MO0 = MI.getOperand(0); 469d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian const MachineOperand &MO1 = MI.getOperand(1); 470d33d9c0cc0cfdcd0b10f35a6acdfb25da4a64f19Fariborz Jahanian assert(MO1.isImm() && ARM_AM::getSOImmVal(MO1.isImm()) != -1 && 4714ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad "Not a valid so_imm value!"); 4720953e767ff7817f97b3ab20896b229891eeff45bJohn McCall unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO1.getImm()); 4730953e767ff7817f97b3ab20896b229891eeff45bJohn McCall unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO1.getImm()); 4740953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 4750953e767ff7817f97b3ab20896b229891eeff45bJohn McCall // Emit the 'mov' instruction. 4764ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned Binary = 0xd << 21; // mov: Insts{24-21} = 0b1101 4770953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 4780953e767ff7817f97b3ab20896b229891eeff45bJohn McCall // Set the conditional execution predicate. 4790953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Binary |= II->getPredicate(&MI) << ARMII::CondShift; 4800953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 4810953e767ff7817f97b3ab20896b229891eeff45bJohn McCall // Encode Rd. 4820953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift; 4834ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 484f7616b9067790757f4e12e834b216c53c8c04ebeDouglas Gregor // Encode so_imm. 485f7616b9067790757f4e12e834b216c53c8c04ebeDouglas Gregor // Set bit I(25) to identify this is the immediate form of <shifter_op> 4860953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Binary |= 1 << ARMII::I_BitShift; 4870953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Binary |= getMachineSoImmOpValue(V1); 4880953e767ff7817f97b3ab20896b229891eeff45bJohn McCall emitWordLE(Binary); 4890953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 4900953e767ff7817f97b3ab20896b229891eeff45bJohn McCall // Now the 'orr' instruction. 4910953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Binary = 0xc << 21; // orr: Insts{24-21} = 0b1100 4920953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 4934ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Set the conditional execution predicate. 4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= II->getPredicate(&MI) << ARMII::CondShift; 495e6a365d772a6b455f1e23ac9ae5f40d65a55a18cJohn McCall 496e6a365d772a6b455f1e23ac9ae5f40d65a55a18cJohn McCall // Encode Rd. 497e6a365d772a6b455f1e23ac9ae5f40d65a55a18cJohn McCall Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift; 498e6a365d772a6b455f1e23ac9ae5f40d65a55a18cJohn McCall 4995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Encode Rn. 5005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRnShift; 5014ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 5024ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Encode so_imm. 503e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall // Set bit I(25) to identify this is the immediate form of <shifter_op> 504e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall Binary |= 1 << ARMII::I_BitShift; 5051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= getMachineSoImmOpValue(V2); 5065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer emitWordLE(Binary); 5075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5084ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 5094ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadtemplate<class CodeEmitter> 510e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCallvoid Emitter<CodeEmitter>::emitLEApcrelJTInstruction(const MachineInstr &MI) { 511e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall // It's basically add r, pc, (LJTI - $+8) 5125618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff 5135618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff const TargetInstrDesc &TID = MI.getDesc(); 5145618bd4a52c45fbbb605e3ba885663b2164db8a3Steve Naroff 5154ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Emit the 'add' instruction. 516f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl unsigned Binary = 0x4 << 21; // add: Insts{24-31} = 0b0100 517adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump 518adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump // Set the conditional execution predicate 5194ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= II->getPredicate(&MI) << ARMII::CondShift; 520adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump 521adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump // Encode S bit if MI modifies CPSR. 522adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump Binary |= getAddrModeSBit(MI, TID); 523adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump 524adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump // Encode Rd. 525adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift; 526adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump 527adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump // Encode Rn which is PC. 528adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump Binary |= ARMRegisterInfo::getRegisterNumbering(ARM::PC) << ARMII::RegRnShift; 529adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump 530083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump // Encode the displacement. 531083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump Binary |= 1 << ARMII::I_BitShift; 5324ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad emitJumpTableAddress(MI.getOperand(1).getIndex(), ARM::reloc_arm_jt_base); 533083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump 534083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump emitWordLE(Binary); 535083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump} 536083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump 537083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stumptemplate<class CodeEmitter> 5384ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadvoid Emitter<CodeEmitter>::emitPseudoMoveInstruction(const MachineInstr &MI) { 539083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump unsigned Opcode = MI.getDesc().Opcode; 540083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump 541083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump // Part of binary is determined by TableGn. 542083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump unsigned Binary = getBinaryCodeForInstr(MI); 543083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump 544adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump // Set the conditional execution predicate 545adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump Binary |= II->getPredicate(&MI) << ARMII::CondShift; 546083c25eea14bb4cc4ecc3ec763c60e2e609e22bdMike Stump 5474ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Encode S bit if MI modifies CPSR. 548adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump if (Opcode == ARM::MOVsrl_flag || Opcode == ARM::MOVsra_flag) 549ea26cb522e88fc86b0d1cae61dcefcfe4cc20231Mike Stump Binary |= 1 << ARMII::S_BitShift; 5504ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 551af7b44d847d3e44c43346d508b2e55a6254b6e9dMike Stump // Encode register def if there is one. 552af7b44d847d3e44c43346d508b2e55a6254b6e9dMike Stump Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift; 5534ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 554adaaad3715c9c26cdcfdfe3401a13d7b4423ddcfMike Stump // Encode the shift operation. 5557c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl switch (Opcode) { 5567c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl default: break; 5574ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad case ARM::MOVrx: 5584ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // rrx 5597c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl Binary |= 0x6 << 4; 5607c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl break; 5617c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl case ARM::MOVsrl_flag: 5624ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // lsr #1 563f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl Binary |= (0x2 << 4) | (1 << 7); 564f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl break; 565f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl case ARM::MOVsra_flag: 566f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl // asr #1 5674ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= (0x4 << 4) | (1 << 7); 568f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl break; 569bdbf7b030a3e0ddb95240076683830e6f78c79a5Steve Naroff } 570bdbf7b030a3e0ddb95240076683830e6f78c79a5Steve Naroff 571c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff // Encode register Rm. 572c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff Binary |= getMachineOpValue(MI, 1); 57363e7d25d2e6036616b42f744fd4a39cd5f911960Abramo Bagnara 5744ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad emitWordLE(Binary); 5751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 576898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor 577898574e7496ba8fd76290079d3a9d06954992734Douglas Gregortemplate<class CodeEmitter> 578898574e7496ba8fd76290079d3a9d06954992734Douglas Gregorvoid Emitter<CodeEmitter>::addPCLabel(unsigned LabelID) { 579898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor DEBUG(errs() << " ** LPC" << LabelID << " @ " 580898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor << (void*)MCE.getCurrentPCValue() << '\n'); 581fea8685bf3036b199c573e70b03affde2583fc44Nate Begeman JTI->addPCLabelAddr(LabelID, MCE.getCurrentPCValue()); 58263e7d25d2e6036616b42f744fd4a39cd5f911960Abramo Bagnara} 5834ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 584fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Narofftemplate<class CodeEmitter> 585c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedmanvoid Emitter<CodeEmitter>::emitPseudoInstruction(const MachineInstr &MI) { 586c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman unsigned Opcode = MI.getDesc().Opcode; 587c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman switch (Opcode) { 588c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman default: 58963e7d25d2e6036616b42f744fd4a39cd5f911960Abramo Bagnara llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");//FIXME: 590c5773c4b8ce1ed6ed5c7112c9020c954a47dce96Eli Friedman case TargetInstrInfo::INLINEASM: { 591bdbf7b030a3e0ddb95240076683830e6f78c79a5Steve Naroff // We allow inline assembler nodes with empty bodies - they can 592bdbf7b030a3e0ddb95240076683830e6f78c79a5Steve Naroff // implicitly define registers, which is ok for JIT. 593c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff if (MI.getOperand(0).getSymbolName()[0]) { 594c9406125e2cac9208098655ac8058c095c2c3a65Steve Naroff llvm_report_error("JIT does not support inline asm!"); 59563e7d25d2e6036616b42f744fd4a39cd5f911960Abramo Bagnara } 596745da3a5bb4ea35f93f50301e7fbbb7d78d3b6bbFariborz Jahanian break; 597745da3a5bb4ea35f93f50301e7fbbb7d78d3b6bbFariborz Jahanian } 598ce8890371fcdb983ae487c87fa40606a34896ff7John McCall case TargetInstrInfo::DBG_LABEL: 5994ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad case TargetInstrInfo::EH_LABEL: 6007e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor MCE.emitLabel(MI.getOperand(0).getImm()); 60173322924127c873c13101b705dd823f5539ffa5fSteve Naroff break; 60273322924127c873c13101b705dd823f5539ffa5fSteve Naroff case TargetInstrInfo::IMPLICIT_DEF: 60382287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson case ARM::DWARF_LOC: 6044ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Do nothing. 60573322924127c873c13101b705dd823f5539ffa5fSteve Naroff break; 606213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman case ARM::CONSTPOOL_ENTRY: 607213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman emitConstPoolInstruction(MI); 608213541a68a3e137d11d2cefb612c6cdb410d7e8eNate Begeman break; 6094ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad case ARM::PICADD: { 6105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Remember of the address of the PC label for relocation later. 6119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor addPCLabel(MI.getOperand(2).getImm()); 6129cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // PICADD is just an add instruction that implicitly read pc. 6139cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor emitDataProcessingInstruction(MI, 0, ARM::PC); 6149cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor break; 6151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 6169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor case ARM::PICLDR: 6174ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad case ARM::PICLDRB: 6189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor case ARM::PICSTR: 61972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor case ARM::PICSTRB: { 6205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Remember of the address of the PC label for relocation later. 621264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola addPCLabel(MI.getOperand(2).getImm()); 6224ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // These are just load / store instructions that implicitly read pc. 623264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola emitLoadStoreInstruction(MI, 0, ARM::PC); 6244ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad break; 625264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola } 6266a6aa53ec6c89ae0881309b0a0dd84b6868b576bRafael Espindola case ARM::PICLDRH: 627465226e23a3008bd68973513dda1f9e3cd27dbddSebastian Redl case ARM::PICLDRSH: 628e23cf437fe76b1ed02d63c3f61b456fd48a915f5John McCall case ARM::PICLDRSB: 629e23cf437fe76b1ed02d63c3f61b456fd48a915f5John McCall case ARM::PICSTRH: { 630e23cf437fe76b1ed02d63c3f61b456fd48a915f5John McCall // Remember of the address of the PC label for relocation later. 631e23cf437fe76b1ed02d63c3f61b456fd48a915f5John McCall addPCLabel(MI.getOperand(2).getImm()); 6324ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // These are just load / store instructions that implicitly read pc. 6332ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor emitMiscLoadStoreInstruction(MI, ARM::PC); 6342ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor break; 6352ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor } 636becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall case ARM::MOVi2pieces: 6374ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Two instructions to materialize a constant. 638becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall emitMOVi2piecesInstruction(MI); 639becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall break; 640becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall case ARM::LEApcrelJT: 641becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall // Materialize jumptable address. 642becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall emitLEApcrelJTInstruction(MI); 643becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall break; 644becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall case ARM::MOVrx: 645becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall case ARM::MOVsrl_flag: 646becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall case ARM::MOVsra_flag: 647becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall emitPseudoMoveInstruction(MI); 648becb8d5a6ab5103393eac5344ae69bcb860601ddJohn McCall break; 6492ce52f3fb95bf544db6bd3d91a72bce7d9cceb6cDouglas Gregor } 6505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6524ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadtemplate<class CodeEmitter> 6534ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadunsigned Emitter<CodeEmitter>::getMachineSoRegOpValue( 654fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor const MachineInstr &MI, 6554ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const TargetInstrDesc &TID, 656400f5125e2432d648f2c8a31b36a7f318a880c47Argyrios Kyrtzidis const MachineOperand &MO, 6574ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned OpIdx) { 658400f5125e2432d648f2c8a31b36a7f318a880c47Argyrios Kyrtzidis unsigned Binary = getMachineOpValue(MI, MO); 6594ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 6603cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall const MachineOperand &MO1 = MI.getOperand(OpIdx + 1); 6619d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall const MachineOperand &MO2 = MI.getOperand(OpIdx + 2); 6629d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm()); 6639d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall 6649d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall // Encode the shift opcode. 66549a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall unsigned SBits = 0; 6664ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned Rs = MO1.getReg(); 667c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor if (Rs) { 668c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor // Set shift operand (bit[7:4]). 669c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor // LSL - 0001 67049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall // LSR - 0011 6711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // ASR - 0101 67276e4ce42a30cee4dc40ce7c6014874fbc4f9baa7Anders Carlsson // ROR - 0111 6734ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // RRX - 0110 and bit[11:8] clear. 674fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor switch (SOpc) { 6757532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor default: llvm_unreachable("Unknown shift opc!"); 6767532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor case ARM_AM::lsl: SBits = 0x1; break; 6777532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor case ARM_AM::lsr: SBits = 0x3; break; 6784ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad case ARM_AM::asr: SBits = 0x5; break; 679833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall case ARM_AM::ror: SBits = 0x7; break; 6809763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis case ARM_AM::rrx: SBits = 0x6; break; 6819763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis } 6824ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad } else { 6839763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis // Set shift operand (bit[6:4]). 684833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall // LSL - 000 685d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall // LSR - 010 6864ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // ASR - 100 68755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor // ROR - 110 6883cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall switch (SOpc) { 6893cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall default: llvm_unreachable("Unknown shift opc!"); 6903cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall case ARM_AM::lsl: SBits = 0x0; break; 6914ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad case ARM_AM::lsr: SBits = 0x2; break; 6923cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall case ARM_AM::asr: SBits = 0x4; break; 6934ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad case ARM_AM::ror: SBits = 0x6; break; 694075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara } 695465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara } 696465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara Binary |= SBits << 4; 6974ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad if (SOpc == ARM_AM::rrx) 6984a2023f5014e82389d5980d307b89c545dbbac81Douglas Gregor return Binary; 6994a2023f5014e82389d5980d307b89c545dbbac81Douglas Gregor 7004a2023f5014e82389d5980d307b89c545dbbac81Douglas Gregor // Encode the shift operation Rs or shift_imm (except rrx). 7014ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad if (Rs) { 70233500955d731c73717af52088b7fc0e7a85681e7John McCall // Encode Rs bit[11:8]. 70333500955d731c73717af52088b7fc0e7a85681e7John McCall assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0); 70433500955d731c73717af52088b7fc0e7a85681e7John McCall return Binary | 70533500955d731c73717af52088b7fc0e7a85681e7John McCall (ARMRegisterInfo::getRegisterNumbering(Rs) << ARMII::RegRsShift); 7064ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad } 70733500955d731c73717af52088b7fc0e7a85681e7John McCall 70833500955d731c73717af52088b7fc0e7a85681e7John McCall // Encode shift_imm bit[11:7]. 70933500955d731c73717af52088b7fc0e7a85681e7John McCall return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7; 71033500955d731c73717af52088b7fc0e7a85681e7John McCall} 7114ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 712e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregortemplate<class CodeEmitter> 713cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregorunsigned Emitter<CodeEmitter>::getMachineSoImmOpValue(unsigned SoImm) { 714cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor int SoImmVal = ARM_AM::getSOImmVal(SoImm); 7157536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor assert(SoImmVal != -1 && "Not a valid so_imm value!"); 7164ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 717c15cb2af27514ecc879daba9aa01389c5203685dSteve Naroff // Encode rotate_imm. 718c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1) 719c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall << ARMII::SoRotImmShift; 7204ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 721c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall // Encode immed_8. 722c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); 723c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return Binary; 7244ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad} 7251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 726d1861fd633d5096a00777c918eb8575ea7162fe7Steve Narofftemplate<class CodeEmitter> 7274ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadunsigned Emitter<CodeEmitter>::getAddrModeSBit(const MachineInstr &MI, 7284ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const TargetInstrDesc &TID) const { 7291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){ 730395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson const MachineOperand &MO = MI.getOperand(i-1); 7314ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) 7321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return 1 << ARMII::S_BitShift; 7335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 7345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 7354ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad} 7361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencertemplate<class CodeEmitter> 7385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid Emitter<CodeEmitter>::emitDataProcessingInstruction( 739a3ccda58913cc1a4b8564e349448b12acc462da7Anders Carlsson const MachineInstr &MI, 740fd888a581d6d329f5b447c8ff4d37cf396315993Eli Friedman unsigned ImplicitRd, 7413a2503227c3db04a3619735127483263c1075ef7Chris Lattner unsigned ImplicitRn) { 7423a2503227c3db04a3619735127483263c1075ef7Chris Lattner const TargetInstrDesc &TID = MI.getDesc(); 7433a2503227c3db04a3619735127483263c1075ef7Chris Lattner 7443a2503227c3db04a3619735127483263c1075ef7Chris Lattner if (TID.Opcode == ARM::BFC) { 74564c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis llvm_report_error("ARMv6t2 JIT is not yet supported."); 74664c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis } 74764c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis 74864c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis // Part of binary is determined by TableGn. 74964c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis unsigned Binary = getBinaryCodeForInstr(MI); 75064c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis 75164c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis // Set the conditional execution predicate 75264c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis Binary |= II->getPredicate(&MI) << ARMII::CondShift; 7531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7548b9023ba35a86838789e2c9034a6128728c547aaChris Lattner // Encode S bit if MI modifies CPSR. 7558b9023ba35a86838789e2c9034a6128728c547aaChris Lattner Binary |= getAddrModeSBit(MI, TID); 7568b9023ba35a86838789e2c9034a6128728c547aaChris Lattner 7571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Encode register def if there is one. 758beaf299a2701c5559a4e5d76b0c40f805afb8e6aSteve Naroff unsigned NumDefs = TID.getNumDefs(); 759beaf299a2701c5559a4e5d76b0c40f805afb8e6aSteve Naroff unsigned OpIdx = 0; 7604ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad if (NumDefs) 7611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; 7622bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian else if (ImplicitRd) 7632bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian // Special handling for implicit use (e.g. PC). 7644ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd) 7652bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian << ARMII::RegRdShift); 7662bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian 7674ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // If this is a two-address operand, skip it. e.g. MOVCCr operand 1. 7682bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) 7692bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian ++OpIdx; 7702bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian 7712bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian // Encode first non-shifter register operand if there is one. 7722bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian bool isUnary = TID.TSFlags & ARMII::UnaryDP; 7732bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian if (!isUnary) { 7742bb5ddaff86ee73d2cea7ec1835978afc88a83f0Fariborz Jahanian if (ImplicitRn) 775319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor // Special handling for implicit use (e.g. PC). 776319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRn) 7774ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad << ARMII::RegRnShift); 778319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor else { 779319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift; 780319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor ++OpIdx; 781319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor } 782319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor } 783319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor 784983df5b2280980e59b0b062bcc2882230465a61eSteve Naroff // Encode shifter operand. 785a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek const MachineOperand &MO = MI.getOperand(OpIdx); 7861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if ((TID.TSFlags & ARMII::FormMask) == ARMII::DPSoRegFrm) { 7871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Encode SoReg. 7882198891824c38d45b2279de5d5e3ef9394eb457cSteve Naroff emitWordLE(Binary | getMachineSoRegOpValue(MI, TID, MO, OpIdx)); 789b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian return; 790bd4c1ada2e8668f43a865dc2c662085cf61940c4Anders Carlsson } 7914ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 7921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (MO.isReg()) { 793319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor // Encode register Rm. 794319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor emitWordLE(Binary | ARMRegisterInfo::getRegisterNumbering(MO.getReg())); 7954ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad return; 796319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor } 797319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor 798319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor // Encode so_imm. 799319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor Binary |= getMachineSoImmOpValue((unsigned)MO.getImm()); 800319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor 801319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor emitWordLE(Binary); 802319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor} 803c29f77b769bcc5b6dc85e72c8e3cc2e348e5cf25Douglas Gregor 804c29f77b769bcc5b6dc85e72c8e3cc2e348e5cf25Douglas Gregortemplate<class CodeEmitter> 8051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Emitter<CodeEmitter>::emitLoadStoreInstruction( 806c29f77b769bcc5b6dc85e72c8e3cc2e348e5cf25Douglas Gregor const MachineInstr &MI, 8074ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned ImplicitRd, 8081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned ImplicitRn) { 809c29f77b769bcc5b6dc85e72c8e3cc2e348e5cf25Douglas Gregor const TargetInstrDesc &TID = MI.getDesc(); 810c29f77b769bcc5b6dc85e72c8e3cc2e348e5cf25Douglas Gregor unsigned Form = TID.TSFlags & ARMII::FormMask; 811c29f77b769bcc5b6dc85e72c8e3cc2e348e5cf25Douglas Gregor bool IsPrePost = (TID.TSFlags & ARMII::IndexModeMask) != 0; 812782fa308a765aeac2acb39c4e697c937ec21185bMike Stump 813782fa308a765aeac2acb39c4e697c937ec21185bMike Stump // Part of binary is determined by TableGn. 814fd612dbb23cd31c03c898ae53ff18d0dfd8488f9Mike Stump unsigned Binary = getBinaryCodeForInstr(MI); 815fd612dbb23cd31c03c898ae53ff18d0dfd8488f9Mike Stump 816fd612dbb23cd31c03c898ae53ff18d0dfd8488f9Mike Stump // Set the conditional execution predicate 8171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= II->getPredicate(&MI) << ARMII::CondShift; 818782fa308a765aeac2acb39c4e697c937ec21185bMike Stump 8194ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned OpIdx = 0; 8201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 821782fa308a765aeac2acb39c4e697c937ec21185bMike Stump // Operand 0 of a pre- and post-indexed store is the address base 822782fa308a765aeac2acb39c4e697c937ec21185bMike Stump // writeback. Skip it. 823782fa308a765aeac2acb39c4e697c937ec21185bMike Stump bool Skipped = false; 824782fa308a765aeac2acb39c4e697c937ec21185bMike Stump if (IsPrePost && Form == ARMII::StFrm) { 825782fa308a765aeac2acb39c4e697c937ec21185bMike Stump ++OpIdx; 826fd612dbb23cd31c03c898ae53ff18d0dfd8488f9Mike Stump Skipped = true; 827fd612dbb23cd31c03c898ae53ff18d0dfd8488f9Mike Stump } 828fd612dbb23cd31c03c898ae53ff18d0dfd8488f9Mike Stump 8291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Set first operand 830782fa308a765aeac2acb39c4e697c937ec21185bMike Stump if (ImplicitRd) 8314ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Special handling for implicit use (e.g. PC). 8321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRd) 833782fa308a765aeac2acb39c4e697c937ec21185bMike Stump << ARMII::RegRdShift); 834782fa308a765aeac2acb39c4e697c937ec21185bMike Stump else 835782fa308a765aeac2acb39c4e697c937ec21185bMike Stump Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; 8361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 837d96b35bc6becf8db00d140c11e3d0e53f27567a1Daniel Dunbar // Set second operand 838d96b35bc6becf8db00d140c11e3d0e53f27567a1Daniel Dunbar if (ImplicitRn) 839d96b35bc6becf8db00d140c11e3d0e53f27567a1Daniel Dunbar // Special handling for implicit use (e.g. PC). 8401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRn) 8414ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad << ARMII::RegRnShift); 842a1c033e9514865f3a7b0d8b3b20e6de926cfec6cFariborz Jahanian else 843a1c033e9514865f3a7b0d8b3b20e6de926cfec6cFariborz Jahanian Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift; 8441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 845ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian // If this is a two-address operand, skip it. e.g. LDR_PRE. 8461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!Skipped && TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) 847ecb01e666665efabd2aa76a76f6080e2a78965faFariborz Jahanian ++OpIdx; 8481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8495389f48b24937ad7b4093307128b3cbf25235654David Chisnall const MachineOperand &MO2 = MI.getOperand(OpIdx); 8505389f48b24937ad7b4093307128b3cbf25235654David Chisnall unsigned AM2Opc = (ImplicitRn == ARM::PC) 8515389f48b24937ad7b4093307128b3cbf25235654David Chisnall ? 0 : MI.getOperand(OpIdx+1).getImm(); 8525389f48b24937ad7b4093307128b3cbf25235654David Chisnall 853a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek // Set bit U(23) according to sign of immed value (positive or negative). 85433e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian Binary |= ((ARM_AM::getAM2Op(AM2Opc) == ARM_AM::add ? 1 : 0) << 8554ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad ARMII::U_BitShift); 8564ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad if (!MO2.getReg()) { // is immediate 8571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (ARM_AM::getAM2Offset(AM2Opc)) 8586b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall // Set the value of offset_12 field 8595e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnall Binary |= ARM_AM::getAM2Offset(AM2Opc); 8606b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall emitWordLE(Binary); 8615e530af5d51572a0ed5dbe50da54bd333840c63dDavid Chisnall return; 862c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar } 863c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar 864c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar // Set bit I(25), because this is not in immediate enconding. 865c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar Binary |= 1 << ARMII::I_BitShift; 8661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg())); 867c56f34a1c1779de15330bdb3eec39b3418802d47Daniel Dunbar // Set bit[3:0] to the corresponding Rm register 8684ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg()); 8691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8700fd8904c5f71a11d29f67716c3ebdf7ad1c855fbFariborz Jahanian // If this instr is in scaled register offset/index instruction, set 8714ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // shift_immed(bit[11:7]) and shift(bit[6:5]) fields. 8721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (unsigned ShImm = ARM_AM::getAM2Offset(AM2Opc)) { 873a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek Binary |= getShiftOp(AM2Opc) << ARMII::ShiftImmShift; // shift 874aa8741a1db98eef05f09b1200dba94aa5dc3bc3dKen Dyck Binary |= ShImm << ARMII::ShiftShift; // shift_immed 8754ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad } 876d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff 877006113841bdae1edb77aef75ba1ffdf2e55a3094Argyrios Kyrtzidis emitWordLE(Binary); 878006113841bdae1edb77aef75ba1ffdf2e55a3094Argyrios Kyrtzidis} 879006113841bdae1edb77aef75ba1ffdf2e55a3094Argyrios Kyrtzidis 880006113841bdae1edb77aef75ba1ffdf2e55a3094Argyrios Kyrtzidistemplate<class CodeEmitter> 881d85376aa66bc16488539f6bb11f97d0170b1fe6bChris Lattnervoid Emitter<CodeEmitter>::emitMiscLoadStoreInstruction(const MachineInstr &MI, 882d85376aa66bc16488539f6bb11f97d0170b1fe6bChris Lattner unsigned ImplicitRn) { 883de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff const TargetInstrDesc &TID = MI.getDesc(); 884319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor unsigned Form = TID.TSFlags & ARMII::FormMask; 8851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool IsPrePost = (TID.TSFlags & ARMII::IndexModeMask) != 0; 886319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor 88713dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian // Part of binary is determined by TableGn. 8881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned Binary = getBinaryCodeForInstr(MI); 889a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek 890a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek // Set the conditional execution predicate 8911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= II->getPredicate(&MI) << ARMII::CondShift; 892d85376aa66bc16488539f6bb11f97d0170b1fe6bChris Lattner 893d85376aa66bc16488539f6bb11f97d0170b1fe6bChris Lattner unsigned OpIdx = 0; 894d85376aa66bc16488539f6bb11f97d0170b1fe6bChris Lattner 895de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff // Operand 0 of a pre- and post-indexed store is the address base 896319ac896a0fef7365d5589b8021db7e41207fe42Douglas Gregor // writeback. Skip it. 8971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool Skipped = false; 898b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson if (IsPrePost && Form == ARMII::StMiscFrm) { 899b2cf3573d7351094f6247fcca94703ce88eb9ee0Anders Carlsson ++OpIdx; 900f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman Skipped = true; 9010953e767ff7817f97b3ab20896b229891eeff45bJohn McCall } 9020953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 9034ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Set first operand 9040953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; 9050953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 9060953e767ff7817f97b3ab20896b229891eeff45bJohn McCall // Skip LDRD and STRD's second operand. 9070953e767ff7817f97b3ab20896b229891eeff45bJohn McCall if (TID.Opcode == ARM::LDRD || TID.Opcode == ARM::STRD) 9084ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad ++OpIdx; 9090953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 9100953e767ff7817f97b3ab20896b229891eeff45bJohn McCall // Set second operand 9110953e767ff7817f97b3ab20896b229891eeff45bJohn McCall if (ImplicitRn) 9120953e767ff7817f97b3ab20896b229891eeff45bJohn McCall // Special handling for implicit use (e.g. PC). 9130953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Binary |= (ARMRegisterInfo::getRegisterNumbering(ImplicitRn) 9140953e767ff7817f97b3ab20896b229891eeff45bJohn McCall << ARMII::RegRnShift); 9150953e767ff7817f97b3ab20896b229891eeff45bJohn McCall else 9160953e767ff7817f97b3ab20896b229891eeff45bJohn McCall Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift; 9174ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 9180953e767ff7817f97b3ab20896b229891eeff45bJohn McCall // If this is a two-address operand, skip it. e.g. LDRH_POST. 9190953e767ff7817f97b3ab20896b229891eeff45bJohn McCall if (!Skipped && TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) 9200953e767ff7817f97b3ab20896b229891eeff45bJohn McCall ++OpIdx; 9210953e767ff7817f97b3ab20896b229891eeff45bJohn McCall 9220953e767ff7817f97b3ab20896b229891eeff45bJohn McCall const MachineOperand &MO2 = MI.getOperand(OpIdx); 9232577743c5650c646fb705df01403707e94f2df04Abramo Bagnara unsigned AM3Opc = (ImplicitRn == ARM::PC) 9244ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad ? 0 : MI.getOperand(OpIdx+1).getImm(); 92580ad16f4b2b350ddbaae21a52975e63df5aafc2cJohn McCall 926eec51cf1ba5f0e62c9cdb81b5c63babdd6e649abJohn McCall // Set bit U(23) according to sign of immed value (positive or negative) 9274ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= ((ARM_AM::getAM3Op(AM3Opc) == ARM_AM::add ? 1 : 0) << 9280bd6feb9e9d40fc889fd47e899985125a43dfed8John McCall ARMII::U_BitShift); 9291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9307532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor // If this instr is in register offset/index encoding, set bit[3:0] 9314ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // to the corresponding Rm register. 9321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (MO2.getReg()) { 9331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= ARMRegisterInfo::getRegisterNumbering(MO2.getReg()); 9344ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad emitWordLE(Binary); 935ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return; 9364ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad } 9371aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor 9381aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor // This instr is in immediate offset/index encoding, set bit 22 to 1. 9391aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor Binary |= 1 << ARMII::AM3_I_BitShift; 94086df27bbdbb98c39ec2184695c0561209f91beddChris Lattner if (unsigned ImmOffs = ARM_AM::getAM3Offset(AM3Opc)) { 941782fa308a765aeac2acb39c4e697c937ec21185bMike Stump // Set operands 942f711c41dd9412a8182793259d355c4f6979ed5edMike Stump Binary |= (ImmOffs >> 4) << ARMII::ImmHiShift; // immedH 943f711c41dd9412a8182793259d355c4f6979ed5edMike Stump Binary |= (ImmOffs & 0xF); // immedL 94486df27bbdbb98c39ec2184695c0561209f91beddChris Lattner } 9451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 94614e0e7436cf6650a72052baea1f8ebe644cef489Chris Lattner emitWordLE(Binary); 94714e0e7436cf6650a72052baea1f8ebe644cef489Chris Lattner} 94814e0e7436cf6650a72052baea1f8ebe644cef489Chris Lattner 94914e0e7436cf6650a72052baea1f8ebe644cef489Chris Lattnerstatic unsigned getAddrModeUPBits(unsigned Mode) { 95014e0e7436cf6650a72052baea1f8ebe644cef489Chris Lattner unsigned Binary = 0; 9514ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 9521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Set addressing mode by modifying bits U(23) and P(24) 953d934112e6170b0fd940d8e40db6936cea2cdcf62Douglas Gregor // IA - Increment after - bit U = 1 and bit P = 0 954e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall // IB - Increment before - bit U = 1 and bit P = 1 955b4e66d5259f90e9aae4d40fc5de801e046c7df94Douglas Gregor // DA - Decrement after - bit U = 0 and bit P = 0 956464175bba1318bef7905122e9fda20cff926df78Chris Lattner // DB - Decrement before - bit U = 0 and bit P = 1 957b6ccaac65ca72f72954eb3893bbd940bedd23f00Ted Kremenek switch (Mode) { 958b6ccaac65ca72f72954eb3893bbd940bedd23f00Ted Kremenek default: llvm_unreachable("Unknown addressing sub-mode!"); 9591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case ARM_AM::da: break; 960d934112e6170b0fd940d8e40db6936cea2cdcf62Douglas Gregor case ARM_AM::db: Binary |= 0x1 << ARMII::P_BitShift; break; 9614fd83ea566f4a0c083001c84b75da6cc8c99c1d6Fariborz Jahanian case ARM_AM::ia: Binary |= 0x1 << ARMII::U_BitShift; break; 9624fd83ea566f4a0c083001c84b75da6cc8c99c1d6Fariborz Jahanian case ARM_AM::ib: Binary |= 0x3 << ARMII::U_BitShift; break; 9634fd83ea566f4a0c083001c84b75da6cc8c99c1d6Fariborz Jahanian } 964ae278a3a57595349a411f6474938d4dd1b263a0eJohn McCall 9651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Binary; 966f69eb7cf8e616b5aad7911ec6f79b24b0a009227Bob Wilson} 967f69eb7cf8e616b5aad7911ec6f79b24b0a009227Bob Wilson 968f69eb7cf8e616b5aad7911ec6f79b24b0a009227Bob Wilsontemplate<class CodeEmitter> 969f69eb7cf8e616b5aad7911ec6f79b24b0a009227Bob Wilsonvoid Emitter<CodeEmitter>::emitLoadStoreMultipleInstruction( 970255210ef415b9893f0e3794e8d9a704194c12f3cDouglas Gregor const MachineInstr &MI) { 971255210ef415b9893f0e3794e8d9a704194c12f3cDouglas Gregor // Part of binary is determined by TableGn. 972fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian unsigned Binary = getBinaryCodeForInstr(MI); 973fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 974fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian // Set the conditional execution predicate 9751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= II->getPredicate(&MI) << ARMII::CondShift; 976b6ccaac65ca72f72954eb3893bbd940bedd23f00Ted Kremenek 977464175bba1318bef7905122e9fda20cff926df78Chris Lattner // Set base address operand 978464175bba1318bef7905122e9fda20cff926df78Chris Lattner Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift; 9791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 980b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // Set addressing mode by modifying bits U(23) and P(24) 981b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner const MachineOperand &MO = MI.getOperand(1); 982b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Binary |= getAddrModeUPBits(ARM_AM::getAM4SubMode(MO.getImm())); 9831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 984464175bba1318bef7905122e9fda20cff926df78Chris Lattner // Set bit W(21) 985464175bba1318bef7905122e9fda20cff926df78Chris Lattner if (ARM_AM::getAM4WBFlag(MO.getImm())) 9864ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= 0x1 << ARMII::W_BitShift; 9874ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 9881d75118af76cae2bfc06389cde410e14bd0a19fcDaniel Dunbar // Set registers 9891d75118af76cae2bfc06389cde410e14bd0a19fcDaniel Dunbar for (unsigned i = 4, e = MI.getNumOperands(); i != e; ++i) { 9901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const MachineOperand &MO = MI.getOperand(i); 991464175bba1318bef7905122e9fda20cff926df78Chris Lattner if (!MO.isReg() || MO.isImplicit()) 992464175bba1318bef7905122e9fda20cff926df78Chris Lattner break; 9934ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(MO.getReg()); 99498be4943e8dc4f3905629a7102668960873cf863Chris Lattner assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && 995464175bba1318bef7905122e9fda20cff926df78Chris Lattner RegNum < 16); 9964ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= 0x1 << RegNum; 9971d75118af76cae2bfc06389cde410e14bd0a19fcDaniel Dunbar } 9981d75118af76cae2bfc06389cde410e14bd0a19fcDaniel Dunbar 9991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump emitWordLE(Binary); 1000cc906ef220c9be2644ad942457766d46a0b3651eKen Dyck} 10014ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1002f5f514477d8a4e04e511d345b9fb896153f70e9dKen Dycktemplate<class CodeEmitter> 1003f5f514477d8a4e04e511d345b9fb896153f70e9dKen Dyckvoid Emitter<CodeEmitter>::emitMulFrmInstruction(const MachineInstr &MI) { 1004f5f514477d8a4e04e511d345b9fb896153f70e9dKen Dyck const TargetInstrDesc &TID = MI.getDesc(); 1005eb6f5dc86531f794ba7746a2da4d28e37cf5da7eKen Dyck 1006eb6f5dc86531f794ba7746a2da4d28e37cf5da7eKen Dyck // Part of binary is determined by TableGn. 1007eb6f5dc86531f794ba7746a2da4d28e37cf5da7eKen Dyck unsigned Binary = getBinaryCodeForInstr(MI); 1008cc906ef220c9be2644ad942457766d46a0b3651eKen Dyck 1009f5f514477d8a4e04e511d345b9fb896153f70e9dKen Dyck // Set the conditional execution predicate 10104ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= II->getPredicate(&MI) << ARMII::CondShift; 10114ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1012f5f514477d8a4e04e511d345b9fb896153f70e9dKen Dyck // Encode S bit if MI modifies CPSR. 101334ebde404dc17d89487b07e6daaf1b47d5dfee39Chris Lattner Binary |= getAddrModeSBit(MI, TID); 101434ebde404dc17d89487b07e6daaf1b47d5dfee39Chris Lattner 10154ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // 32x32->64bit operations have two destination registers. The number 101698be4943e8dc4f3905629a7102668960873cf863Chris Lattner // of register definitions will tell us if that's what we're dealing with. 1017464175bba1318bef7905122e9fda20cff926df78Chris Lattner unsigned OpIdx = 0; 10184ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad if (TID.getNumDefs() == 2) 10191d75118af76cae2bfc06389cde410e14bd0a19fcDaniel Dunbar Binary |= getMachineOpValue (MI, OpIdx++) << ARMII::RegRdLoShift; 10201d75118af76cae2bfc06389cde410e14bd0a19fcDaniel Dunbar 10211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Encode Rd 102216e20cce43385001f33f8e3f90ee345609c805d1Ken Dyck Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdHiShift; 102386fa4311c8a330957ff5b765fbb0a7750ecd38c9Ken Dyck 10244ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Encode Rm 10254ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= getMachineOpValue(MI, OpIdx++); 102686fa4311c8a330957ff5b765fbb0a7750ecd38c9Ken Dyck 1027ea1471e0e967548c596a71469702f8846dbaf3c0John McCall // Encode Rs 1028ea1471e0e967548c596a71469702f8846dbaf3c0John McCall Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRsShift; 1029ea1471e0e967548c596a71469702f8846dbaf3c0John McCall 103034ebde404dc17d89487b07e6daaf1b47d5dfee39Chris Lattner // Many multiple instructions (e.g. MLA) have three src operands. Encode 103134ebde404dc17d89487b07e6daaf1b47d5dfee39Chris Lattner // it as Rn (for multiply, that's in the same offset as RdLo. 103234ebde404dc17d89487b07e6daaf1b47d5dfee39Chris Lattner if (TID.getNumOperands() > OpIdx && 103334ebde404dc17d89487b07e6daaf1b47d5dfee39Chris Lattner !TID.OpInfo[OpIdx].isPredicate() && 10344ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad !TID.OpInfo[OpIdx].isOptionalDef()) 10351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRdLoShift; 10368b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck 10378b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck emitWordLE(Binary); 10388b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck} 10398b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck 10408b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dycktemplate<class CodeEmitter> 10414ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadvoid Emitter<CodeEmitter>::emitExtendInstruction(const MachineInstr &MI) { 10421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const TargetInstrDesc &TID = MI.getDesc(); 104388a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel 1044464175bba1318bef7905122e9fda20cff926df78Chris Lattner // Part of binary is determined by TableGn. 1045464175bba1318bef7905122e9fda20cff926df78Chris Lattner unsigned Binary = getBinaryCodeForInstr(MI); 10464ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 10471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Set the conditional execution predicate 1048b2dbbb99e12806eaaf53b7ccabc32f42b5719443Daniel Dunbar Binary |= II->getPredicate(&MI) << ARMII::CondShift; 1049b2dbbb99e12806eaaf53b7ccabc32f42b5719443Daniel Dunbar 10504ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned OpIdx = 0; 10514ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1052b2dbbb99e12806eaaf53b7ccabc32f42b5719443Daniel Dunbar // Encode Rd 10534ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; 1054bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1055b2dbbb99e12806eaaf53b7ccabc32f42b5719443Daniel Dunbar const MachineOperand &MO1 = MI.getOperand(OpIdx++); 1056b2dbbb99e12806eaaf53b7ccabc32f42b5719443Daniel Dunbar const MachineOperand &MO2 = MI.getOperand(OpIdx); 1057b2dbbb99e12806eaaf53b7ccabc32f42b5719443Daniel Dunbar if (MO2.isReg()) { 1058b2dbbb99e12806eaaf53b7ccabc32f42b5719443Daniel Dunbar // Two register operand form. 10594ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Encode Rn. 1060b2dbbb99e12806eaaf53b7ccabc32f42b5719443Daniel Dunbar Binary |= getMachineOpValue(MI, MO1) << ARMII::RegRnShift; 1061fe8ec01bba74f6841576a2ee93d2c62cdfa4eff2Jeffrey Yasskin 1062fe8ec01bba74f6841576a2ee93d2c62cdfa4eff2Jeffrey Yasskin // Encode Rm. 1063fe8ec01bba74f6841576a2ee93d2c62cdfa4eff2Jeffrey Yasskin Binary |= getMachineOpValue(MI, MO2); 1064f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson ++OpIdx; 1065f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson } else { 1066f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson Binary |= getMachineOpValue(MI, MO1); 1067f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson } 1068f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 10694ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Encode rot imm (0, 8, 16, or 24) if it has a rotate immediate operand. 1070dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson if (MI.getOperand(OpIdx).isImm() && 107114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne !TID.OpInfo[OpIdx].isPredicate() && 107214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne !TID.OpInfo[OpIdx].isOptionalDef()) 10738e6ac1d80055fa37b9b84029c7e751624ba7f84cFariborz Jahanian Binary |= (getMachineOpValue(MI, OpIdx) / 8) << ARMII::ExtRotImmShift; 10744ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 10754ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad emitWordLE(Binary); 10762c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian} 10772c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanian 10784ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadtemplate<class CodeEmitter> 10792c18bb7c9fca66c30b6eabbdcbc6399d24a54fa9Fariborz Jahanianvoid Emitter<CodeEmitter>::emitMiscArithInstruction(const MachineInstr &MI) { 10804ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const TargetInstrDesc &TID = MI.getDesc(); 1081e23fa2d0e84d1b878e012442a726c664216a9adfFariborz Jahanian 1082432a8893f7e30d141d7f279bd00b741a3cdac81fFariborz Jahanian // Part of binary is determined by TableGn. 1083525c9b7baeeff022127cd1b167579f3bda73b3edDaniel Dunbar unsigned Binary = getBinaryCodeForInstr(MI); 1084464175bba1318bef7905122e9fda20cff926df78Chris Lattner 1085464175bba1318bef7905122e9fda20cff926df78Chris Lattner // Set the conditional execution predicate 1086464175bba1318bef7905122e9fda20cff926df78Chris Lattner Binary |= II->getPredicate(&MI) << ARMII::CondShift; 10871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 108877c9647cae939104c6cb2b6a4dd8ca859d2e5770Chris Lattner unsigned OpIdx = 0; 108977c9647cae939104c6cb2b6a4dd8ca859d2e5770Chris Lattner 109077c9647cae939104c6cb2b6a4dd8ca859d2e5770Chris Lattner // Encode Rd 109177c9647cae939104c6cb2b6a4dd8ca859d2e5770Chris Lattner Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift; 109277c9647cae939104c6cb2b6a4dd8ca859d2e5770Chris Lattner 109377c9647cae939104c6cb2b6a4dd8ca859d2e5770Chris Lattner const MachineOperand &MO = MI.getOperand(OpIdx++); 10943b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall if (OpIdx == TID.getNumOperands() || 10953b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall TID.OpInfo[OpIdx].isPredicate() || 10963b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall TID.OpInfo[OpIdx].isOptionalDef()) { 1097f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall // Encode Rm and it's done. 10984ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= getMachineOpValue(MI, MO); 10991d75118af76cae2bfc06389cde410e14bd0a19fcDaniel Dunbar emitWordLE(Binary); 11001d75118af76cae2bfc06389cde410e14bd0a19fcDaniel Dunbar return; 11012a3009a432bdcec59e6383d7b2b17494d6f91649Douglas Gregor } 110254e14c4db764c0636160d26c5bbf491637c83a76John McCall 110354e14c4db764c0636160d26c5bbf491637c83a76John McCall // Encode Rn. 110454e14c4db764c0636160d26c5bbf491637c83a76John McCall Binary |= getMachineOpValue(MI, MO) << ARMII::RegRnShift; 110554e14c4db764c0636160d26c5bbf491637c83a76John McCall 11064ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Encode Rm. 110754e14c4db764c0636160d26c5bbf491637c83a76John McCall Binary |= getMachineOpValue(MI, OpIdx++); 11088e6563ba097732dc1fffcfc85f8dbbceac899a80Douglas Gregor 11098e6563ba097732dc1fffcfc85f8dbbceac899a80Douglas Gregor // Encode shift_imm. 11108e6563ba097732dc1fffcfc85f8dbbceac899a80Douglas Gregor unsigned ShiftAmt = MI.getOperand(OpIdx).getImm(); 11118e6563ba097732dc1fffcfc85f8dbbceac899a80Douglas Gregor assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!"); 11121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= ShiftAmt << ARMII::ShiftShift; 11135535c38a2fcface6c13bc8bbeca66882de2fa227Chandler Carruth 11145535c38a2fcface6c13bc8bbeca66882de2fa227Chandler Carruth emitWordLE(Binary); 11155535c38a2fcface6c13bc8bbeca66882de2fa227Chandler Carruth} 11165535c38a2fcface6c13bc8bbeca66882de2fa227Chandler Carruth 111728e318cc6008c2bc008f0caee70dc736a03d6289Chandler Carruthtemplate<class CodeEmitter> 11185535c38a2fcface6c13bc8bbeca66882de2fa227Chandler Carruthvoid Emitter<CodeEmitter>::emitBranchInstruction(const MachineInstr &MI) { 111928e318cc6008c2bc008f0caee70dc736a03d6289Chandler Carruth const TargetInstrDesc &TID = MI.getDesc(); 112028e318cc6008c2bc008f0caee70dc736a03d6289Chandler Carruth 11215535c38a2fcface6c13bc8bbeca66882de2fa227Chandler Carruth if (TID.Opcode == ARM::TPsoft) { 112228e318cc6008c2bc008f0caee70dc736a03d6289Chandler Carruth llvm_unreachable("ARM::TPsoft FIXME"); // FIXME 112328e318cc6008c2bc008f0caee70dc736a03d6289Chandler Carruth } 11245535c38a2fcface6c13bc8bbeca66882de2fa227Chandler Carruth 112528e318cc6008c2bc008f0caee70dc736a03d6289Chandler Carruth // Part of binary is determined by TableGn. 112628e318cc6008c2bc008f0caee70dc736a03d6289Chandler Carruth unsigned Binary = getBinaryCodeForInstr(MI); 11278e6563ba097732dc1fffcfc85f8dbbceac899a80Douglas Gregor 11288e6563ba097732dc1fffcfc85f8dbbceac899a80Douglas Gregor // Set the conditional execution predicate 11298e6563ba097732dc1fffcfc85f8dbbceac899a80Douglas Gregor Binary |= II->getPredicate(&MI) << ARMII::CondShift; 11303b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall 11313b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall // Set signed_immed_24 field 11328e6563ba097732dc1fffcfc85f8dbbceac899a80Douglas Gregor Binary |= getMachineOpValue(MI, 0); 11338e6563ba097732dc1fffcfc85f8dbbceac899a80Douglas Gregor 11345a57efd7bf88a4a13018e0471ded8063a4abe8afDouglas Gregor emitWordLE(Binary); 11355a57efd7bf88a4a13018e0471ded8063a4abe8afDouglas Gregor} 1136d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor 1137d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregortemplate<class CodeEmitter> 1138d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregorvoid Emitter<CodeEmitter>::emitInlineJumpTable(unsigned JTIndex) { 1139d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor // Remember the base address of the inline jump table. 1140d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor uintptr_t JTBase = MCE.getCurrentPCValue(); 1141d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor JTI->addJumpTableBaseAddr(JTIndex, JTBase); 1142d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor DEBUG(errs() << " ** Jump Table #" << JTIndex << " @ " << (void*)JTBase 1143d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor << '\n'); 1144d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor 1145d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor // Now emit the jump table entries. 1146d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor const std::vector<MachineBasicBlock*> &MBBs = (*MJTEs)[JTIndex].MBBs; 1147d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor for (unsigned i = 0, e = MBBs.size(); i != e; ++i) { 1148d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor if (IsPIC) 1149d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor // DestBB address - JT base. 1150d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor emitMachineBasicBlock(MBBs[i], ARM::reloc_arm_pic_jt, JTBase); 1151d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor else 1152d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor // Absolute DestBB address. 1153d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor emitMachineBasicBlock(MBBs[i], ARM::reloc_arm_absolute); 1154d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor emitWordLE(0); 1155d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor } 1156d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor} 1157d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor 1158d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregortemplate<class CodeEmitter> 1159d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregorvoid Emitter<CodeEmitter>::emitMiscBranchInstruction(const MachineInstr &MI) { 11604ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const TargetInstrDesc &TID = MI.getDesc(); 1161d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor 1162ee743f903858e337434ac0335f147f4de4ecae05Charles Davis // Handle jump tables. 1163ee743f903858e337434ac0335f147f4de4ecae05Charles Davis if (TID.Opcode == ARM::BR_JTr || TID.Opcode == ARM::BR_JTadd) { 1164ee743f903858e337434ac0335f147f4de4ecae05Charles Davis // First emit a ldr pc, [] instruction. 1165ee743f903858e337434ac0335f147f4de4ecae05Charles Davis emitDataProcessingInstruction(MI, ARM::PC); 116604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall 116704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall // Then emit the inline jump table. 11684ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned JTIndex = 116904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall (TID.Opcode == ARM::BR_JTr) 117004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall ? MI.getOperand(1).getIndex() : MI.getOperand(2).getIndex(); 117104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall emitInlineJumpTable(JTIndex); 117204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall return; 117304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall } else if (TID.Opcode == ARM::BR_JTm) { 117404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall // First emit a ldr pc, [] instruction. 117504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall emitLoadStoreInstruction(MI, ARM::PC); 117604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall 117704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall // Then emit the inline jump table. 117804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall emitInlineJumpTable(MI.getOperand(3).getIndex()); 117904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall return; 118025a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor } 118125a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor 118225a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor // Part of binary is determined by TableGn. 118325a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor unsigned Binary = getBinaryCodeForInstr(MI); 118425a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor 118525a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor // Set the conditional execution predicate 118625a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor Binary |= II->getPredicate(&MI) << ARMII::CondShift; 118725a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor 118825a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor if (TID.Opcode == ARM::BX_RET) 118925a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor // The return register is LR. 119025a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor Binary |= ARMRegisterInfo::getRegisterNumbering(ARM::LR); 119125a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor else 119225a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor // otherwise, set the return register 119325a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor Binary |= getMachineOpValue(MI, 0); 119425a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor 119525a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor emitWordLE(Binary); 119625a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor} 119725a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor 11984ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadstatic unsigned encodeVFPRd(const MachineInstr &MI, unsigned OpIdx) { 119925a3ef7cc5fd55dc8cc67c6e6770c8595657e082Douglas Gregor unsigned RegD = MI.getOperand(OpIdx).getReg(); 1200db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor unsigned Binary = 0; 1201db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor bool isSPVFP = false; 1202db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor RegD = ARMRegisterInfo::getRegisterNumbering(RegD, &isSPVFP); 1203db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor if (!isSPVFP) 12041275ae098acda31fe0e434510c729fcfed0458a1Douglas Gregor Binary |= RegD << ARMII::RegRdShift; 12051275ae098acda31fe0e434510c729fcfed0458a1Douglas Gregor else { 12061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift; 12071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= (RegD & 0x01) << ARMII::D_BitShift; 12081275ae098acda31fe0e434510c729fcfed0458a1Douglas Gregor } 12094ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad return Binary; 12104ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad} 12111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1212c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattnerstatic unsigned encodeVFPRn(const MachineInstr &MI, unsigned OpIdx) { 1213c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner unsigned RegN = MI.getOperand(OpIdx).getReg(); 1214c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner unsigned Binary = 0; 1215c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner bool isSPVFP = false; 12164ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad RegN = ARMRegisterInfo::getRegisterNumbering(RegN, &isSPVFP); 12174ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad if (!isSPVFP) 1218c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner Binary |= RegN << ARMII::RegRnShift; 1219c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner else { 12204ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift; 1221c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner Binary |= (RegN & 0x01) << ARMII::N_BitShift; 1222c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner } 12234ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad return Binary; 1224c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner} 1225c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner 12264ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadstatic unsigned encodeVFPRm(const MachineInstr &MI, unsigned OpIdx) { 12274ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned RegM = MI.getOperand(OpIdx).getReg(); 1228442471309fa97348f849687a6a8ef4acc3bc2c1fDouglas Gregor unsigned Binary = 0; 1229442471309fa97348f849687a6a8ef4acc3bc2c1fDouglas Gregor bool isSPVFP = false; 1230442471309fa97348f849687a6a8ef4acc3bc2c1fDouglas Gregor RegM = ARMRegisterInfo::getRegisterNumbering(RegM, &isSPVFP); 1231fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson if (!isSPVFP) 1232fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson Binary |= RegM; 12334ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad else { 12345e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor Binary |= ((RegM & 0x1E) >> 1); 12355e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor Binary |= (RegM & 0x01) << ARMII::M_BitShift; 12365e03f9ea8174ae588c5e69ec6b5ef4c68f8fd766Douglas Gregor } 12374ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad return Binary; 12381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 12390de78998e7bda473b408437053e48661b510d453Fariborz Jahanian 12400de78998e7bda473b408437053e48661b510d453Fariborz Jahaniantemplate<class CodeEmitter> 12411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Emitter<CodeEmitter>::emitVFPArithInstruction(const MachineInstr &MI) { 1242e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner const TargetInstrDesc &TID = MI.getDesc(); 1243e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner 1244e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner // Part of binary is determined by TableGn. 1245e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner unsigned Binary = getBinaryCodeForInstr(MI); 1246e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner 1247e6327747b72bb687c948270f702ff53c30f411a6Chris Lattner // Set the conditional execution predicate 12484ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad Binary |= II->getPredicate(&MI) << ARMII::CondShift; 12491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1250a95d75769edae299816ec7fd9bbcdf1ef617c5c9Eli Friedman unsigned OpIdx = 0; 1251a95d75769edae299816ec7fd9bbcdf1ef617c5c9Eli Friedman assert((Binary & ARMII::D_BitShift) == 0 && 1252a95d75769edae299816ec7fd9bbcdf1ef617c5c9Eli Friedman (Binary & ARMII::N_BitShift) == 0 && 12534ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad (Binary & ARMII::M_BitShift) == 0 && "VFP encoding bug!"); 1254a95d75769edae299816ec7fd9bbcdf1ef617c5c9Eli Friedman 125504e8357f6801e9ff52673e7e899a67bbabf9de93Eli Friedman // Encode Dd / Sd. 125604e8357f6801e9ff52673e7e899a67bbabf9de93Eli Friedman Binary |= encodeVFPRd(MI, OpIdx++); 125704e8357f6801e9ff52673e7e899a67bbabf9de93Eli Friedman 125804e8357f6801e9ff52673e7e899a67bbabf9de93Eli Friedman // If this is a two-address operand, skip it, e.g. FMACD. 125904e8357f6801e9ff52673e7e899a67bbabf9de93Eli Friedman if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) 12604ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad ++OpIdx; 126104e8357f6801e9ff52673e7e899a67bbabf9de93Eli Friedman 12621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Encode Dn / Sn. 12637cfeb08f2466d6263ec6ff1402298f93f6d6991fChris Lattner if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPBinaryFrm) 12641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= encodeVFPRn(MI, OpIdx++); 12654ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 12661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (OpIdx == TID.getNumOperands() || 1267a75cea3f6be0daa8054d36af81a6ffda1713f82dChris Lattner TID.OpInfo[OpIdx].isPredicate() || 1268a75cea3f6be0daa8054d36af81a6ffda1713f82dChris Lattner TID.OpInfo[OpIdx].isOptionalDef()) { 1269a75cea3f6be0daa8054d36af81a6ffda1713f82dChris Lattner // FCMPEZD etc. has only one operand. 12701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump emitWordLE(Binary); 12714ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad return; 12725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 12731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Encode Dm / Sm. 1275716c7304ff5d27a95e1e7823acd1d09d5ec3e37fSteve Naroff Binary |= encodeVFPRm(MI, OpIdx); 1276716c7304ff5d27a95e1e7823acd1d09d5ec3e37fSteve Naroff 12771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump emitWordLE(Binary); 1278f1448a0e4a1e868ff873a8530a61a09cb68666ccSteve Naroff} 1279ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff 1280f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedmantemplate<class CodeEmitter> 1281f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedmanvoid Emitter<CodeEmitter>::emitVFPConversionInstruction( 1282f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall const MachineInstr &MI) { 1283f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman const TargetInstrDesc &TID = MI.getDesc(); 1284f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman unsigned Form = TID.TSFlags & ARMII::FormMask; 1285f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman 1286ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff // Part of binary is determined by TableGn. 1287ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff unsigned Binary = getBinaryCodeForInstr(MI); 1288ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff 12891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Set the conditional execution predicate 1290ec0550fa3653d46560bf4484a2e988329c228e39Steve Naroff Binary |= II->getPredicate(&MI) << ARMII::CondShift; 1291447234dd459a00a5ed9b7c3e066162cd7a75bf2dDouglas Gregor 1292447234dd459a00a5ed9b7c3e066162cd7a75bf2dDouglas Gregor switch (Form) { 12931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump default: break; 1294132f2a2da34f378fc675b9e174564b0f52c31d98Fariborz Jahanian case ARMII::VFPConv1Frm: 1295132f2a2da34f378fc675b9e174564b0f52c31d98Fariborz Jahanian case ARMII::VFPConv2Frm: 1296a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek case ARMII::VFPConv3Frm: 1297de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff // Encode Dd / Sd. 1298389bf46ae41241a656ed71b00ac2177d7f385651Steve Naroff Binary |= encodeVFPRd(MI, 0); 1299a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek break; 1300de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff case ARMII::VFPConv4Frm: 1301389bf46ae41241a656ed71b00ac2177d7f385651Steve Naroff // Encode Dn / Sn. 1302a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek Binary |= encodeVFPRn(MI, 0); 130313dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian break; 13048baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson case ARMII::VFPConv5Frm: 13054084c306635b70f37029dca938444e6013f08684Steve Naroff // Encode Dm / Sm. 13064084c306635b70f37029dca938444e6013f08684Steve Naroff Binary |= encodeVFPRm(MI, 0); 13074084c306635b70f37029dca938444e6013f08684Steve Naroff break; 13088baaca50f07d0c10bba69c8d88c1b9078c92d06dAnders Carlsson } 1309a8f8dac6a29f6d33474a38a32ce9dd859b696da9Fariborz Jahanian 1310a8f8dac6a29f6d33474a38a32ce9dd859b696da9Fariborz Jahanian switch (Form) { 13113d815e7eb56c25d7ed812eced32e41df43039f9aEli Friedman default: break; 131214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff case ARMII::VFPConv1Frm: 131314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff // Encode Dm / Sm. 1314c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall Binary |= encodeVFPRm(MI, 1); 1315c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall break; 1316132f2a2da34f378fc675b9e174564b0f52c31d98Fariborz Jahanian case ARMII::VFPConv2Frm: 1317132f2a2da34f378fc675b9e174564b0f52c31d98Fariborz Jahanian case ARMII::VFPConv3Frm: 1318132f2a2da34f378fc675b9e174564b0f52c31d98Fariborz Jahanian // Encode Dn / Sn. 1319389bf46ae41241a656ed71b00ac2177d7f385651Steve Naroff Binary |= encodeVFPRn(MI, 1); 1320db07b3f7cdcb505329c1280d7cf70791739a7cadFariborz Jahanian break; 1321db07b3f7cdcb505329c1280d7cf70791739a7cadFariborz Jahanian case ARMII::VFPConv4Frm: 1322569c3166874324c24011f8ade6978421f0d39b3cDouglas Gregor case ARMII::VFPConv5Frm: 1323569c3166874324c24011f8ade6978421f0d39b3cDouglas Gregor // Encode Dd / Sd. 13243d815e7eb56c25d7ed812eced32e41df43039f9aEli Friedman Binary |= encodeVFPRd(MI, 1); 1325447234dd459a00a5ed9b7c3e066162cd7a75bf2dDouglas Gregor break; 1326447234dd459a00a5ed9b7c3e066162cd7a75bf2dDouglas Gregor } 1327447234dd459a00a5ed9b7c3e066162cd7a75bf2dDouglas Gregor 1328447234dd459a00a5ed9b7c3e066162cd7a75bf2dDouglas Gregor if (Form == ARMII::VFPConv5Frm) 13294846675e0e42d1802b0ffd8972a45e72aeb3758dPeter Collingbourne // Encode Dn / Sn. 13304846675e0e42d1802b0ffd8972a45e72aeb3758dPeter Collingbourne Binary |= encodeVFPRn(MI, 2); 13314846675e0e42d1802b0ffd8972a45e72aeb3758dPeter Collingbourne else if (Form == ARMII::VFPConv3Frm) 13324846675e0e42d1802b0ffd8972a45e72aeb3758dPeter Collingbourne // Encode Dm / Sm. 13334846675e0e42d1802b0ffd8972a45e72aeb3758dPeter Collingbourne Binary |= encodeVFPRm(MI, 2); 13344846675e0e42d1802b0ffd8972a45e72aeb3758dPeter Collingbourne 13352390a72a3ebd37737fec5ba1385db9c3bb22fc59Fariborz Jahanian emitWordLE(Binary); 13362390a72a3ebd37737fec5ba1385db9c3bb22fc59Fariborz Jahanian} 13373d815e7eb56c25d7ed812eced32e41df43039f9aEli Friedman 1338000835d0b04345c0014c603fe6339b3bc154050eFariborz Jahaniantemplate<class CodeEmitter> 1339000835d0b04345c0014c603fe6339b3bc154050eFariborz Jahanianvoid Emitter<CodeEmitter>::emitVFPLoadStoreInstruction(const MachineInstr &MI) { 1340000835d0b04345c0014c603fe6339b3bc154050eFariborz Jahanian // Part of binary is determined by TableGn. 1341a95d75769edae299816ec7fd9bbcdf1ef617c5c9Eli Friedman unsigned Binary = getBinaryCodeForInstr(MI); 1342368eefa081d12f0a265ee90ee8ec61b54168d57dChris Lattner 1343ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman // Set the conditional execution predicate 1344ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman Binary |= II->getPredicate(&MI) << ARMII::CondShift; 1345ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman 1346ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman unsigned OpIdx = 0; 1347ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman 13484ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad // Encode Dd / Sd. 1349ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman Binary |= encodeVFPRd(MI, OpIdx++); 1350ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman 1351ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman // Encode address base. 1352ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman const MachineOperand &Base = MI.getOperand(OpIdx++); 1353ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman Binary |= getMachineOpValue(MI, Base) << ARMII::RegRnShift; 1354ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman 1355ad74a758189180b8ab8faea648e4766c3bfd7fcbEli Friedman // If there is a non-zero immediate offset, encode it. 1356e22d911dcff7a9c18b583817b7319c07600fd3eeTed Kremenek if (Base.isReg()) { 1357e22d911dcff7a9c18b583817b7319c07600fd3eeTed Kremenek const MachineOperand &Offset = MI.getOperand(OpIdx); 13581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (unsigned ImmOffs = ARM_AM::getAM5Offset(Offset.getImm())) { 1359e22d911dcff7a9c18b583817b7319c07600fd3eeTed Kremenek if (ARM_AM::getAM5Op(Offset.getImm()) == ARM_AM::add) 1360e22d911dcff7a9c18b583817b7319c07600fd3eeTed Kremenek Binary |= 1 << ARMII::U_BitShift; 13611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Binary |= ImmOffs; 1362e22d911dcff7a9c18b583817b7319c07600fd3eeTed Kremenek emitWordLE(Binary); 1363e22d911dcff7a9c18b583817b7319c07600fd3eeTed Kremenek return; 1364e22d911dcff7a9c18b583817b7319c07600fd3eeTed Kremenek } 13651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 13661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1367e22d911dcff7a9c18b583817b7319c07600fd3eeTed Kremenek // If immediate offset is omitted, default to +0. 13680cd7fc28d4f69b281522b1bc96decd2b92cfd812Daniel Dunbar Binary |= 1 << ARMII::U_BitShift; 13690cd7fc28d4f69b281522b1bc96decd2b92cfd812Daniel Dunbar 13700cd7fc28d4f69b281522b1bc96decd2b92cfd812Daniel Dunbar emitWordLE(Binary); 13710cd7fc28d4f69b281522b1bc96decd2b92cfd812Daniel Dunbar} 13720cd7fc28d4f69b281522b1bc96decd2b92cfd812Daniel Dunbar 13734ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadtemplate<class CodeEmitter> 13740cd7fc28d4f69b281522b1bc96decd2b92cfd812Daniel Dunbarvoid Emitter<CodeEmitter>::emitVFPLoadStoreMultipleInstruction( 13750cd7fc28d4f69b281522b1bc96decd2b92cfd812Daniel Dunbar const MachineInstr &MI) { 13760cd7fc28d4f69b281522b1bc96decd2b92cfd812Daniel Dunbar // Part of binary is determined by TableGn. 13770cd7fc28d4f69b281522b1bc96decd2b92cfd812Daniel Dunbar unsigned Binary = getBinaryCodeForInstr(MI); 13780cd7fc28d4f69b281522b1bc96decd2b92cfd812Daniel Dunbar 13798a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis // Set the conditional execution predicate 13808a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis Binary |= II->getPredicate(&MI) << ARMII::CondShift; 13818a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis 13828a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis // Set base address operand 13838a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift; 13848b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian 13858b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian // Set addressing mode by modifying bits U(23) and P(24) 13868b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian const MachineOperand &MO = MI.getOperand(1); 13878b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian Binary |= getAddrModeUPBits(ARM_AM::getAM5SubMode(MO.getImm())); 13888b789139167d721e3ef1e3d433eabeb351c36fadFariborz Jahanian 13898a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis // Set bit W(21) 13908a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis if (ARM_AM::getAM5WBFlag(MO.getImm())) 13918a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis Binary |= 0x1 << ARMII::W_BitShift; 13928a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis 13938a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis // First register is encoded in Dd. 13948a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis Binary |= encodeVFPRd(MI, 4); 13951ceee5c42d5c410217f67d384eecc6ea4a2bba9bFariborz Jahanian 13961ceee5c42d5c410217f67d384eecc6ea4a2bba9bFariborz Jahanian // Number of registers are encoded in offset field. 13971ceee5c42d5c410217f67d384eecc6ea4a2bba9bFariborz Jahanian unsigned NumRegs = 1; 13981ceee5c42d5c410217f67d384eecc6ea4a2bba9bFariborz Jahanian for (unsigned i = 5, e = MI.getNumOperands(); i != e; ++i) { 13991ceee5c42d5c410217f67d384eecc6ea4a2bba9bFariborz Jahanian const MachineOperand &MO = MI.getOperand(i); 1400830937bc1100fba7682f7c32c40512085870f50cFariborz Jahanian if (!MO.isReg() || MO.isImplicit()) 14018a1d722f13df383600f36d77f842957c8adb5f1bArgyrios Kyrtzidis break; 1402a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall ++NumRegs; 1403b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis } 1404a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall Binary |= NumRegs * 2; 1405b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis 1406b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis emitWordLE(Binary); 1407b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis} 1408b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis 1409b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidistemplate<class CodeEmitter> 1410109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCallvoid Emitter<CodeEmitter>::emitMiscInstruction(const MachineInstr &MI) { 1411109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall // Part of binary is determined by TableGn. 1412109de5ead1dfcb3bc985cddb8cb3ed5bcecad88dJohn McCall unsigned Binary = getBinaryCodeForInstr(MI); 14134ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad 1414b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis // Set the conditional execution predicate 1415a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall Binary |= II->getPredicate(&MI) << ARMII::CondShift; 1416a4eb74d4dfe126c686dc708fec444c85ffb73b47John McCall 1417a4eb74d4dfe126c686dc708fec444c85ffb73b47John McCall emitWordLE(Binary); 1418a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall} 14196952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor 14206952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor#include "ARMGenCodeEmitter.inc" 1421a4eb74d4dfe126c686dc708fec444c85ffb73b47John McCall