Use TableGen to emit information for dwarf register numbers.
[oota-llvm.git] / lib / Target / Alpha / AlphaRegisterInfo.cpp
1 //===- AlphaRegisterInfo.cpp - Alpha Register Information -------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the Alpha implementation of the MRegisterInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "reginfo"
15 #include "Alpha.h"
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"
33 #include <cstdlib>
34 using namespace llvm;
35
36 //These describe LDAx
37 static const int IMM_LOW  = -32768;
38 static const int IMM_HIGH = 32767;
39 static const int IMM_MULT = 65536;
40
41 static long getUpper16(long l)
42 {
43   long y = l / IMM_MULT;
44   if (l % IMM_MULT > IMM_HIGH)
45     ++y;
46   return y;
47 }
48
49 static long getLower16(long l)
50 {
51   long h = getUpper16(l);
52   return l - h * IMM_MULT;
53 }
54
55 AlphaRegisterInfo::AlphaRegisterInfo(const TargetInstrInfo &tii)
56   : AlphaGenRegisterInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP),
57     TII(tii)
58 {
59 }
60
61 void
62 AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
63                                        MachineBasicBlock::iterator MI,
64                                        unsigned SrcReg, int FrameIdx,
65                                        const TargetRegisterClass *RC) const {
66   //cerr << "Trying to store " << getPrettyName(SrcReg) << " to "
67   //     << FrameIdx << "\n";
68   //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg);
69   if (RC == Alpha::F4RCRegisterClass)
70     BuildMI(MBB, MI, TII.get(Alpha::STS))
71       .addReg(SrcReg, false, false, true)
72       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
73   else if (RC == Alpha::F8RCRegisterClass)
74     BuildMI(MBB, MI, TII.get(Alpha::STT))
75       .addReg(SrcReg, false, false, true)
76       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
77   else if (RC == Alpha::GPRCRegisterClass)
78     BuildMI(MBB, MI, TII.get(Alpha::STQ))
79       .addReg(SrcReg, false, false, true)
80       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
81   else
82     abort();
83 }
84
85 void AlphaRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
86                                        SmallVectorImpl<MachineOperand> &Addr,
87                                        const TargetRegisterClass *RC,
88                                  SmallVectorImpl<MachineInstr*> &NewMIs) const {
89   unsigned Opc = 0;
90   if (RC == Alpha::F4RCRegisterClass)
91     Opc = Alpha::STS;
92   else if (RC == Alpha::F8RCRegisterClass)
93     Opc = Alpha::STT;
94   else if (RC == Alpha::GPRCRegisterClass)
95     Opc = Alpha::STQ;
96   else
97     abort();
98   MachineInstrBuilder MIB = 
99     BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, true);
100   for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
101     MachineOperand &MO = Addr[i];
102     if (MO.isRegister())
103       MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit());
104     else
105       MIB.addImm(MO.getImm());
106   }
107   NewMIs.push_back(MIB);
108 }
109
110 void
111 AlphaRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
112                                         MachineBasicBlock::iterator MI,
113                                         unsigned DestReg, int FrameIdx,
114                                         const TargetRegisterClass *RC) const {
115   //cerr << "Trying to load " << getPrettyName(DestReg) << " to "
116   //     << FrameIdx << "\n";
117   if (RC == Alpha::F4RCRegisterClass)
118     BuildMI(MBB, MI, TII.get(Alpha::LDS), DestReg)
119       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
120   else if (RC == Alpha::F8RCRegisterClass)
121     BuildMI(MBB, MI, TII.get(Alpha::LDT), DestReg)
122       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
123   else if (RC == Alpha::GPRCRegisterClass)
124     BuildMI(MBB, MI, TII.get(Alpha::LDQ), DestReg)
125       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
126   else
127     abort();
128 }
129
130 void AlphaRegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
131                                         SmallVectorImpl<MachineOperand> &Addr,
132                                         const TargetRegisterClass *RC,
133                                  SmallVectorImpl<MachineInstr*> &NewMIs) const {
134   unsigned Opc = 0;
135   if (RC == Alpha::F4RCRegisterClass)
136     Opc = Alpha::LDS;
137   else if (RC == Alpha::F8RCRegisterClass)
138     Opc = Alpha::LDT;
139   else if (RC == Alpha::GPRCRegisterClass)
140     Opc = Alpha::LDQ;
141   else
142     abort();
143   MachineInstrBuilder MIB = 
144     BuildMI(TII.get(Opc), DestReg);
145   for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
146     MachineOperand &MO = Addr[i];
147     if (MO.isRegister())
148       MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit());
149     else
150       MIB.addImm(MO.getImm());
151   }
152   NewMIs.push_back(MIB);
153 }
154
155 MachineInstr *AlphaRegisterInfo::foldMemoryOperand(MachineInstr *MI,
156                                                  unsigned OpNum,
157                                                  int FrameIndex) const {
158    // Make sure this is a reg-reg copy.
159    unsigned Opc = MI->getOpcode();
160
161    MachineInstr *NewMI = NULL;
162    switch(Opc) {
163    default:
164      break;
165    case Alpha::BISr:
166    case Alpha::CPYSS:
167    case Alpha::CPYST:
168      if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
169        if (OpNum == 0) {  // move -> store
170          unsigned InReg = MI->getOperand(1).getReg();
171          Opc = (Opc == Alpha::BISr) ? Alpha::STQ : 
172            ((Opc == Alpha::CPYSS) ? Alpha::STS : Alpha::STT);
173          NewMI = BuildMI(TII.get(Opc)).addReg(InReg).addFrameIndex(FrameIndex)
174            .addReg(Alpha::F31);
175        } else {           // load -> move
176          unsigned OutReg = MI->getOperand(0).getReg();
177          Opc = (Opc == Alpha::BISr) ? Alpha::LDQ : 
178            ((Opc == Alpha::CPYSS) ? Alpha::LDS : Alpha::LDT);
179          NewMI = BuildMI(TII.get(Opc), OutReg).addFrameIndex(FrameIndex)
180            .addReg(Alpha::F31);
181        }
182      }
183      break;
184    }
185   if (NewMI)
186     NewMI->copyKillDeadInfo(MI);
187   return 0;
188 }
189
190
191 void AlphaRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
192                                      MachineBasicBlock::iterator MI,
193                                      unsigned DestReg, unsigned SrcReg,
194                                      const TargetRegisterClass *DestRC,
195                                      const TargetRegisterClass *SrcRC) const {
196   //cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n";
197   if (DestRC != SrcRC) {
198     cerr << "Not yet supported!";
199     abort();
200   }
201
202   if (DestRC == Alpha::GPRCRegisterClass) {
203     BuildMI(MBB, MI, TII.get(Alpha::BISr), DestReg).addReg(SrcReg).addReg(SrcReg);
204   } else if (DestRC == Alpha::F4RCRegisterClass) {
205     BuildMI(MBB, MI, TII.get(Alpha::CPYSS), DestReg).addReg(SrcReg).addReg(SrcReg);
206   } else if (DestRC == Alpha::F8RCRegisterClass) {
207     BuildMI(MBB, MI, TII.get(Alpha::CPYST), DestReg).addReg(SrcReg).addReg(SrcReg);
208   } else {
209     cerr << "Attempt to copy register that is not GPR or FPR";
210     abort();
211   }
212 }
213
214 void AlphaRegisterInfo::reMaterialize(MachineBasicBlock &MBB,
215                                       MachineBasicBlock::iterator I,
216                                       unsigned DestReg,
217                                       const MachineInstr *Orig) const {
218   MachineInstr *MI = Orig->clone();
219   MI->getOperand(0).setReg(DestReg);
220   MBB.insert(I, MI);
221 }
222
223 const unsigned* AlphaRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
224                                                                          const {
225   static const unsigned CalleeSavedRegs[] = {
226     Alpha::R9, Alpha::R10,
227     Alpha::R11, Alpha::R12,
228     Alpha::R13, Alpha::R14,
229     Alpha::F2, Alpha::F3,
230     Alpha::F4, Alpha::F5,
231     Alpha::F6, Alpha::F7,
232     Alpha::F8, Alpha::F9,  0
233   };
234   return CalleeSavedRegs;
235 }
236
237 const TargetRegisterClass* const*
238 AlphaRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
239   static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
240     &Alpha::GPRCRegClass, &Alpha::GPRCRegClass,
241     &Alpha::GPRCRegClass, &Alpha::GPRCRegClass,
242     &Alpha::GPRCRegClass, &Alpha::GPRCRegClass,
243     &Alpha::F8RCRegClass, &Alpha::F8RCRegClass,
244     &Alpha::F8RCRegClass, &Alpha::F8RCRegClass,
245     &Alpha::F8RCRegClass, &Alpha::F8RCRegClass,
246     &Alpha::F8RCRegClass, &Alpha::F8RCRegClass,  0
247   };
248   return CalleeSavedRegClasses;
249 }
250
251 BitVector AlphaRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
252   BitVector Reserved(getNumRegs());
253   Reserved.set(Alpha::R15);
254   Reserved.set(Alpha::R30);
255   Reserved.set(Alpha::R31);
256   return Reserved;
257 }
258
259 //===----------------------------------------------------------------------===//
260 // Stack Frame Processing methods
261 //===----------------------------------------------------------------------===//
262
263 // hasFP - Return true if the specified function should have a dedicated frame
264 // pointer register.  This is true if the function has variable sized allocas or
265 // if frame pointer elimination is disabled.
266 //
267 bool AlphaRegisterInfo::hasFP(const MachineFunction &MF) const {
268   MachineFrameInfo *MFI = MF.getFrameInfo();
269   return MFI->hasVarSizedObjects();
270 }
271
272 void AlphaRegisterInfo::
273 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
274                               MachineBasicBlock::iterator I) const {
275   if (hasFP(MF)) {
276     // If we have a frame pointer, turn the adjcallstackup instruction into a
277     // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP,
278     // <amt>'
279     MachineInstr *Old = I;
280     uint64_t Amount = Old->getOperand(0).getImmedValue();
281     if (Amount != 0) {
282       // We need to keep the stack aligned properly.  To do this, we round the
283       // amount of space needed for the outgoing arguments up to the next
284       // alignment boundary.
285       unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
286       Amount = (Amount+Align-1)/Align*Align;
287
288       MachineInstr *New;
289       if (Old->getOpcode() == Alpha::ADJUSTSTACKDOWN) {
290         New=BuildMI(TII.get(Alpha::LDA), Alpha::R30)
291           .addImm(-Amount).addReg(Alpha::R30);
292       } else {
293          assert(Old->getOpcode() == Alpha::ADJUSTSTACKUP);
294          New=BuildMI(TII.get(Alpha::LDA), Alpha::R30)
295           .addImm(Amount).addReg(Alpha::R30);
296       }
297
298       // Replace the pseudo instruction with a new instruction...
299       MBB.insert(I, New);
300     }
301   }
302
303   MBB.erase(I);
304 }
305
306 //Alpha has a slightly funny stack:
307 //Args
308 //<- incoming SP
309 //fixed locals (and spills, callee saved, etc)
310 //<- FP
311 //variable locals
312 //<- SP
313
314 void AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
315                                             int SPAdj, RegScavenger *RS) const {
316   assert(SPAdj == 0 && "Unexpected");
317
318   unsigned i = 0;
319   MachineInstr &MI = *II;
320   MachineBasicBlock &MBB = *MI.getParent();
321   MachineFunction &MF = *MBB.getParent();
322   bool FP = hasFP(MF);
323
324   while (!MI.getOperand(i).isFrameIndex()) {
325     ++i;
326     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
327   }
328
329   int FrameIndex = MI.getOperand(i).getFrameIndex();
330
331   // Add the base register of R30 (SP) or R15 (FP).
332   MI.getOperand(i + 1).ChangeToRegister(FP ? Alpha::R15 : Alpha::R30, false);
333
334   // Now add the frame object offset to the offset from the virtual frame index.
335   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
336
337   DOUT << "FI: " << FrameIndex << " Offset: " << Offset << "\n";
338
339   Offset += MF.getFrameInfo()->getStackSize();
340
341   DOUT << "Corrected Offset " << Offset
342        << " for stack size: " << MF.getFrameInfo()->getStackSize() << "\n";
343
344   if (Offset > IMM_HIGH || Offset < IMM_LOW) {
345     DOUT << "Unconditionally using R28 for evil purposes Offset: "
346          << Offset << "\n";
347     //so in this case, we need to use a temporary register, and move the
348     //original inst off the SP/FP
349     //fix up the old:
350     MI.getOperand(i + 1).ChangeToRegister(Alpha::R28, false);
351     MI.getOperand(i).ChangeToImmediate(getLower16(Offset));
352     //insert the new
353     MachineInstr* nMI=BuildMI(TII.get(Alpha::LDAH), Alpha::R28)
354       .addImm(getUpper16(Offset)).addReg(FP ? Alpha::R15 : Alpha::R30);
355     MBB.insert(II, nMI);
356   } else {
357     MI.getOperand(i).ChangeToImmediate(Offset);
358   }
359 }
360
361
362 void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const {
363   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
364   MachineBasicBlock::iterator MBBI = MBB.begin();
365   MachineFrameInfo *MFI = MF.getFrameInfo();
366   bool FP = hasFP(MF);
367
368   static int curgpdist = 0;
369
370   //handle GOP offset
371   BuildMI(MBB, MBBI, TII.get(Alpha::LDAHg), Alpha::R29)
372     .addGlobalAddress(const_cast<Function*>(MF.getFunction()))
373     .addReg(Alpha::R27).addImm(++curgpdist);
374   BuildMI(MBB, MBBI, TII.get(Alpha::LDAg), Alpha::R29)
375     .addGlobalAddress(const_cast<Function*>(MF.getFunction()))
376     .addReg(Alpha::R29).addImm(curgpdist);
377
378   //evil const_cast until MO stuff setup to handle const
379   BuildMI(MBB, MBBI, TII.get(Alpha::ALTENT))
380     .addGlobalAddress(const_cast<Function*>(MF.getFunction()));
381
382   // Get the number of bytes to allocate from the FrameInfo
383   long NumBytes = MFI->getStackSize();
384
385   if (FP)
386     NumBytes += 8; //reserve space for the old FP
387
388   // Do we need to allocate space on the stack?
389   if (NumBytes == 0) return;
390
391   unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
392   NumBytes = (NumBytes+Align-1)/Align*Align;
393
394   // Update frame info to pretend that this is part of the stack...
395   MFI->setStackSize(NumBytes);
396
397   // adjust stack pointer: r30 -= numbytes
398   NumBytes = -NumBytes;
399   if (NumBytes >= IMM_LOW) {
400     BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes)
401       .addReg(Alpha::R30);
402   } else if (getUpper16(NumBytes) >= IMM_LOW) {
403     BuildMI(MBB, MBBI, TII.get(Alpha::LDAH), Alpha::R30).addImm(getUpper16(NumBytes))
404       .addReg(Alpha::R30);
405     BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30).addImm(getLower16(NumBytes))
406       .addReg(Alpha::R30);
407   } else {
408     cerr << "Too big a stack frame at " << NumBytes << "\n";
409     abort();
410   }
411
412   //now if we need to, save the old FP and set the new
413   if (FP)
414   {
415     BuildMI(MBB, MBBI, TII.get(Alpha::STQ))
416       .addReg(Alpha::R15).addImm(0).addReg(Alpha::R30);
417     //this must be the last instr in the prolog
418     BuildMI(MBB, MBBI, TII.get(Alpha::BISr), Alpha::R15)
419       .addReg(Alpha::R30).addReg(Alpha::R30);
420   }
421
422 }
423
424 void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF,
425                                      MachineBasicBlock &MBB) const {
426   const MachineFrameInfo *MFI = MF.getFrameInfo();
427   MachineBasicBlock::iterator MBBI = prior(MBB.end());
428   assert(MBBI->getOpcode() == Alpha::RETDAG ||
429          MBBI->getOpcode() == Alpha::RETDAGp
430          && "Can only insert epilog into returning blocks");
431
432   bool FP = hasFP(MF);
433
434   // Get the number of bytes allocated from the FrameInfo...
435   long NumBytes = MFI->getStackSize();
436
437   //now if we need to, restore the old FP
438   if (FP)
439   {
440     //copy the FP into the SP (discards allocas)
441     BuildMI(MBB, MBBI, TII.get(Alpha::BISr), Alpha::R30).addReg(Alpha::R15)
442       .addReg(Alpha::R15);
443     //restore the FP
444     BuildMI(MBB, MBBI, TII.get(Alpha::LDQ), Alpha::R15).addImm(0).addReg(Alpha::R15);
445   }
446
447    if (NumBytes != 0)
448      {
449        if (NumBytes <= IMM_HIGH) {
450          BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes)
451            .addReg(Alpha::R30);
452        } else if (getUpper16(NumBytes) <= IMM_HIGH) {
453          BuildMI(MBB, MBBI, TII.get(Alpha::LDAH), Alpha::R30)
454            .addImm(getUpper16(NumBytes)).addReg(Alpha::R30);
455          BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30)
456            .addImm(getLower16(NumBytes)).addReg(Alpha::R30);
457        } else {
458          cerr << "Too big a stack frame at " << NumBytes << "\n";
459          abort();
460        }
461      }
462 }
463
464 unsigned AlphaRegisterInfo::getRARegister() const {
465   assert(0 && "What is the return address register");
466   return 0;
467 }
468
469 unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const {
470   return hasFP(MF) ? Alpha::R15 : Alpha::R30;
471 }
472
473 unsigned AlphaRegisterInfo::getEHExceptionRegister() const {
474   assert(0 && "What is the exception register");
475   return 0;
476 }
477
478 unsigned AlphaRegisterInfo::getEHHandlerRegister() const {
479   assert(0 && "What is the exception handler register");
480   return 0;
481 }
482
483 int AlphaRegisterInfo::getDwarfRegNum(unsigned RegNum) const {
484   assert(0 && "What is the dwarf register number");
485   return -1;
486 }
487
488 #include "AlphaGenRegisterInfo.inc"
489
490 std::string AlphaRegisterInfo::getPrettyName(unsigned reg)
491 {
492   std::string s(RegisterDescriptors[reg].Name);
493   return s;
494 }