1 //===- AlphaRegisterInfo.cpp - Alpha Register 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 the TargetRegisterInfo class.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "reginfo"
16 #include "AlphaRegisterInfo.h"
17 #include "llvm/Constants.h"
18 #include "llvm/Type.h"
19 #include "llvm/Function.h"
20 #include "llvm/CodeGen/ValueTypes.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineFrameInfo.h"
24 #include "llvm/CodeGen/MachineLocation.h"
25 #include "llvm/Target/TargetFrameInfo.h"
26 #include "llvm/Target/TargetMachine.h"
27 #include "llvm/Target/TargetOptions.h"
28 #include "llvm/Target/TargetInstrInfo.h"
29 #include "llvm/Support/CommandLine.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/ADT/BitVector.h"
32 #include "llvm/ADT/STLExtras.h"
37 static const int IMM_LOW
= -32768;
38 static const int IMM_HIGH
= 32767;
39 static const int IMM_MULT
= 65536;
41 static long getUpper16(long l
)
43 long y
= l
/ IMM_MULT
;
44 if (l
% IMM_MULT
> IMM_HIGH
)
49 static long getLower16(long l
)
51 long h
= getUpper16(l
);
52 return l
- h
* IMM_MULT
;
55 AlphaRegisterInfo::AlphaRegisterInfo(const TargetInstrInfo
&tii
)
56 : AlphaGenRegisterInfo(Alpha::ADJUSTSTACKDOWN
, Alpha::ADJUSTSTACKUP
),
61 const unsigned* AlphaRegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
)
63 static const unsigned CalleeSavedRegs
[] = {
64 Alpha::R9
, Alpha::R10
,
65 Alpha::R11
, Alpha::R12
,
66 Alpha::R13
, Alpha::R14
,
70 Alpha::F8
, Alpha::F9
, 0
72 return CalleeSavedRegs
;
75 const TargetRegisterClass
* const*
76 AlphaRegisterInfo::getCalleeSavedRegClasses(const MachineFunction
*MF
) const {
77 static const TargetRegisterClass
* const CalleeSavedRegClasses
[] = {
78 &Alpha::GPRCRegClass
, &Alpha::GPRCRegClass
,
79 &Alpha::GPRCRegClass
, &Alpha::GPRCRegClass
,
80 &Alpha::GPRCRegClass
, &Alpha::GPRCRegClass
,
81 &Alpha::F8RCRegClass
, &Alpha::F8RCRegClass
,
82 &Alpha::F8RCRegClass
, &Alpha::F8RCRegClass
,
83 &Alpha::F8RCRegClass
, &Alpha::F8RCRegClass
,
84 &Alpha::F8RCRegClass
, &Alpha::F8RCRegClass
, 0
86 return CalleeSavedRegClasses
;
89 BitVector
AlphaRegisterInfo::getReservedRegs(const MachineFunction
&MF
) const {
90 BitVector
Reserved(getNumRegs());
91 Reserved
.set(Alpha::R15
);
92 Reserved
.set(Alpha::R30
);
93 Reserved
.set(Alpha::R31
);
97 //===----------------------------------------------------------------------===//
98 // Stack Frame Processing methods
99 //===----------------------------------------------------------------------===//
101 // hasFP - Return true if the specified function should have a dedicated frame
102 // pointer register. This is true if the function has variable sized allocas or
103 // if frame pointer elimination is disabled.
105 bool AlphaRegisterInfo::hasFP(const MachineFunction
&MF
) const {
106 const MachineFrameInfo
*MFI
= MF
.getFrameInfo();
107 return MFI
->hasVarSizedObjects();
110 void AlphaRegisterInfo::
111 eliminateCallFramePseudoInstr(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
112 MachineBasicBlock::iterator I
) const {
114 // If we have a frame pointer, turn the adjcallstackup instruction into a
115 // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP,
117 MachineInstr
*Old
= I
;
118 uint64_t Amount
= Old
->getOperand(0).getImm();
120 // We need to keep the stack aligned properly. To do this, we round the
121 // amount of space needed for the outgoing arguments up to the next
122 // alignment boundary.
123 unsigned Align
= MF
.getTarget().getFrameInfo()->getStackAlignment();
124 Amount
= (Amount
+Align
-1)/Align
*Align
;
127 if (Old
->getOpcode() == Alpha::ADJUSTSTACKDOWN
) {
128 New
=BuildMI(MF
, Old
->getDebugLoc(), TII
.get(Alpha::LDA
), Alpha::R30
)
129 .addImm(-Amount
).addReg(Alpha::R30
);
131 assert(Old
->getOpcode() == Alpha::ADJUSTSTACKUP
);
132 New
=BuildMI(MF
, Old
->getDebugLoc(), TII
.get(Alpha::LDA
), Alpha::R30
)
133 .addImm(Amount
).addReg(Alpha::R30
);
136 // Replace the pseudo instruction with a new instruction...
144 //Alpha has a slightly funny stack:
147 //fixed locals (and spills, callee saved, etc)
152 void AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II
,
153 int SPAdj
, RegScavenger
*RS
) const {
154 assert(SPAdj
== 0 && "Unexpected");
157 MachineInstr
&MI
= *II
;
158 MachineBasicBlock
&MBB
= *MI
.getParent();
159 MachineFunction
&MF
= *MBB
.getParent();
162 while (!MI
.getOperand(i
).isFI()) {
164 assert(i
< MI
.getNumOperands() && "Instr doesn't have FrameIndex operand!");
167 int FrameIndex
= MI
.getOperand(i
).getIndex();
169 // Add the base register of R30 (SP) or R15 (FP).
170 MI
.getOperand(i
+ 1).ChangeToRegister(FP
? Alpha::R15
: Alpha::R30
, false);
172 // Now add the frame object offset to the offset from the virtual frame index.
173 int Offset
= MF
.getFrameInfo()->getObjectOffset(FrameIndex
);
175 DOUT
<< "FI: " << FrameIndex
<< " Offset: " << Offset
<< "\n";
177 Offset
+= MF
.getFrameInfo()->getStackSize();
179 DOUT
<< "Corrected Offset " << Offset
180 << " for stack size: " << MF
.getFrameInfo()->getStackSize() << "\n";
182 if (Offset
> IMM_HIGH
|| Offset
< IMM_LOW
) {
183 DOUT
<< "Unconditionally using R28 for evil purposes Offset: "
185 //so in this case, we need to use a temporary register, and move the
186 //original inst off the SP/FP
188 MI
.getOperand(i
+ 1).ChangeToRegister(Alpha::R28
, false);
189 MI
.getOperand(i
).ChangeToImmediate(getLower16(Offset
));
191 MachineInstr
* nMI
=BuildMI(MF
, MI
.getDebugLoc(),
192 TII
.get(Alpha::LDAH
), Alpha::R28
)
193 .addImm(getUpper16(Offset
)).addReg(FP
? Alpha::R15
: Alpha::R30
);
196 MI
.getOperand(i
).ChangeToImmediate(Offset
);
201 void AlphaRegisterInfo::emitPrologue(MachineFunction
&MF
) const {
202 MachineBasicBlock
&MBB
= MF
.front(); // Prolog goes in entry BB
203 MachineBasicBlock::iterator MBBI
= MBB
.begin();
204 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
205 DebugLoc dl
= (MBBI
!= MBB
.end() ?
206 MBBI
->getDebugLoc() : DebugLoc::getUnknownLoc());
209 static int curgpdist
= 0;
212 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDAHg
), Alpha::R29
)
213 .addGlobalAddress(const_cast<Function
*>(MF
.getFunction()))
214 .addReg(Alpha::R27
).addImm(++curgpdist
);
215 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDAg
), Alpha::R29
)
216 .addGlobalAddress(const_cast<Function
*>(MF
.getFunction()))
217 .addReg(Alpha::R29
).addImm(curgpdist
);
219 //evil const_cast until MO stuff setup to handle const
220 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::ALTENT
))
221 .addGlobalAddress(const_cast<Function
*>(MF
.getFunction()));
223 // Get the number of bytes to allocate from the FrameInfo
224 long NumBytes
= MFI
->getStackSize();
227 NumBytes
+= 8; //reserve space for the old FP
229 // Do we need to allocate space on the stack?
230 if (NumBytes
== 0) return;
232 unsigned Align
= MF
.getTarget().getFrameInfo()->getStackAlignment();
233 NumBytes
= (NumBytes
+Align
-1)/Align
*Align
;
235 // Update frame info to pretend that this is part of the stack...
236 MFI
->setStackSize(NumBytes
);
238 // adjust stack pointer: r30 -= numbytes
239 NumBytes
= -NumBytes
;
240 if (NumBytes
>= IMM_LOW
) {
241 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDA
), Alpha::R30
).addImm(NumBytes
)
243 } else if (getUpper16(NumBytes
) >= IMM_LOW
) {
244 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDAH
), Alpha::R30
)
245 .addImm(getUpper16(NumBytes
)).addReg(Alpha::R30
);
246 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDA
), Alpha::R30
)
247 .addImm(getLower16(NumBytes
)).addReg(Alpha::R30
);
249 cerr
<< "Too big a stack frame at " << NumBytes
<< "\n";
253 //now if we need to, save the old FP and set the new
256 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::STQ
))
257 .addReg(Alpha::R15
).addImm(0).addReg(Alpha::R30
);
258 //this must be the last instr in the prolog
259 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::BISr
), Alpha::R15
)
260 .addReg(Alpha::R30
).addReg(Alpha::R30
);
265 void AlphaRegisterInfo::emitEpilogue(MachineFunction
&MF
,
266 MachineBasicBlock
&MBB
) const {
267 const MachineFrameInfo
*MFI
= MF
.getFrameInfo();
268 MachineBasicBlock::iterator MBBI
= prior(MBB
.end());
269 assert((MBBI
->getOpcode() == Alpha::RETDAG
||
270 MBBI
->getOpcode() == Alpha::RETDAGp
)
271 && "Can only insert epilog into returning blocks");
272 DebugLoc dl
= MBBI
->getDebugLoc();
276 // Get the number of bytes allocated from the FrameInfo...
277 long NumBytes
= MFI
->getStackSize();
279 //now if we need to, restore the old FP
281 //copy the FP into the SP (discards allocas)
282 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::BISr
), Alpha::R30
).addReg(Alpha::R15
)
285 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDQ
), Alpha::R15
)
286 .addImm(0).addReg(Alpha::R15
);
290 if (NumBytes
<= IMM_HIGH
) {
291 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDA
), Alpha::R30
).addImm(NumBytes
)
293 } else if (getUpper16(NumBytes
) <= IMM_HIGH
) {
294 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDAH
), Alpha::R30
)
295 .addImm(getUpper16(NumBytes
)).addReg(Alpha::R30
);
296 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDA
), Alpha::R30
)
297 .addImm(getLower16(NumBytes
)).addReg(Alpha::R30
);
299 cerr
<< "Too big a stack frame at " << NumBytes
<< "\n";
305 unsigned AlphaRegisterInfo::getRARegister() const {
306 assert(0 && "What is the return address register");
310 unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction
&MF
) const {
311 return hasFP(MF
) ? Alpha::R15
: Alpha::R30
;
314 unsigned AlphaRegisterInfo::getEHExceptionRegister() const {
315 assert(0 && "What is the exception register");
319 unsigned AlphaRegisterInfo::getEHHandlerRegister() const {
320 assert(0 && "What is the exception handler register");
324 int AlphaRegisterInfo::getDwarfRegNum(unsigned RegNum
, bool isEH
) const {
325 assert(0 && "What is the dwarf register number");
329 #include "AlphaGenRegisterInfo.inc"
331 std::string
AlphaRegisterInfo::getPrettyName(unsigned reg
)
333 std::string
s(RegisterDescriptors
[reg
].Name
);