15
15
16
16
#include " llvm/CodeGen/MachineFunctionPass.h"
17
17
#include " llvm/CodeGen/MachineInstrBuilder.h"
18
+ #include " llvm/CodeGen/MachineRegisterInfo.h"
18
19
#include " llvm/Target/TargetRegisterInfo.h"
19
20
20
21
#include " AVR.h"
@@ -30,8 +31,15 @@ namespace llvm {
30
31
class AVRExpandPseudo : public MachineFunctionPass {
31
32
public:
32
33
static char ID;
34
+
33
35
const AVRRegisterInfo *TRI;
34
36
const TargetInstrInfo *TII;
37
+
38
+ // / The register to be used for temporary storage.
39
+ const unsigned SCRATCH_REGISTER = AVR::R0;
40
+ // / The IO address of the status register.
41
+ const unsigned SREG_ADDR = 0x3f ;
42
+
35
43
AVRExpandPseudo () : MachineFunctionPass(ID) {}
36
44
37
45
bool runOnMachineFunction (MachineFunction &MF) override ;
@@ -57,6 +65,13 @@ class AVRExpandPseudo : public MachineFunctionPass {
57
65
unsigned DstReg) {
58
66
return BuildMI (MBB, MBBI, MBBI->getDebugLoc (), TII->get (Opcode), DstReg);
59
67
}
68
+
69
+ MachineRegisterInfo &getRegInfo (Block &MBB) { return MBB.getParent ()->getRegInfo (); }
70
+
71
+ template <typename Func>
72
+ bool expandAtomic (Block &MBB, BlockIt MBBI, Func f);
73
+
74
+ bool expandAtomicBinaryOp (unsigned Opcode, Block &MBB, BlockIt MBBI);
60
75
};
61
76
62
77
char AVRExpandPseudo::ID = 0 ;
@@ -80,9 +95,16 @@ bool AVRExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
80
95
TRI = static_cast <const AVRRegisterInfo*>(TM.getSubtargetImpl ()->getRegisterInfo ());
81
96
TII = TM.getSubtargetImpl ()->getInstrInfo ();
82
97
83
- typedef MachineFunction::iterator FuncIt;
84
- for (FuncIt MFI = MF.begin (), E = MF.end (); MFI != E; ++MFI) {
85
- Modified |= expandMBB (*MFI);
98
+ for (Block &MBB : MF) {
99
+ bool ContinueExpanding = true ;
100
+
101
+ // Continue expanding the block until all pseudos are expanded.
102
+ do {
103
+ bool BlockModified = expandMBB (MBB);
104
+ Modified |= BlockModified;
105
+
106
+ ContinueExpanding = BlockModified;
107
+ } while (ContinueExpanding);
86
108
}
87
109
88
110
return Modified;
@@ -799,6 +821,60 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
799
821
return true ;
800
822
}
801
823
824
+ template <typename Func>
825
+ bool AVRExpandPseudo::expandAtomic (Block &MBB, BlockIt MBBI, Func f) {
826
+ // Remove the pseudo instruction.
827
+ MachineInstr &MI = *MBBI;
828
+
829
+ // Store the SREG.
830
+ buildMI (MBB, MBBI, AVR::INRdA)
831
+ .addReg (SCRATCH_REGISTER, RegState::Define)
832
+ .addImm (SREG_ADDR);
833
+
834
+ // Disable exceptions.
835
+ buildMI (MBB, MBBI, AVR::BCLRs).addImm (7 ); // CLI
836
+
837
+ f (MI);
838
+
839
+ // Restore the status reg.
840
+ buildMI (MBB, MBBI, AVR::OUTARr)
841
+ .addImm (SREG_ADDR)
842
+ .addReg (SCRATCH_REGISTER);
843
+
844
+ MI.eraseFromParent ();
845
+ return true ;
846
+ }
847
+
848
+ bool AVRExpandPseudo::expandAtomicBinaryOp (unsigned Opcode, Block &MBB, BlockIt MBBI) {
849
+ return expandAtomic (MBB, MBBI, [&](MachineInstr &MI) {
850
+ auto Op1 = MI.getOperand (0 );
851
+ auto Op2 = MI.getOperand (1 );
852
+
853
+ buildMI (MBB, MBBI, Opcode).addOperand (Op1).addOperand (Op2);
854
+ });
855
+ }
856
+
857
+ template <>
858
+ bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) {
859
+ return expandAtomicBinaryOp (AVR::LDRdPtr, MBB, MBBI);
860
+ }
861
+
862
+
863
+ template <>
864
+ bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(Block &MBB, BlockIt MBBI) {
865
+ return expandAtomicBinaryOp (AVR::LDWRdPtr, MBB, MBBI);
866
+ }
867
+
868
+ template <>
869
+ bool AVRExpandPseudo::expand<AVR::AtomicStore8>(Block &MBB, BlockIt MBBI) {
870
+ return expandAtomicBinaryOp (AVR::STPtrRr, MBB, MBBI);
871
+ }
872
+
873
+ template <>
874
+ bool AVRExpandPseudo::expand<AVR::AtomicStore16>(Block &MBB, BlockIt MBBI) {
875
+ return expandAtomicBinaryOp (AVR::STWPtrRr, MBB, MBBI);
876
+ }
877
+
802
878
template <>
803
879
bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) {
804
880
MachineInstr &MI = *MBBI;
@@ -1305,7 +1381,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
1305
1381
1306
1382
buildMI (MBB, MBBI, AVR::INRdA)
1307
1383
.addReg (AVR::R0, RegState::Define)
1308
- .addImm (0x3f )
1384
+ .addImm (SREG_ADDR )
1309
1385
.setMIFlags (Flags);
1310
1386
1311
1387
buildMI (MBB, MBBI, AVR::BCLRs).addImm (0x07 ).setMIFlags (Flags);
@@ -1316,7 +1392,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
1316
1392
.setMIFlags (Flags);
1317
1393
1318
1394
buildMI (MBB, MBBI, AVR::OUTARr)
1319
- .addImm (0x3f )
1395
+ .addImm (SREG_ADDR )
1320
1396
.addReg (AVR::R0, RegState::Kill)
1321
1397
.setMIFlags (Flags);
1322
1398
@@ -1359,6 +1435,10 @@ bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
1359
1435
EXPAND (AVR::LDWRdPtrPd);
1360
1436
case AVR::LDDWRdYQ: // :FIXME: remove this once PR13375 gets fixed
1361
1437
EXPAND (AVR::LDDWRdPtrQ);
1438
+ EXPAND (AVR::AtomicLoad8);
1439
+ EXPAND (AVR::AtomicLoad16);
1440
+ EXPAND (AVR::AtomicStore8);
1441
+ EXPAND (AVR::AtomicStore16);
1362
1442
EXPAND (AVR::STSWKRr);
1363
1443
EXPAND (AVR::STWPtrRr);
1364
1444
EXPAND (AVR::STWPtrPiRr);
0 commit comments