@@ -71,6 +71,7 @@ class AVRExpandPseudo : public MachineFunctionPass {
71
71
72
72
MachineRegisterInfo &getRegInfo (Block &MBB) { return MBB.getParent ()->getRegInfo (); }
73
73
74
+ bool expandBR (Block &MBB, BlockIt MBBI, int OppositeOpcode);
74
75
bool expandArith (unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI);
75
76
bool expandLogic (unsigned Op, Block &MBB, BlockIt MBBI);
76
77
bool expandLogicImm (unsigned Op, Block &MBB, BlockIt MBBI);
@@ -583,8 +584,8 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
583
584
unsigned TmpReg = 0 ; // 0 for no temporary register
584
585
unsigned SrcReg = MI.getOperand (1 ).getReg ();
585
586
bool SrcIsKill = MI.getOperand (1 ).isKill ();
586
- OpLo = AVR::LDRdPtr ;
587
- OpHi = AVR::LDDRdPtrQ ;
587
+ OpLo = AVR::LDRdPtrPi ;
588
+ OpHi = AVR::LDRdPtr ;
588
589
TRI->splitReg (DstReg, DstLoReg, DstHiReg);
589
590
590
591
// Use a temporary register if src and dst registers are the same.
@@ -597,6 +598,7 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
597
598
// Load low byte.
598
599
auto MIBLO = buildMI (MBB, MBBI, OpLo)
599
600
.addReg (CurDstLoReg, RegState::Define)
601
+ .addReg (SrcReg, RegState::Define)
600
602
.addReg (SrcReg);
601
603
602
604
// Push low byte onto stack if necessary.
@@ -606,8 +608,7 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
606
608
// Load high byte.
607
609
auto MIBHI = buildMI (MBB, MBBI, OpHi)
608
610
.addReg (CurDstHiReg, RegState::Define)
609
- .addReg (SrcReg, getKillRegState (SrcIsKill))
610
- .addImm (1 );
611
+ .addReg (SrcReg, getKillRegState (SrcIsKill));
611
612
612
613
if (TmpReg) {
613
614
// Move the high byte into the final destination.
@@ -741,7 +742,50 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
741
742
742
743
template <>
743
744
bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) {
744
- llvm_unreachable (" wide LPM is unimplemented" );
745
+ MachineInstr &MI = *MBBI;
746
+ unsigned OpLo, OpHi, DstLoReg, DstHiReg;
747
+ unsigned DstReg = MI.getOperand (0 ).getReg ();
748
+ unsigned TmpReg = 0 ; // 0 for no temporary register
749
+ unsigned SrcReg = MI.getOperand (1 ).getReg ();
750
+ bool SrcIsKill = MI.getOperand (1 ).isKill ();
751
+ OpLo = AVR::LPMRdZPi;
752
+ OpHi = AVR::LPMRdZ;
753
+ TRI->splitReg (DstReg, DstLoReg, DstHiReg);
754
+
755
+ // Use a temporary register if src and dst registers are the same.
756
+ if (DstReg == SrcReg)
757
+ TmpReg = scavengeGPR8 (MI);
758
+
759
+ unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
760
+ unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
761
+
762
+ // Load low byte.
763
+ auto MIBLO = buildMI (MBB, MBBI, OpLo)
764
+ .addReg (CurDstLoReg, RegState::Define)
765
+ .addReg (SrcReg);
766
+
767
+ // Push low byte onto stack if necessary.
768
+ if (TmpReg)
769
+ buildMI (MBB, MBBI, AVR::PUSHRr).addReg (TmpReg);
770
+
771
+ // Load high byte.
772
+ auto MIBHI = buildMI (MBB, MBBI, OpHi)
773
+ .addReg (CurDstHiReg, RegState::Define)
774
+ .addReg (SrcReg, getKillRegState (SrcIsKill));
775
+
776
+ if (TmpReg) {
777
+ // Move the high byte into the final destination.
778
+ buildMI (MBB, MBBI, AVR::MOVRdRr).addReg (DstHiReg).addReg (TmpReg);
779
+
780
+ // Move the low byte from the scratch space into the final destination.
781
+ buildMI (MBB, MBBI, AVR::POPRd).addReg (DstLoReg);
782
+ }
783
+
784
+ MIBLO->setMemRefs (MI.memoperands_begin (), MI.memoperands_end ());
785
+ MIBHI->setMemRefs (MI.memoperands_begin (), MI.memoperands_end ());
786
+
787
+ MI.eraseFromParent ();
788
+ return true ;
745
789
}
746
790
747
791
template <>
@@ -1457,6 +1501,57 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
1457
1501
return true ;
1458
1502
}
1459
1503
1504
+ bool AVRExpandPseudo::expandBR (Block &MBB, BlockIt MBBI, int OppositeOpcode) {
1505
+ MachineInstr &MI = *MBBI;
1506
+ MachineBasicBlock *targetMBB = MI.getOperand (0 ).getMBB ();
1507
+
1508
+ buildMI (MBB, MBBI, OppositeOpcode).addImm (2 );
1509
+ buildMI (MBB, MBBI, AVR::RJMPk).addMBB (targetMBB);
1510
+
1511
+ MI.eraseFromParent ();
1512
+ return true ;
1513
+ }
1514
+
1515
+ template <>
1516
+ bool AVRExpandPseudo::expand<AVR::RBRGEk>(Block &MBB, BlockIt MBBI) {
1517
+ return expandBR (MBB, MBBI, AVR::BRLTk);
1518
+ }
1519
+
1520
+ template <>
1521
+ bool AVRExpandPseudo::expand<AVR::RBRLTk>(Block &MBB, BlockIt MBBI) {
1522
+ return expandBR (MBB, MBBI, AVR::BRGEk);
1523
+ }
1524
+
1525
+ template <>
1526
+ bool AVRExpandPseudo::expand<AVR::RBREQk>(Block &MBB, BlockIt MBBI) {
1527
+ return expandBR (MBB, MBBI, AVR::BRNEk);
1528
+ }
1529
+
1530
+ template <>
1531
+ bool AVRExpandPseudo::expand<AVR::RBRNEk>(Block &MBB, BlockIt MBBI) {
1532
+ return expandBR (MBB, MBBI, AVR::BREQk);
1533
+ }
1534
+
1535
+ template <>
1536
+ bool AVRExpandPseudo::expand<AVR::RBRSHk>(Block &MBB, BlockIt MBBI) {
1537
+ return expandBR (MBB, MBBI, AVR::BRLOk);
1538
+ }
1539
+
1540
+ template <>
1541
+ bool AVRExpandPseudo::expand<AVR::RBRLOk>(Block &MBB, BlockIt MBBI) {
1542
+ return expandBR (MBB, MBBI, AVR::BRSHk);
1543
+ }
1544
+
1545
+ template <>
1546
+ bool AVRExpandPseudo::expand<AVR::RBRPLk>(Block &MBB, BlockIt MBBI) {
1547
+ return expandBR (MBB, MBBI, AVR::BRMIk);
1548
+ }
1549
+
1550
+ template <>
1551
+ bool AVRExpandPseudo::expand<AVR::RBRMIk>(Block &MBB, BlockIt MBBI) {
1552
+ return expandBR (MBB, MBBI, AVR::BRPLk);
1553
+ }
1554
+
1460
1555
bool AVRExpandPseudo::expandMI (Block &MBB, BlockIt MBBI) {
1461
1556
MachineInstr &MI = *MBBI;
1462
1557
int Opcode = MBBI->getOpcode ();
@@ -1522,6 +1617,14 @@ bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
1522
1617
EXPAND (AVR::ZEXT);
1523
1618
EXPAND (AVR::SPREAD);
1524
1619
EXPAND (AVR::SPWRITE);
1620
+ EXPAND (AVR::RBRGEk);
1621
+ EXPAND (AVR::RBRLTk);
1622
+ EXPAND (AVR::RBREQk);
1623
+ EXPAND (AVR::RBRNEk);
1624
+ EXPAND (AVR::RBRSHk);
1625
+ EXPAND (AVR::RBRLOk);
1626
+ EXPAND (AVR::RBRMIk);
1627
+ EXPAND (AVR::RBRPLk);
1525
1628
}
1526
1629
#undef EXPAND
1527
1630
return false ;
0 commit comments