131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information -------------===// 2d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov// 3d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov// The LLVM Compiler Infrastructure 4d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov// 5d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov// This file is distributed under the University of Illinois Open Source 6d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov// License. See LICENSE.TXT for details. 7d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov// 8d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov//===----------------------------------------------------------------------===// 9d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov// 10b50ea5c48f8b1ce259e034ca5c16dc14af1a582cDavid Goodwin// This file contains the Thumb-2 implementation of the TargetInstrInfo class. 11d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov// 12d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov//===----------------------------------------------------------------------===// 13d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov 14b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#include "Thumb2InstrInfo.h" 15d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov#include "ARM.h" 16b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#include "ARMConstantPoolValue.h" 17d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov#include "ARMMachineFunctionInfo.h" 18ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 19d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 20d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 21e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng#include "llvm/CodeGen/MachineMemOperand.h" 22c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach#include "llvm/MC/MCInst.h" 2313151432edace19ee867a93b5c14573df4f75d24Evan Cheng#include "llvm/Support/CommandLine.h" 24d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov 25d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikovusing namespace llvm; 26d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov 27aa9f0a57d03b1eef5a58c48b05f6657d2a5a0d0aOwen Andersonstatic cl::opt<bool> 28aa9f0a57d03b1eef5a58c48b05f6657d2a5a0d0aOwen AndersonOldT2IfCvt("old-thumb2-ifcvt", cl::Hidden, 29aa9f0a57d03b1eef5a58c48b05f6657d2a5a0d0aOwen Anderson cl::desc("Use old-style Thumb2 if-conversion heuristics"), 30aa9f0a57d03b1eef5a58c48b05f6657d2a5a0d0aOwen Anderson cl::init(false)); 31aa9f0a57d03b1eef5a58c48b05f6657d2a5a0d0aOwen Anderson 32f95215f551949d5e5adfbf4753aa833b9009b77aAnton KorobeynikovThumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI) 33f95215f551949d5e5adfbf4753aa833b9009b77aAnton Korobeynikov : ARMBaseInstrInfo(STI), RI(*this, STI) { 34d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov} 35d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov 36c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach/// getNoopForMachoTarget - Return the noop instruction to use for a noop. 37c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbachvoid Thumb2InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { 38c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach NopInst.setOpcode(ARM::tNOP); 39c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 40c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach NopInst.addOperand(MCOperand::CreateReg(0)); 41c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach} 42c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach 43446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Chengunsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const { 44334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin // FIXME 45334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin return 0; 46334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin} 47334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin 4886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Chengvoid 4986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan ChengThumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, 5086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng MachineBasicBlock *NewDest) const { 5186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng MachineBasicBlock *MBB = Tail->getParent(); 5286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>(); 5386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng if (!AFI->hasITBlocks()) { 5486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng TargetInstrInfoImpl::ReplaceTailWithBranchTo(Tail, NewDest); 5586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng return; 5686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng } 5786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng 5886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng // If the first instruction of Tail is predicated, we may have to update 5986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng // the IT instruction. 6086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng unsigned PredReg = 0; 61c89c744b69cecac576317a98322fd295e36e9886Craig Topper ARMCC::CondCodes CC = getInstrPredicate(Tail, PredReg); 6286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng MachineBasicBlock::iterator MBBI = Tail; 6386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng if (CC != ARMCC::AL) 6486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng // Expecting at least the t2IT instruction before it. 6586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng --MBBI; 6686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng 6786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng // Actually replace the tail. 6886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng TargetInstrInfoImpl::ReplaceTailWithBranchTo(Tail, NewDest); 6986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng 7086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng // Fix up IT. 7186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng if (CC != ARMCC::AL) { 7286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng MachineBasicBlock::iterator E = MBB->begin(); 7386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng unsigned Count = 4; // At most 4 instructions in an IT block. 7486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng while (Count && MBBI != E) { 7586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng if (MBBI->isDebugValue()) { 7686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng --MBBI; 7786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng continue; 7886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng } 7986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng if (MBBI->getOpcode() == ARM::t2IT) { 8086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng unsigned Mask = MBBI->getOperand(1).getImm(); 8186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng if (Count == 4) 8286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng MBBI->eraseFromParent(); 8386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng else { 8486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng unsigned MaskOn = 1 << Count; 8586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng unsigned MaskOff = ~(MaskOn - 1); 8686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn); 8786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng } 8886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng return; 8986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng } 9086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng --MBBI; 9186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng --Count; 9286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng } 9386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng 9486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng // Ctrl flow can reach here if branch folding is run before IT block 9586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng // formation pass. 9686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng } 9786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng} 9886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng 99334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwinbool 1004d54e5b2dd4a3d3bed38ff9c7aa57fc66adb5855Evan ChengThumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB, 1014d54e5b2dd4a3d3bed38ff9c7aa57fc66adb5855Evan Cheng MachineBasicBlock::iterator MBBI) const { 1020a921698b6d6f8a40df3893a72c7e6ced1c919a0Evan Cheng while (MBBI->isDebugValue()) { 103557b297f35395a6104a77ed6a798f10c2b46bfbeEvan Cheng ++MBBI; 1040a921698b6d6f8a40df3893a72c7e6ced1c919a0Evan Cheng if (MBBI == MBB.end()) 1050a921698b6d6f8a40df3893a72c7e6ced1c919a0Evan Cheng return false; 1060a921698b6d6f8a40df3893a72c7e6ced1c919a0Evan Cheng } 107557b297f35395a6104a77ed6a798f10c2b46bfbeEvan Cheng 1084d54e5b2dd4a3d3bed38ff9c7aa57fc66adb5855Evan Cheng unsigned PredReg = 0; 109c89c744b69cecac576317a98322fd295e36e9886Craig Topper return getITInstrPredicate(MBBI, PredReg) == ARMCC::AL; 11013151432edace19ee867a93b5c14573df4f75d24Evan Cheng} 1114d54e5b2dd4a3d3bed38ff9c7aa57fc66adb5855Evan Cheng 112ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesenvoid Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 113ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen MachineBasicBlock::iterator I, DebugLoc DL, 114ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen unsigned DestReg, unsigned SrcReg, 115ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen bool KillSrc) const { 11608b93c6a70ae59af375f205cfcffeaa3517577abEvan Cheng // Handle SPR, DPR, and QPR copies. 117ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen if (!ARM::GPRRegClass.contains(DestReg, SrcReg)) 118ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc); 119ac2736670034e8942939b9fccf8e4618a0bda908Jakob Stoklund Olesen 1202a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg) 12163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach .addReg(SrcReg, getKillRegState(KillSrc))); 122b8e9ac834a9c253e3f8f5caa8f229bafba0b4fcfAnton Korobeynikov} 1235732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng 1245732ca084aaa0cd26149e50dd4b487efff37fe41Evan Chengvoid Thumb2InstrInfo:: 1255732ca084aaa0cd26149e50dd4b487efff37fe41Evan ChengstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 1265732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng unsigned SrcReg, bool isKill, int FI, 127746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterClass *RC, 128746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterInfo *TRI) const { 129420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass || 130420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass || 131420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC == &ARM::GPRnopcRegClass) { 132746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng DebugLoc DL; 133746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng if (I != MBB.end()) DL = I->getDebugLoc(); 134746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng 135e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng MachineFunction &MF = *MBB.getParent(); 136e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng MachineFrameInfo &MFI = *MF.getFrameInfo(); 137e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng MachineMemOperand *MMO = 138978e0dfe46e481bfb1281e683aa308329e879e95Jay Foad MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), 13959db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner MachineMemOperand::MOStore, 140e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng MFI.getObjectSize(FI), 141e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng MFI.getObjectAlignment(FI)); 1425732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2STRi12)) 1435732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng .addReg(SrcReg, getKillRegState(isKill)) 144e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 1455732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng return; 1465732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng } 1475732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng 148746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI); 1495732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng} 1505732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng 1515732ca084aaa0cd26149e50dd4b487efff37fe41Evan Chengvoid Thumb2InstrInfo:: 1525732ca084aaa0cd26149e50dd4b487efff37fe41Evan ChengloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 1535732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng unsigned DestReg, int FI, 154746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterClass *RC, 155746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterInfo *TRI) const { 156420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass || 157420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass || 158420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC == &ARM::GPRnopcRegClass) { 159746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng DebugLoc DL; 160746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng if (I != MBB.end()) DL = I->getDebugLoc(); 161746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng 162e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng MachineFunction &MF = *MBB.getParent(); 163e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng MachineFrameInfo &MFI = *MF.getFrameInfo(); 164e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng MachineMemOperand *MMO = 165978e0dfe46e481bfb1281e683aa308329e879e95Jay Foad MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), 16659db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner MachineMemOperand::MOLoad, 167e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng MFI.getObjectSize(FI), 168e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng MFI.getObjectAlignment(FI)); 1695732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg) 170e3ce8aab0a6de939f8cfa4f8cb2e3a3bf4e1fe21Evan Cheng .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 1715732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng return; 1725732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng } 1735732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng 174746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI); 1755732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng} 1766495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 1776495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengvoid llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB, 1786495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MachineBasicBlock::iterator &MBBI, DebugLoc dl, 1796495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng unsigned DestReg, unsigned BaseReg, int NumBytes, 1806495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng ARMCC::CondCodes Pred, unsigned PredReg, 18157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov const ARMBaseInstrInfo &TII, unsigned MIFlags) { 1826495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng bool isSub = NumBytes < 0; 1836495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (isSub) NumBytes = -NumBytes; 1846495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 1856495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // If profitable, use a movw or movt to materialize the offset. 1866495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // FIXME: Use the scavenger to grab a scratch register. 1876495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (DestReg != ARM::SP && DestReg != BaseReg && 1886495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng NumBytes >= 4096 && 1896495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng ARM_AM::getT2SOImmVal(NumBytes) == -1) { 1906495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng bool Fits = false; 1916495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (NumBytes < 65536) { 1926495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Use a movw to materialize the 16-bit constant. 1936495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg) 1946495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng .addImm(NumBytes) 19557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags); 1966495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Fits = true; 1976495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } else if ((NumBytes & 0xffff) == 0) { 1986495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Use a movt to materialize the 32-bit constant. 1996495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg) 2006495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng .addReg(DestReg) 2016495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng .addImm(NumBytes >> 16) 20257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags); 2036495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Fits = true; 2046495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 2056495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 2066495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (Fits) { 2076495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (isSub) { 2086495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg) 2096495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng .addReg(BaseReg, RegState::Kill) 2106495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng .addReg(DestReg, RegState::Kill) 21157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov .addImm((unsigned)Pred).addReg(PredReg).addReg(0) 21257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov .setMIFlags(MIFlags); 2136495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } else { 2146495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg) 2156495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng .addReg(DestReg, RegState::Kill) 2166495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng .addReg(BaseReg, RegState::Kill) 21757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov .addImm((unsigned)Pred).addReg(PredReg).addReg(0) 21857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov .setMIFlags(MIFlags); 2196495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 2206495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng return; 2216495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 2226495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 2236495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 2246495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng while (NumBytes) { 2256495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng unsigned ThisVal = NumBytes; 226861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng unsigned Opc = 0; 227861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng if (DestReg == ARM::SP && BaseReg != ARM::SP) { 228861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng // mov sp, rn. Note t2MOVr cannot be used. 2292a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),DestReg) 23063b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach .addReg(BaseReg).setMIFlags(MIFlags)); 231861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng BaseReg = ARM::SP; 232861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng continue; 233861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng } 234861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng 235f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson bool HasCCOut = true; 236861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng if (BaseReg == ARM::SP) { 237861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng // sub sp, sp, #imm7 238861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) { 239861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?"); 240861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 2415b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 2425b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach .addReg(BaseReg).addImm(ThisVal/4).setMIFlags(MIFlags)); 243861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng NumBytes = 0; 244861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng continue; 245861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng } 246861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng 247861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng // sub rd, sp, so_imm 248f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri; 249861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng if (ARM_AM::getT2SOImmVal(NumBytes) != -1) { 250861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng NumBytes = 0; 251861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng } else { 252861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng // FIXME: Move this to ARMAddressingModes.h? 253861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng unsigned RotAmt = CountLeadingZeros_32(ThisVal); 254861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); 255861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng NumBytes &= ~ThisVal; 256861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && 257861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng "Bit extraction didn't work?"); 258861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng } 2596495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } else { 260861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng assert(DestReg != ARM::SP && BaseReg != ARM::SP); 261861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri; 262861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng if (ARM_AM::getT2SOImmVal(NumBytes) != -1) { 263861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng NumBytes = 0; 264861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng } else if (ThisVal < 4096) { 265861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; 266f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson HasCCOut = false; 267861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng NumBytes = 0; 268861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng } else { 269861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng // FIXME: Move this to ARMAddressingModes.h? 270861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng unsigned RotAmt = CountLeadingZeros_32(ThisVal); 271861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt); 272861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng NumBytes &= ~ThisVal; 273861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 && 274861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng "Bit extraction didn't work?"); 275861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng } 2766495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 2776495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 2786495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Build the new ADD / SUB. 279f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson MachineInstrBuilder MIB = 280f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 281f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson .addReg(BaseReg, RegState::Kill) 28257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov .addImm(ThisVal)).setMIFlags(MIFlags); 283f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson if (HasCCOut) 284f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson AddDefaultCC(MIB); 285861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng 2866495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng BaseReg = DestReg; 2876495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 2886495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng} 2896495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 2906495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengstatic unsigned 2916495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengnegativeOffsetOpcode(unsigned opcode) 2926495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng{ 2936495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng switch (opcode) { 2946495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRi12: return ARM::t2LDRi8; 2956495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRHi12: return ARM::t2LDRHi8; 2966495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRBi12: return ARM::t2LDRBi8; 2976495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSHi12: return ARM::t2LDRSHi8; 2986495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSBi12: return ARM::t2LDRSBi8; 2996495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRi12: return ARM::t2STRi8; 3006495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRBi12: return ARM::t2STRBi8; 3016495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRHi12: return ARM::t2STRHi8; 3026495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3036495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRi8: 3046495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRHi8: 3056495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRBi8: 3066495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSHi8: 3076495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSBi8: 3086495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRi8: 3096495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRBi8: 3106495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRHi8: 3116495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng return opcode; 3126495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3136495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng default: 3146495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng break; 3156495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 3166495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3176495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng return 0; 3186495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng} 3196495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3206495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengstatic unsigned 3216495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengpositiveOffsetOpcode(unsigned opcode) 3226495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng{ 3236495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng switch (opcode) { 3246495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRi8: return ARM::t2LDRi12; 3256495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRHi8: return ARM::t2LDRHi12; 3266495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRBi8: return ARM::t2LDRBi12; 3276495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSHi8: return ARM::t2LDRSHi12; 3286495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSBi8: return ARM::t2LDRSBi12; 3296495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRi8: return ARM::t2STRi12; 3306495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRBi8: return ARM::t2STRBi12; 3316495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRHi8: return ARM::t2STRHi12; 3326495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3336495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRi12: 3346495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRHi12: 3356495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRBi12: 3366495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSHi12: 3376495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSBi12: 3386495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRi12: 3396495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRBi12: 3406495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRHi12: 3416495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng return opcode; 3426495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3436495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng default: 3446495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng break; 3456495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 3466495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3476495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng return 0; 3486495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng} 3496495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3506495f63945e8dbde81f03a1dc2ab421993b9a495Evan Chengstatic unsigned 3516495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengimmediateOffsetOpcode(unsigned opcode) 3526495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng{ 3536495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng switch (opcode) { 3546495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRs: return ARM::t2LDRi12; 3556495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRHs: return ARM::t2LDRHi12; 3566495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRBs: return ARM::t2LDRBi12; 3576495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSHs: return ARM::t2LDRSHi12; 3586495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSBs: return ARM::t2LDRSBi12; 3596495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRs: return ARM::t2STRi12; 3606495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRBs: return ARM::t2STRBi12; 3616495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRHs: return ARM::t2STRHi12; 3626495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3636495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRi12: 3646495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRHi12: 3656495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRBi12: 3666495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSHi12: 3676495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSBi12: 3686495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRi12: 3696495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRBi12: 3706495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRHi12: 3716495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRi8: 3726495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRHi8: 3736495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRBi8: 3746495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSHi8: 3756495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2LDRSBi8: 3766495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRi8: 3776495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRBi8: 3786495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng case ARM::t2STRHi8: 3796495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng return opcode; 3806495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3816495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng default: 3826495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng break; 3836495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 3846495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3856495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng return 0; 3866495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng} 3876495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 388cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Chengbool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 389cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng unsigned FrameReg, int &Offset, 390cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng const ARMBaseInstrInfo &TII) { 3916495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng unsigned Opcode = MI.getOpcode(); 392e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng const MCInstrDesc &Desc = MI.getDesc(); 3936495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 3946495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng bool isSub = false; 3956495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 3966495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Memory operands in inline assembly always use AddrModeT2_i12. 3976495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (Opcode == ARM::INLINEASM) 3986495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2? 399764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach 4006495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) { 4016495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Offset += MI.getOperand(FrameRegIdx+1).getImm(); 402861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng 40335f0febcb66b5a50a5a750efcbefc95f7fc25c7bJakob Stoklund Olesen unsigned PredReg; 40435f0febcb66b5a50a5a750efcbefc95f7fc25c7bJakob Stoklund Olesen if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) { 4056495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Turn it into a move. 4062a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach MI.setDesc(TII.get(ARM::tMOVr)); 4076495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 40835f0febcb66b5a50a5a750efcbefc95f7fc25c7bJakob Stoklund Olesen // Remove offset and remaining explicit predicate operands. 40935f0febcb66b5a50a5a750efcbefc95f7fc25c7bJakob Stoklund Olesen do MI.RemoveOperand(FrameRegIdx+1); 41063b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach while (MI.getNumOperands() > FrameRegIdx+1); 41163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach MachineInstrBuilder MIB(&MI); 41263b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach AddDefaultPred(MIB); 413cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng return true; 4146495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 4156495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 416f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson bool HasCCOut = Opcode != ARM::t2ADDri12; 417f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson 4186495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (Offset < 0) { 4196495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Offset = -Offset; 4206495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng isSub = true; 421f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach MI.setDesc(TII.get(ARM::t2SUBri)); 422861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng } else { 423f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach MI.setDesc(TII.get(ARM::t2ADDri)); 4246495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 4256495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 4266495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Common case: small offset, fits into instruction. 4276495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (ARM_AM::getT2SOImmVal(Offset) != -1) { 4286495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 4296495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); 430f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson // Add cc_out operand if the original instruction did not have one. 431f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson if (!HasCCOut) 432f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson MI.addOperand(MachineOperand::CreateReg(0, false)); 433cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng Offset = 0; 434cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng return true; 4356495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 4366495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Another common case: imm12. 437f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson if (Offset < 4096 && 438f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) { 439f6fd90910a552ad9883f031350ae517e26dfdb44Jim Grosbach unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; 440861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng MI.setDesc(TII.get(NewOpc)); 4416495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 4426495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); 443f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson // Remove the cc_out operand. 444f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson if (HasCCOut) 445f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson MI.RemoveOperand(MI.getNumOperands()-1); 446cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng Offset = 0; 447cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng return true; 4486495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 4496495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 4506495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Otherwise, extract 8 adjacent bits from the immediate into this 4516495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // t2ADDri/t2SUBri. 4526495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng unsigned RotAmt = CountLeadingZeros_32(Offset); 4536495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt); 4546495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 4556495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // We will handle these bits from offset, clear them. 4566495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Offset &= ~ThisImmVal; 4576495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 4586495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 && 4596495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng "Bit extraction didn't work?"); 4606495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal); 461f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson // Add cc_out operand if the original instruction did not have one. 462f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson if (!HasCCOut) 463f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson MI.addOperand(MachineOperand::CreateReg(0, false)); 464f5fd499791bd65a31183324dabc5eefc201f9e2eBob Wilson 4656495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } else { 466e4863f47596794df3dd955b6b7064863c50eabe4Bob Wilson 467e6373eb8264ba4804de28d8224e9f7725d3a483cBob Wilson // AddrMode4 and AddrMode6 cannot handle any offset. 468e6373eb8264ba4804de28d8224e9f7725d3a483cBob Wilson if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6) 469e4863f47596794df3dd955b6b7064863c50eabe4Bob Wilson return false; 470e4863f47596794df3dd955b6b7064863c50eabe4Bob Wilson 4716495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // AddrModeT2_so cannot handle any offset. If there is no offset 4726495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // register then we change to an immediate version. 473861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng unsigned NewOpc = Opcode; 4746495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (AddrMode == ARMII::AddrModeT2_so) { 4756495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg(); 4766495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (OffsetReg != 0) { 4776495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 478cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng return Offset == 0; 4796495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 480764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach 4816495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.RemoveOperand(FrameRegIdx+1); 4826495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0); 4836495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng NewOpc = immediateOffsetOpcode(Opcode); 4846495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng AddrMode = ARMII::AddrModeT2_i12; 4856495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 4866495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 4876495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng unsigned NumBits = 0; 4886495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng unsigned Scale = 1; 4896495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) { 4906495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // i8 supports only negative, and i12 supports only positive, so 4916495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // based on Offset sign convert Opcode to the appropriate 4926495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // instruction 4936495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Offset += MI.getOperand(FrameRegIdx+1).getImm(); 4946495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (Offset < 0) { 4956495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng NewOpc = negativeOffsetOpcode(Opcode); 4966495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng NumBits = 8; 4976495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng isSub = true; 4986495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Offset = -Offset; 4996495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } else { 5006495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng NewOpc = positiveOffsetOpcode(Opcode); 5016495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng NumBits = 12; 5026495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 503e6373eb8264ba4804de28d8224e9f7725d3a483cBob Wilson } else if (AddrMode == ARMII::AddrMode5) { 504e6373eb8264ba4804de28d8224e9f7725d3a483cBob Wilson // VFP address mode. 505e6373eb8264ba4804de28d8224e9f7725d3a483cBob Wilson const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1); 506e6373eb8264ba4804de28d8224e9f7725d3a483cBob Wilson int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm()); 507e6373eb8264ba4804de28d8224e9f7725d3a483cBob Wilson if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub) 508e6373eb8264ba4804de28d8224e9f7725d3a483cBob Wilson InstrOffs *= -1; 5096495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng NumBits = 8; 5106495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Scale = 4; 5116495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Offset += InstrOffs * 4; 5126495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); 5136495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (Offset < 0) { 5146495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Offset = -Offset; 5156495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng isSub = true; 5166495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 517e6373eb8264ba4804de28d8224e9f7725d3a483cBob Wilson } else { 518e6373eb8264ba4804de28d8224e9f7725d3a483cBob Wilson llvm_unreachable("Unsupported addressing mode!"); 5196495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 5206495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 5216495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (NewOpc != Opcode) 5226495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.setDesc(TII.get(NewOpc)); 5236495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 5246495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1); 5256495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 5266495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Attempt to fold address computation 5276495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Common case: small offset, fits into instruction. 5286495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng int ImmedOffset = Offset / Scale; 5296495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng unsigned Mask = (1 << NumBits) - 1; 5306495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if ((unsigned)Offset <= Mask * Scale) { 5316495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Replace the FrameIndex with fp/sp 5326495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 5336495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (isSub) { 5346495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (AddrMode == ARMII::AddrMode5) 5356495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // FIXME: Not consistent. 5366495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng ImmedOffset |= 1 << NumBits; 537764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach else 5386495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng ImmedOffset = -ImmedOffset; 5396495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 5406495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng ImmOp.ChangeToImmediate(ImmedOffset); 541cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng Offset = 0; 542cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng return true; 5436495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 544764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach 5456495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // Otherwise, offset doesn't fit. Pull in what we can to simplify 546d9453784fbcbbf052a32752d00e3b7d0004fda55David Goodwin ImmedOffset = ImmedOffset & Mask; 5476495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (isSub) { 5486495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (AddrMode == ARMII::AddrMode5) 5496495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng // FIXME: Not consistent. 5506495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng ImmedOffset |= 1 << NumBits; 551a8e8984ee4c197634839cf228f5b1d79a77fa4b9Evan Cheng else { 5526495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng ImmedOffset = -ImmedOffset; 553a8e8984ee4c197634839cf228f5b1d79a77fa4b9Evan Cheng if (ImmedOffset == 0) 554a8e8984ee4c197634839cf228f5b1d79a77fa4b9Evan Cheng // Change the opcode back if the encoded offset is zero. 555a8e8984ee4c197634839cf228f5b1d79a77fa4b9Evan Cheng MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc))); 556a8e8984ee4c197634839cf228f5b1d79a77fa4b9Evan Cheng } 5576495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 5586495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng ImmOp.ChangeToImmediate(ImmedOffset); 5596495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Offset &= ~(Mask*Scale); 5606495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 5616495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 562cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng Offset = (isSub) ? -Offset : Offset; 563cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng return Offset == 0; 5646495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng} 56568fc2daf8fa446be04d2ed2b3cbb1b00c382458fEvan Cheng 5664d54e5b2dd4a3d3bed38ff9c7aa57fc66adb5855Evan ChengARMCC::CondCodes 5674d54e5b2dd4a3d3bed38ff9c7aa57fc66adb5855Evan Chengllvm::getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg) { 5684d54e5b2dd4a3d3bed38ff9c7aa57fc66adb5855Evan Cheng unsigned Opc = MI->getOpcode(); 5694d54e5b2dd4a3d3bed38ff9c7aa57fc66adb5855Evan Cheng if (Opc == ARM::tBcc || Opc == ARM::t2Bcc) 5704d54e5b2dd4a3d3bed38ff9c7aa57fc66adb5855Evan Cheng return ARMCC::AL; 571c89c744b69cecac576317a98322fd295e36e9886Craig Topper return getInstrPredicate(MI, PredReg); 5724d54e5b2dd4a3d3bed38ff9c7aa57fc66adb5855Evan Cheng} 573