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/Support/ErrorHandling.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/ADT/BitVector.h"
34 #include "llvm/ADT/STLExtras.h"
39 static const int IMM_LOW
= -32768;
40 static const int IMM_HIGH
= 32767;
41 static const int IMM_MULT
= 65536;
43 static long getUpper16(long l
)
45 long y
= l
/ IMM_MULT
;
46 if (l
% IMM_MULT
> IMM_HIGH
)
51 static long getLower16(long l
)
53 long h
= getUpper16(l
);
54 return l
- h
* IMM_MULT
;
57 AlphaRegisterInfo::AlphaRegisterInfo(const TargetInstrInfo
&tii
)
58 : AlphaGenRegisterInfo(Alpha::ADJUSTSTACKDOWN
, Alpha::ADJUSTSTACKUP
),
59 TII(tii
), curgpdist(0)
63 const unsigned* AlphaRegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
)
65 static const unsigned CalleeSavedRegs
[] = {
66 Alpha::R9
, Alpha::R10
,
67 Alpha::R11
, Alpha::R12
,
68 Alpha::R13
, Alpha::R14
,
72 Alpha::F8
, Alpha::F9
, 0
74 return CalleeSavedRegs
;
77 const TargetRegisterClass
* const*
78 AlphaRegisterInfo::getCalleeSavedRegClasses(const MachineFunction
*MF
) const {
79 static const TargetRegisterClass
* const CalleeSavedRegClasses
[] = {
80 &Alpha::GPRCRegClass
, &Alpha::GPRCRegClass
,
81 &Alpha::GPRCRegClass
, &Alpha::GPRCRegClass
,
82 &Alpha::GPRCRegClass
, &Alpha::GPRCRegClass
,
83 &Alpha::F8RCRegClass
, &Alpha::F8RCRegClass
,
84 &Alpha::F8RCRegClass
, &Alpha::F8RCRegClass
,
85 &Alpha::F8RCRegClass
, &Alpha::F8RCRegClass
,
86 &Alpha::F8RCRegClass
, &Alpha::F8RCRegClass
, 0
88 return CalleeSavedRegClasses
;
91 BitVector
AlphaRegisterInfo::getReservedRegs(const MachineFunction
&MF
) const {
92 BitVector
Reserved(getNumRegs());
93 Reserved
.set(Alpha::R15
);
94 Reserved
.set(Alpha::R30
);
95 Reserved
.set(Alpha::R31
);
99 //===----------------------------------------------------------------------===//
100 // Stack Frame Processing methods
101 //===----------------------------------------------------------------------===//
103 // hasFP - Return true if the specified function should have a dedicated frame
104 // pointer register. This is true if the function has variable sized allocas or
105 // if frame pointer elimination is disabled.
107 bool AlphaRegisterInfo::hasFP(const MachineFunction
&MF
) const {
108 const MachineFrameInfo
*MFI
= MF
.getFrameInfo();
109 return MFI
->hasVarSizedObjects();
112 void AlphaRegisterInfo::
113 eliminateCallFramePseudoInstr(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
114 MachineBasicBlock::iterator I
) const {
116 // If we have a frame pointer, turn the adjcallstackup instruction into a
117 // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP,
119 MachineInstr
*Old
= I
;
120 uint64_t Amount
= Old
->getOperand(0).getImm();
122 // We need to keep the stack aligned properly. To do this, we round the
123 // amount of space needed for the outgoing arguments up to the next
124 // alignment boundary.
125 unsigned Align
= MF
.getTarget().getFrameInfo()->getStackAlignment();
126 Amount
= (Amount
+Align
-1)/Align
*Align
;
129 if (Old
->getOpcode() == Alpha::ADJUSTSTACKDOWN
) {
130 New
=BuildMI(MF
, Old
->getDebugLoc(), TII
.get(Alpha::LDA
), Alpha::R30
)
131 .addImm(-Amount
).addReg(Alpha::R30
);
133 assert(Old
->getOpcode() == Alpha::ADJUSTSTACKUP
);
134 New
=BuildMI(MF
, Old
->getDebugLoc(), TII
.get(Alpha::LDA
), Alpha::R30
)
135 .addImm(Amount
).addReg(Alpha::R30
);
138 // Replace the pseudo instruction with a new instruction...
146 //Alpha has a slightly funny stack:
149 //fixed locals (and spills, callee saved, etc)
154 void AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II
,
155 int SPAdj
, RegScavenger
*RS
) const {
156 assert(SPAdj
== 0 && "Unexpected");
159 MachineInstr
&MI
= *II
;
160 MachineBasicBlock
&MBB
= *MI
.getParent();
161 MachineFunction
&MF
= *MBB
.getParent();
164 while (!MI
.getOperand(i
).isFI()) {
166 assert(i
< MI
.getNumOperands() && "Instr doesn't have FrameIndex operand!");
169 int FrameIndex
= MI
.getOperand(i
).getIndex();
171 // Add the base register of R30 (SP) or R15 (FP).
172 MI
.getOperand(i
+ 1).ChangeToRegister(FP
? Alpha::R15
: Alpha::R30
, false);
174 // Now add the frame object offset to the offset from the virtual frame index.
175 int Offset
= MF
.getFrameInfo()->getObjectOffset(FrameIndex
);
177 DOUT
<< "FI: " << FrameIndex
<< " Offset: " << Offset
<< "\n";
179 Offset
+= MF
.getFrameInfo()->getStackSize();
181 DOUT
<< "Corrected Offset " << Offset
182 << " for stack size: " << MF
.getFrameInfo()->getStackSize() << "\n";
184 if (Offset
> IMM_HIGH
|| Offset
< IMM_LOW
) {
185 DOUT
<< "Unconditionally using R28 for evil purposes Offset: "
187 //so in this case, we need to use a temporary register, and move the
188 //original inst off the SP/FP
190 MI
.getOperand(i
+ 1).ChangeToRegister(Alpha::R28
, false);
191 MI
.getOperand(i
).ChangeToImmediate(getLower16(Offset
));
193 MachineInstr
* nMI
=BuildMI(MF
, MI
.getDebugLoc(),
194 TII
.get(Alpha::LDAH
), Alpha::R28
)
195 .addImm(getUpper16(Offset
)).addReg(FP
? Alpha::R15
: Alpha::R30
);
198 MI
.getOperand(i
).ChangeToImmediate(Offset
);
203 void AlphaRegisterInfo::emitPrologue(MachineFunction
&MF
) const {
204 MachineBasicBlock
&MBB
= MF
.front(); // Prolog goes in entry BB
205 MachineBasicBlock::iterator MBBI
= MBB
.begin();
206 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
207 DebugLoc dl
= (MBBI
!= MBB
.end() ?
208 MBBI
->getDebugLoc() : DebugLoc::getUnknownLoc());
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
);
250 raw_string_ostream
Msg(msg
);
251 Msg
<< "Too big a stack frame at " + NumBytes
;
252 llvm_report_error(Msg
.str());
255 //now if we need to, save the old FP and set the new
258 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::STQ
))
259 .addReg(Alpha::R15
).addImm(0).addReg(Alpha::R30
);
260 //this must be the last instr in the prolog
261 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::BISr
), Alpha::R15
)
262 .addReg(Alpha::R30
).addReg(Alpha::R30
);
267 void AlphaRegisterInfo::emitEpilogue(MachineFunction
&MF
,
268 MachineBasicBlock
&MBB
) const {
269 const MachineFrameInfo
*MFI
= MF
.getFrameInfo();
270 MachineBasicBlock::iterator MBBI
= prior(MBB
.end());
271 assert((MBBI
->getOpcode() == Alpha::RETDAG
||
272 MBBI
->getOpcode() == Alpha::RETDAGp
)
273 && "Can only insert epilog into returning blocks");
274 DebugLoc dl
= MBBI
->getDebugLoc();
278 // Get the number of bytes allocated from the FrameInfo...
279 long NumBytes
= MFI
->getStackSize();
281 //now if we need to, restore the old FP
283 //copy the FP into the SP (discards allocas)
284 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::BISr
), Alpha::R30
).addReg(Alpha::R15
)
287 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDQ
), Alpha::R15
)
288 .addImm(0).addReg(Alpha::R15
);
292 if (NumBytes
<= IMM_HIGH
) {
293 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDA
), Alpha::R30
).addImm(NumBytes
)
295 } else if (getUpper16(NumBytes
) <= IMM_HIGH
) {
296 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDAH
), Alpha::R30
)
297 .addImm(getUpper16(NumBytes
)).addReg(Alpha::R30
);
298 BuildMI(MBB
, MBBI
, dl
, TII
.get(Alpha::LDA
), Alpha::R30
)
299 .addImm(getLower16(NumBytes
)).addReg(Alpha::R30
);
302 raw_string_ostream
Msg(msg
);
303 Msg
<< "Too big a stack frame at " + NumBytes
;
304 llvm_report_error(Msg
.str());
309 unsigned AlphaRegisterInfo::getRARegister() const {
310 llvm_unreachable("What is the return address register");
314 unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction
&MF
) const {
315 return hasFP(MF
) ? Alpha::R15
: Alpha::R30
;
318 unsigned AlphaRegisterInfo::getEHExceptionRegister() const {
319 llvm_unreachable("What is the exception register");
323 unsigned AlphaRegisterInfo::getEHHandlerRegister() const {
324 llvm_unreachable("What is the exception handler register");
328 int AlphaRegisterInfo::getDwarfRegNum(unsigned RegNum
, bool isEH
) const {
329 llvm_unreachable("What is the dwarf register number");
333 #include "AlphaGenRegisterInfo.inc"
335 std::string
AlphaRegisterInfo::getPrettyName(unsigned reg
)
337 std::string
s(RegisterDescriptors
[reg
].Name
);