1 //=====- AlphaFrameLowering.cpp - Alpha Frame Information ------*- C++ -*-====//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Alpha implementation of TargetFrameLowering class.
12 //===----------------------------------------------------------------------===//
14 #include "AlphaFrameLowering.h"
15 #include "AlphaInstrInfo.h"
16 #include "AlphaMachineFunctionInfo.h"
17 #include "llvm/Function.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/ADT/Twine.h"
25 static long getUpper16(long l
) {
26 long y
= l
/ Alpha::IMM_MULT
;
27 if (l
% Alpha::IMM_MULT
> Alpha::IMM_HIGH
)
32 static long getLower16(long l
) {
33 long h
= getUpper16(l
);
34 return l
- h
* Alpha::IMM_MULT
;
37 // hasFP - Return true if the specified function should have a dedicated frame
38 // pointer register. This is true if the function has variable sized allocas or
39 // if frame pointer elimination is disabled.
41 bool AlphaFrameLowering::hasFP(const MachineFunction
&MF
) const {
42 const MachineFrameInfo
*MFI
= MF
.getFrameInfo();
43 return MFI
->hasVarSizedObjects();
46 void AlphaFrameLowering::emitPrologue(MachineFunction
&MF
) const {
47 MachineBasicBlock
&MBB
= MF
.front(); // Prolog goes in entry BB
48 MachineBasicBlock::iterator MBBI
= MBB
.begin();
49 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
50 const TargetInstrInfo
&TII
= *MF
.getTarget().getInstrInfo();
52 DebugLoc dl
= (MBBI
!= MBB
.end() ? MBBI
->getDebugLoc() : DebugLoc());
56 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDAHg
), Alpha::R29
)
57 .addGlobalAddress(MF
.getFunction()).addReg(Alpha::R27
).addImm(++curgpdist
);
58 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDAg
), Alpha::R29
)
59 .addGlobalAddress(MF
.getFunction()).addReg(Alpha::R29
).addImm(curgpdist
);
61 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::ALTENT
))
62 .addGlobalAddress(MF
.getFunction());
64 // Get the number of bytes to allocate from the FrameInfo
65 long NumBytes
= MFI
->getStackSize();
68 NumBytes
+= 8; //reserve space for the old FP
70 // Do we need to allocate space on the stack?
71 if (NumBytes
== 0) return;
73 unsigned Align
= getStackAlignment();
74 NumBytes
= (NumBytes
+Align
-1)/Align
*Align
;
76 // Update frame info to pretend that this is part of the stack...
77 MFI
->setStackSize(NumBytes
);
79 // adjust stack pointer: r30 -= numbytes
81 if (NumBytes
>= Alpha::IMM_LOW
) {
82 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDA
), Alpha::R30
).addImm(NumBytes
)
84 } else if (getUpper16(NumBytes
) >= Alpha::IMM_LOW
) {
85 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDAH
), Alpha::R30
)
86 .addImm(getUpper16(NumBytes
)).addReg(Alpha::R30
);
87 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDA
), Alpha::R30
)
88 .addImm(getLower16(NumBytes
)).addReg(Alpha::R30
);
90 report_fatal_error("Too big a stack frame at " + Twine(NumBytes
));
93 // Now if we need to, save the old FP and set the new
95 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::STQ
))
96 .addReg(Alpha::R15
).addImm(0).addReg(Alpha::R30
);
97 // This must be the last instr in the prolog
98 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::BISr
), Alpha::R15
)
99 .addReg(Alpha::R30
).addReg(Alpha::R30
);
104 void AlphaFrameLowering::emitEpilogue(MachineFunction
&MF
,
105 MachineBasicBlock
&MBB
) const {
106 const MachineFrameInfo
*MFI
= MF
.getFrameInfo();
107 MachineBasicBlock::iterator MBBI
= MBB
.getLastNonDebugInstr();
108 const TargetInstrInfo
&TII
= *MF
.getTarget().getInstrInfo();
110 assert((MBBI
->getOpcode() == Alpha::RETDAG
||
111 MBBI
->getOpcode() == Alpha::RETDAGp
)
112 && "Can only insert epilog into returning blocks");
113 DebugLoc dl
= MBBI
->getDebugLoc();
117 // Get the number of bytes allocated from the FrameInfo...
118 long NumBytes
= MFI
->getStackSize();
120 //now if we need to, restore the old FP
122 //copy the FP into the SP (discards allocas)
123 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::BISr
), Alpha::R30
).addReg(Alpha::R15
)
126 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDQ
), Alpha::R15
)
127 .addImm(0).addReg(Alpha::R15
);
131 if (NumBytes
<= Alpha::IMM_HIGH
) {
132 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDA
), Alpha::R30
).addImm(NumBytes
)
134 } else if (getUpper16(NumBytes
) <= Alpha::IMM_HIGH
) {
135 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDAH
), Alpha::R30
)
136 .addImm(getUpper16(NumBytes
)).addReg(Alpha::R30
);
137 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDA
), Alpha::R30
)
138 .addImm(getLower16(NumBytes
)).addReg(Alpha::R30
);
140 report_fatal_error("Too big a stack frame at " + Twine(NumBytes
));