llvm.org GIT mirror llvm / b50ea5c
Checkpoint refactoring of ThumbInstrInfo and ThumbRegisterInfo into Thumb1InstrInfo, Thumb2InstrInfo, Thumb1RegisterInfo and Thumb2RegisterInfo. Move methods from ARMInstrInfo to ARMBaseInstrInfo to prepare for sharing with Thumb2. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74731 91177308-0d34-0410-b5e6-96231b3b80d8 David Goodwin 11 years ago
17 changed file(s) with 2816 addition(s) and 1581 deletion(s). Raw diff Collapse all Expand all
4444
4545 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
4646 : ARMBaseInstrInfo(STI), RI(*this, STI) {
47 }
48
49 /// Return true if the instruction is a register to register move and
50 /// leave the source and dest operands in the passed parameters.
51 ///
52 bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
53 unsigned &SrcReg, unsigned &DstReg,
54 unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
55 SrcSubIdx = DstSubIdx = 0; // No sub-registers.
56
57 unsigned oc = MI.getOpcode();
58 switch (oc) {
59 default:
60 return false;
61 case ARM::FCPYS:
62 case ARM::FCPYD:
63 case ARM::VMOVD:
64 case ARM::VMOVQ:
65 SrcReg = MI.getOperand(1).getReg();
66 DstReg = MI.getOperand(0).getReg();
67 return true;
68 case ARM::MOVr:
69 assert(MI.getDesc().getNumOperands() >= 2 &&
70 MI.getOperand(0).isReg() &&
71 MI.getOperand(1).isReg() &&
72 "Invalid ARM MOV instruction");
73 SrcReg = MI.getOperand(1).getReg();
74 DstReg = MI.getOperand(0).getReg();
75 return true;
76 }
77 }
78
79 unsigned ARMInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
80 int &FrameIndex) const {
81 switch (MI->getOpcode()) {
82 default: break;
83 case ARM::LDR:
84 if (MI->getOperand(1).isFI() &&
85 MI->getOperand(2).isReg() &&
86 MI->getOperand(3).isImm() &&
87 MI->getOperand(2).getReg() == 0 &&
88 MI->getOperand(3).getImm() == 0) {
89 FrameIndex = MI->getOperand(1).getIndex();
90 return MI->getOperand(0).getReg();
91 }
92 break;
93 case ARM::FLDD:
94 case ARM::FLDS:
95 if (MI->getOperand(1).isFI() &&
96 MI->getOperand(2).isImm() &&
97 MI->getOperand(2).getImm() == 0) {
98 FrameIndex = MI->getOperand(1).getIndex();
99 return MI->getOperand(0).getReg();
100 }
101 break;
102 }
103 return 0;
104 }
105
106 unsigned ARMInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
107 int &FrameIndex) const {
108 switch (MI->getOpcode()) {
109 default: break;
110 case ARM::STR:
111 if (MI->getOperand(1).isFI() &&
112 MI->getOperand(2).isReg() &&
113 MI->getOperand(3).isImm() &&
114 MI->getOperand(2).getReg() == 0 &&
115 MI->getOperand(3).getImm() == 0) {
116 FrameIndex = MI->getOperand(1).getIndex();
117 return MI->getOperand(0).getReg();
118 }
119 break;
120 case ARM::FSTD:
121 case ARM::FSTS:
122 if (MI->getOperand(1).isFI() &&
123 MI->getOperand(2).isImm() &&
124 MI->getOperand(2).getImm() == 0) {
125 FrameIndex = MI->getOperand(1).getIndex();
126 return MI->getOperand(0).getReg();
127 }
128 break;
129 }
130
131 return 0;
13247 }
13348
13449 void ARMInstrInfo::reMaterialize(MachineBasicBlock &MBB,
334249
335250 // Branch analysis.
336251 bool
337 ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
338 MachineBasicBlock *&FBB,
339 SmallVectorImpl &Cond,
340 bool AllowModify) const {
252 ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
253 MachineBasicBlock *&FBB,
254 SmallVectorImpl &Cond,
255 bool AllowModify) const {
341256 // If the block has no terminators, it just falls into the block after it.
342257 MachineBasicBlock::iterator I = MBB.end();
343258 if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
475390 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
476391 BuildMI(&MBB, dl, get(BOpc)).addMBB(FBB);
477392 return 2;
478 }
479
480 bool ARMInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
481 MachineBasicBlock::iterator I,
482 unsigned DestReg, unsigned SrcReg,
483 const TargetRegisterClass *DestRC,
484 const TargetRegisterClass *SrcRC) const {
485 DebugLoc DL = DebugLoc::getUnknownLoc();
486 if (I != MBB.end()) DL = I->getDebugLoc();
487
488 if (DestRC != SrcRC) {
489 // Not yet supported!
490 return false;
491 }
492
493 if (DestRC == ARM::GPRRegisterClass)
494 AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), DestReg)
495 .addReg(SrcReg)));
496 else if (DestRC == ARM::SPRRegisterClass)
497 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg)
498 .addReg(SrcReg));
499 else if (DestRC == ARM::DPRRegisterClass)
500 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg)
501 .addReg(SrcReg));
502 else if (DestRC == ARM::QPRRegisterClass)
503 BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg);
504 else
505 return false;
506
507 return true;
508 }
509
510 void ARMInstrInfo::
511 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
512 unsigned SrcReg, bool isKill, int FI,
513 const TargetRegisterClass *RC) const {
514 DebugLoc DL = DebugLoc::getUnknownLoc();
515 if (I != MBB.end()) DL = I->getDebugLoc();
516
517 if (RC == ARM::GPRRegisterClass) {
518 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
519 .addReg(SrcReg, getKillRegState(isKill))
520 .addFrameIndex(FI).addReg(0).addImm(0));
521 } else if (RC == ARM::DPRRegisterClass) {
522 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
523 .addReg(SrcReg, getKillRegState(isKill))
524 .addFrameIndex(FI).addImm(0));
525 } else {
526 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
527 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS))
528 .addReg(SrcReg, getKillRegState(isKill))
529 .addFrameIndex(FI).addImm(0));
530 }
531 }
532
533 void ARMInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
534 bool isKill,
535 SmallVectorImpl &Addr,
536 const TargetRegisterClass *RC,
537 SmallVectorImpl &NewMIs) const{
538 DebugLoc DL = DebugLoc::getUnknownLoc();
539 unsigned Opc = 0;
540 if (RC == ARM::GPRRegisterClass) {
541 Opc = ARM::STR;
542 } else if (RC == ARM::DPRRegisterClass) {
543 Opc = ARM::FSTD;
544 } else {
545 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
546 Opc = ARM::FSTS;
547 }
548
549 MachineInstrBuilder MIB =
550 BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill));
551 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
552 MIB.addOperand(Addr[i]);
553 AddDefaultPred(MIB);
554 NewMIs.push_back(MIB);
555 return;
556 }
557
558 void ARMInstrInfo::
559 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
560 unsigned DestReg, int FI,
561 const TargetRegisterClass *RC) const {
562 DebugLoc DL = DebugLoc::getUnknownLoc();
563 if (I != MBB.end()) DL = I->getDebugLoc();
564
565 if (RC == ARM::GPRRegisterClass) {
566 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
567 .addFrameIndex(FI).addReg(0).addImm(0));
568 } else if (RC == ARM::DPRRegisterClass) {
569 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
570 .addFrameIndex(FI).addImm(0));
571 } else {
572 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
573 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg)
574 .addFrameIndex(FI).addImm(0));
575 }
576 }
577
578 void ARMInstrInfo::
579 loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
580 SmallVectorImpl &Addr,
581 const TargetRegisterClass *RC,
582 SmallVectorImpl &NewMIs) const {
583 DebugLoc DL = DebugLoc::getUnknownLoc();
584 unsigned Opc = 0;
585 if (RC == ARM::GPRRegisterClass) {
586 Opc = ARM::LDR;
587 } else if (RC == ARM::DPRRegisterClass) {
588 Opc = ARM::FLDD;
589 } else {
590 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
591 Opc = ARM::FLDS;
592 }
593
594 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
595 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
596 MIB.addOperand(Addr[i]);
597 AddDefaultPred(MIB);
598 NewMIs.push_back(MIB);
599 return;
600 }
601
602 MachineInstr *ARMInstrInfo::
603 foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
604 const SmallVectorImpl &Ops, int FI) const {
605 if (Ops.size() != 1) return NULL;
606
607 unsigned OpNum = Ops[0];
608 unsigned Opc = MI->getOpcode();
609 MachineInstr *NewMI = NULL;
610 switch (Opc) {
611 default: break;
612 case ARM::MOVr: {
613 if (MI->getOperand(4).getReg() == ARM::CPSR)
614 // If it is updating CPSR, then it cannot be folded.
615 break;
616 unsigned Pred = MI->getOperand(2).getImm();
617 unsigned PredReg = MI->getOperand(3).getReg();
618 if (OpNum == 0) { // move -> store
619 unsigned SrcReg = MI->getOperand(1).getReg();
620 bool isKill = MI->getOperand(1).isKill();
621 bool isUndef = MI->getOperand(1).isUndef();
622 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR))
623 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
624 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
625 } else { // move -> load
626 unsigned DstReg = MI->getOperand(0).getReg();
627 bool isDead = MI->getOperand(0).isDead();
628 bool isUndef = MI->getOperand(0).isUndef();
629 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR))
630 .addReg(DstReg,
631 RegState::Define |
632 getDeadRegState(isDead) |
633 getUndefRegState(isUndef))
634 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
635 }
636 break;
637 }
638 case ARM::FCPYS: {
639 unsigned Pred = MI->getOperand(2).getImm();
640 unsigned PredReg = MI->getOperand(3).getReg();
641 if (OpNum == 0) { // move -> store
642 unsigned SrcReg = MI->getOperand(1).getReg();
643 bool isKill = MI->getOperand(1).isKill();
644 bool isUndef = MI->getOperand(1).isUndef();
645 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTS))
646 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
647 .addFrameIndex(FI)
648 .addImm(0).addImm(Pred).addReg(PredReg);
649 } else { // move -> load
650 unsigned DstReg = MI->getOperand(0).getReg();
651 bool isDead = MI->getOperand(0).isDead();
652 bool isUndef = MI->getOperand(0).isUndef();
653 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS))
654 .addReg(DstReg,
655 RegState::Define |
656 getDeadRegState(isDead) |
657 getUndefRegState(isUndef))
658 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
659 }
660 break;
661 }
662 case ARM::FCPYD: {
663 unsigned Pred = MI->getOperand(2).getImm();
664 unsigned PredReg = MI->getOperand(3).getReg();
665 if (OpNum == 0) { // move -> store
666 unsigned SrcReg = MI->getOperand(1).getReg();
667 bool isKill = MI->getOperand(1).isKill();
668 bool isUndef = MI->getOperand(1).isUndef();
669 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTD))
670 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
671 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
672 } else { // move -> load
673 unsigned DstReg = MI->getOperand(0).getReg();
674 bool isDead = MI->getOperand(0).isDead();
675 bool isUndef = MI->getOperand(0).isUndef();
676 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDD))
677 .addReg(DstReg,
678 RegState::Define |
679 getDeadRegState(isDead) |
680 getUndefRegState(isUndef))
681 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
682 }
683 break;
684 }
685 }
686
687 return NewMI;
688 }
689
690 bool
691 ARMInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
692 const SmallVectorImpl &Ops) const {
693 if (Ops.size() != 1) return false;
694
695 unsigned Opc = MI->getOpcode();
696 switch (Opc) {
697 default: break;
698 case ARM::MOVr:
699 // If it is updating CPSR, then it cannot be folded.
700 return MI->getOperand(4).getReg() != ARM::CPSR;
701 case ARM::FCPYS:
702 case ARM::FCPYD:
703 return true;
704
705 case ARM::VMOVD:
706 case ARM::VMOVQ:
707 return false; // FIXME
708 }
709
710 return false;
711393 }
712394
713395 bool
897579 }
898580 return 0; // Not reached
899581 }
582
583 /// Return true if the instruction is a register to register move and
584 /// leave the source and dest operands in the passed parameters.
585 ///
586 bool
587 ARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI,
588 unsigned &SrcReg, unsigned &DstReg,
589 unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
590 SrcSubIdx = DstSubIdx = 0; // No sub-registers.
591
592 unsigned oc = MI.getOpcode();
593 switch (oc) {
594 default:
595 return false;
596 case ARM::FCPYS:
597 case ARM::FCPYD:
598 case ARM::VMOVD:
599 case ARM::VMOVQ:
600 SrcReg = MI.getOperand(1).getReg();
601 DstReg = MI.getOperand(0).getReg();
602 return true;
603 case ARM::MOVr:
604 assert(MI.getDesc().getNumOperands() >= 2 &&
605 MI.getOperand(0).isReg() &&
606 MI.getOperand(1).isReg() &&
607 "Invalid ARM MOV instruction");
608 SrcReg = MI.getOperand(1).getReg();
609 DstReg = MI.getOperand(0).getReg();
610 return true;
611 }
612 }
613
614 unsigned
615 ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
616 int &FrameIndex) const {
617 switch (MI->getOpcode()) {
618 default: break;
619 case ARM::LDR:
620 if (MI->getOperand(1).isFI() &&
621 MI->getOperand(2).isReg() &&
622 MI->getOperand(3).isImm() &&
623 MI->getOperand(2).getReg() == 0 &&
624 MI->getOperand(3).getImm() == 0) {
625 FrameIndex = MI->getOperand(1).getIndex();
626 return MI->getOperand(0).getReg();
627 }
628 break;
629 case ARM::FLDD:
630 case ARM::FLDS:
631 if (MI->getOperand(1).isFI() &&
632 MI->getOperand(2).isImm() &&
633 MI->getOperand(2).getImm() == 0) {
634 FrameIndex = MI->getOperand(1).getIndex();
635 return MI->getOperand(0).getReg();
636 }
637 break;
638 }
639 return 0;
640 }
641
642 unsigned
643 ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
644 int &FrameIndex) const {
645 switch (MI->getOpcode()) {
646 default: break;
647 case ARM::STR:
648 if (MI->getOperand(1).isFI() &&
649 MI->getOperand(2).isReg() &&
650 MI->getOperand(3).isImm() &&
651 MI->getOperand(2).getReg() == 0 &&
652 MI->getOperand(3).getImm() == 0) {
653 FrameIndex = MI->getOperand(1).getIndex();
654 return MI->getOperand(0).getReg();
655 }
656 break;
657 case ARM::FSTD:
658 case ARM::FSTS:
659 if (MI->getOperand(1).isFI() &&
660 MI->getOperand(2).isImm() &&
661 MI->getOperand(2).getImm() == 0) {
662 FrameIndex = MI->getOperand(1).getIndex();
663 return MI->getOperand(0).getReg();
664 }
665 break;
666 }
667
668 return 0;
669 }
670
671 bool
672 ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
673 MachineBasicBlock::iterator I,
674 unsigned DestReg, unsigned SrcReg,
675 const TargetRegisterClass *DestRC,
676 const TargetRegisterClass *SrcRC) const {
677 DebugLoc DL = DebugLoc::getUnknownLoc();
678 if (I != MBB.end()) DL = I->getDebugLoc();
679
680 if (DestRC != SrcRC) {
681 // Not yet supported!
682 return false;
683 }
684
685 if (DestRC == ARM::GPRRegisterClass)
686 AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), DestReg)
687 .addReg(SrcReg)));
688 else if (DestRC == ARM::SPRRegisterClass)
689 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg)
690 .addReg(SrcReg));
691 else if (DestRC == ARM::DPRRegisterClass)
692 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg)
693 .addReg(SrcReg));
694 else if (DestRC == ARM::QPRRegisterClass)
695 BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg);
696 else
697 return false;
698
699 return true;
700 }
701
702 void ARMBaseInstrInfo::
703 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
704 unsigned SrcReg, bool isKill, int FI,
705 const TargetRegisterClass *RC) const {
706 DebugLoc DL = DebugLoc::getUnknownLoc();
707 if (I != MBB.end()) DL = I->getDebugLoc();
708
709 if (RC == ARM::GPRRegisterClass) {
710 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
711 .addReg(SrcReg, getKillRegState(isKill))
712 .addFrameIndex(FI).addReg(0).addImm(0));
713 } else if (RC == ARM::DPRRegisterClass) {
714 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
715 .addReg(SrcReg, getKillRegState(isKill))
716 .addFrameIndex(FI).addImm(0));
717 } else {
718 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
719 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS))
720 .addReg(SrcReg, getKillRegState(isKill))
721 .addFrameIndex(FI).addImm(0));
722 }
723 }
724
725 void
726 ARMBaseInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
727 bool isKill,
728 SmallVectorImpl &Addr,
729 const TargetRegisterClass *RC,
730 SmallVectorImpl &NewMIs) const{
731 DebugLoc DL = DebugLoc::getUnknownLoc();
732 unsigned Opc = 0;
733 if (RC == ARM::GPRRegisterClass) {
734 Opc = ARM::STR;
735 } else if (RC == ARM::DPRRegisterClass) {
736 Opc = ARM::FSTD;
737 } else {
738 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
739 Opc = ARM::FSTS;
740 }
741
742 MachineInstrBuilder MIB =
743 BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill));
744 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
745 MIB.addOperand(Addr[i]);
746 AddDefaultPred(MIB);
747 NewMIs.push_back(MIB);
748 return;
749 }
750
751 void ARMBaseInstrInfo::
752 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
753 unsigned DestReg, int FI,
754 const TargetRegisterClass *RC) const {
755 DebugLoc DL = DebugLoc::getUnknownLoc();
756 if (I != MBB.end()) DL = I->getDebugLoc();
757
758 if (RC == ARM::GPRRegisterClass) {
759 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
760 .addFrameIndex(FI).addReg(0).addImm(0));
761 } else if (RC == ARM::DPRRegisterClass) {
762 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
763 .addFrameIndex(FI).addImm(0));
764 } else {
765 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
766 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg)
767 .addFrameIndex(FI).addImm(0));
768 }
769 }
770
771 void ARMBaseInstrInfo::
772 loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
773 SmallVectorImpl &Addr,
774 const TargetRegisterClass *RC,
775 SmallVectorImpl &NewMIs) const {
776 DebugLoc DL = DebugLoc::getUnknownLoc();
777 unsigned Opc = 0;
778 if (RC == ARM::GPRRegisterClass) {
779 Opc = ARM::LDR;
780 } else if (RC == ARM::DPRRegisterClass) {
781 Opc = ARM::FLDD;
782 } else {
783 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
784 Opc = ARM::FLDS;
785 }
786
787 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
788 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
789 MIB.addOperand(Addr[i]);
790 AddDefaultPred(MIB);
791 NewMIs.push_back(MIB);
792 return;
793 }
794
795 MachineInstr *ARMBaseInstrInfo::
796 foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
797 const SmallVectorImpl &Ops, int FI) const {
798 if (Ops.size() != 1) return NULL;
799
800 unsigned OpNum = Ops[0];
801 unsigned Opc = MI->getOpcode();
802 MachineInstr *NewMI = NULL;
803 switch (Opc) {
804 default: break;
805 case ARM::MOVr: {
806 if (MI->getOperand(4).getReg() == ARM::CPSR)
807 // If it is updating CPSR, then it cannot be folded.
808 break;
809 unsigned Pred = MI->getOperand(2).getImm();
810 unsigned PredReg = MI->getOperand(3).getReg();
811 if (OpNum == 0) { // move -> store
812 unsigned SrcReg = MI->getOperand(1).getReg();
813 bool isKill = MI->getOperand(1).isKill();
814 bool isUndef = MI->getOperand(1).isUndef();
815 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR))
816 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
817 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
818 } else { // move -> load
819 unsigned DstReg = MI->getOperand(0).getReg();
820 bool isDead = MI->getOperand(0).isDead();
821 bool isUndef = MI->getOperand(0).isUndef();
822 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR))
823 .addReg(DstReg,
824 RegState::Define |
825 getDeadRegState(isDead) |
826 getUndefRegState(isUndef))
827 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
828 }
829 break;
830 }
831 case ARM::FCPYS: {
832 unsigned Pred = MI->getOperand(2).getImm();
833 unsigned PredReg = MI->getOperand(3).getReg();
834 if (OpNum == 0) { // move -> store
835 unsigned SrcReg = MI->getOperand(1).getReg();
836 bool isKill = MI->getOperand(1).isKill();
837 bool isUndef = MI->getOperand(1).isUndef();
838 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTS))
839 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
840 .addFrameIndex(FI)
841 .addImm(0).addImm(Pred).addReg(PredReg);
842 } else { // move -> load
843 unsigned DstReg = MI->getOperand(0).getReg();
844 bool isDead = MI->getOperand(0).isDead();
845 bool isUndef = MI->getOperand(0).isUndef();
846 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS))
847 .addReg(DstReg,
848 RegState::Define |
849 getDeadRegState(isDead) |
850 getUndefRegState(isUndef))
851 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
852 }
853 break;
854 }
855 case ARM::FCPYD: {
856 unsigned Pred = MI->getOperand(2).getImm();
857 unsigned PredReg = MI->getOperand(3).getReg();
858 if (OpNum == 0) { // move -> store
859 unsigned SrcReg = MI->getOperand(1).getReg();
860 bool isKill = MI->getOperand(1).isKill();
861 bool isUndef = MI->getOperand(1).isUndef();
862 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTD))
863 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
864 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
865 } else { // move -> load
866 unsigned DstReg = MI->getOperand(0).getReg();
867 bool isDead = MI->getOperand(0).isDead();
868 bool isUndef = MI->getOperand(0).isUndef();
869 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDD))
870 .addReg(DstReg,
871 RegState::Define |
872 getDeadRegState(isDead) |
873 getUndefRegState(isUndef))
874 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
875 }
876 break;
877 }
878 }
879
880 return NewMI;
881 }
882
883 MachineInstr*
884 ARMBaseInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
885 MachineInstr* MI,
886 const SmallVectorImpl &Ops,
887 MachineInstr* LoadMI) const {
888 return 0;
889 }
890
891 bool
892 ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
893 const SmallVectorImpl &Ops) const {
894 if (Ops.size() != 1) return false;
895
896 unsigned Opc = MI->getOpcode();
897 switch (Opc) {
898 default: break;
899 case ARM::MOVr:
900 // If it is updating CPSR, then it cannot be folded.
901 return MI->getOperand(4).getReg() != ARM::CPSR;
902 case ARM::FCPYS:
903 case ARM::FCPYD:
904 return true;
905
906 case ARM::VMOVD:
907 case ARM::VMOVQ:
908 return false; // FIXME
909 }
910
911 return false;
912 }
160160 MachineBasicBlock::iterator &MBBI,
161161 LiveVariables *LV) const;
162162
163 virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0;
164
163165 // Branch analysis.
164166 virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
165167 MachineBasicBlock *&FBB,
197199 /// GetInstSize - Returns the size of the specified MachineInstr.
198200 ///
199201 virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const;
200 };
201
202 class ARMInstrInfo : public ARMBaseInstrInfo {
203 ARMRegisterInfo RI;
204 public:
205 explicit ARMInstrInfo(const ARMSubtarget &STI);
206
207 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
208 /// such, whenever a client has an instance of instruction info, it should
209 /// always be able to get register info as well (through this method).
210 ///
211 virtual const ARMRegisterInfo &getRegisterInfo() const { return RI; }
212202
213203 /// Return true if the instruction is a register to register move and return
214204 /// the source and dest operands and their sub-register indices by reference.
246236 const TargetRegisterClass *RC,
247237 SmallVectorImpl &NewMIs) const;
248238
239 virtual bool canFoldMemoryOperand(const MachineInstr *MI,
240 const SmallVectorImpl &Ops) const;
241
242 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
243 MachineInstr* MI,
244 const SmallVectorImpl &Ops,
245 int FrameIndex) const;
246
247 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
248 MachineInstr* MI,
249 const SmallVectorImpl &Ops,
250 MachineInstr* LoadMI) const;
251 };
252
253 class ARMInstrInfo : public ARMBaseInstrInfo {
254 ARMRegisterInfo RI;
255 public:
256 explicit ARMInstrInfo(const ARMSubtarget &STI);
257
258 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
259 /// such, whenever a client has an instance of instruction info, it should
260 /// always be able to get register info as well (through this method).
261 ///
262 const ARMRegisterInfo &getRegisterInfo() const { return RI; }
263
249264 void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
250265 unsigned DestReg, const MachineInstr *Orig) const;
251
252 virtual bool canFoldMemoryOperand(const MachineInstr *MI,
253 const SmallVectorImpl &Ops) const;
254
255 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
256 MachineInstr* MI,
257 const SmallVectorImpl &Ops,
258 int FrameIndex) const;
259
260 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
261 MachineInstr* MI,
262 const SmallVectorImpl &Ops,
263 MachineInstr* LoadMI) const {
264 return 0;
265 }
266266 };
267267
268268 }
9494 }
9595
9696 ThumbTargetMachine::ThumbTargetMachine(const Module &M, const std::string &FS)
97 : ARMBaseTargetMachine(M, FS, true), InstrInfo(Subtarget),
97 : ARMBaseTargetMachine(M, FS, true),
9898 DataLayout(Subtarget.isAPCS_ABI() ?
9999 std::string("e-p:32:32-f64:32:32-i64:32:32-"
100100 "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
101101 std::string("e-p:32:32-f64:64:64-i64:64:64-"
102102 "i16:16:32-i8:8:32-i1:8:32-a:0:32")),
103103 TLInfo(*this) {
104 // Create the approriate type of Thumb InstrInfo
105 if (Subtarget.hasThumb2())
106 InstrInfo = new Thumb2InstrInfo(Subtarget);
107 else
108 InstrInfo = new Thumb1InstrInfo(Subtarget);
104109 }
105110
106111 unsigned ARMTargetMachine::getJITMatchQuality() {
2121 #include "ARMJITInfo.h"
2222 #include "ARMSubtarget.h"
2323 #include "ARMISelLowering.h"
24 #include "ThumbInstrInfo.h"
24 #include "Thumb1InstrInfo.h"
25 #include "Thumb2InstrInfo.h"
2526
2627 namespace llvm {
2728
110111 };
111112
112113 /// ThumbTargetMachine - Thumb target machine.
114 /// Due to the way architectures are handled, this represents both
115 /// Thumb-1 and Thumb-2.
113116 ///
114117 class ThumbTargetMachine : public ARMBaseTargetMachine {
115 ThumbInstrInfo InstrInfo;
116 const TargetData DataLayout; // Calculates type size & alignment
118 ARMBaseInstrInfo *InstrInfo; // either Thumb1InstrInfo or Thumb2InstrInfo
119 const TargetData DataLayout; // Calculates type size & alignment
117120 ARMTargetLowering TLInfo;
118121 public:
119122 ThumbTargetMachine(const Module &M, const std::string &FS);
120123
121 virtual const ThumbRegisterInfo *getRegisterInfo() const {
122 return &InstrInfo.getRegisterInfo();
124 /// returns either Thumb1RegisterInfo of Thumb2RegisterInfo
125 virtual const ARMBaseRegisterInfo *getRegisterInfo() const {
126 return &InstrInfo->getRegisterInfo();
123127 }
124128
125 virtual ARMTargetLowering *getTargetLowering() const {
129 virtual ARMTargetLowering *getTargetLowering() const {
126130 return const_cast(&TLInfo);
127131 }
128132
129 virtual const ThumbInstrInfo *getInstrInfo() const { return &InstrInfo; }
133 /// returns either Thumb1InstrInfo or Thumb2InstrInfo
134 virtual const ARMBaseInstrInfo *getInstrInfo() const { return InstrInfo; }
130135 virtual const TargetData *getTargetData() const { return &DataLayout; }
131136
132137 static unsigned getJITMatchQuality();
2323 ARMSubtarget.cpp
2424 ARMTargetAsmInfo.cpp
2525 ARMTargetMachine.cpp
26 ThumbInstrInfo.cpp
27 ThumbRegisterInfo.cpp
26 Thumb1InstrInfo.cpp
27 Thumb1RegisterInfo.cpp
28 Thumb2InstrInfo.cpp
29 Thumb2RegisterInfo.cpp
2830 )
2931
3032 target_link_libraries (LLVMARMCodeGen LLVMSelectionDAG)
0 //===- Thumb1InstrInfo.cpp - Thumb-1 Instruction Information --------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-1 implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "ARMInstrInfo.h"
14 #include "ARM.h"
15 #include "ARMGenInstrInfo.inc"
16 #include "ARMMachineFunctionInfo.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "Thumb1InstrInfo.h"
21
22 using namespace llvm;
23
24 Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
25 : ARMBaseInstrInfo(STI), RI(*this, STI) {
26 }
27
28 bool Thumb1InstrInfo::isMoveInstr(const MachineInstr &MI,
29 unsigned &SrcReg, unsigned &DstReg,
30 unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
31 SrcSubIdx = DstSubIdx = 0; // No sub-registers.
32
33 unsigned oc = MI.getOpcode();
34 switch (oc) {
35 default:
36 return false;
37 case ARM::tMOVr:
38 case ARM::tMOVhir2lor:
39 case ARM::tMOVlor2hir:
40 case ARM::tMOVhir2hir:
41 assert(MI.getDesc().getNumOperands() >= 2 &&
42 MI.getOperand(0).isReg() &&
43 MI.getOperand(1).isReg() &&
44 "Invalid Thumb MOV instruction");
45 SrcReg = MI.getOperand(1).getReg();
46 DstReg = MI.getOperand(0).getReg();
47 return true;
48 }
49 }
50
51 unsigned Thumb1InstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
52 int &FrameIndex) const {
53 switch (MI->getOpcode()) {
54 default: break;
55 case ARM::tRestore:
56 if (MI->getOperand(1).isFI() &&
57 MI->getOperand(2).isImm() &&
58 MI->getOperand(2).getImm() == 0) {
59 FrameIndex = MI->getOperand(1).getIndex();
60 return MI->getOperand(0).getReg();
61 }
62 break;
63 }
64 return 0;
65 }
66
67 unsigned Thumb1InstrInfo::isStoreToStackSlot(const MachineInstr *MI,
68 int &FrameIndex) const {
69 switch (MI->getOpcode()) {
70 default: break;
71 case ARM::tSpill:
72 if (MI->getOperand(1).isFI() &&
73 MI->getOperand(2).isImm() &&
74 MI->getOperand(2).getImm() == 0) {
75 FrameIndex = MI->getOperand(1).getIndex();
76 return MI->getOperand(0).getReg();
77 }
78 break;
79 }
80 return 0;
81 }
82
83 bool Thumb1InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
84 MachineBasicBlock::iterator I,
85 unsigned DestReg, unsigned SrcReg,
86 const TargetRegisterClass *DestRC,
87 const TargetRegisterClass *SrcRC) const {
88 DebugLoc DL = DebugLoc::getUnknownLoc();
89 if (I != MBB.end()) DL = I->getDebugLoc();
90
91 if (DestRC == ARM::GPRRegisterClass) {
92 if (SrcRC == ARM::GPRRegisterClass) {
93 BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg(SrcReg);
94 return true;
95 } else if (SrcRC == ARM::tGPRRegisterClass) {
96 BuildMI(MBB, I, DL, get(ARM::tMOVlor2hir), DestReg).addReg(SrcReg);
97 return true;
98 }
99 } else if (DestRC == ARM::tGPRRegisterClass) {
100 if (SrcRC == ARM::GPRRegisterClass) {
101 BuildMI(MBB, I, DL, get(ARM::tMOVhir2lor), DestReg).addReg(SrcReg);
102 return true;
103 } else if (SrcRC == ARM::tGPRRegisterClass) {
104 BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg);
105 return true;
106 }
107 }
108
109 return false;
110 }
111
112 bool Thumb1InstrInfo::
113 canFoldMemoryOperand(const MachineInstr *MI,
114 const SmallVectorImpl &Ops) const {
115 if (Ops.size() != 1) return false;
116
117 unsigned OpNum = Ops[0];
118 unsigned Opc = MI->getOpcode();
119 switch (Opc) {
120 default: break;
121 case ARM::tMOVr:
122 case ARM::tMOVlor2hir:
123 case ARM::tMOVhir2lor:
124 case ARM::tMOVhir2hir: {
125 if (OpNum == 0) { // move -> store
126 unsigned SrcReg = MI->getOperand(1).getReg();
127 if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
128 // tSpill cannot take a high register operand.
129 return false;
130 } else { // move -> load
131 unsigned DstReg = MI->getOperand(0).getReg();
132 if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
133 // tRestore cannot target a high register operand.
134 return false;
135 }
136 return true;
137 }
138 }
139
140 return false;
141 }
142
143 void Thumb1InstrInfo::
144 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
145 unsigned SrcReg, bool isKill, int FI,
146 const TargetRegisterClass *RC) const {
147 DebugLoc DL = DebugLoc::getUnknownLoc();
148 if (I != MBB.end()) DL = I->getDebugLoc();
149
150 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
151
152 if (RC == ARM::tGPRRegisterClass) {
153 BuildMI(MBB, I, DL, get(ARM::tSpill))
154 .addReg(SrcReg, getKillRegState(isKill))
155 .addFrameIndex(FI).addImm(0);
156 }
157 }
158
159 void Thumb1InstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
160 bool isKill,
161 SmallVectorImpl &Addr,
162 const TargetRegisterClass *RC,
163 SmallVectorImpl &NewMIs) const{
164 DebugLoc DL = DebugLoc::getUnknownLoc();
165 unsigned Opc = 0;
166
167 assert(RC == ARM::GPRRegisterClass && "Unknown regclass!");
168 if (RC == ARM::GPRRegisterClass) {
169 Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR;
170 }
171
172 MachineInstrBuilder MIB =
173 BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill));
174 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
175 MIB.addOperand(Addr[i]);
176 NewMIs.push_back(MIB);
177 return;
178 }
179
180 void Thumb1InstrInfo::
181 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
182 unsigned DestReg, int FI,
183 const TargetRegisterClass *RC) const {
184 DebugLoc DL = DebugLoc::getUnknownLoc();
185 if (I != MBB.end()) DL = I->getDebugLoc();
186
187 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
188
189 if (RC == ARM::tGPRRegisterClass) {
190 BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
191 .addFrameIndex(FI).addImm(0);
192 }
193 }
194
195 void Thumb1InstrInfo::
196 loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
197 SmallVectorImpl &Addr,
198 const TargetRegisterClass *RC,
199 SmallVectorImpl &NewMIs) const {
200 DebugLoc DL = DebugLoc::getUnknownLoc();
201 unsigned Opc = 0;
202
203 if (RC == ARM::GPRRegisterClass) {
204 Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR;
205 }
206
207 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
208 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
209 MIB.addOperand(Addr[i]);
210 NewMIs.push_back(MIB);
211 return;
212 }
213
214 bool Thumb1InstrInfo::
215 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
216 MachineBasicBlock::iterator MI,
217 const std::vector &CSI) const {
218 if (CSI.empty())
219 return false;
220
221 DebugLoc DL = DebugLoc::getUnknownLoc();
222 if (MI != MBB.end()) DL = MI->getDebugLoc();
223
224 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
225 for (unsigned i = CSI.size(); i != 0; --i) {
226 unsigned Reg = CSI[i-1].getReg();
227 // Add the callee-saved register as live-in. It's killed at the spill.
228 MBB.addLiveIn(Reg);
229 MIB.addReg(Reg, RegState::Kill);
230 }
231 return true;
232 }
233
234 bool Thumb1InstrInfo::
235 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
236 MachineBasicBlock::iterator MI,
237 const std::vector &CSI) const {
238 MachineFunction &MF = *MBB.getParent();
239 ARMFunctionInfo *AFI = MF.getInfo();
240 if (CSI.empty())
241 return false;
242
243 bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
244 MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI->getDebugLoc());
245 for (unsigned i = CSI.size(); i != 0; --i) {
246 unsigned Reg = CSI[i-1].getReg();
247 if (Reg == ARM::LR) {
248 // Special epilogue for vararg functions. See emitEpilogue
249 if (isVarArg)
250 continue;
251 Reg = ARM::PC;
252 PopMI->setDesc(get(ARM::tPOP_RET));
253 MI = MBB.erase(MI);
254 }
255 PopMI->addOperand(MachineOperand::CreateReg(Reg, true));
256 }
257
258 // It's illegal to emit pop instruction without operands.
259 if (PopMI->getNumOperands() > 0)
260 MBB.insert(MI, PopMI);
261
262 return true;
263 }
264
265 MachineInstr *Thumb1InstrInfo::
266 foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
267 const SmallVectorImpl &Ops, int FI) const {
268 if (Ops.size() != 1) return NULL;
269
270 unsigned OpNum = Ops[0];
271 unsigned Opc = MI->getOpcode();
272 MachineInstr *NewMI = NULL;
273 switch (Opc) {
274 default: break;
275 case ARM::tMOVr:
276 case ARM::tMOVlor2hir:
277 case ARM::tMOVhir2lor:
278 case ARM::tMOVhir2hir: {
279 if (OpNum == 0) { // move -> store
280 unsigned SrcReg = MI->getOperand(1).getReg();
281 bool isKill = MI->getOperand(1).isKill();
282 if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
283 // tSpill cannot take a high register operand.
284 break;
285 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill))
286 .addReg(SrcReg, getKillRegState(isKill))
287 .addFrameIndex(FI).addImm(0);
288 } else { // move -> load
289 unsigned DstReg = MI->getOperand(0).getReg();
290 if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
291 // tRestore cannot target a high register operand.
292 break;
293 bool isDead = MI->getOperand(0).isDead();
294 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore))
295 .addReg(DstReg, RegState::Define | getDeadRegState(isDead))
296 .addFrameIndex(FI).addImm(0);
297 }
298 break;
299 }
300 }
301
302 return NewMI;
303 }
0 //===- Thumb1InstrInfo.h - Thumb-1 Instruction Information ----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-1 implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef THUMB1INSTRUCTIONINFO_H
14 #define THUMB1INSTRUCTIONINFO_H
15
16 #include "llvm/Target/TargetInstrInfo.h"
17 #include "ARM.h"
18 #include "ARMInstrInfo.h"
19 #include "Thumb1RegisterInfo.h"
20
21 namespace llvm {
22 class ARMSubtarget;
23
24 class Thumb1InstrInfo : public ARMBaseInstrInfo {
25 Thumb1RegisterInfo RI;
26 public:
27 explicit Thumb1InstrInfo(const ARMSubtarget &STI);
28
29 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
30 /// such, whenever a client has an instance of instruction info, it should
31 /// always be able to get register info as well (through this method).
32 ///
33 const Thumb1RegisterInfo &getRegisterInfo() const { return RI; }
34
35 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
36 MachineBasicBlock::iterator MI,
37 const std::vector &CSI) const;
38 bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
39 MachineBasicBlock::iterator MI,
40 const std::vector &CSI) const;
41
42 bool isMoveInstr(const MachineInstr &MI,
43 unsigned &SrcReg, unsigned &DstReg,
44 unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
45 unsigned isLoadFromStackSlot(const MachineInstr *MI,
46 int &FrameIndex) const;
47 unsigned isStoreToStackSlot(const MachineInstr *MI,
48 int &FrameIndex) const;
49
50 bool copyRegToReg(MachineBasicBlock &MBB,
51 MachineBasicBlock::iterator I,
52 unsigned DestReg, unsigned SrcReg,
53 const TargetRegisterClass *DestRC,
54 const TargetRegisterClass *SrcRC) const;
55 void storeRegToStackSlot(MachineBasicBlock &MBB,
56 MachineBasicBlock::iterator MBBI,
57 unsigned SrcReg, bool isKill, int FrameIndex,
58 const TargetRegisterClass *RC) const;
59
60 void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill,
61 SmallVectorImpl &Addr,
62 const TargetRegisterClass *RC,
63 SmallVectorImpl &NewMIs) const;
64
65 void loadRegFromStackSlot(MachineBasicBlock &MBB,
66 MachineBasicBlock::iterator MBBI,
67 unsigned DestReg, int FrameIndex,
68 const TargetRegisterClass *RC) const;
69
70 void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
71 SmallVectorImpl &Addr,
72 const TargetRegisterClass *RC,
73 SmallVectorImpl &NewMIs) const;
74
75 bool canFoldMemoryOperand(const MachineInstr *MI,
76 const SmallVectorImpl &Ops) const;
77
78 MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
79 MachineInstr* MI,
80 const SmallVectorImpl &Ops,
81 int FrameIndex) const;
82
83 MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
84 MachineInstr* MI,
85 const SmallVectorImpl &Ops,
86 MachineInstr* LoadMI) const {
87 return 0;
88 }
89 };
90 }
91
92 #endif // THUMB1INSTRUCTIONINFO_H
0 //===- Thumb1RegisterInfo.cpp - Thumb-1 Register Information -------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-1 implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "ARM.h"
14 #include "ARMAddressingModes.h"
15 #include "ARMMachineFunctionInfo.h"
16 #include "ARMSubtarget.h"
17 #include "Thumb1InstrInfo.h"
18 #include "Thumb1RegisterInfo.h"
19 #include "llvm/Constants.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/CodeGen/MachineConstantPool.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineLocation.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/Target/TargetFrameInfo.h"
28 #include "llvm/Target/TargetMachine.h"
29 #include "llvm/ADT/BitVector.h"
30 #include "llvm/ADT/SmallVector.h"
31 #include "llvm/Support/CommandLine.h"
32 using namespace llvm;
33
34 static cl::opt
35 ThumbRegScavenging("enable-thumb-reg-scavenging",
36 cl::Hidden,
37 cl::desc("Enable register scavenging on Thumb"));
38
39 Thumb1RegisterInfo::Thumb1RegisterInfo(const TargetInstrInfo &tii,
40 const ARMSubtarget &sti)
41 : ARMBaseRegisterInfo(tii, sti) {
42 }
43
44 /// emitLoadConstPool - Emits a load from constpool to materialize the
45 /// specified immediate.
46 void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
47 MachineBasicBlock::iterator &MBBI,
48 unsigned DestReg, int Val,
49 const TargetInstrInfo *TII,
50 DebugLoc dl) const {
51 MachineFunction &MF = *MBB.getParent();
52 MachineConstantPool *ConstantPool = MF.getConstantPool();
53 Constant *C = ConstantInt::get(Type::Int32Ty, Val);
54 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
55
56 BuildMI(MBB, MBBI, dl, TII->get(ARM::tLDRcp), DestReg)
57 .addConstantPoolIndex(Idx);
58 }
59
60 const TargetRegisterClass*
61 Thumb1RegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const {
62 if (isARMLowRegister(Reg))
63 return ARM::tGPRRegisterClass;
64 switch (Reg) {
65 default:
66 break;
67 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
68 case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC:
69 return ARM::GPRRegisterClass;
70 }
71
72 return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT);
73 }
74
75 bool
76 Thumb1RegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
77 return ThumbRegScavenging;
78 }
79
80 bool Thumb1RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
81 const MachineFrameInfo *FFI = MF.getFrameInfo();
82 unsigned CFSize = FFI->getMaxCallFrameSize();
83 // It's not always a good idea to include the call frame as part of the
84 // stack frame. ARM (especially Thumb) has small immediate offset to
85 // address the stack frame. So a large call frame can cause poor codegen
86 // and may even makes it impossible to scavenge a register.
87 if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
88 return false;
89
90 return !MF.getFrameInfo()->hasVarSizedObjects();
91 }
92
93 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
94 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
95 /// in a register using mov / mvn sequences or load the immediate from a
96 /// constpool entry.
97 static
98 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
99 MachineBasicBlock::iterator &MBBI,
100 unsigned DestReg, unsigned BaseReg,
101 int NumBytes, bool CanChangeCC,
102 const TargetInstrInfo &TII,
103 const Thumb1RegisterInfo& MRI,
104 DebugLoc dl) {
105 bool isHigh = !isARMLowRegister(DestReg) ||
106 (BaseReg != 0 && !isARMLowRegister(BaseReg));
107 bool isSub = false;
108 // Subtract doesn't have high register version. Load the negative value
109 // if either base or dest register is a high register. Also, if do not
110 // issue sub as part of the sequence if condition register is to be
111 // preserved.
112 if (NumBytes < 0 && !isHigh && CanChangeCC) {
113 isSub = true;
114 NumBytes = -NumBytes;
115 }
116 unsigned LdReg = DestReg;
117 if (DestReg == ARM::SP) {
118 assert(BaseReg == ARM::SP && "Unexpected!");
119 LdReg = ARM::R3;
120 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
121 .addReg(ARM::R3, RegState::Kill);
122 }
123
124 if (NumBytes <= 255 && NumBytes >= 0)
125 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
126 else if (NumBytes < 0 && NumBytes >= -255) {
127 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
128 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg)
129 .addReg(LdReg, RegState::Kill);
130 } else
131 MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, &TII, dl);
132
133 // Emit add / sub.
134 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
135 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl,
136 TII.get(Opc), DestReg);
137 if (DestReg == ARM::SP || isSub)
138 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
139 else
140 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
141 if (DestReg == ARM::SP)
142 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
143 .addReg(ARM::R12, RegState::Kill);
144 }
145
146 /// calcNumMI - Returns the number of instructions required to materialize
147 /// the specific add / sub r, c instruction.
148 static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
149 unsigned NumBits, unsigned Scale) {
150 unsigned NumMIs = 0;
151 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
152
153 if (Opc == ARM::tADDrSPi) {
154 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
155 Bytes -= ThisVal;
156 NumMIs++;
157 NumBits = 8;
158 Scale = 1; // Followed by a number of tADDi8.
159 Chunk = ((1 << NumBits) - 1) * Scale;
160 }
161
162 NumMIs += Bytes / Chunk;
163 if ((Bytes % Chunk) != 0)
164 NumMIs++;
165 if (ExtraOpc)
166 NumMIs++;
167 return NumMIs;
168 }
169
170 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
171 /// a destreg = basereg + immediate in Thumb code.
172 static
173 void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
174 MachineBasicBlock::iterator &MBBI,
175 unsigned DestReg, unsigned BaseReg,
176 int NumBytes, const TargetInstrInfo &TII,
177 const Thumb1RegisterInfo& MRI,
178 DebugLoc dl) {
179 bool isSub = NumBytes < 0;
180 unsigned Bytes = (unsigned)NumBytes;
181 if (isSub) Bytes = -NumBytes;
182 bool isMul4 = (Bytes & 3) == 0;
183 bool isTwoAddr = false;
184 bool DstNotEqBase = false;
185 unsigned NumBits = 1;
186 unsigned Scale = 1;
187 int Opc = 0;
188 int ExtraOpc = 0;
189
190 if (DestReg == BaseReg && BaseReg == ARM::SP) {
191 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
192 NumBits = 7;
193 Scale = 4;
194 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
195 isTwoAddr = true;
196 } else if (!isSub && BaseReg == ARM::SP) {
197 // r1 = add sp, 403
198 // =>
199 // r1 = add sp, 100 * 4
200 // r1 = add r1, 3
201 if (!isMul4) {
202 Bytes &= ~3;
203 ExtraOpc = ARM::tADDi3;
204 }
205 NumBits = 8;
206 Scale = 4;
207 Opc = ARM::tADDrSPi;
208 } else {
209 // sp = sub sp, c
210 // r1 = sub sp, c
211 // r8 = sub sp, c
212 if (DestReg != BaseReg)
213 DstNotEqBase = true;
214 NumBits = 8;
215 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
216 isTwoAddr = true;
217 }
218
219 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
220 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
221 if (NumMIs > Threshold) {
222 // This will expand into too many instructions. Load the immediate from a
223 // constpool entry.
224 emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII,
225 MRI, dl);
226 return;
227 }
228
229 if (DstNotEqBase) {
230 if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) {
231 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
232 unsigned Chunk = (1 << 3) - 1;
233 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
234 Bytes -= ThisVal;
235 BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg)
236 .addReg(BaseReg, RegState::Kill).addImm(ThisVal);
237 } else {
238 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
239 .addReg(BaseReg, RegState::Kill);
240 }
241 BaseReg = DestReg;
242 }
243
244 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
245 while (Bytes) {
246 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
247 Bytes -= ThisVal;
248 ThisVal /= Scale;
249 // Build the new tADD / tSUB.
250 if (isTwoAddr)
251 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
252 .addReg(DestReg).addImm(ThisVal);
253 else {
254 bool isKill = BaseReg != ARM::SP;
255 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
256 .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
257 BaseReg = DestReg;
258
259 if (Opc == ARM::tADDrSPi) {
260 // r4 = add sp, imm
261 // r4 = add r4, imm
262 // ...
263 NumBits = 8;
264 Scale = 1;
265 Chunk = ((1 << NumBits) - 1) * Scale;
266 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
267 isTwoAddr = true;
268 }
269 }
270 }
271
272 if (ExtraOpc)
273 BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg)
274 .addReg(DestReg, RegState::Kill)
275 .addImm(((unsigned)NumBytes) & 3);
276 }
277
278 static void emitSPUpdate(MachineBasicBlock &MBB,
279 MachineBasicBlock::iterator &MBBI,
280 const TargetInstrInfo &TII, DebugLoc dl,
281 const Thumb1RegisterInfo &MRI,
282 int NumBytes) {
283 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII,
284 MRI, dl);
285 }
286
287 void Thumb1RegisterInfo::
288 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
289 MachineBasicBlock::iterator I) const {
290 if (!hasReservedCallFrame(MF)) {
291 // If we have alloca, convert as follows:
292 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
293 // ADJCALLSTACKUP -> add, sp, sp, amount
294 MachineInstr *Old = I;
295 DebugLoc dl = Old->getDebugLoc();
296 unsigned Amount = Old->getOperand(0).getImm();
297 if (Amount != 0) {
298 // We need to keep the stack aligned properly. To do this, we round the
299 // amount of space needed for the outgoing arguments up to the next
300 // alignment boundary.
301 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
302 Amount = (Amount+Align-1)/Align*Align;
303
304 // Replace the pseudo instruction with a new instruction...
305 unsigned Opc = Old->getOpcode();
306 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
307 emitSPUpdate(MBB, I, TII, dl, *this, -Amount);
308 } else {
309 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
310 emitSPUpdate(MBB, I, TII, dl, *this, Amount);
311 }
312 }
313 }
314 MBB.erase(I);
315 }
316
317 /// emitThumbConstant - Emit a series of instructions to materialize a
318 /// constant.
319 static void emitThumbConstant(MachineBasicBlock &MBB,
320 MachineBasicBlock::iterator &MBBI,
321 unsigned DestReg, int Imm,
322 const TargetInstrInfo &TII,
323 const Thumb1RegisterInfo& MRI,
324 DebugLoc dl) {
325 bool isSub = Imm < 0;
326 if (isSub) Imm = -Imm;
327
328 int Chunk = (1 << 8) - 1;
329 int ThisVal = (Imm > Chunk) ? Chunk : Imm;
330 Imm -= ThisVal;
331 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal);
332 if (Imm > 0)
333 emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl);
334 if (isSub)
335 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg)
336 .addReg(DestReg, RegState::Kill);
337 }
338
339 void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
340 int SPAdj, RegScavenger *RS) const{
341 unsigned i = 0;
342 MachineInstr &MI = *II;
343 MachineBasicBlock &MBB = *MI.getParent();
344 MachineFunction &MF = *MBB.getParent();
345 ARMFunctionInfo *AFI = MF.getInfo();
346 DebugLoc dl = MI.getDebugLoc();
347
348 while (!MI.getOperand(i).isFI()) {
349 ++i;
350 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
351 }
352
353 unsigned FrameReg = ARM::SP;
354 int FrameIndex = MI.getOperand(i).getIndex();
355 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
356 MF.getFrameInfo()->getStackSize() + SPAdj;
357
358 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
359 Offset -= AFI->getGPRCalleeSavedArea1Offset();
360 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
361 Offset -= AFI->getGPRCalleeSavedArea2Offset();
362 else if (hasFP(MF)) {
363 assert(SPAdj == 0 && "Unexpected");
364 // There is alloca()'s in this function, must reference off the frame
365 // pointer instead.
366 FrameReg = getFrameRegister(MF);
367 Offset -= AFI->getFramePtrSpillOffset();
368 }
369
370 unsigned Opcode = MI.getOpcode();
371 const TargetInstrDesc &Desc = MI.getDesc();
372 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
373
374 if (Opcode == ARM::tADDrSPi) {
375 Offset += MI.getOperand(i+1).getImm();
376
377 // Can't use tADDrSPi if it's based off the frame pointer.
378 unsigned NumBits = 0;
379 unsigned Scale = 1;
380 if (FrameReg != ARM::SP) {
381 Opcode = ARM::tADDi3;
382 MI.setDesc(TII.get(ARM::tADDi3));
383 NumBits = 3;
384 } else {
385 NumBits = 8;
386 Scale = 4;
387 assert((Offset & 3) == 0 &&
388 "Thumb add/sub sp, #imm immediate must be multiple of 4!");
389 }
390
391 if (Offset == 0) {
392 // Turn it into a move.
393 MI.setDesc(TII.get(ARM::tMOVhir2lor));
394 MI.getOperand(i).ChangeToRegister(FrameReg, false);
395 MI.RemoveOperand(i+1);
396 return;
397 }
398
399 // Common case: small offset, fits into instruction.
400 unsigned Mask = (1 << NumBits) - 1;
401 if (((Offset / Scale) & ~Mask) == 0) {
402 // Replace the FrameIndex with sp / fp
403 MI.getOperand(i).ChangeToRegister(FrameReg, false);
404 MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
405 return;
406 }
407
408 unsigned DestReg = MI.getOperand(0).getReg();
409 unsigned Bytes = (Offset > 0) ? Offset : -Offset;
410 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
411 // MI would expand into a large number of instructions. Don't try to
412 // simplify the immediate.
413 if (NumMIs > 2) {
414 emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII,
415 *this, dl);
416 MBB.erase(II);
417 return;
418 }
419
420 if (Offset > 0) {
421 // Translate r0 = add sp, imm to
422 // r0 = add sp, 255*4
423 // r0 = add r0, (imm - 255*4)
424 MI.getOperand(i).ChangeToRegister(FrameReg, false);
425 MI.getOperand(i+1).ChangeToImmediate(Mask);
426 Offset = (Offset - Mask * Scale);
427 MachineBasicBlock::iterator NII = next(II);
428 emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII,
429 *this, dl);
430 } else {
431 // Translate r0 = add sp, -imm to
432 // r0 = -imm (this is then translated into a series of instructons)
433 // r0 = add r0, sp
434 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
435 MI.setDesc(TII.get(ARM::tADDhirr));
436 MI.getOperand(i).ChangeToRegister(DestReg, false, false, true);
437 MI.getOperand(i+1).ChangeToRegister(FrameReg, false);
438 }
439 return;
440 } else {
441 unsigned ImmIdx = 0;
442 int InstrOffs = 0;
443 unsigned NumBits = 0;
444 unsigned Scale = 1;
445 switch (AddrMode) {
446 case ARMII::AddrModeT1_s: {
447 ImmIdx = i+1;
448 InstrOffs = MI.getOperand(ImmIdx).getImm();
449 NumBits = (FrameReg == ARM::SP) ? 8 : 5;
450 Scale = 4;
451 break;
452 }
453 default:
454 assert(0 && "Unsupported addressing mode!");
455 abort();
456 break;
457 }
458
459 Offset += InstrOffs * Scale;
460 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
461
462 // Common case: small offset, fits into instruction.
463 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
464 int ImmedOffset = Offset / Scale;
465 unsigned Mask = (1 << NumBits) - 1;
466 if ((unsigned)Offset <= Mask * Scale) {
467 // Replace the FrameIndex with sp
468 MI.getOperand(i).ChangeToRegister(FrameReg, false);
469 ImmOp.ChangeToImmediate(ImmedOffset);
470 return;
471 }
472
473 bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
474 if (AddrMode == ARMII::AddrModeT1_s) {
475 // Thumb tLDRspi, tSTRspi. These will change to instructions that use
476 // a different base register.
477 NumBits = 5;
478 Mask = (1 << NumBits) - 1;
479 }
480 // If this is a thumb spill / restore, we will be using a constpool load to
481 // materialize the offset.
482 if (AddrMode == ARMII::AddrModeT1_s && isThumSpillRestore)
483 ImmOp.ChangeToImmediate(0);
484 else {
485 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
486 ImmedOffset = ImmedOffset & Mask;
487 ImmOp.ChangeToImmediate(ImmedOffset);
488 Offset &= ~(Mask*Scale);
489 }
490 }
491
492 // If we get here, the immediate doesn't fit into the instruction. We folded
493 // as much as possible above, handle the rest, providing a register that is
494 // SP+LargeImm.
495 assert(Offset && "This code isn't needed if offset already handled!");
496
497 if (Desc.mayLoad()) {
498 // Use the destination register to materialize sp + offset.
499 unsigned TmpReg = MI.getOperand(0).getReg();
500 bool UseRR = false;
501 if (Opcode == ARM::tRestore) {
502 if (FrameReg == ARM::SP)
503 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
504 Offset, false, TII, *this, dl);
505 else {
506 emitLoadConstPool(MBB, II, TmpReg, Offset, &TII, dl);
507 UseRR = true;
508 }
509 } else
510 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
511 *this, dl);
512 MI.setDesc(TII.get(ARM::tLDR));
513 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
514 if (UseRR)
515 // Use [reg, reg] addrmode.
516 MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
517 else // tLDR has an extra register operand.
518 MI.addOperand(MachineOperand::CreateReg(0, false));
519 } else if (Desc.mayStore()) {
520 // FIXME! This is horrific!!! We need register scavenging.
521 // Our temporary workaround has marked r3 unavailable. Of course, r3 is
522 // also a ABI register so it's possible that is is the register that is
523 // being storing here. If that's the case, we do the following:
524 // r12 = r2
525 // Use r2 to materialize sp + offset
526 // str r3, r2
527 // r2 = r12
528 unsigned ValReg = MI.getOperand(0).getReg();
529 unsigned TmpReg = ARM::R3;
530 bool UseRR = false;
531 if (ValReg == ARM::R3) {
532 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
533 .addReg(ARM::R2, RegState::Kill);
534 TmpReg = ARM::R2;
535 }
536 if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
537 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
538 .addReg(ARM::R3, RegState::Kill);
539 if (Opcode == ARM::tSpill) {
540 if (FrameReg == ARM::SP)
541 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
542 Offset, false, TII, *this, dl);
543 else {
544 emitLoadConstPool(MBB, II, TmpReg, Offset, &TII, dl);
545 UseRR = true;
546 }
547 } else
548 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
549 *this, dl);
550 MI.setDesc(TII.get(ARM::tSTR));
551 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
552 if (UseRR) // Use [reg, reg] addrmode.
553 MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
554 else // tSTR has an extra register operand.
555 MI.addOperand(MachineOperand::CreateReg(0, false));
556
557 MachineBasicBlock::iterator NII = next(II);
558 if (ValReg == ARM::R3)
559 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2)
560 .addReg(ARM::R12, RegState::Kill);
561 if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
562 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
563 .addReg(ARM::R12, RegState::Kill);
564 } else
565 assert(false && "Unexpected opcode!");
566 }
567
568 void Thumb1RegisterInfo::emitPrologue(MachineFunction &MF) const {
569 MachineBasicBlock &MBB = MF.front();
570 MachineBasicBlock::iterator MBBI = MBB.begin();
571 MachineFrameInfo *MFI = MF.getFrameInfo();
572 ARMFunctionInfo *AFI = MF.getInfo();
573 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
574 unsigned NumBytes = MFI->getStackSize();
575 const std::vector &CSI = MFI->getCalleeSavedInfo();
576 DebugLoc dl = (MBBI != MBB.end() ?
577 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
578
579 // Check if R3 is live in. It might have to be used as a scratch register.
580 for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(),
581 E = MF.getRegInfo().livein_end(); I != E; ++I) {
582 if (I->first == ARM::R3) {
583 AFI->setR3IsLiveIn(true);
584 break;
585 }
586 }
587
588 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
589 NumBytes = (NumBytes + 3) & ~3;
590 MFI->setStackSize(NumBytes);
591
592 // Determine the sizes of each callee-save spill areas and record which frame
593 // belongs to which callee-save spill areas.
594 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
595 int FramePtrSpillFI = 0;
596
597 if (VARegSaveSize)
598 emitSPUpdate(MBB, MBBI, TII, dl, *this, -VARegSaveSize);
599
600 if (!AFI->hasStackFrame()) {
601 if (NumBytes != 0)
602 emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
603 return;
604 }
605
606 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
607 unsigned Reg = CSI[i].getReg();
608 int FI = CSI[i].getFrameIdx();
609 switch (Reg) {
610 case ARM::R4:
611 case ARM::R5:
612 case ARM::R6:
613 case ARM::R7:
614 case ARM::LR:
615 if (Reg == FramePtr)
616 FramePtrSpillFI = FI;
617 AFI->addGPRCalleeSavedArea1Frame(FI);
618 GPRCS1Size += 4;
619 break;
620 case ARM::R8:
621 case ARM::R9:
622 case ARM::R10:
623 case ARM::R11:
624 if (Reg == FramePtr)
625 FramePtrSpillFI = FI;
626 if (STI.isTargetDarwin()) {
627 AFI->addGPRCalleeSavedArea2Frame(FI);
628 GPRCS2Size += 4;
629 } else {
630 AFI->addGPRCalleeSavedArea1Frame(FI);
631 GPRCS1Size += 4;
632 }
633 break;
634 default:
635 AFI->addDPRCalleeSavedAreaFrame(FI);
636 DPRCSSize += 8;
637 }
638 }
639
640 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
641 ++MBBI;
642 if (MBBI != MBB.end())
643 dl = MBBI->getDebugLoc();
644 }
645
646 // Darwin ABI requires FP to point to the stack slot that contains the
647 // previous FP.
648 if (STI.isTargetDarwin() || hasFP(MF)) {
649 MachineInstrBuilder MIB =
650 BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
651 .addFrameIndex(FramePtrSpillFI).addImm(0);
652 }
653
654 // Determine starting offsets of spill areas.
655 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
656 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
657 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
658 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
659 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
660 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
661 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
662
663 NumBytes = DPRCSOffset;
664 if (NumBytes) {
665 // Insert it after all the callee-save spills.
666 emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
667 }
668
669 if (STI.isTargetELF() && hasFP(MF)) {
670 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
671 AFI->getFramePtrSpillOffset());
672 }
673
674 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
675 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
676 AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
677 }
678
679 static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
680 for (unsigned i = 0; CSRegs[i]; ++i)
681 if (Reg == CSRegs[i])
682 return true;
683 return false;
684 }
685
686 static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
687 return (MI->getOpcode() == ARM::tRestore &&
688 MI->getOperand(1).isFI() &&
689 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
690 }
691
692 void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
693 MachineBasicBlock &MBB) const {
694 MachineBasicBlock::iterator MBBI = prior(MBB.end());
695 assert((MBBI->getOpcode() == ARM::tBX_RET ||
696 MBBI->getOpcode() == ARM::tPOP_RET) &&
697 "Can only insert epilog into returning blocks");
698 DebugLoc dl = MBBI->getDebugLoc();
699 MachineFrameInfo *MFI = MF.getFrameInfo();
700 ARMFunctionInfo *AFI = MF.getInfo();
701 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
702 int NumBytes = (int)MFI->getStackSize();
703
704 if (!AFI->hasStackFrame()) {
705 if (NumBytes != 0)
706 emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
707 } else {
708 // Unwind MBBI to point to first LDR / FLDD.
709 const unsigned *CSRegs = getCalleeSavedRegs();
710 if (MBBI != MBB.begin()) {
711 do
712 --MBBI;
713 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
714 if (!isCSRestore(MBBI, CSRegs))
715 ++MBBI;
716 }
717
718 // Move SP to start of FP callee save spill area.
719 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
720 AFI->getGPRCalleeSavedArea2Size() +
721 AFI->getDPRCalleeSavedAreaSize());
722
723 if (hasFP(MF)) {
724 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
725 // Reset SP based on frame pointer only if the stack frame extends beyond
726 // frame pointer stack slot or target is ELF and the function has FP.
727 if (NumBytes)
728 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes,
729 TII, *this, dl);
730 else
731 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP)
732 .addReg(FramePtr);
733 } else {
734 if (MBBI->getOpcode() == ARM::tBX_RET &&
735 &MBB.front() != MBBI &&
736 prior(MBBI)->getOpcode() == ARM::tPOP) {
737 MachineBasicBlock::iterator PMBBI = prior(MBBI);
738 emitSPUpdate(MBB, PMBBI, TII, dl, *this, NumBytes);
739 } else
740 emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
741 }
742 }
743
744 if (VARegSaveSize) {
745 // Epilogue for vararg functions: pop LR to R3 and branch off it.
746 // FIXME: Verify this is still ok when R3 is no longer being reserved.
747 BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3);
748
749 emitSPUpdate(MBB, MBBI, TII, dl, *this, VARegSaveSize);
750
751 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3);
752 MBB.erase(MBBI);
753 }
754 }
0 //===- Thumb1RegisterInfo.h - Thumb-1 Register Information Impl ----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-1 implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef THUMB1REGISTERINFO_H
14 #define THUMB1REGISTERINFO_H
15
16 #include "ARM.h"
17 #include "ARMRegisterInfo.h"
18 #include "llvm/Target/TargetRegisterInfo.h"
19
20 namespace llvm {
21 class ARMSubtarget;
22 class TargetInstrInfo;
23 class Type;
24
25 struct Thumb1RegisterInfo : public ARMBaseRegisterInfo {
26 public:
27 Thumb1RegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
28
29 /// emitLoadConstPool - Emits a load from constpool to materialize the
30 /// specified immediate.
31 void emitLoadConstPool(MachineBasicBlock &MBB,
32 MachineBasicBlock::iterator &MBBI,
33 unsigned DestReg, int Val,
34 const TargetInstrInfo *TII,
35 DebugLoc dl) const;
36
37 /// Code Generation virtual methods...
38 const TargetRegisterClass *
39 getPhysicalRegisterRegClass(unsigned Reg, MVT VT = MVT::Other) const;
40
41 bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
42
43 bool requiresRegisterScavenging(const MachineFunction &MF) const;
44
45 bool hasReservedCallFrame(MachineFunction &MF) const;
46
47 void eliminateCallFramePseudoInstr(MachineFunction &MF,
48 MachineBasicBlock &MBB,
49 MachineBasicBlock::iterator I) const;
50
51 void eliminateFrameIndex(MachineBasicBlock::iterator II,
52 int SPAdj, RegScavenger *RS = NULL) const;
53
54 void emitPrologue(MachineFunction &MF) const;
55 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
56 };
57 }
58
59 #endif // THUMB1REGISTERINFO_H
0 //===- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information --------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-2 implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "ARMInstrInfo.h"
14 #include "ARM.h"
15 #include "ARMGenInstrInfo.inc"
16 #include "ARMMachineFunctionInfo.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "Thumb2InstrInfo.h"
21
22 using namespace llvm;
23
24 Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
25 : ARMBaseInstrInfo(STI), RI(*this, STI) {
26 }
27
28 bool Thumb2InstrInfo::isMoveInstr(const MachineInstr &MI,
29 unsigned &SrcReg, unsigned &DstReg,
30 unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
31 SrcSubIdx = DstSubIdx = 0; // No sub-registers.
32
33 unsigned oc = MI.getOpcode();
34 switch (oc) {
35 default:
36 return false;
37 // FIXME: Thumb2
38 case ARM::tMOVr:
39 case ARM::tMOVhir2lor:
40 case ARM::tMOVlor2hir:
41 case ARM::tMOVhir2hir:
42 assert(MI.getDesc().getNumOperands() >= 2 &&
43 MI.getOperand(0).isReg() &&
44 MI.getOperand(1).isReg() &&
45 "Invalid Thumb MOV instruction");
46 SrcReg = MI.getOperand(1).getReg();
47 DstReg = MI.getOperand(0).getReg();
48 return true;
49 }
50 }
51
52 unsigned Thumb2InstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
53 int &FrameIndex) const {
54 switch (MI->getOpcode()) {
55 default: break;
56 // FIXME: Thumb2
57 case ARM::tRestore:
58 if (MI->getOperand(1).isFI() &&
59 MI->getOperand(2).isImm() &&
60 MI->getOperand(2).getImm() == 0) {
61 FrameIndex = MI->getOperand(1).getIndex();
62 return MI->getOperand(0).getReg();
63 }
64 break;
65 }
66 return 0;
67 }
68
69 unsigned Thumb2InstrInfo::isStoreToStackSlot(const MachineInstr *MI,
70 int &FrameIndex) const {
71 switch (MI->getOpcode()) {
72 default: break;
73 // FIXME: Thumb2
74 case ARM::tSpill:
75 if (MI->getOperand(1).isFI() &&
76 MI->getOperand(2).isImm() &&
77 MI->getOperand(2).getImm() == 0) {
78 FrameIndex = MI->getOperand(1).getIndex();
79 return MI->getOperand(0).getReg();
80 }
81 break;
82 }
83 return 0;
84 }
85
86 bool Thumb2InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
87 MachineBasicBlock::iterator I,
88 unsigned DestReg, unsigned SrcReg,
89 const TargetRegisterClass *DestRC,
90 const TargetRegisterClass *SrcRC) const {
91 DebugLoc DL = DebugLoc::getUnknownLoc();
92 if (I != MBB.end()) DL = I->getDebugLoc();
93
94 // FIXME: Thumb2
95 if (DestRC == ARM::GPRRegisterClass) {
96 if (SrcRC == ARM::GPRRegisterClass) {
97 BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg(SrcReg);
98 return true;
99 } else if (SrcRC == ARM::tGPRRegisterClass) {
100 BuildMI(MBB, I, DL, get(ARM::tMOVlor2hir), DestReg).addReg(SrcReg);
101 return true;
102 }
103 } else if (DestRC == ARM::tGPRRegisterClass) {
104 if (SrcRC == ARM::GPRRegisterClass) {
105 BuildMI(MBB, I, DL, get(ARM::tMOVhir2lor), DestReg).addReg(SrcReg);
106 return true;
107 } else if (SrcRC == ARM::tGPRRegisterClass) {
108 BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg);
109 return true;
110 }
111 }
112
113 return false;
114 }
115
116 bool Thumb2InstrInfo::
117 canFoldMemoryOperand(const MachineInstr *MI,
118 const SmallVectorImpl &Ops) const {
119 if (Ops.size() != 1) return false;
120
121 unsigned OpNum = Ops[0];
122 unsigned Opc = MI->getOpcode();
123 switch (Opc) {
124 default: break;
125 case ARM::tMOVr:
126 case ARM::tMOVlor2hir:
127 case ARM::tMOVhir2lor:
128 case ARM::tMOVhir2hir: {
129 if (OpNum == 0) { // move -> store
130 unsigned SrcReg = MI->getOperand(1).getReg();
131 if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
132 // tSpill cannot take a high register operand.
133 return false;
134 } else { // move -> load
135 unsigned DstReg = MI->getOperand(0).getReg();
136 if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
137 // tRestore cannot target a high register operand.
138 return false;
139 }
140 return true;
141 }
142 }
143
144 return false;
145 }
146
147 void Thumb2InstrInfo::
148 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
149 unsigned SrcReg, bool isKill, int FI,
150 const TargetRegisterClass *RC) const {
151 DebugLoc DL = DebugLoc::getUnknownLoc();
152 if (I != MBB.end()) DL = I->getDebugLoc();
153
154 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
155
156 // FIXME: Thumb2
157 if (RC == ARM::tGPRRegisterClass) {
158 BuildMI(MBB, I, DL, get(ARM::tSpill))
159 .addReg(SrcReg, getKillRegState(isKill))
160 .addFrameIndex(FI).addImm(0);
161 }
162 }
163
164 void Thumb2InstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
165 bool isKill,
166 SmallVectorImpl &Addr,
167 const TargetRegisterClass *RC,
168 SmallVectorImpl &NewMIs) const{
169 DebugLoc DL = DebugLoc::getUnknownLoc();
170 unsigned Opc = 0;
171
172 // FIXME: Thumb2. Is GPRRegClass here correct?
173 assert(RC == ARM::GPRRegisterClass && "Unknown regclass!");
174 if (RC == ARM::GPRRegisterClass) {
175 Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR;
176 }
177
178 MachineInstrBuilder MIB =
179 BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill));
180 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
181 MIB.addOperand(Addr[i]);
182 NewMIs.push_back(MIB);
183 return;
184 }
185
186 void Thumb2InstrInfo::
187 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
188 unsigned DestReg, int FI,
189 const TargetRegisterClass *RC) const {
190 DebugLoc DL = DebugLoc::getUnknownLoc();
191 if (I != MBB.end()) DL = I->getDebugLoc();
192
193 // FIXME: Thumb2
194 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
195
196 if (RC == ARM::tGPRRegisterClass) {
197 BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
198 .addFrameIndex(FI).addImm(0);
199 }
200 }
201
202 void Thumb2InstrInfo::
203 loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
204 SmallVectorImpl &Addr,
205 const TargetRegisterClass *RC,
206 SmallVectorImpl &NewMIs) const {
207 DebugLoc DL = DebugLoc::getUnknownLoc();
208 unsigned Opc = 0;
209
210 // FIXME: Thumb2. Is GPRRegClass ok here?
211 if (RC == ARM::GPRRegisterClass) {
212 Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR;
213 }
214
215 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
216 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
217 MIB.addOperand(Addr[i]);
218 NewMIs.push_back(MIB);
219 return;
220 }
221
222 bool Thumb2InstrInfo::
223 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
224 MachineBasicBlock::iterator MI,
225 const std::vector &CSI) const {
226 if (CSI.empty())
227 return false;
228
229 DebugLoc DL = DebugLoc::getUnknownLoc();
230 if (MI != MBB.end()) DL = MI->getDebugLoc();
231
232 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
233 for (unsigned i = CSI.size(); i != 0; --i) {
234 unsigned Reg = CSI[i-1].getReg();
235 // Add the callee-saved register as live-in. It's killed at the spill.
236 MBB.addLiveIn(Reg);
237 MIB.addReg(Reg, RegState::Kill);
238 }
239 return true;
240 }
241
242 bool Thumb2InstrInfo::
243 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
244 MachineBasicBlock::iterator MI,
245 const std::vector &CSI) const {
246 MachineFunction &MF = *MBB.getParent();
247 ARMFunctionInfo *AFI = MF.getInfo();
248 if (CSI.empty())
249 return false;
250
251 bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
252 MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI->getDebugLoc());
253 for (unsigned i = CSI.size(); i != 0; --i) {
254 unsigned Reg = CSI[i-1].getReg();
255 if (Reg == ARM::LR) {
256 // Special epilogue for vararg functions. See emitEpilogue
257 if (isVarArg)
258 continue;
259 Reg = ARM::PC;
260 PopMI->setDesc(get(ARM::tPOP_RET));
261 MI = MBB.erase(MI);
262 }
263 PopMI->addOperand(MachineOperand::CreateReg(Reg, true));
264 }
265
266 // It's illegal to emit pop instruction without operands.
267 if (PopMI->getNumOperands() > 0)
268 MBB.insert(MI, PopMI);
269
270 return true;
271 }
272
273 MachineInstr *Thumb2InstrInfo::
274 foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
275 const SmallVectorImpl &Ops, int FI) const {
276 if (Ops.size() != 1) return NULL;
277
278 unsigned OpNum = Ops[0];
279 unsigned Opc = MI->getOpcode();
280 MachineInstr *NewMI = NULL;
281 switch (Opc) {
282 default: break;
283 case ARM::tMOVr:
284 case ARM::tMOVlor2hir:
285 case ARM::tMOVhir2lor:
286 case ARM::tMOVhir2hir: {
287 if (OpNum == 0) { // move -> store
288 unsigned SrcReg = MI->getOperand(1).getReg();
289 bool isKill = MI->getOperand(1).isKill();
290 if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
291 // tSpill cannot take a high register operand.
292 break;
293 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill))
294 .addReg(SrcReg, getKillRegState(isKill))
295 .addFrameIndex(FI).addImm(0);
296 } else { // move -> load
297 unsigned DstReg = MI->getOperand(0).getReg();
298 if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
299 // tRestore cannot target a high register operand.
300 break;
301 bool isDead = MI->getOperand(0).isDead();
302 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore))
303 .addReg(DstReg, RegState::Define | getDeadRegState(isDead))
304 .addFrameIndex(FI).addImm(0);
305 }
306 break;
307 }
308 }
309
310 return NewMI;
311 }
0 //===- Thumb2InstrInfo.h - Thumb-2 Instruction Information ----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-2 implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef THUMB2INSTRUCTIONINFO_H
14 #define THUMB2INSTRUCTIONINFO_H
15
16 #include "llvm/Target/TargetInstrInfo.h"
17 #include "ARM.h"
18 #include "ARMInstrInfo.h"
19 #include "Thumb2RegisterInfo.h"
20
21 namespace llvm {
22 class ARMSubtarget;
23
24 class Thumb2InstrInfo : public ARMBaseInstrInfo {
25 Thumb2RegisterInfo RI;
26 public:
27 explicit Thumb2InstrInfo(const ARMSubtarget &STI);
28
29 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
30 /// such, whenever a client has an instance of instruction info, it should
31 /// always be able to get register info as well (through this method).
32 ///
33 const Thumb2RegisterInfo &getRegisterInfo() const { return RI; }
34
35 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
36 MachineBasicBlock::iterator MI,
37 const std::vector &CSI) const;
38 bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
39 MachineBasicBlock::iterator MI,
40 const std::vector &CSI) const;
41
42 bool isMoveInstr(const MachineInstr &MI,
43 unsigned &SrcReg, unsigned &DstReg,
44 unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
45 unsigned isLoadFromStackSlot(const MachineInstr *MI,
46 int &FrameIndex) const;
47 unsigned isStoreToStackSlot(const MachineInstr *MI,
48 int &FrameIndex) const;
49
50 bool copyRegToReg(MachineBasicBlock &MBB,
51 MachineBasicBlock::iterator I,
52 unsigned DestReg, unsigned SrcReg,
53 const TargetRegisterClass *DestRC,
54 const TargetRegisterClass *SrcRC) const;
55 void storeRegToStackSlot(MachineBasicBlock &MBB,
56 MachineBasicBlock::iterator MBBI,
57 unsigned SrcReg, bool isKill, int FrameIndex,
58 const TargetRegisterClass *RC) const;
59
60 void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill,
61 SmallVectorImpl &Addr,
62 const TargetRegisterClass *RC,
63 SmallVectorImpl &NewMIs) const;
64
65 void loadRegFromStackSlot(MachineBasicBlock &MBB,
66 MachineBasicBlock::iterator MBBI,
67 unsigned DestReg, int FrameIndex,
68 const TargetRegisterClass *RC) const;
69
70 void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
71 SmallVectorImpl &Addr,
72 const TargetRegisterClass *RC,
73 SmallVectorImpl &NewMIs) const;
74
75 bool canFoldMemoryOperand(const MachineInstr *MI,
76 const SmallVectorImpl &Ops) const;
77
78 MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
79 MachineInstr* MI,
80 const SmallVectorImpl &Ops,
81 int FrameIndex) const;
82
83 MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
84 MachineInstr* MI,
85 const SmallVectorImpl &Ops,
86 MachineInstr* LoadMI) const {
87 return 0;
88 }
89 };
90 }
91
92 #endif // THUMB2INSTRUCTIONINFO_H
0 //===- Thumb2RegisterInfo.cpp - Thumb-2 Register Information -------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-2 implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "ARM.h"
14 #include "ARMAddressingModes.h"
15 #include "ARMMachineFunctionInfo.h"
16 #include "ARMSubtarget.h"
17 #include "Thumb2InstrInfo.h"
18 #include "Thumb2RegisterInfo.h"
19 #include "llvm/Constants.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/CodeGen/MachineConstantPool.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineLocation.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/Target/TargetFrameInfo.h"
28 #include "llvm/Target/TargetMachine.h"
29 #include "llvm/ADT/BitVector.h"
30 #include "llvm/ADT/SmallVector.h"
31 #include "llvm/Support/CommandLine.h"
32 using namespace llvm;
33
34 static cl::opt
35 Thumb2RegScavenging("enable-thumb2-reg-scavenging",
36 cl::Hidden,
37 cl::desc("Enable register scavenging on Thumb-2"));
38
39 Thumb2RegisterInfo::Thumb2RegisterInfo(const TargetInstrInfo &tii,
40 const ARMSubtarget &sti)
41 : ARMBaseRegisterInfo(tii, sti) {
42 }
43
44 /// emitLoadConstPool - Emits a load from constpool to materialize the
45 /// specified immediate.
46 void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
47 MachineBasicBlock::iterator &MBBI,
48 unsigned DestReg, int Val,
49 const TargetInstrInfo *TII,
50 DebugLoc dl) const {
51 MachineFunction &MF = *MBB.getParent();
52 MachineConstantPool *ConstantPool = MF.getConstantPool();
53 Constant *C = ConstantInt::get(Type::Int32Ty, Val);
54 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
55
56 BuildMI(MBB, MBBI, dl, TII->get(ARM::tLDRcp), DestReg)
57 .addConstantPoolIndex(Idx);
58 }
59
60 const TargetRegisterClass*
61 Thumb2RegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const {
62 if (isARMLowRegister(Reg))
63 return ARM::tGPRRegisterClass;
64 switch (Reg) {
65 default:
66 break;
67 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
68 case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC:
69 return ARM::GPRRegisterClass;
70 }
71
72 return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT);
73 }
74
75 bool
76 Thumb2RegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
77 return Thumb2RegScavenging;
78 }
79
80 bool Thumb2RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
81 const MachineFrameInfo *FFI = MF.getFrameInfo();
82 unsigned CFSize = FFI->getMaxCallFrameSize();
83 // It's not always a good idea to include the call frame as part of the
84 // stack frame. ARM (especially Thumb) has small immediate offset to
85 // address the stack frame. So a large call frame can cause poor codegen
86 // and may even makes it impossible to scavenge a register.
87 if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
88 return false;
89
90 return !MF.getFrameInfo()->hasVarSizedObjects();
91 }
92
93 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
94 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
95 /// in a register using mov / mvn sequences or load the immediate from a
96 /// constpool entry.
97 static
98 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
99 MachineBasicBlock::iterator &MBBI,
100 unsigned DestReg, unsigned BaseReg,
101 int NumBytes, bool CanChangeCC,
102 const TargetInstrInfo &TII,
103 const Thumb2RegisterInfo& MRI,
104 DebugLoc dl) {
105 bool isHigh = !isARMLowRegister(DestReg) ||
106 (BaseReg != 0 && !isARMLowRegister(BaseReg));
107 bool isSub = false;
108 // Subtract doesn't have high register version. Load the negative value
109 // if either base or dest register is a high register. Also, if do not
110 // issue sub as part of the sequence if condition register is to be
111 // preserved.
112 if (NumBytes < 0 && !isHigh && CanChangeCC) {
113 isSub = true;
114 NumBytes = -NumBytes;
115 }
116 unsigned LdReg = DestReg;
117 if (DestReg == ARM::SP) {
118 assert(BaseReg == ARM::SP && "Unexpected!");
119 LdReg = ARM::R3;
120 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
121 .addReg(ARM::R3, RegState::Kill);
122 }
123
124 if (NumBytes <= 255 && NumBytes >= 0)
125 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
126 else if (NumBytes < 0 && NumBytes >= -255) {
127 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
128 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg)
129 .addReg(LdReg, RegState::Kill);
130 } else
131 MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, &TII, dl);
132
133 // Emit add / sub.
134 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
135 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl,
136 TII.get(Opc), DestReg);
137 if (DestReg == ARM::SP || isSub)
138 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
139 else
140 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
141 if (DestReg == ARM::SP)
142 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
143 .addReg(ARM::R12, RegState::Kill);
144 }
145
146 /// calcNumMI - Returns the number of instructions required to materialize
147 /// the specific add / sub r, c instruction.
148 static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
149 unsigned NumBits, unsigned Scale) {
150 unsigned NumMIs = 0;
151 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
152
153 if (Opc == ARM::tADDrSPi) {
154 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
155 Bytes -= ThisVal;
156 NumMIs++;
157 NumBits = 8;
158 Scale = 1; // Followed by a number of tADDi8.
159 Chunk = ((1 << NumBits) - 1) * Scale;
160 }
161
162 NumMIs += Bytes / Chunk;
163 if ((Bytes % Chunk) != 0)
164 NumMIs++;
165 if (ExtraOpc)
166 NumMIs++;
167 return NumMIs;
168 }
169
170 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
171 /// a destreg = basereg + immediate in Thumb code.
172 static
173 void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
174 MachineBasicBlock::iterator &MBBI,
175 unsigned DestReg, unsigned BaseReg,
176 int NumBytes, const TargetInstrInfo &TII,
177 const Thumb2RegisterInfo& MRI,
178 DebugLoc dl) {
179 bool isSub = NumBytes < 0;
180 unsigned Bytes = (unsigned)NumBytes;
181 if (isSub) Bytes = -NumBytes;
182 bool isMul4 = (Bytes & 3) == 0;
183 bool isTwoAddr = false;
184 bool DstNotEqBase = false;
185 unsigned NumBits = 1;
186 unsigned Scale = 1;
187 int Opc = 0;
188 int ExtraOpc = 0;
189
190 if (DestReg == BaseReg && BaseReg == ARM::SP) {
191 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
192 NumBits = 7;
193 Scale = 4;
194 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
195 isTwoAddr = true;
196 } else if (!isSub && BaseReg == ARM::SP) {
197 // r1 = add sp, 403
198 // =>
199 // r1 = add sp, 100 * 4
200 // r1 = add r1, 3
201 if (!isMul4) {
202 Bytes &= ~3;
203 ExtraOpc = ARM::tADDi3;
204 }
205 NumBits = 8;
206 Scale = 4;
207 Opc = ARM::tADDrSPi;
208 } else {
209 // sp = sub sp, c
210 // r1 = sub sp, c
211 // r8 = sub sp, c
212 if (DestReg != BaseReg)
213 DstNotEqBase = true;
214 NumBits = 8;
215 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
216 isTwoAddr = true;
217 }
218
219 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
220 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
221 if (NumMIs > Threshold) {
222 // This will expand into too many instructions. Load the immediate from a
223 // constpool entry.
224 emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII,
225 MRI, dl);
226 return;
227 }
228
229 if (DstNotEqBase) {
230 if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) {
231 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
232 unsigned Chunk = (1 << 3) - 1;
233 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
234 Bytes -= ThisVal;
235 BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg)
236 .addReg(BaseReg, RegState::Kill).addImm(ThisVal);
237 } else {
238 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
239 .addReg(BaseReg, RegState::Kill);
240 }
241 BaseReg = DestReg;
242 }
243
244 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
245 while (Bytes) {
246 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
247 Bytes -= ThisVal;
248 ThisVal /= Scale;
249 // Build the new tADD / tSUB.
250 if (isTwoAddr)
251 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
252 .addReg(DestReg).addImm(ThisVal);
253 else {
254 bool isKill = BaseReg != ARM::SP;
255 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
256 .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
257 BaseReg = DestReg;
258
259 if (Opc == ARM::tADDrSPi) {
260 // r4 = add sp, imm
261 // r4 = add r4, imm
262 // ...
263 NumBits = 8;
264 Scale = 1;
265 Chunk = ((1 << NumBits) - 1) * Scale;
266 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
267 isTwoAddr = true;
268 }
269 }
270 }
271
272 if (ExtraOpc)
273 BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg)
274 .addReg(DestReg, RegState::Kill)
275 .addImm(((unsigned)NumBytes) & 3);
276 }
277
278 static void emitSPUpdate(MachineBasicBlock &MBB,
279 MachineBasicBlock::iterator &MBBI,
280 const TargetInstrInfo &TII, DebugLoc dl,
281 const Thumb2RegisterInfo &MRI,
282 int NumBytes) {
283 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII,
284 MRI, dl);
285 }
286
287 void Thumb2RegisterInfo::
288 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
289 MachineBasicBlock::iterator I) const {
290 if (!hasReservedCallFrame(MF)) {
291 // If we have alloca, convert as follows:
292 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
293 // ADJCALLSTACKUP -> add, sp, sp, amount
294 MachineInstr *Old = I;
295 DebugLoc dl = Old->getDebugLoc();
296 unsigned Amount = Old->getOperand(0).getImm();
297 if (Amount != 0) {
298 // We need to keep the stack aligned properly. To do this, we round the
299 // amount of space needed for the outgoing arguments up to the next
300 // alignment boundary.
301 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
302 Amount = (Amount+Align-1)/Align*Align;
303
304 // Replace the pseudo instruction with a new instruction...
305 unsigned Opc = Old->getOpcode();
306 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
307 emitSPUpdate(MBB, I, TII, dl, *this, -Amount);
308 } else {
309 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
310 emitSPUpdate(MBB, I, TII, dl, *this, Amount);
311 }
312 }
313 }
314 MBB.erase(I);
315 }
316
317 /// emitThumbConstant - Emit a series of instructions to materialize a
318 /// constant.
319 static void emitThumbConstant(MachineBasicBlock &MBB,
320 MachineBasicBlock::iterator &MBBI,
321 unsigned DestReg, int Imm,
322 const TargetInstrInfo &TII,
323 const Thumb2RegisterInfo& MRI,
324 DebugLoc dl) {
325 bool isSub = Imm < 0;
326 if (isSub) Imm = -Imm;
327
328 int Chunk = (1 << 8) - 1;
329 int ThisVal = (Imm > Chunk) ? Chunk : Imm;
330 Imm -= ThisVal;
331 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal);
332 if (Imm > 0)
333 emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl);
334 if (isSub)
335 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg)
336 .addReg(DestReg, RegState::Kill);
337 }
338
339 void Thumb2RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
340 int SPAdj, RegScavenger *RS) const{
341 unsigned i = 0;
342 MachineInstr &MI = *II;
343 MachineBasicBlock &MBB = *MI.getParent();
344 MachineFunction &MF = *MBB.getParent();
345 ARMFunctionInfo *AFI = MF.getInfo();
346 DebugLoc dl = MI.getDebugLoc();
347
348 while (!MI.getOperand(i).isFI()) {
349 ++i;
350 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
351 }
352
353 unsigned FrameReg = ARM::SP;
354 int FrameIndex = MI.getOperand(i).getIndex();
355 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
356 MF.getFrameInfo()->getStackSize() + SPAdj;
357
358 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
359 Offset -= AFI->getGPRCalleeSavedArea1Offset();
360 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
361 Offset -= AFI->getGPRCalleeSavedArea2Offset();
362 else if (hasFP(MF)) {
363 assert(SPAdj == 0 && "Unexpected");
364 // There is alloca()'s in this function, must reference off the frame
365 // pointer instead.
366 FrameReg = getFrameRegister(MF);
367 Offset -= AFI->getFramePtrSpillOffset();
368 }
369
370 unsigned Opcode = MI.getOpcode();
371 const TargetInstrDesc &Desc = MI.getDesc();
372 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
373
374 if (Opcode == ARM::tADDrSPi) {
375 Offset += MI.getOperand(i+1).getImm();
376
377 // Can't use tADDrSPi if it's based off the frame pointer.
378 unsigned NumBits = 0;
379 unsigned Scale = 1;
380 if (FrameReg != ARM::SP) {
381 Opcode = ARM::tADDi3;
382 MI.setDesc(TII.get(ARM::tADDi3));
383 NumBits = 3;
384 } else {
385 NumBits = 8;
386 Scale = 4;
387 assert((Offset & 3) == 0 &&
388 "Thumb add/sub sp, #imm immediate must be multiple of 4!");
389 }
390
391 if (Offset == 0) {
392 // Turn it into a move.
393 MI.setDesc(TII.get(ARM::tMOVhir2lor));
394 MI.getOperand(i).ChangeToRegister(FrameReg, false);
395 MI.RemoveOperand(i+1);
396 return;
397 }
398
399 // Common case: small offset, fits into instruction.
400 unsigned Mask = (1 << NumBits) - 1;
401 if (((Offset / Scale) & ~Mask) == 0) {
402 // Replace the FrameIndex with sp / fp
403 MI.getOperand(i).ChangeToRegister(FrameReg, false);
404 MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
405 return;
406 }
407
408 unsigned DestReg = MI.getOperand(0).getReg();
409 unsigned Bytes = (Offset > 0) ? Offset : -Offset;
410 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
411 // MI would expand into a large number of instructions. Don't try to
412 // simplify the immediate.
413 if (NumMIs > 2) {
414 emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII,
415 *this, dl);
416 MBB.erase(II);
417 return;
418 }
419
420 if (Offset > 0) {
421 // Translate r0 = add sp, imm to
422 // r0 = add sp, 255*4
423 // r0 = add r0, (imm - 255*4)
424 MI.getOperand(i).ChangeToRegister(FrameReg, false);
425 MI.getOperand(i+1).ChangeToImmediate(Mask);
426 Offset = (Offset - Mask * Scale);
427 MachineBasicBlock::iterator NII = next(II);
428 emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII,
429 *this, dl);
430 } else {
431 // Translate r0 = add sp, -imm to
432 // r0 = -imm (this is then translated into a series of instructons)
433 // r0 = add r0, sp
434 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
435 MI.setDesc(TII.get(ARM::tADDhirr));
436 MI.getOperand(i).ChangeToRegister(DestReg, false, false, true);
437 MI.getOperand(i+1).ChangeToRegister(FrameReg, false);
438 }
439 return;
440 } else {
441 unsigned ImmIdx = 0;
442 int InstrOffs = 0;
443 unsigned NumBits = 0;
444 unsigned Scale = 1;
445 switch (AddrMode) {
446 case ARMII::AddrModeT1_s: {
447 ImmIdx = i+1;
448 InstrOffs = MI.getOperand(ImmIdx).getImm();
449 NumBits = (FrameReg == ARM::SP) ? 8 : 5;
450 Scale = 4;
451 break;
452 }
453 default:
454 assert(0 && "Unsupported addressing mode!");
455 abort();
456 break;
457 }
458
459 Offset += InstrOffs * Scale;
460 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
461
462 // Common case: small offset, fits into instruction.
463 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
464 int ImmedOffset = Offset / Scale;
465 unsigned Mask = (1 << NumBits) - 1;
466 if ((unsigned)Offset <= Mask * Scale) {
467 // Replace the FrameIndex with sp
468 MI.getOperand(i).ChangeToRegister(FrameReg, false);
469 ImmOp.ChangeToImmediate(ImmedOffset);
470 return;
471 }
472
473 bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
474 if (AddrMode == ARMII::AddrModeT1_s) {
475 // Thumb tLDRspi, tSTRspi. These will change to instructions that use
476 // a different base register.
477 NumBits = 5;
478 Mask = (1 << NumBits) - 1;
479 }
480 // If this is a thumb spill / restore, we will be using a constpool load to
481 // materialize the offset.
482 if (AddrMode == ARMII::AddrModeT1_s && isThumSpillRestore)
483 ImmOp.ChangeToImmediate(0);
484 else {
485 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
486 ImmedOffset = ImmedOffset & Mask;
487 ImmOp.ChangeToImmediate(ImmedOffset);
488 Offset &= ~(Mask*Scale);
489 }
490 }
491
492 // If we get here, the immediate doesn't fit into the instruction. We folded
493 // as much as possible above, handle the rest, providing a register that is
494 // SP+LargeImm.
495 assert(Offset && "This code isn't needed if offset already handled!");
496
497 if (Desc.mayLoad()) {
498 // Use the destination register to materialize sp + offset.
499 unsigned TmpReg = MI.getOperand(0).getReg();
500 bool UseRR = false;
501 if (Opcode == ARM::tRestore) {
502 if (FrameReg == ARM::SP)
503 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
504 Offset, false, TII, *this, dl);
505 else {
506 emitLoadConstPool(MBB, II, TmpReg, Offset, &TII, dl);
507 UseRR = true;
508 }
509 } else
510 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
511 *this, dl);
512 MI.setDesc(TII.get(ARM::tLDR));
513 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
514 if (UseRR)
515 // Use [reg, reg] addrmode.
516 MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
517 else // tLDR has an extra register operand.
518 MI.addOperand(MachineOperand::CreateReg(0, false));
519 } else if (Desc.mayStore()) {
520 // FIXME! This is horrific!!! We need register scavenging.
521 // Our temporary workaround has marked r3 unavailable. Of course, r3 is
522 // also a ABI register so it's possible that is is the register that is
523 // being storing here. If that's the case, we do the following:
524 // r12 = r2
525 // Use r2 to materialize sp + offset
526 // str r3, r2
527 // r2 = r12
528 unsigned ValReg = MI.getOperand(0).getReg();
529 unsigned TmpReg = ARM::R3;
530 bool UseRR = false;
531 if (ValReg == ARM::R3) {
532 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
533 .addReg(ARM::R2, RegState::Kill);
534 TmpReg = ARM::R2;
535 }
536 if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
537 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
538 .addReg(ARM::R3, RegState::Kill);
539 if (Opcode == ARM::tSpill) {
540 if (FrameReg == ARM::SP)
541 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
542 Offset, false, TII, *this, dl);
543 else {
544 emitLoadConstPool(MBB, II, TmpReg, Offset, &TII, dl);
545 UseRR = true;
546 }
547 } else
548 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
549 *this, dl);
550 MI.setDesc(TII.get(ARM::tSTR));
551 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
552 if (UseRR) // Use [reg, reg] addrmode.
553 MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
554 else // tSTR has an extra register operand.
555 MI.addOperand(MachineOperand::CreateReg(0, false));
556
557 MachineBasicBlock::iterator NII = next(II);
558 if (ValReg == ARM::R3)
559 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2)
560 .addReg(ARM::R12, RegState::Kill);
561 if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
562 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
563 .addReg(ARM::R12, RegState::Kill);
564 } else
565 assert(false && "Unexpected opcode!");
566 }
567
568 void Thumb2RegisterInfo::emitPrologue(MachineFunction &MF) const {
569 MachineBasicBlock &MBB = MF.front();
570 MachineBasicBlock::iterator MBBI = MBB.begin();
571 MachineFrameInfo *MFI = MF.getFrameInfo();
572 ARMFunctionInfo *AFI = MF.getInfo();
573 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
574 unsigned NumBytes = MFI->getStackSize();
575 const std::vector &CSI = MFI->getCalleeSavedInfo();
576 DebugLoc dl = (MBBI != MBB.end() ?
577 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
578
579 // Check if R3 is live in. It might have to be used as a scratch register.
580 for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(),
581 E = MF.getRegInfo().livein_end(); I != E; ++I) {
582 if (I->first == ARM::R3) {
583 AFI->setR3IsLiveIn(true);
584 break;
585 }
586 }
587
588 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
589 NumBytes = (NumBytes + 3) & ~3;
590 MFI->setStackSize(NumBytes);
591
592 // Determine the sizes of each callee-save spill areas and record which frame
593 // belongs to which callee-save spill areas.
594 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
595 int FramePtrSpillFI = 0;
596
597 if (VARegSaveSize)
598 emitSPUpdate(MBB, MBBI, TII, dl, *this, -VARegSaveSize);
599
600 if (!AFI->hasStackFrame()) {
601 if (NumBytes != 0)
602 emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
603 return;
604 }
605
606 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
607 unsigned Reg = CSI[i].getReg();
608 int FI = CSI[i].getFrameIdx();
609 switch (Reg) {
610 case ARM::R4:
611 case ARM::R5:
612 case ARM::R6:
613 case ARM::R7:
614 case ARM::LR:
615 if (Reg == FramePtr)
616 FramePtrSpillFI = FI;
617 AFI->addGPRCalleeSavedArea1Frame(FI);
618 GPRCS1Size += 4;
619 break;
620 case ARM::R8:
621 case ARM::R9:
622 case ARM::R10:
623 case ARM::R11:
624 if (Reg == FramePtr)
625 FramePtrSpillFI = FI;
626 if (STI.isTargetDarwin()) {
627 AFI->addGPRCalleeSavedArea2Frame(FI);
628 GPRCS2Size += 4;
629 } else {
630 AFI->addGPRCalleeSavedArea1Frame(FI);
631 GPRCS1Size += 4;
632 }
633 break;
634 default:
635 AFI->addDPRCalleeSavedAreaFrame(FI);
636 DPRCSSize += 8;
637 }
638 }
639
640 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
641 ++MBBI;
642 if (MBBI != MBB.end())
643 dl = MBBI->getDebugLoc();
644 }
645
646 // Darwin ABI requires FP to point to the stack slot that contains the
647 // previous FP.
648 if (STI.isTargetDarwin() || hasFP(MF)) {
649 MachineInstrBuilder MIB =
650 BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
651 .addFrameIndex(FramePtrSpillFI).addImm(0);
652 }
653
654 // Determine starting offsets of spill areas.
655 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
656 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
657 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
658 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
659 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
660 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
661 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
662
663 NumBytes = DPRCSOffset;
664 if (NumBytes) {
665 // Insert it after all the callee-save spills.
666 emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
667 }
668
669 if (STI.isTargetELF() && hasFP(MF)) {
670 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
671 AFI->getFramePtrSpillOffset());
672 }
673
674 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
675 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
676 AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
677 }
678
679 static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
680 for (unsigned i = 0; CSRegs[i]; ++i)
681 if (Reg == CSRegs[i])
682 return true;
683 return false;
684 }
685
686 static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
687 return (MI->getOpcode() == ARM::tRestore &&
688 MI->getOperand(1).isFI() &&
689 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
690 }
691
692 void Thumb2RegisterInfo::emitEpilogue(MachineFunction &MF,
693 MachineBasicBlock &MBB) const {
694 MachineBasicBlock::iterator MBBI = prior(MBB.end());
695 assert((MBBI->getOpcode() == ARM::tBX_RET ||
696 MBBI->getOpcode() == ARM::tPOP_RET) &&
697 "Can only insert epilog into returning blocks");
698 DebugLoc dl = MBBI->getDebugLoc();
699 MachineFrameInfo *MFI = MF.getFrameInfo();
700 ARMFunctionInfo *AFI = MF.getInfo();
701 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
702 int NumBytes = (int)MFI->getStackSize();
703
704 if (!AFI->hasStackFrame()) {
705 if (NumBytes != 0)
706 emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
707 } else {
708 // Unwind MBBI to point to first LDR / FLDD.
709 const unsigned *CSRegs = getCalleeSavedRegs();
710 if (MBBI != MBB.begin()) {
711 do
712 --MBBI;
713 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
714 if (!isCSRestore(MBBI, CSRegs))
715 ++MBBI;
716 }
717
718 // Move SP to start of FP callee save spill area.
719 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
720 AFI->getGPRCalleeSavedArea2Size() +
721 AFI->getDPRCalleeSavedAreaSize());
722
723 if (hasFP(MF)) {
724 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
725 // Reset SP based on frame pointer only if the stack frame extends beyond
726 // frame pointer stack slot or target is ELF and the function has FP.
727 if (NumBytes)
728 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes,
729 TII, *this, dl);
730 else
731 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP)
732 .addReg(FramePtr);
733 } else {
734 if (MBBI->getOpcode() == ARM::tBX_RET &&
735 &MBB.front() != MBBI &&
736 prior(MBBI)->getOpcode() == ARM::tPOP) {
737 MachineBasicBlock::iterator PMBBI = prior(MBBI);
738 emitSPUpdate(MBB, PMBBI, TII, dl, *this, NumBytes);
739 } else
740 emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
741 }
742 }
743
744 if (VARegSaveSize) {
745 // Epilogue for vararg functions: pop LR to R3 and branch off it.
746 // FIXME: Verify this is still ok when R3 is no longer being reserved.
747 BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3);
748
749 emitSPUpdate(MBB, MBBI, TII, dl, *this, VARegSaveSize);
750
751 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3);
752 MBB.erase(MBBI);
753 }
754 }
0 //===- Thumb2RegisterInfo.h - Thumb-2 Register Information Impl ----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb-2 implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef THUMB2REGISTERINFO_H
14 #define THUMB2REGISTERINFO_H
15
16 #include "ARM.h"
17 #include "ARMRegisterInfo.h"
18 #include "llvm/Target/TargetRegisterInfo.h"
19
20 namespace llvm {
21 class ARMSubtarget;
22 class TargetInstrInfo;
23 class Type;
24
25 struct Thumb2RegisterInfo : public ARMBaseRegisterInfo {
26 public:
27 Thumb2RegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
28
29 /// emitLoadConstPool - Emits a load from constpool to materialize the
30 /// specified immediate.
31 void emitLoadConstPool(MachineBasicBlock &MBB,
32 MachineBasicBlock::iterator &MBBI,
33 unsigned DestReg, int Val,
34 const TargetInstrInfo *TII,
35 DebugLoc dl) const;
36
37 /// Code Generation virtual methods...
38 const TargetRegisterClass *
39 getPhysicalRegisterRegClass(unsigned Reg, MVT VT = MVT::Other) const;
40
41 bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
42
43 bool requiresRegisterScavenging(const MachineFunction &MF) const;
44
45 bool hasReservedCallFrame(MachineFunction &MF) const;
46
47 void eliminateCallFramePseudoInstr(MachineFunction &MF,
48 MachineBasicBlock &MBB,
49 MachineBasicBlock::iterator I) const;
50
51 void eliminateFrameIndex(MachineBasicBlock::iterator II,
52 int SPAdj, RegScavenger *RS = NULL) const;
53
54 void emitPrologue(MachineFunction &MF) const;
55 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
56 };
57 }
58
59 #endif // THUMB2REGISTERINFO_H
+0
-312
lib/Target/ARM/ThumbInstrInfo.cpp less more
None //===- ThumbInstrInfo.cpp - Thumb Instruction Information --------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Thumb implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "ARMInstrInfo.h"
14 #include "ARM.h"
15 #include "ARMGenInstrInfo.inc"
16 #include "ARMMachineFunctionInfo.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "ThumbInstrInfo.h"
21
22 using namespace llvm;
23
24 ThumbInstrInfo::ThumbInstrInfo(const ARMSubtarget &STI)
25 : ARMBaseInstrInfo(STI), RI(*this, STI) {
26 }
27
28 bool ThumbInstrInfo::isMoveInstr(const MachineInstr &MI,
29 unsigned &SrcReg, unsigned &DstReg,
30 unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
31 SrcSubIdx = DstSubIdx = 0; // No sub-registers.
32
33 unsigned oc = MI.getOpcode();
34 switch (oc) {
35 default:
36 return false;
37 // FIXME: Thumb2
38 case ARM::tMOVr:
39 case ARM::tMOVhir2lor:
40 case ARM::tMOVlor2hir:
41 case ARM::tMOVhir2hir:
42 assert(MI.getDesc().getNumOperands() >= 2 &&
43 MI.getOperand(0).isReg() &&
44 MI.getOperand(1).isReg() &&
45 "Invalid Thumb MOV instruction");
46 SrcReg = MI.getOperand(1).getReg();
47 DstReg = MI.getOperand(0).getReg();
48 return true;
49 }
50 }
51
52 unsigned ThumbInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
53 int &FrameIndex) const {
54 switch (MI->getOpcode()) {
55 default: break;
56 // FIXME: Thumb2
57 case ARM::tRestore:
58 if (MI->getOperand(1).isFI() &&
59 MI->getOperand(2).isImm() &&
60 MI->getOperand(2).getImm() == 0) {
61 FrameIndex = MI->getOperand(1).getIndex();
62 return MI->getOperand(0).getReg();
63 }
64 break;
65 }
66 return 0;
67 }
68
69 unsigned ThumbInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
70 int &FrameIndex) const {
71 switch (MI->getOpcode()) {
72 default: break;
73 // FIXME: Thumb2
74 case ARM::tSpill:
75 if (MI->getOperand(1).isFI() &&
76 MI->getOperand(2).isImm() &&
77 MI->getOperand(2).getImm() == 0) {
78 FrameIndex = MI->getOperand(1).getIndex();
79 return MI->getOperand(0).getReg();
80 }
81 break;
82 }
83 return 0;
84 }
85
86 bool ThumbInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
87 MachineBasicBlock::iterator I,
88 unsigned DestReg, unsigned SrcReg,
89 const TargetRegisterClass *DestRC,
90 const TargetRegisterClass *SrcRC) const {
91 DebugLoc DL = DebugLoc::getUnknownLoc();
92 if (I != MBB.end()) DL = I->getDebugLoc();
93
94 // FIXME: Thumb2
95 if (DestRC == ARM::GPRRegisterClass) {
96 if (SrcRC == ARM::GPRRegisterClass) {
97 BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg(SrcReg);
98 return true;
99 } else if (SrcRC == ARM::tGPRRegisterClass) {
100 BuildMI(MBB, I, DL, get(ARM::tMOVlor2hir), DestReg).addReg(SrcReg);
101 return true;
102 }
103 } else if (DestRC == ARM::tGPRRegisterClass) {
104 if (SrcRC == ARM::GPRRegisterClass) {
105 BuildMI(MBB, I, DL, get(ARM::tMOVhir2lor), DestReg).addReg(SrcReg);
106 return true;
107 } else if (SrcRC == ARM::tGPRRegisterClass) {
108 BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg);
109 return true;
110 }
111 }
112
113 return false;
114 }
115
116 bool ThumbInstrInfo::
117 canFoldMemoryOperand(const MachineInstr *MI,
118 const SmallVectorImpl &Ops) const {
119 if (Ops.size() != 1) return false;
120
121 unsigned OpNum = Ops[0];
122 unsigned Opc = MI->getOpcode();
123 switch (Opc) {
124 default: break;
125 case ARM::tMOVr:
126 case ARM::tMOVlor2hir:
127 case ARM::tMOVhir2lor:
128 case ARM::tMOVhir2hir: {
129 if (OpNum == 0) { // move -> store
130 unsigned SrcReg = MI->getOperand(1).getReg();
131 if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
132 // tSpill cannot take a high register operand.
133 return false;
134 } else { // move -> load
135 unsigned DstReg = MI->getOperand(0).getReg();
136 if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
137 // tRestore cannot target a high register operand.
138 return false;
139 }
140 return true;
141 }
142 }
143
144 return false;
145 }
146
147 void ThumbInstrInfo::
148 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
149 unsigned SrcReg, bool isKill, int FI,
150 const TargetRegisterClass *RC) const {
151 DebugLoc DL = DebugLoc::getUnknownLoc();
152 if (I != MBB.end()) DL = I->getDebugLoc();
153
154 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
155
156 // FIXME: Thumb2
157 if (RC == ARM::tGPRRegisterClass) {
158 BuildMI(MBB, I, DL, get(ARM::tSpill))
159 .addReg(SrcReg, getKillRegState(isKill))
160 .addFrameIndex(FI).addImm(0);
161 }
162 }
163
164 void ThumbInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
165 bool isKill,
166 SmallVectorImpl &Addr,
167 const TargetRegisterClass *RC,
168 SmallVectorImpl &NewMIs) const{
169 DebugLoc DL = DebugLoc::getUnknownLoc();
170 unsigned Opc = 0;
171
172 // FIXME: Thumb2. Is GPRRegClass here correct?
173 assert(RC == ARM::GPRRegisterClass && "Unknown regclass!");
174 if (RC == ARM::GPRRegisterClass) {
175 Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR;
176 }
177
178 MachineInstrBuilder MIB =
179 BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill));
180 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
181 MIB.addOperand(Addr[i]);
182 NewMIs.push_back(MIB);
183 return;
184 }
185
186 void ThumbInstrInfo::
187 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
188 unsigned DestReg, int FI,
189 const TargetRegisterClass *RC) const {
190 DebugLoc DL = DebugLoc::getUnknownLoc();
191 if (I != MBB.end()) DL = I->getDebugLoc();
192
193 // FIXME: Thumb2
194 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
195
196 if (RC == ARM::tGPRRegisterClass) {
197 BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
198 .addFrameIndex(FI).addImm(0);
199 }
200 }
201
202 void ThumbInstrInfo::
203 loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
204 SmallVectorImpl &Addr,
205 const TargetRegisterClass *RC,
206 SmallVectorImpl &NewMIs) const {
207 DebugLoc DL = DebugLoc::getUnknownLoc();
208 unsigned Opc = 0;
209
210 // FIXME: Thumb2. Is GPRRegClass ok here?
211 if (RC == ARM::GPRRegisterClass) {
212 Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR;
213 }
214
215 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
216 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
217 MIB.addOperand(Addr[i]);
218 NewMIs.push_back(MIB);
219 return;
220 }
221
222 bool ThumbInstrInfo::
223 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
224 MachineBasicBlock::iterator MI,
225 const std::vector &CSI) const {
226 if (CSI.empty())
227 return false;
228
229 DebugLoc DL = DebugLoc::getUnknownLoc();
230 if (MI != MBB.end()) DL = MI->getDebugLoc();
231
232 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
233 for (unsigned i = CSI.size(); i != 0; --i) {
234 unsigned Reg = CSI[i-1].getReg();
235 // Add the callee-saved register as live-in. It's killed at the spill.
236 MBB.addLiveIn(Reg);
237 MIB.addReg(Reg, RegState::Kill);
238 }
239 return true;
240 }
241
242 bool ThumbInstrInfo::
243 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
244 MachineBasicBlock::iterator MI,
245 const std::vector &CSI) const {
246