llvm.org GIT mirror llvm / a01faf4
eliminateFrameIndex() is even more complicated if frame ptr is used instead of SP when there are dynamic alloca's. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33975 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 13 years ago
1 changed file(s) with 34 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
365365 void emitThumbRegPlusConstPool(MachineBasicBlock &MBB,
366366 MachineBasicBlock::iterator &MBBI,
367367 unsigned DestReg, unsigned BaseReg,
368 int NumBytes, const TargetInstrInfo &TII) {
368 int NumBytes, bool CanChangeCC,
369 const TargetInstrInfo &TII) {
369370 MachineFunction &MF = *MBB.getParent();
370371 MachineConstantPool *ConstantPool = MF.getConstantPool();
371372 bool isHigh = !isLowRegister(DestReg) || !isLowRegister(BaseReg);
372373 bool isSub = false;
373374 // Subtract doesn't have high register version. Load the negative value
374 // if either base or dest register is a high register.
375 if (NumBytes < 0 && !isHigh) {
375 // if either base or dest register is a high register. Also, if do not
376 // issue sub as part of the sequence if condition register is to be
377 // preserved.
378 if (NumBytes < 0 && !isHigh && CanChangeCC) {
376379 isSub = true;
377380 NumBytes = -NumBytes;
378381 }
379 Constant *C = ConstantInt::get(Type::Int32Ty, NumBytes);
380 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2);
381382 unsigned LdReg = DestReg;
382383 if (DestReg == ARM::SP) {
383384 assert(BaseReg == ARM::SP && "Unexpected!");
384385 LdReg = ARM::R3;
385386 BuildMI(MBB, MBBI, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R3);
386387 }
387 // Load the constant.
388 BuildMI(MBB, MBBI, TII.get(ARM::tLDRpci), LdReg).addConstantPoolIndex(Idx);
388
389 if (NumBytes <= 255 && NumBytes >= 0)
390 BuildMI(MBB, MBBI, TII.get(ARM::tMOVri8), LdReg).addImm(NumBytes);
391 else {
392 // Load the constant.
393 Constant *C = ConstantInt::get(Type::Int32Ty, NumBytes);
394 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2);
395 BuildMI(MBB, MBBI, TII.get(ARM::tLDRpci), LdReg).addConstantPoolIndex(Idx);
396 }
389397 // Emit add / sub.
390398 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
391399 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(Opc), DestReg);
451459 if (NumMIs > Threshold) {
452460 // This will expand into too many instructions. Load the immediate from a
453461 // constpool entry.
454 emitThumbRegPlusConstPool(MBB, MBBI, DestReg, BaseReg, NumBytes, TII);
462 emitThumbRegPlusConstPool(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII);
455463 return;
456464 }
457465
712720 case ARMII::AddrModeTs: {
713721 ImmIdx = i+1;
714722 InstrOffs = MI.getOperand(ImmIdx).getImm();
715 NumBits = (FrameReg == ARM::SP) ? 8 : 5;
716 Scale = 4;
723 NumBits = isSub ? 3 : ((FrameReg == ARM::SP) ? 8 : 5);
724 Scale = isSub ? 1 : 4;
717725 break;
718726 }
719727 default:
724732
725733 Offset += InstrOffs * Scale;
726734 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
727 if (Offset < 0) {
735 if (Offset < 0 && !isThumb) {
728736 Offset = -Offset;
729737 isSub = true;
730738 }
731739
740 // Common case: small offset, fits into instruction.
732741 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
733742 int ImmedOffset = Offset / Scale;
734743 unsigned Mask = (1 << NumBits) - 1;
741750 return;
742751 }
743752
744 if (!isThumb) {
753 // If this is a thumb spill / restore, we will be using a constpool load to
754 // materialize the offset.
755 bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
756 if (AddrMode == ARMII::AddrModeTs || !isThumSpillRestore) {
757 if (AddrMode == ARMII::AddrModeTs) {
758 // Thumb tLDRspi, tSTRspi. These will change to instructions that use
759 // a different base register.
760 NumBits = 5;
761 Mask = (1 << NumBits) - 1;
762 }
745763 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
746764 ImmedOffset = ImmedOffset & Mask;
747765 if (isSub)
761779 // Use the destination register to materialize sp + offset.
762780 unsigned TmpReg = MI.getOperand(0).getReg();
763781 if (Opcode == ARM::tRestore)
764 emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,
765 isSub ? -Offset : Offset, TII);
782 emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg, Offset, false, TII);
766783 else
767 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
768 isSub ? -Offset : Offset, TII);
784 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII);
769785 MI.setInstrDescriptor(TII.get(ARM::tLDR));
770786 MI.getOperand(i).ChangeToRegister(TmpReg, false);
771787 MI.addRegOperand(0, false); // tLDR has an extra register operand.
785801 TmpReg = ARM::R2;
786802 }
787803 if (Opcode == ARM::tSpill)
788 emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,
789 isSub ? -Offset : Offset, TII);
804 emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg, Offset, false, TII);
790805 else
791 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
792 isSub ? -Offset : Offset, TII);
806 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII);
793807 MI.setInstrDescriptor(TII.get(ARM::tSTR));
794808 MI.getOperand(i).ChangeToRegister(TmpReg, false);
795809 MI.addRegOperand(0, false); // tSTR has an extra register operand.