@@ -88,6 +88,9 @@ class AVRExpandPseudo : public MachineFunctionPass {
88
88
unsigned ArithOpcode,
89
89
Block &MBB,
90
90
BlockIt MBBI);
91
+
92
+ // / Scavenges a free GPR8 register for use.
93
+ unsigned scavengeGPR8 (MachineInstr &MI);
91
94
};
92
95
93
96
char AVRExpandPseudo::ID = 0 ;
@@ -577,24 +580,43 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
577
580
MachineInstr &MI = *MBBI;
578
581
unsigned OpLo, OpHi, DstLoReg, DstHiReg;
579
582
unsigned DstReg = MI.getOperand (0 ).getReg ();
583
+ unsigned TmpReg = 0 ; // 0 for no temporary register
580
584
unsigned SrcReg = MI.getOperand (1 ).getReg ();
581
- bool DstIsDead = MI.getOperand (0 ).isDead ();
582
585
bool SrcIsKill = MI.getOperand (1 ).isKill ();
583
586
OpLo = AVR::LDRdPtr;
584
587
OpHi = AVR::LDDRdPtrQ;
585
588
TRI->splitReg (DstReg, DstLoReg, DstHiReg);
586
589
587
- assert (DstReg != SrcReg && " SrcReg and DstReg cannot be the same" );
590
+ // Use a temporary register if src and dst registers are the same.
591
+ if (DstReg == SrcReg)
592
+ TmpReg = scavengeGPR8 (MI);
593
+
594
+ unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
595
+ unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
588
596
597
+ // Load low byte.
589
598
auto MIBLO = buildMI (MBB, MBBI, OpLo)
590
- .addReg (DstLoReg , RegState::Define | getDeadRegState (DstIsDead) )
599
+ .addReg (CurDstLoReg , RegState::Define)
591
600
.addReg (SrcReg);
592
601
602
+ // Push low byte onto stack if necessary.
603
+ if (TmpReg)
604
+ buildMI (MBB, MBBI, AVR::PUSHRr).addReg (TmpReg);
605
+
606
+ // Load high byte.
593
607
auto MIBHI = buildMI (MBB, MBBI, OpHi)
594
- .addReg (DstHiReg , RegState::Define | getDeadRegState (DstIsDead) )
608
+ .addReg (CurDstHiReg , RegState::Define)
595
609
.addReg (SrcReg, getKillRegState (SrcIsKill))
596
610
.addImm (1 );
597
611
612
+ if (TmpReg) {
613
+ // Move the high byte into the final destination.
614
+ buildMI (MBB, MBBI, AVR::MOVRdRr).addReg (DstHiReg).addReg (TmpReg);
615
+
616
+ // Move the low byte from the scratch space into the final destination.
617
+ buildMI (MBB, MBBI, AVR::POPRd).addReg (DstLoReg);
618
+ }
619
+
598
620
MIBLO->setMemRefs (MI.memoperands_begin (), MI.memoperands_end ());
599
621
MIBHI->setMemRefs (MI.memoperands_begin (), MI.memoperands_end ());
600
622
@@ -669,70 +691,45 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
669
691
MachineInstr &MI = *MBBI;
670
692
unsigned OpLo, OpHi, DstLoReg, DstHiReg;
671
693
unsigned DstReg = MI.getOperand (0 ).getReg ();
694
+ unsigned TmpReg = 0 ; // 0 for no temporary register
672
695
unsigned SrcReg = MI.getOperand (1 ).getReg ();
673
696
unsigned Imm = MI.getOperand (2 ).getImm ();
674
- bool DstIsDead = MI.getOperand (0 ).isDead ();
675
697
bool SrcIsKill = MI.getOperand (1 ).isKill ();
676
698
OpLo = AVR::LDDRdPtrQ;
677
699
OpHi = AVR::LDDRdPtrQ;
678
700
TRI->splitReg (DstReg, DstLoReg, DstHiReg);
679
701
680
702
assert (Imm <= 63 && " Offset is out of range" );
681
703
682
- MachineInstr *MIBLO, *MIBHI;
683
-
684
- // HACK: We shouldn't have instances of this instruction
685
- // where src==dest because the instruction itself is
686
- // marked earlyclobber. We do however get this instruction when
687
- // loading from stack slots where the earlyclobber isn't useful.
688
- //
689
- // In this case, just use a temporary register.
690
- if (DstReg == SrcReg) {
691
- RegScavenger RS;
692
-
693
- RS.enterBasicBlock (MBB);
694
- RS.forward (MBBI);
695
-
696
- BitVector Candidates =
697
- TRI->getAllocatableSet
698
- (*MBB.getParent (), &AVR::GPR8RegClass);
699
-
700
- // Exclude all the registers being used by the instruction.
701
- for (MachineOperand &MO : MI.operands ()) {
702
- if (MO.isReg () && MO.getReg () != 0 && !MO.isDef () &&
703
- !TargetRegisterInfo::isVirtualRegister (MO.getReg ()))
704
- Candidates.reset (MO.getReg ());
705
- }
706
-
707
- BitVector Available = RS.getRegsAvailable (&AVR::GPR8RegClass);
708
- Available &= Candidates;
704
+ // Use a temporary register if src and dst registers are the same.
705
+ if (DstReg == SrcReg)
706
+ TmpReg = scavengeGPR8 (MI);
709
707
710
- signed TmpReg = Available. find_first () ;
711
- assert (TmpReg != - 1 && " ran out of registers " ) ;
708
+ unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg ;
709
+ unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg ;
712
710
713
- MIBLO = buildMI (MBB, MBBI, OpLo)
714
- .addReg (TmpReg, RegState::Define)
715
- .addReg (SrcReg)
716
- .addImm (Imm);
711
+ // Load low byte.
712
+ auto MIBLO = buildMI (MBB, MBBI, OpLo)
713
+ .addReg (CurDstLoReg, RegState::Define)
714
+ .addReg (SrcReg)
715
+ .addImm (Imm);
717
716
718
- buildMI (MBB, MBBI, AVR::MOVRdRr).addReg (DstLoReg).addReg (TmpReg);
717
+ // Push low byte onto stack if necessary.
718
+ if (TmpReg)
719
+ buildMI (MBB, MBBI, AVR::PUSHRr).addReg (TmpReg);
719
720
720
- MIBHI = buildMI (MBB, MBBI, OpHi)
721
- .addReg (TmpReg, RegState::Define)
722
- .addReg (SrcReg, getKillRegState (SrcIsKill))
723
- .addImm (Imm + 1 );
721
+ // Load high byte.
722
+ auto MIBHI = buildMI (MBB, MBBI, OpHi)
723
+ .addReg (CurDstHiReg, RegState::Define)
724
+ .addReg (SrcReg, getKillRegState (SrcIsKill))
725
+ .addImm (Imm + 1 );
724
726
727
+ if (TmpReg) {
728
+ // Move the high byte into the final destination.
725
729
buildMI (MBB, MBBI, AVR::MOVRdRr).addReg (DstHiReg).addReg (TmpReg);
726
- } else {
727
- MIBLO = buildMI (MBB, MBBI, OpLo)
728
- .addReg (DstLoReg, RegState::Define | getDeadRegState (DstIsDead))
729
- .addReg (SrcReg)
730
- .addImm (Imm);
731
730
732
- MIBHI = buildMI (MBB, MBBI, OpHi)
733
- .addReg (DstHiReg, RegState::Define | getDeadRegState (DstIsDead))
734
- .addReg (SrcReg, getKillRegState (SrcIsKill))
735
- .addImm (Imm + 1 );
731
+ // Move the low byte from the scratch space into the final destination.
732
+ buildMI (MBB, MBBI, AVR::POPRd).addReg (DstLoReg);
736
733
}
737
734
738
735
MIBLO->setMemRefs (MI.memoperands_begin (), MI.memoperands_end ());
@@ -819,6 +816,32 @@ bool AVRExpandPseudo::expandAtomicArithmeticOp(unsigned Width,
819
816
});
820
817
}
821
818
819
+ unsigned AVRExpandPseudo::scavengeGPR8 (MachineInstr &MI) {
820
+ MachineBasicBlock &MBB = *MI.getParent ();
821
+ RegScavenger RS;
822
+
823
+ RS.enterBasicBlock (MBB);
824
+ RS.forward (MI);
825
+
826
+ BitVector Candidates =
827
+ TRI->getAllocatableSet
828
+ (*MBB.getParent (), &AVR::GPR8RegClass);
829
+
830
+ // Exclude all the registers being used by the instruction.
831
+ for (MachineOperand &MO : MI.operands ()) {
832
+ if (MO.isReg () && MO.getReg () != 0 && !MO.isDef () &&
833
+ !TargetRegisterInfo::isVirtualRegister (MO.getReg ()))
834
+ Candidates.reset (MO.getReg ());
835
+ }
836
+
837
+ BitVector Available = RS.getRegsAvailable (&AVR::GPR8RegClass);
838
+ Available &= Candidates;
839
+
840
+ signed Reg = Available.find_first ();
841
+ assert (Reg != -1 && " ran out of registers" );
842
+ return Reg;
843
+ }
844
+
822
845
template <>
823
846
bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) {
824
847
return expandAtomicBinaryOp (AVR::LDRdPtr, MBB, MBBI);
0 commit comments