/3rd_party/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp

https://code.google.com/p/softart/ · C++ · 631 lines · 498 code · 69 blank · 64 comment · 158 complexity · 3fac9cfa93ebf5ca4cff3a07d7777011 MD5 · raw file

  1. //===-- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information -------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file contains the Thumb-2 implementation of the TargetInstrInfo class.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "Thumb2InstrInfo.h"
  14. #include "ARM.h"
  15. #include "ARMConstantPoolValue.h"
  16. #include "ARMMachineFunctionInfo.h"
  17. #include "MCTargetDesc/ARMAddressingModes.h"
  18. #include "llvm/CodeGen/MachineFrameInfo.h"
  19. #include "llvm/CodeGen/MachineInstrBuilder.h"
  20. #include "llvm/CodeGen/MachineMemOperand.h"
  21. #include "llvm/CodeGen/MachineRegisterInfo.h"
  22. #include "llvm/MC/MCInst.h"
  23. #include "llvm/Support/CommandLine.h"
  24. using namespace llvm;
  25. static cl::opt<bool>
  26. OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden,
  27. cl::desc("Use old-style Thumb2 if-conversion heuristics"),
  28. cl::init(false));
  29. Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
  30. : ARMBaseInstrInfo(STI), RI(STI) {
  31. }
  32. /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
  33. void Thumb2InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
  34. NopInst.setOpcode(ARM::tHINT);
  35. NopInst.addOperand(MCOperand::CreateImm(0));
  36. NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
  37. NopInst.addOperand(MCOperand::CreateReg(0));
  38. }
  39. unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
  40. // FIXME
  41. return 0;
  42. }
  43. void
  44. Thumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
  45. MachineBasicBlock *NewDest) const {
  46. MachineBasicBlock *MBB = Tail->getParent();
  47. ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
  48. if (!AFI->hasITBlocks()) {
  49. TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest);
  50. return;
  51. }
  52. // If the first instruction of Tail is predicated, we may have to update
  53. // the IT instruction.
  54. unsigned PredReg = 0;
  55. ARMCC::CondCodes CC = getInstrPredicate(Tail, PredReg);
  56. MachineBasicBlock::iterator MBBI = Tail;
  57. if (CC != ARMCC::AL)
  58. // Expecting at least the t2IT instruction before it.
  59. --MBBI;
  60. // Actually replace the tail.
  61. TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest);
  62. // Fix up IT.
  63. if (CC != ARMCC::AL) {
  64. MachineBasicBlock::iterator E = MBB->begin();
  65. unsigned Count = 4; // At most 4 instructions in an IT block.
  66. while (Count && MBBI != E) {
  67. if (MBBI->isDebugValue()) {
  68. --MBBI;
  69. continue;
  70. }
  71. if (MBBI->getOpcode() == ARM::t2IT) {
  72. unsigned Mask = MBBI->getOperand(1).getImm();
  73. if (Count == 4)
  74. MBBI->eraseFromParent();
  75. else {
  76. unsigned MaskOn = 1 << Count;
  77. unsigned MaskOff = ~(MaskOn - 1);
  78. MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
  79. }
  80. return;
  81. }
  82. --MBBI;
  83. --Count;
  84. }
  85. // Ctrl flow can reach here if branch folding is run before IT block
  86. // formation pass.
  87. }
  88. }
  89. bool
  90. Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB,
  91. MachineBasicBlock::iterator MBBI) const {
  92. while (MBBI->isDebugValue()) {
  93. ++MBBI;
  94. if (MBBI == MBB.end())
  95. return false;
  96. }
  97. unsigned PredReg = 0;
  98. return getITInstrPredicate(MBBI, PredReg) == ARMCC::AL;
  99. }
  100. void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
  101. MachineBasicBlock::iterator I, DebugLoc DL,
  102. unsigned DestReg, unsigned SrcReg,
  103. bool KillSrc) const {
  104. // Handle SPR, DPR, and QPR copies.
  105. if (!ARM::GPRRegClass.contains(DestReg, SrcReg))
  106. return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc);
  107. AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
  108. .addReg(SrcReg, getKillRegState(KillSrc)));
  109. }
  110. void Thumb2InstrInfo::
  111. storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
  112. unsigned SrcReg, bool isKill, int FI,
  113. const TargetRegisterClass *RC,
  114. const TargetRegisterInfo *TRI) const {
  115. DebugLoc DL;
  116. if (I != MBB.end()) DL = I->getDebugLoc();
  117. MachineFunction &MF = *MBB.getParent();
  118. MachineFrameInfo &MFI = *MF.getFrameInfo();
  119. MachineMemOperand *MMO =
  120. MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
  121. MachineMemOperand::MOStore,
  122. MFI.getObjectSize(FI),
  123. MFI.getObjectAlignment(FI));
  124. if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass ||
  125. RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
  126. RC == &ARM::GPRnopcRegClass) {
  127. AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2STRi12))
  128. .addReg(SrcReg, getKillRegState(isKill))
  129. .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
  130. return;
  131. }
  132. if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
  133. // Thumb2 STRD expects its dest-registers to be in rGPR. Not a problem for
  134. // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
  135. // otherwise).
  136. MachineRegisterInfo *MRI = &MF.getRegInfo();
  137. MRI->constrainRegClass(SrcReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
  138. MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2STRDi8));
  139. AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill), TRI);
  140. AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
  141. MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
  142. AddDefaultPred(MIB);
  143. return;
  144. }
  145. ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI);
  146. }
  147. void Thumb2InstrInfo::
  148. loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
  149. unsigned DestReg, int FI,
  150. const TargetRegisterClass *RC,
  151. const TargetRegisterInfo *TRI) const {
  152. MachineFunction &MF = *MBB.getParent();
  153. MachineFrameInfo &MFI = *MF.getFrameInfo();
  154. MachineMemOperand *MMO =
  155. MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
  156. MachineMemOperand::MOLoad,
  157. MFI.getObjectSize(FI),
  158. MFI.getObjectAlignment(FI));
  159. DebugLoc DL;
  160. if (I != MBB.end()) DL = I->getDebugLoc();
  161. if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass ||
  162. RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
  163. RC == &ARM::GPRnopcRegClass) {
  164. AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg)
  165. .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
  166. return;
  167. }
  168. if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
  169. // Thumb2 LDRD expects its dest-registers to be in rGPR. Not a problem for
  170. // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
  171. // otherwise).
  172. MachineRegisterInfo *MRI = &MF.getRegInfo();
  173. MRI->constrainRegClass(DestReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
  174. MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2LDRDi8));
  175. AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI);
  176. AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI);
  177. MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
  178. AddDefaultPred(MIB);
  179. if (TargetRegisterInfo::isPhysicalRegister(DestReg))
  180. MIB.addReg(DestReg, RegState::ImplicitDefine);
  181. return;
  182. }
  183. ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI);
  184. }
  185. void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
  186. MachineBasicBlock::iterator &MBBI, DebugLoc dl,
  187. unsigned DestReg, unsigned BaseReg, int NumBytes,
  188. ARMCC::CondCodes Pred, unsigned PredReg,
  189. const ARMBaseInstrInfo &TII, unsigned MIFlags) {
  190. if (NumBytes == 0 && DestReg != BaseReg) {
  191. BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
  192. .addReg(BaseReg, RegState::Kill)
  193. .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
  194. return;
  195. }
  196. bool isSub = NumBytes < 0;
  197. if (isSub) NumBytes = -NumBytes;
  198. // If profitable, use a movw or movt to materialize the offset.
  199. // FIXME: Use the scavenger to grab a scratch register.
  200. if (DestReg != ARM::SP && DestReg != BaseReg &&
  201. NumBytes >= 4096 &&
  202. ARM_AM::getT2SOImmVal(NumBytes) == -1) {
  203. bool Fits = false;
  204. if (NumBytes < 65536) {
  205. // Use a movw to materialize the 16-bit constant.
  206. BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
  207. .addImm(NumBytes)
  208. .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
  209. Fits = true;
  210. } else if ((NumBytes & 0xffff) == 0) {
  211. // Use a movt to materialize the 32-bit constant.
  212. BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
  213. .addReg(DestReg)
  214. .addImm(NumBytes >> 16)
  215. .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
  216. Fits = true;
  217. }
  218. if (Fits) {
  219. if (isSub) {
  220. BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
  221. .addReg(BaseReg, RegState::Kill)
  222. .addReg(DestReg, RegState::Kill)
  223. .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
  224. .setMIFlags(MIFlags);
  225. } else {
  226. BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
  227. .addReg(DestReg, RegState::Kill)
  228. .addReg(BaseReg, RegState::Kill)
  229. .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
  230. .setMIFlags(MIFlags);
  231. }
  232. return;
  233. }
  234. }
  235. while (NumBytes) {
  236. unsigned ThisVal = NumBytes;
  237. unsigned Opc = 0;
  238. if (DestReg == ARM::SP && BaseReg != ARM::SP) {
  239. // mov sp, rn. Note t2MOVr cannot be used.
  240. AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),DestReg)
  241. .addReg(BaseReg).setMIFlags(MIFlags));
  242. BaseReg = ARM::SP;
  243. continue;
  244. }
  245. bool HasCCOut = true;
  246. if (BaseReg == ARM::SP) {
  247. // sub sp, sp, #imm7
  248. if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
  249. assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?");
  250. Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
  251. AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
  252. .addReg(BaseReg).addImm(ThisVal/4).setMIFlags(MIFlags));
  253. NumBytes = 0;
  254. continue;
  255. }
  256. // sub rd, sp, so_imm
  257. Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
  258. if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
  259. NumBytes = 0;
  260. } else {
  261. // FIXME: Move this to ARMAddressingModes.h?
  262. unsigned RotAmt = countLeadingZeros(ThisVal);
  263. ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
  264. NumBytes &= ~ThisVal;
  265. assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
  266. "Bit extraction didn't work?");
  267. }
  268. } else {
  269. assert(DestReg != ARM::SP && BaseReg != ARM::SP);
  270. Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
  271. if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
  272. NumBytes = 0;
  273. } else if (ThisVal < 4096) {
  274. Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
  275. HasCCOut = false;
  276. NumBytes = 0;
  277. } else {
  278. // FIXME: Move this to ARMAddressingModes.h?
  279. unsigned RotAmt = countLeadingZeros(ThisVal);
  280. ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
  281. NumBytes &= ~ThisVal;
  282. assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
  283. "Bit extraction didn't work?");
  284. }
  285. }
  286. // Build the new ADD / SUB.
  287. MachineInstrBuilder MIB =
  288. AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
  289. .addReg(BaseReg, RegState::Kill)
  290. .addImm(ThisVal)).setMIFlags(MIFlags);
  291. if (HasCCOut)
  292. AddDefaultCC(MIB);
  293. BaseReg = DestReg;
  294. }
  295. }
  296. static unsigned
  297. negativeOffsetOpcode(unsigned opcode)
  298. {
  299. switch (opcode) {
  300. case ARM::t2LDRi12: return ARM::t2LDRi8;
  301. case ARM::t2LDRHi12: return ARM::t2LDRHi8;
  302. case ARM::t2LDRBi12: return ARM::t2LDRBi8;
  303. case ARM::t2LDRSHi12: return ARM::t2LDRSHi8;
  304. case ARM::t2LDRSBi12: return ARM::t2LDRSBi8;
  305. case ARM::t2STRi12: return ARM::t2STRi8;
  306. case ARM::t2STRBi12: return ARM::t2STRBi8;
  307. case ARM::t2STRHi12: return ARM::t2STRHi8;
  308. case ARM::t2PLDi12: return ARM::t2PLDi8;
  309. case ARM::t2LDRi8:
  310. case ARM::t2LDRHi8:
  311. case ARM::t2LDRBi8:
  312. case ARM::t2LDRSHi8:
  313. case ARM::t2LDRSBi8:
  314. case ARM::t2STRi8:
  315. case ARM::t2STRBi8:
  316. case ARM::t2STRHi8:
  317. case ARM::t2PLDi8:
  318. return opcode;
  319. default:
  320. break;
  321. }
  322. return 0;
  323. }
  324. static unsigned
  325. positiveOffsetOpcode(unsigned opcode)
  326. {
  327. switch (opcode) {
  328. case ARM::t2LDRi8: return ARM::t2LDRi12;
  329. case ARM::t2LDRHi8: return ARM::t2LDRHi12;
  330. case ARM::t2LDRBi8: return ARM::t2LDRBi12;
  331. case ARM::t2LDRSHi8: return ARM::t2LDRSHi12;
  332. case ARM::t2LDRSBi8: return ARM::t2LDRSBi12;
  333. case ARM::t2STRi8: return ARM::t2STRi12;
  334. case ARM::t2STRBi8: return ARM::t2STRBi12;
  335. case ARM::t2STRHi8: return ARM::t2STRHi12;
  336. case ARM::t2PLDi8: return ARM::t2PLDi12;
  337. case ARM::t2LDRi12:
  338. case ARM::t2LDRHi12:
  339. case ARM::t2LDRBi12:
  340. case ARM::t2LDRSHi12:
  341. case ARM::t2LDRSBi12:
  342. case ARM::t2STRi12:
  343. case ARM::t2STRBi12:
  344. case ARM::t2STRHi12:
  345. case ARM::t2PLDi12:
  346. return opcode;
  347. default:
  348. break;
  349. }
  350. return 0;
  351. }
  352. static unsigned
  353. immediateOffsetOpcode(unsigned opcode)
  354. {
  355. switch (opcode) {
  356. case ARM::t2LDRs: return ARM::t2LDRi12;
  357. case ARM::t2LDRHs: return ARM::t2LDRHi12;
  358. case ARM::t2LDRBs: return ARM::t2LDRBi12;
  359. case ARM::t2LDRSHs: return ARM::t2LDRSHi12;
  360. case ARM::t2LDRSBs: return ARM::t2LDRSBi12;
  361. case ARM::t2STRs: return ARM::t2STRi12;
  362. case ARM::t2STRBs: return ARM::t2STRBi12;
  363. case ARM::t2STRHs: return ARM::t2STRHi12;
  364. case ARM::t2PLDs: return ARM::t2PLDi12;
  365. case ARM::t2LDRi12:
  366. case ARM::t2LDRHi12:
  367. case ARM::t2LDRBi12:
  368. case ARM::t2LDRSHi12:
  369. case ARM::t2LDRSBi12:
  370. case ARM::t2STRi12:
  371. case ARM::t2STRBi12:
  372. case ARM::t2STRHi12:
  373. case ARM::t2PLDi12:
  374. case ARM::t2LDRi8:
  375. case ARM::t2LDRHi8:
  376. case ARM::t2LDRBi8:
  377. case ARM::t2LDRSHi8:
  378. case ARM::t2LDRSBi8:
  379. case ARM::t2STRi8:
  380. case ARM::t2STRBi8:
  381. case ARM::t2STRHi8:
  382. case ARM::t2PLDi8:
  383. return opcode;
  384. default:
  385. break;
  386. }
  387. return 0;
  388. }
  389. bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
  390. unsigned FrameReg, int &Offset,
  391. const ARMBaseInstrInfo &TII) {
  392. unsigned Opcode = MI.getOpcode();
  393. const MCInstrDesc &Desc = MI.getDesc();
  394. unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
  395. bool isSub = false;
  396. // Memory operands in inline assembly always use AddrModeT2_i12.
  397. if (Opcode == ARM::INLINEASM)
  398. AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
  399. if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
  400. Offset += MI.getOperand(FrameRegIdx+1).getImm();
  401. unsigned PredReg;
  402. if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
  403. // Turn it into a move.
  404. MI.setDesc(TII.get(ARM::tMOVr));
  405. MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
  406. // Remove offset and remaining explicit predicate operands.
  407. do MI.RemoveOperand(FrameRegIdx+1);
  408. while (MI.getNumOperands() > FrameRegIdx+1);
  409. MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI);
  410. AddDefaultPred(MIB);
  411. return true;
  412. }
  413. bool HasCCOut = Opcode != ARM::t2ADDri12;
  414. if (Offset < 0) {
  415. Offset = -Offset;
  416. isSub = true;
  417. MI.setDesc(TII.get(ARM::t2SUBri));
  418. } else {
  419. MI.setDesc(TII.get(ARM::t2ADDri));
  420. }
  421. // Common case: small offset, fits into instruction.
  422. if (ARM_AM::getT2SOImmVal(Offset) != -1) {
  423. MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
  424. MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
  425. // Add cc_out operand if the original instruction did not have one.
  426. if (!HasCCOut)
  427. MI.addOperand(MachineOperand::CreateReg(0, false));
  428. Offset = 0;
  429. return true;
  430. }
  431. // Another common case: imm12.
  432. if (Offset < 4096 &&
  433. (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
  434. unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
  435. MI.setDesc(TII.get(NewOpc));
  436. MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
  437. MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
  438. // Remove the cc_out operand.
  439. if (HasCCOut)
  440. MI.RemoveOperand(MI.getNumOperands()-1);
  441. Offset = 0;
  442. return true;
  443. }
  444. // Otherwise, extract 8 adjacent bits from the immediate into this
  445. // t2ADDri/t2SUBri.
  446. unsigned RotAmt = countLeadingZeros<unsigned>(Offset);
  447. unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
  448. // We will handle these bits from offset, clear them.
  449. Offset &= ~ThisImmVal;
  450. assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
  451. "Bit extraction didn't work?");
  452. MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
  453. // Add cc_out operand if the original instruction did not have one.
  454. if (!HasCCOut)
  455. MI.addOperand(MachineOperand::CreateReg(0, false));
  456. } else {
  457. // AddrMode4 and AddrMode6 cannot handle any offset.
  458. if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
  459. return false;
  460. // AddrModeT2_so cannot handle any offset. If there is no offset
  461. // register then we change to an immediate version.
  462. unsigned NewOpc = Opcode;
  463. if (AddrMode == ARMII::AddrModeT2_so) {
  464. unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg();
  465. if (OffsetReg != 0) {
  466. MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
  467. return Offset == 0;
  468. }
  469. MI.RemoveOperand(FrameRegIdx+1);
  470. MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
  471. NewOpc = immediateOffsetOpcode(Opcode);
  472. AddrMode = ARMII::AddrModeT2_i12;
  473. }
  474. unsigned NumBits = 0;
  475. unsigned Scale = 1;
  476. if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) {
  477. // i8 supports only negative, and i12 supports only positive, so
  478. // based on Offset sign convert Opcode to the appropriate
  479. // instruction
  480. Offset += MI.getOperand(FrameRegIdx+1).getImm();
  481. if (Offset < 0) {
  482. NewOpc = negativeOffsetOpcode(Opcode);
  483. NumBits = 8;
  484. isSub = true;
  485. Offset = -Offset;
  486. } else {
  487. NewOpc = positiveOffsetOpcode(Opcode);
  488. NumBits = 12;
  489. }
  490. } else if (AddrMode == ARMII::AddrMode5) {
  491. // VFP address mode.
  492. const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
  493. int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
  494. if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
  495. InstrOffs *= -1;
  496. NumBits = 8;
  497. Scale = 4;
  498. Offset += InstrOffs * 4;
  499. assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
  500. if (Offset < 0) {
  501. Offset = -Offset;
  502. isSub = true;
  503. }
  504. } else if (AddrMode == ARMII::AddrModeT2_i8s4) {
  505. Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
  506. NumBits = 8;
  507. // MCInst operand has already scaled value.
  508. Scale = 1;
  509. if (Offset < 0) {
  510. isSub = true;
  511. Offset = -Offset;
  512. }
  513. } else {
  514. llvm_unreachable("Unsupported addressing mode!");
  515. }
  516. if (NewOpc != Opcode)
  517. MI.setDesc(TII.get(NewOpc));
  518. MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
  519. // Attempt to fold address computation
  520. // Common case: small offset, fits into instruction.
  521. int ImmedOffset = Offset / Scale;
  522. unsigned Mask = (1 << NumBits) - 1;
  523. if ((unsigned)Offset <= Mask * Scale) {
  524. // Replace the FrameIndex with fp/sp
  525. MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
  526. if (isSub) {
  527. if (AddrMode == ARMII::AddrMode5)
  528. // FIXME: Not consistent.
  529. ImmedOffset |= 1 << NumBits;
  530. else
  531. ImmedOffset = -ImmedOffset;
  532. }
  533. ImmOp.ChangeToImmediate(ImmedOffset);
  534. Offset = 0;
  535. return true;
  536. }
  537. // Otherwise, offset doesn't fit. Pull in what we can to simplify
  538. ImmedOffset = ImmedOffset & Mask;
  539. if (isSub) {
  540. if (AddrMode == ARMII::AddrMode5)
  541. // FIXME: Not consistent.
  542. ImmedOffset |= 1 << NumBits;
  543. else {
  544. ImmedOffset = -ImmedOffset;
  545. if (ImmedOffset == 0)
  546. // Change the opcode back if the encoded offset is zero.
  547. MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc)));
  548. }
  549. }
  550. ImmOp.ChangeToImmediate(ImmedOffset);
  551. Offset &= ~(Mask*Scale);
  552. }
  553. Offset = (isSub) ? -Offset : Offset;
  554. return Offset == 0;
  555. }
  556. ARMCC::CondCodes
  557. llvm::getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg) {
  558. unsigned Opc = MI->getOpcode();
  559. if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
  560. return ARMCC::AL;
  561. return getInstrPredicate(MI, PredReg);
  562. }