llvm.org GIT mirror llvm / 5b91c7f
Thumb eliminateFrameIndex fixes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33652 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 13 years ago
1 changed file(s) with 27 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
335335 bool isMul4 = (Bytes & 3) == 0;
336336 bool isTwoAddr = false;
337337 unsigned NumBits = 1;
338 unsigned Scale = 1;
338339 unsigned Opc = 0;
339340 unsigned ExtraOpc = 0;
340341
341342 if (DestReg == BaseReg && BaseReg == ARM::SP) {
342343 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
343 Bytes >>= 2; // Implicitly multiplied by 4.
344344 NumBits = 7;
345 Scale = 4;
345346 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
346347 isTwoAddr = true;
347348 } else if (!isSub && BaseReg == ARM::SP) {
349 // r1 = add sp, 403
350 // =>
351 // r1 = add sp, 100 * 4
352 // r1 = add r1, 3
348353 if (!isMul4) {
349354 Bytes &= ~3;
350355 ExtraOpc = ARM::tADDi3;
351356 }
352 Bytes >>= 2; // Implicitly multiplied by 4.
353357 NumBits = 8;
358 Scale = 4;
354359 Opc = ARM::tADDrSPi;
355360 } else {
356361 if (DestReg != BaseReg) {
371376 isTwoAddr = true;
372377 }
373378
374 unsigned Chunk = (1 << NumBits) - 1;
379 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
375380 while (Bytes) {
376381 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
377 Bytes -= ThisVal;
382 Bytes -= ThisVal;
383 ThisVal /= Scale;
378384 // Build the new tADD / tSUB.
379385 if (isTwoAddr)
380386 BuildMI(MBB, MBBI, TII.get(Opc), DestReg).addReg(DestReg).addImm(ThisVal);
387393 // r4 = add r4, imm
388394 // ...
389395 NumBits = 8;
396 Scale = 1;
397 Chunk = ((1 << NumBits) - 1) * Scale;
390398 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
391399 isTwoAddr = true;
392400 }
635643 }
636644
637645 // Otherwise, it didn't fit. Pull in what we can to simplify the immediate.
646 if (AddrMode == ARMII::AddrModeTs) {
647 // Thumb tLDRspi, tSTRspi. These will change to instructions that use a
648 // different base register.
649 NumBits = 5;
650 Mask = (1 << NumBits) - 1;
651 }
652
638653 ImmedOffset = ImmedOffset & Mask;
639654 if (isSub)
640655 ImmedOffset |= 1 << NumBits;
653668 unsigned TmpReg = MI.getOperand(0).getReg();
654669 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
655670 isSub ? -Offset : Offset, TII);
671 MI.setInstrDescriptor(TII.get(ARM::tLDR));
656672 MI.getOperand(i).ChangeToRegister(TmpReg, false);
673 MI.addRegOperand(0, false); // tLDR has an extra register operand.
657674 } else if (TII.isStore(Opcode)) {
658675 // FIXME! This is horrific!!! We need register scavenging.
659676 // Our temporary workaround has marked r3 unavailable. Of course, r3 is
663680 // Use r2 to materialize sp + offset
664681 // str r12, r2
665682 // r2 = r12
666 unsigned DestReg = MI.getOperand(0).getReg();
683 unsigned ValReg = MI.getOperand(0).getReg();
667684 unsigned TmpReg = ARM::R3;
668 if (DestReg == ARM::R3) {
685 if (ValReg == ARM::R3) {
669686 BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R2);
670687 TmpReg = ARM::R2;
671688 }
672689 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
673690 isSub ? -Offset : Offset, TII);
674 MI.getOperand(i).ChangeToRegister(DestReg, false);
675 if (DestReg == ARM::R3)
691 MI.setInstrDescriptor(TII.get(ARM::tSTR));
692 MI.getOperand(i).ChangeToRegister(TmpReg, false);
693 MI.addRegOperand(0, false); // tSTR has an extra register operand.
694 if (ValReg == ARM::R3)
676695 BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R2).addReg(ARM::R12);
677696 } else
678697 assert(false && "Unexpected opcode!");