@@ -62,18 +62,6 @@ SystemZFrameLowering::SystemZFrameLowering()
62
62
RegSpillOffsets[SpillOffsetTable[I].Reg ] = SpillOffsetTable[I].Offset ;
63
63
}
64
64
65
- static bool usePackedStack (MachineFunction &MF) {
66
- bool HasPackedStackAttr = MF.getFunction ().hasFnAttribute (" packed-stack" );
67
- bool IsVarArg = MF.getFunction ().isVarArg ();
68
- bool CallConv = MF.getFunction ().getCallingConv () != CallingConv::GHC;
69
- bool BackChain = MF.getFunction ().hasFnAttribute (" backchain" );
70
- bool FramAddressTaken = MF.getFrameInfo ().isFrameAddressTaken ();
71
- if (HasPackedStackAttr && BackChain)
72
- report_fatal_error (" packed-stack with backchain is currently unsupported." );
73
- return HasPackedStackAttr && !IsVarArg && CallConv && !BackChain &&
74
- !FramAddressTaken;
75
- }
76
-
77
65
bool SystemZFrameLowering::
78
66
assignCalleeSavedSpillSlots (MachineFunction &MF,
79
67
const TargetRegisterInfo *TRI,
@@ -87,71 +75,44 @@ assignCalleeSavedSpillSlots(MachineFunction &MF,
87
75
unsigned LowGPR = 0 ;
88
76
unsigned HighGPR = SystemZ::R15D;
89
77
int StartSPOffset = SystemZMC::CallFrameSize;
90
- int CurrOffset;
91
- if (!usePackedStack (MF)) {
92
- for (auto &CS : CSI) {
93
- unsigned Reg = CS.getReg ();
94
- int Offset = RegSpillOffsets[Reg];
95
- if (Offset) {
96
- if (SystemZ::GR64BitRegClass.contains (Reg) && StartSPOffset > Offset) {
97
- LowGPR = Reg;
98
- StartSPOffset = Offset;
99
- }
100
- Offset -= SystemZMC::CallFrameSize;
101
- int FrameIdx = MFFrame.CreateFixedSpillStackObject (8 , Offset);
102
- CS.setFrameIdx (FrameIdx);
103
- } else
104
- CS.setFrameIdx (INT32_MAX);
105
- }
78
+ for (auto &CS : CSI) {
79
+ unsigned Reg = CS.getReg ();
80
+ int Offset = getRegSpillOffset (MF, Reg);
81
+ if (Offset) {
82
+ if (SystemZ::GR64BitRegClass.contains (Reg) && StartSPOffset > Offset) {
83
+ LowGPR = Reg;
84
+ StartSPOffset = Offset;
85
+ }
86
+ Offset -= SystemZMC::CallFrameSize;
87
+ int FrameIdx = MFFrame.CreateFixedSpillStackObject (8 , Offset);
88
+ CS.setFrameIdx (FrameIdx);
89
+ } else
90
+ CS.setFrameIdx (INT32_MAX);
91
+ }
106
92
107
- // Save the range of call-saved registers, for use by the
108
- // prologue/epilogue inserters.
109
- ZFI->setRestoreGPRRegs (LowGPR, HighGPR, StartSPOffset);
110
- if (IsVarArg) {
111
- // Also save the GPR varargs, if any. R6D is call-saved, so would
112
- // already be included, but we also need to handle the call-clobbered
113
- // argument registers.
114
- unsigned FirstGPR = ZFI->getVarArgsFirstGPR ();
115
- if (FirstGPR < SystemZ::NumArgGPRs) {
116
- unsigned Reg = SystemZ::ArgGPRs[FirstGPR];
117
- int Offset = RegSpillOffsets[Reg];
118
- if (StartSPOffset > Offset) {
119
- LowGPR = Reg; StartSPOffset = Offset;
120
- }
93
+ // Save the range of call-saved registers, for use by the
94
+ // prologue/epilogue inserters.
95
+ ZFI->setRestoreGPRRegs (LowGPR, HighGPR, StartSPOffset);
96
+ if (IsVarArg) {
97
+ // Also save the GPR varargs, if any. R6D is call-saved, so would
98
+ // already be included, but we also need to handle the call-clobbered
99
+ // argument registers.
100
+ unsigned FirstGPR = ZFI->getVarArgsFirstGPR ();
101
+ if (FirstGPR < SystemZ::NumArgGPRs) {
102
+ unsigned Reg = SystemZ::ArgGPRs[FirstGPR];
103
+ int Offset = getRegSpillOffset (MF, Reg);
104
+ if (StartSPOffset > Offset) {
105
+ LowGPR = Reg; StartSPOffset = Offset;
121
106
}
122
107
}
123
- ZFI->setSpillGPRRegs (LowGPR, HighGPR, StartSPOffset);
124
-
125
- CurrOffset = -SystemZMC::CallFrameSize;
126
- } else {
127
- // Packed stack: put all the GPRs at the top of the Register save area.
128
- uint32_t LowGR64Num = UINT32_MAX;
129
- for (auto &CS : CSI) {
130
- unsigned Reg = CS.getReg ();
131
- if (SystemZ::GR64BitRegClass.contains (Reg)) {
132
- unsigned GR64Num = SystemZMC::getFirstReg (Reg);
133
- int Offset = -8 * (15 - GR64Num + 1 );
134
- if (LowGR64Num > GR64Num) {
135
- LowGR64Num = GR64Num;
136
- StartSPOffset = SystemZMC::CallFrameSize + Offset;
137
- }
138
- int FrameIdx = MFFrame.CreateFixedSpillStackObject (8 , Offset);
139
- CS.setFrameIdx (FrameIdx);
140
- } else
141
- CS.setFrameIdx (INT32_MAX);
142
- }
143
- if (LowGR64Num < UINT32_MAX)
144
- LowGPR = SystemZMC::GR64Regs[LowGR64Num];
145
-
146
- // Save the range of call-saved registers, for use by the
147
- // prologue/epilogue inserters.
148
- ZFI->setRestoreGPRRegs (LowGPR, HighGPR, StartSPOffset);
149
- ZFI->setSpillGPRRegs (LowGPR, HighGPR, StartSPOffset);
150
-
151
- CurrOffset = LowGPR ? -(SystemZMC::CallFrameSize - StartSPOffset) : 0 ;
152
108
}
109
+ ZFI->setSpillGPRRegs (LowGPR, HighGPR, StartSPOffset);
153
110
154
111
// Create fixed stack objects for the remaining registers.
112
+ int CurrOffset = -SystemZMC::CallFrameSize;
113
+ if (usePackedStack (MF))
114
+ CurrOffset += StartSPOffset;
115
+
155
116
for (auto &CS : CSI) {
156
117
if (CS.getFrameIdx () != INT32_MAX)
157
118
continue ;
@@ -511,10 +472,13 @@ void SystemZFrameLowering::emitPrologue(MachineFunction &MF,
511
472
.addCFIIndex (CFIIndex);
512
473
SPOffsetFromCFA += Delta;
513
474
514
- if (StoreBackchain)
475
+ if (StoreBackchain) {
476
+ // The back chain is stored topmost with packed-stack.
477
+ int Offset = usePackedStack (MF) ? SystemZMC::CallFrameSize - 8 : 0 ;
515
478
BuildMI (MBB, MBBI, DL, ZII->get (SystemZ::STG))
516
- .addReg (SystemZ::R1D, RegState::Kill).addReg (SystemZ::R15D).addImm (0 )
517
- .addReg (0 );
479
+ .addReg (SystemZ::R1D, RegState::Kill).addReg (SystemZ::R15D)
480
+ .addImm (Offset).addReg (0 );
481
+ }
518
482
}
519
483
520
484
if (HasFP) {
@@ -662,14 +626,43 @@ eliminateCallFramePseudoInstr(MachineFunction &MF,
662
626
}
663
627
}
664
628
629
+ unsigned SystemZFrameLowering::getRegSpillOffset (MachineFunction &MF,
630
+ unsigned Reg) const {
631
+ bool IsVarArg = MF.getFunction ().isVarArg ();
632
+ bool BackChain = MF.getFunction ().hasFnAttribute (" backchain" );
633
+ bool SoftFloat = MF.getSubtarget <SystemZSubtarget>().hasSoftFloat ();
634
+ unsigned Offset = RegSpillOffsets[Reg];
635
+ if (usePackedStack (MF) && !(IsVarArg && !SoftFloat)) {
636
+ if (SystemZ::GR64BitRegClass.contains (Reg))
637
+ // Put all GPRs at the top of the Register save area with packed
638
+ // stack. Make room for the backchain if needed.
639
+ Offset += BackChain ? 24 : 32 ;
640
+ else
641
+ Offset = 0 ;
642
+ }
643
+ return Offset;
644
+ }
645
+
665
646
int SystemZFrameLowering::
666
647
getOrCreateFramePointerSaveIndex (MachineFunction &MF) const {
667
648
SystemZMachineFunctionInfo *ZFI = MF.getInfo <SystemZMachineFunctionInfo>();
668
649
int FI = ZFI->getFramePointerSaveIndex ();
669
650
if (!FI) {
670
651
MachineFrameInfo &MFFrame = MF.getFrameInfo ();
671
- FI = MFFrame.CreateFixedObject (8 , -SystemZMC::CallFrameSize, false );
652
+ // The back chain is stored topmost with packed-stack.
653
+ int Offset = usePackedStack (MF) ? -8 : -SystemZMC::CallFrameSize;
654
+ FI = MFFrame.CreateFixedObject (8 , Offset, false );
672
655
ZFI->setFramePointerSaveIndex (FI);
673
656
}
674
657
return FI;
675
658
}
659
+
660
+ bool SystemZFrameLowering::usePackedStack (MachineFunction &MF) const {
661
+ bool HasPackedStackAttr = MF.getFunction ().hasFnAttribute (" packed-stack" );
662
+ bool BackChain = MF.getFunction ().hasFnAttribute (" backchain" );
663
+ bool SoftFloat = MF.getSubtarget <SystemZSubtarget>().hasSoftFloat ();
664
+ if (HasPackedStackAttr && BackChain && !SoftFloat)
665
+ report_fatal_error (" packed-stack + backchain + hard-float is unsupported." );
666
+ bool CallConv = MF.getFunction ().getCallingConv () != CallingConv::GHC;
667
+ return HasPackedStackAttr && CallConv;
668
+ }
0 commit comments