1 //===- IA64RegisterInfo.cpp - IA64 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 IA64 implementation of the TargetRegisterInfo class.
11 // This file is responsible for the frame pointer elimination optimization
14 //===----------------------------------------------------------------------===//
17 #include "IA64RegisterInfo.h"
18 #include "IA64InstrBuilder.h"
19 #include "IA64MachineFunctionInfo.h"
20 #include "llvm/Constants.h"
21 #include "llvm/Type.h"
22 #include "llvm/CodeGen/ValueTypes.h"
23 #include "llvm/CodeGen/MachineInstrBuilder.h"
24 #include "llvm/CodeGen/MachineFunction.h"
25 #include "llvm/CodeGen/MachineFrameInfo.h"
26 #include "llvm/CodeGen/MachineLocation.h"
27 #include "llvm/CodeGen/MachineRegisterInfo.h"
28 #include "llvm/Target/TargetFrameInfo.h"
29 #include "llvm/Target/TargetMachine.h"
30 #include "llvm/Target/TargetOptions.h"
31 #include "llvm/Target/TargetInstrInfo.h"
32 #include "llvm/ADT/BitVector.h"
33 #include "llvm/ADT/STLExtras.h"
36 IA64RegisterInfo::IA64RegisterInfo(const TargetInstrInfo
&tii
)
37 : IA64GenRegisterInfo(IA64::ADJUSTCALLSTACKDOWN
, IA64::ADJUSTCALLSTACKUP
),
40 const unsigned* IA64RegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
)
42 static const unsigned CalleeSavedRegs
[] = {
45 return CalleeSavedRegs
;
48 const TargetRegisterClass
* const*
49 IA64RegisterInfo::getCalleeSavedRegClasses(const MachineFunction
*MF
) const {
50 static const TargetRegisterClass
* const CalleeSavedRegClasses
[] = {
53 return CalleeSavedRegClasses
;
56 BitVector
IA64RegisterInfo::getReservedRegs(const MachineFunction
&MF
) const {
57 BitVector
Reserved(getNumRegs());
58 Reserved
.set(IA64::r0
);
59 Reserved
.set(IA64::r1
);
60 Reserved
.set(IA64::r2
);
61 Reserved
.set(IA64::r5
);
62 Reserved
.set(IA64::r12
);
63 Reserved
.set(IA64::r13
);
64 Reserved
.set(IA64::r22
);
65 Reserved
.set(IA64::rp
);
69 //===----------------------------------------------------------------------===//
70 // Stack Frame Processing methods
71 //===----------------------------------------------------------------------===//
73 // hasFP - Return true if the specified function should have a dedicated frame
74 // pointer register. This is true if the function has variable sized allocas or
75 // if frame pointer elimination is disabled.
77 bool IA64RegisterInfo::hasFP(const MachineFunction
&MF
) const {
78 const MachineFrameInfo
*MFI
= MF
.getFrameInfo();
79 return NoFramePointerElim
|| MFI
->hasVarSizedObjects();
82 void IA64RegisterInfo::
83 eliminateCallFramePseudoInstr(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
84 MachineBasicBlock::iterator I
) const {
86 // If we have a frame pointer, turn the adjcallstackup instruction into a
87 // 'sub SP, <amt>' and the adjcallstackdown instruction into 'add SP,
89 MachineInstr
*Old
= I
;
90 unsigned Amount
= Old
->getOperand(0).getImm();
91 DebugLoc dl
= Old
->getDebugLoc();
93 // We need to keep the stack aligned properly. To do this, we round the
94 // amount of space needed for the outgoing arguments up to the next
95 // alignment boundary.
96 unsigned Align
= MF
.getTarget().getFrameInfo()->getStackAlignment();
97 Amount
= (Amount
+Align
-1)/Align
*Align
;
99 // Replace the pseudo instruction with a new instruction...
100 if (Old
->getOpcode() == IA64::ADJUSTCALLSTACKDOWN
) {
101 BuildMI(MBB
, I
, dl
, TII
.get(IA64::ADDIMM22
), IA64::r12
)
102 .addReg(IA64::r12
).addImm(-Amount
);
104 assert(Old
->getOpcode() == IA64::ADJUSTCALLSTACKUP
);
105 BuildMI(MBB
, I
, dl
, TII
.get(IA64::ADDIMM22
), IA64::r12
)
106 .addReg(IA64::r12
).addImm(Amount
);
114 void IA64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II
,
115 int SPAdj
, RegScavenger
*RS
)const{
116 assert(SPAdj
== 0 && "Unexpected");
119 MachineInstr
&MI
= *II
;
120 MachineBasicBlock
&MBB
= *MI
.getParent();
121 MachineFunction
&MF
= *MBB
.getParent();
122 DebugLoc dl
= MI
.getDebugLoc();
126 while (!MI
.getOperand(i
).isFI()) {
128 assert(i
< MI
.getNumOperands() && "Instr doesn't have FrameIndex operand!");
131 int FrameIndex
= MI
.getOperand(i
).getIndex();
133 // choose a base register: ( hasFP? framepointer : stack pointer )
134 unsigned BaseRegister
= FP
? IA64::r5
: IA64::r12
;
135 // Add the base register
136 MI
.getOperand(i
).ChangeToRegister(BaseRegister
, false);
138 // Now add the frame object offset to the offset from r1.
139 int Offset
= MF
.getFrameInfo()->getObjectOffset(FrameIndex
);
141 // If we're not using a Frame Pointer that has been set to the value of the
142 // SP before having the stack size subtracted from it, then add the stack size
143 // to Offset to get the correct offset.
144 Offset
+= MF
.getFrameInfo()->getStackSize();
146 // XXX: we use 'r22' as another hack+slash temporary register here :(
147 if (Offset
<= 8191 && Offset
>= -8192) { // smallish offset
149 MI
.getOperand(i
).ChangeToRegister(IA64::r22
, false);
151 BuildMI(MBB
, II
, dl
, TII
.get(IA64::ADDIMM22
), IA64::r22
)
152 .addReg(BaseRegister
).addImm(Offset
);
155 MI
.getOperand(i
).ChangeToRegister(IA64::r22
, false);
156 BuildMI(MBB
, II
, dl
, TII
.get(IA64::MOVLIMM64
), IA64::r22
).addImm(Offset
);
157 BuildMI(MBB
, II
, dl
, TII
.get(IA64::ADD
), IA64::r22
).addReg(BaseRegister
)
163 void IA64RegisterInfo::emitPrologue(MachineFunction
&MF
) const {
164 MachineBasicBlock
&MBB
= MF
.front(); // Prolog goes in entry BB
165 MachineBasicBlock::iterator MBBI
= MBB
.begin();
166 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
168 DebugLoc dl
= (MBBI
!= MBB
.end() ?
169 MBBI
->getDebugLoc() : DebugLoc::getUnknownLoc());
171 // first, we handle the 'alloc' instruction, that should be right up the
172 // top of any function
173 static const unsigned RegsInOrder
[96] = { // there are 96 GPRs the
175 IA64::r32
, IA64::r33
, IA64::r34
, IA64::r35
,
176 IA64::r36
, IA64::r37
, IA64::r38
, IA64::r39
, IA64::r40
, IA64::r41
,
177 IA64::r42
, IA64::r43
, IA64::r44
, IA64::r45
, IA64::r46
, IA64::r47
,
178 IA64::r48
, IA64::r49
, IA64::r50
, IA64::r51
, IA64::r52
, IA64::r53
,
179 IA64::r54
, IA64::r55
, IA64::r56
, IA64::r57
, IA64::r58
, IA64::r59
,
180 IA64::r60
, IA64::r61
, IA64::r62
, IA64::r63
, IA64::r64
, IA64::r65
,
181 IA64::r66
, IA64::r67
, IA64::r68
, IA64::r69
, IA64::r70
, IA64::r71
,
182 IA64::r72
, IA64::r73
, IA64::r74
, IA64::r75
, IA64::r76
, IA64::r77
,
183 IA64::r78
, IA64::r79
, IA64::r80
, IA64::r81
, IA64::r82
, IA64::r83
,
184 IA64::r84
, IA64::r85
, IA64::r86
, IA64::r87
, IA64::r88
, IA64::r89
,
185 IA64::r90
, IA64::r91
, IA64::r92
, IA64::r93
, IA64::r94
, IA64::r95
,
186 IA64::r96
, IA64::r97
, IA64::r98
, IA64::r99
, IA64::r100
, IA64::r101
,
187 IA64::r102
, IA64::r103
, IA64::r104
, IA64::r105
, IA64::r106
, IA64::r107
,
188 IA64::r108
, IA64::r109
, IA64::r110
, IA64::r111
, IA64::r112
, IA64::r113
,
189 IA64::r114
, IA64::r115
, IA64::r116
, IA64::r117
, IA64::r118
, IA64::r119
,
190 IA64::r120
, IA64::r121
, IA64::r122
, IA64::r123
, IA64::r124
, IA64::r125
,
191 IA64::r126
, IA64::r127
};
193 unsigned numStackedGPRsUsed
=0;
194 for (int i
=0; i
!= 96; i
++) {
195 if (MF
.getRegInfo().isPhysRegUsed(RegsInOrder
[i
]))
196 numStackedGPRsUsed
=i
+1; // (i+1 and not ++ - consider fn(fp, fp, int)
199 unsigned numOutRegsUsed
=MF
.getInfo
<IA64FunctionInfo
>()->outRegsUsed
;
201 // XXX FIXME : this code should be a bit more reliable (in case there _isn't_
202 // a pseudo_alloc in the MBB)
203 unsigned dstRegOfPseudoAlloc
;
204 for(MBBI
= MBB
.begin(); /*MBBI->getOpcode() != IA64::PSEUDO_ALLOC*/; ++MBBI
) {
205 assert(MBBI
!= MBB
.end());
206 if(MBBI
->getOpcode() == IA64::PSEUDO_ALLOC
) {
207 dstRegOfPseudoAlloc
=MBBI
->getOperand(0).getReg();
212 if (MBBI
!= MBB
.end()) dl
= MBBI
->getDebugLoc();
214 BuildMI(MBB
, MBBI
, dl
, TII
.get(IA64::ALLOC
)).
215 addReg(dstRegOfPseudoAlloc
).addImm(0).
216 addImm(numStackedGPRsUsed
).addImm(numOutRegsUsed
).addImm(0);
218 // Get the number of bytes to allocate from the FrameInfo
219 unsigned NumBytes
= MFI
->getStackSize();
222 NumBytes
+= 8; // reserve space for the old FP
224 // Do we need to allocate space on the stack?
228 // Add 16 bytes at the bottom of the stack (scratch area)
229 // and round the size to a multiple of the alignment.
230 unsigned Align
= MF
.getTarget().getFrameInfo()->getStackAlignment();
231 unsigned Size
= 16 + (FP
? 8 : 0);
232 NumBytes
= (NumBytes
+Size
+Align
-1)/Align
*Align
;
234 // Update frame info to pretend that this is part of the stack...
235 MFI
->setStackSize(NumBytes
);
237 // adjust stack pointer: r12 -= numbytes
238 if (NumBytes
<= 8191) {
239 BuildMI(MBB
, MBBI
, dl
, TII
.get(IA64::ADDIMM22
),IA64::r12
).addReg(IA64::r12
).
241 } else { // we use r22 as a scratch register here
242 // first load the decrement into r22
243 BuildMI(MBB
, MBBI
, dl
, TII
.get(IA64::MOVLIMM64
), IA64::r22
).
245 // FIXME: MOVLSI32 expects a _u_32imm
246 // then add (subtract) it to r12 (stack ptr)
247 BuildMI(MBB
, MBBI
, dl
, TII
.get(IA64::ADD
), IA64::r12
)
248 .addReg(IA64::r12
).addReg(IA64::r22
);
252 // now if we need to, save the old FP and set the new
254 BuildMI(MBB
, MBBI
,dl
,TII
.get(IA64::ST8
)).addReg(IA64::r12
).addReg(IA64::r5
);
255 // this must be the last instr in the prolog ? (XXX: why??)
256 BuildMI(MBB
, MBBI
, dl
, TII
.get(IA64::MOV
), IA64::r5
).addReg(IA64::r12
);
261 void IA64RegisterInfo::emitEpilogue(MachineFunction
&MF
,
262 MachineBasicBlock
&MBB
) const {
263 const MachineFrameInfo
*MFI
= MF
.getFrameInfo();
264 MachineBasicBlock::iterator MBBI
= prior(MBB
.end());
265 assert(MBBI
->getOpcode() == IA64::RET
&&
266 "Can only insert epilog into returning blocks");
267 DebugLoc dl
= MBBI
->getDebugLoc();
270 // Get the number of bytes allocated from the FrameInfo...
271 unsigned NumBytes
= MFI
->getStackSize();
273 //now if we need to, restore the old FP
275 //copy the FP into the SP (discards allocas)
276 BuildMI(MBB
, MBBI
, dl
, TII
.get(IA64::MOV
), IA64::r12
).addReg(IA64::r5
);
278 BuildMI(MBB
, MBBI
, dl
, TII
.get(IA64::LD8
), IA64::r5
).addReg(IA64::r5
);
282 if (NumBytes
<= 8191) {
283 BuildMI(MBB
, MBBI
, dl
, TII
.get(IA64::ADDIMM22
),IA64::r12
).
284 addReg(IA64::r12
).addImm(NumBytes
);
286 BuildMI(MBB
, MBBI
, dl
, TII
.get(IA64::MOVLIMM64
), IA64::r22
).
288 BuildMI(MBB
, MBBI
, dl
, TII
.get(IA64::ADD
), IA64::r12
).addReg(IA64::r12
).
294 unsigned IA64RegisterInfo::getRARegister() const {
295 assert(0 && "What is the return address register");
299 unsigned IA64RegisterInfo::getFrameRegister(MachineFunction
&MF
) const {
300 return hasFP(MF
) ? IA64::r5
: IA64::r12
;
303 unsigned IA64RegisterInfo::getEHExceptionRegister() const {
304 assert(0 && "What is the exception register");
308 unsigned IA64RegisterInfo::getEHHandlerRegister() const {
309 assert(0 && "What is the exception handler register");
313 int IA64RegisterInfo::getDwarfRegNum(unsigned RegNum
, bool isEH
) const {
314 assert(0 && "What is the dwarf register number");
318 #include "IA64GenRegisterInfo.inc"