Clean ups, and taught the instruction selector about immediate forms
[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 "AlphaInstrBuilder.h"
17 #include "AlphaRegisterInfo.h"
18 #include "llvm/Constants.h"
19 #include "llvm/Type.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/Target/TargetFrameInfo.h"
25 #include "llvm/Target/TargetMachine.h"
26 #include "llvm/Target/TargetOptions.h"
27 #include "llvm/Support/CommandLine.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/ADT/STLExtras.h"
30 #include <cstdlib>
31 #include <iostream>
32 using namespace llvm;
33
34
35 AlphaRegisterInfo::AlphaRegisterInfo()
36   : AlphaGenRegisterInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP)
37 {
38 }
39
40 static const TargetRegisterClass *getClass(unsigned SrcReg) {
41   if (Alpha::FPRCRegisterClass->contains(SrcReg))
42     return Alpha::FPRCRegisterClass;
43   assert(Alpha::GPRCRegisterClass->contains(SrcReg) && "Reg not FPR or GPR");
44   return Alpha::GPRCRegisterClass;
45 }
46
47 void 
48 AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
49                                        MachineBasicBlock::iterator MI,
50                                        unsigned SrcReg, int FrameIdx) const {
51   std::cerr << "Trying to store " << getPrettyName(SrcReg) << " to " << FrameIdx << "\n";
52   //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg);
53   BuildMI(MBB, MI, Alpha::STQ, 3).addReg(SrcReg).addImm(FrameIdx * 8).addReg(Alpha::R30);
54   //  assert(0 && "TODO");
55 }
56
57 void
58 AlphaRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
59                                         MachineBasicBlock::iterator MI,
60                                         unsigned DestReg, int FrameIdx) const{
61   std::cerr << "Trying to load " << getPrettyName(DestReg) << " to " << FrameIdx << "\n";
62   //BuildMI(MBB, MI, Alpha::WTF, 0, DestReg);
63   BuildMI(MBB, MI, Alpha::LDQ, 2, DestReg).addImm(FrameIdx * 8).addReg(Alpha::R30);
64   //  assert(0 && "TODO");
65 }
66
67 void AlphaRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
68                                      MachineBasicBlock::iterator MI,
69                                      unsigned DestReg, unsigned SrcReg,
70                                      const TargetRegisterClass *RC) const {
71   //  std::cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n";
72   if (RC == Alpha::GPRCRegisterClass) {
73     BuildMI(MBB, MI, Alpha::BIS, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
74 //   } else if (RC == Alpha::FPRCRegisterClass) {
75 //     BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg);
76   } else { 
77     std::cerr << "Attempt to copy register that is not GPR or FPR";
78      abort();
79   }
80 }
81
82 //===----------------------------------------------------------------------===//
83 // Stack Frame Processing methods
84 //===----------------------------------------------------------------------===//
85
86 // hasFP - Return true if the specified function should have a dedicated frame
87 // pointer register.  This is true if the function has variable sized allocas or
88 // if frame pointer elimination is disabled.
89 //
90 static bool hasFP(MachineFunction &MF) {
91   MachineFrameInfo *MFI = MF.getFrameInfo();
92   return MFI->hasVarSizedObjects();
93 }
94
95 void AlphaRegisterInfo::
96 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
97                               MachineBasicBlock::iterator I) const {
98   if (hasFP(MF)) {
99     assert(0 && "TODO");
100     // If we have a frame pointer, turn the adjcallstackup instruction into a
101     // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP,
102     // <amt>'
103     MachineInstr *Old = I;
104     unsigned Amount = Old->getOperand(0).getImmedValue();
105     if (Amount != 0) {
106       // We need to keep the stack aligned properly.  To do this, we round the
107       // amount of space needed for the outgoing arguments up to the next
108       // alignment boundary.
109       unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
110       Amount = (Amount+Align-1)/Align*Align;
111
112       MachineInstr *New;
113 //       if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) {
114 //      New=BuildMI(X86::SUB32ri, 1, X86::ESP, MachineOperand::UseAndDef)
115 //               .addZImm(Amount);
116 //       } else {
117 //      assert(Old->getOpcode() == X86::ADJCALLSTACKUP);
118 //      New=BuildMI(X86::ADD32ri, 1, X86::ESP, MachineOperand::UseAndDef)
119 //               .addZImm(Amount);
120 //       }
121
122       // Replace the pseudo instruction with a new instruction...
123       MBB.insert(I, New);
124     }
125   }
126
127   MBB.erase(I);
128 }
129
130 void
131 AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
132   assert(0 && "TODO");
133 //   unsigned i = 0;
134 //   MachineInstr &MI = *II;
135 //   MachineBasicBlock &MBB = *MI.getParent();
136 //   MachineFunction &MF = *MBB.getParent();
137   
138 //   while (!MI.getOperand(i).isFrameIndex()) {
139 //     ++i;
140 //     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
141 //   }
142
143 //   int FrameIndex = MI.getOperand(i).getFrameIndex();
144
145 //   // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
146 //   MI.SetMachineOperandReg(i, hasFP(MF) ? PPC::R31 : PPC::R1);
147
148 //   // Take into account whether it's an add or mem instruction
149 //   unsigned OffIdx = (i == 2) ? 1 : 2;
150
151 //   // Now add the frame object offset to the offset from r1.
152 //   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
153 //                MI.getOperand(OffIdx).getImmedValue();
154
155 //   // If we're not using a Frame Pointer that has been set to the value of the
156 //   // SP before having the stack size subtracted from it, then add the stack size
157 //   // to Offset to get the correct offset.
158 //   Offset += MF.getFrameInfo()->getStackSize();
159   
160 //   if (Offset > 32767 || Offset < -32768) {
161 //     // Insert a set of r0 with the full offset value before the ld, st, or add
162 //     MachineBasicBlock *MBB = MI.getParent();
163 //     MBB->insert(II, BuildMI(PPC::LIS, 1, PPC::R0).addSImm(Offset >> 16));
164 //     MBB->insert(II, BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0)
165 //       .addImm(Offset));
166 //     // convert into indexed form of the instruction
167 //     // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
168 //     // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
169 //     unsigned NewOpcode = 
170 //       const_cast<std::map<unsigned, unsigned>& >(ImmToIdxMap)[MI.getOpcode()];
171 //     assert(NewOpcode && "No indexed form of load or store available!");
172 //     MI.setOpcode(NewOpcode);
173 //     MI.SetMachineOperandReg(1, MI.getOperand(i).getReg());
174 //     MI.SetMachineOperandReg(2, PPC::R0);
175 //   } else {
176 //     MI.SetMachineOperandConst(OffIdx, MachineOperand::MO_SignExtendedImmed,
177 //                               Offset);
178 //   }
179 }
180
181
182 void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const {
183   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
184   MachineBasicBlock::iterator MBBI = MBB.begin();
185   MachineFrameInfo *MFI = MF.getFrameInfo();
186   MachineInstr *MI;
187   
188   //handle GOP offset
189   MI = BuildMI(Alpha::LDGP, 0);
190   MBB.insert(MBBI, MI);
191
192   // Get the number of bytes to allocate from the FrameInfo
193   unsigned NumBytes = MFI->getStackSize();
194
195   // Do we need to allocate space on the stack?
196   if (NumBytes == 0) return;
197
198   // Add the size of R30 to  NumBytes size for the store of R30 to the 
199   // stack
200 //   std::cerr << "Spillsize of R30 is " << getSpillSize(Alpha::R30) << "\n";
201 //   NumBytes = NumBytes + getSpillSize(Alpha::R30)/8;
202
203   // Update frame info to pretend that this is part of the stack...
204   MFI->setStackSize(NumBytes);
205   
206   // adjust stack pointer: r30 -= numbytes
207   
208   if (NumBytes <= 32000) //FIXME: do this better 
209     {
210       MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(-NumBytes).addReg(Alpha::R30);
211       MBB.insert(MBBI, MI);
212     } else {
213       std::cerr << "Too big a stack frame\n";
214       abort();
215     }
216 }
217
218 void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF,
219                                      MachineBasicBlock &MBB) const {
220   const MachineFrameInfo *MFI = MF.getFrameInfo();
221   MachineBasicBlock::iterator MBBI = prior(MBB.end());
222   MachineInstr *MI;
223   assert((MBBI->getOpcode() == Alpha::RET || MBBI->getOpcode() == Alpha::RETURN) &&
224          "Can only insert epilog into returning blocks");
225   
226   // Get the number of bytes allocated from the FrameInfo...
227   unsigned NumBytes = MFI->getStackSize();
228
229    if (NumBytes != 0) 
230      {
231        if (NumBytes <= 32000) //FIXME: do this better 
232          {
233            MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(NumBytes).addReg(Alpha::R30);
234            MBB.insert(MBBI, MI);
235          } else {
236            std::cerr << "Too big a stack frame\n";
237            abort();
238          }
239      }
240 }
241
242 #include "AlphaGenRegisterInfo.inc"
243
244 const TargetRegisterClass*
245 AlphaRegisterInfo::getRegClassForType(const Type* Ty) const {
246   switch (Ty->getTypeID()) {
247     default:              assert(0 && "Invalid type to getClass!");
248     case Type::BoolTyID:
249     case Type::SByteTyID:
250     case Type::UByteTyID:
251     case Type::ShortTyID:
252     case Type::UShortTyID:
253     case Type::IntTyID:
254     case Type::UIntTyID:
255     case Type::PointerTyID:
256     case Type::LongTyID:
257     case Type::ULongTyID:  return &GPRCInstance;
258      
259   case Type::FloatTyID:
260   case Type::DoubleTyID: return &FPRCInstance;
261   }
262 }
263
264 std::string AlphaRegisterInfo::getPrettyName(unsigned reg)
265 {
266   std::string s(RegisterDescriptors[reg].Name);
267   return s;
268 }