Misha Brukman | 2a8350a | 2005-02-05 02:24:26 +0000 | [diff] [blame] | 1 | //===- AlphaRegisterInfo.cpp - Alpha Register Information -------*- C++ -*-===// |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 2 | // |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 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. |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 7 | // |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
Andrew Lenharth | 2d6f022 | 2005-01-24 19:44:07 +0000 | [diff] [blame] | 10 | // This file contains the Alpha implementation of the MRegisterInfo class. |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #define DEBUG_TYPE "reginfo" |
| 15 | #include "Alpha.h" |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 16 | #include "AlphaRegisterInfo.h" |
| 17 | #include "llvm/Constants.h" |
| 18 | #include "llvm/Type.h" |
Andrew Lenharth | c24b537 | 2005-04-13 17:17:28 +0000 | [diff] [blame] | 19 | #include "llvm/Function.h" |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 20 | #include "llvm/CodeGen/ValueTypes.h" |
| 21 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
| 22 | #include "llvm/CodeGen/MachineFunction.h" |
| 23 | #include "llvm/CodeGen/MachineFrameInfo.h" |
Jim Laskey | f1d78e8 | 2006-03-23 18:12:57 +0000 | [diff] [blame] | 24 | #include "llvm/CodeGen/MachineLocation.h" |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 25 | #include "llvm/Target/TargetFrameInfo.h" |
| 26 | #include "llvm/Target/TargetMachine.h" |
| 27 | #include "llvm/Target/TargetOptions.h" |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 28 | #include "llvm/Target/TargetInstrInfo.h" |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 29 | #include "llvm/Support/CommandLine.h" |
| 30 | #include "llvm/Support/Debug.h" |
| 31 | #include "llvm/ADT/STLExtras.h" |
| 32 | #include <cstdlib> |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 33 | using namespace llvm; |
| 34 | |
Andrew Lenharth | f69a98c | 2005-03-04 21:40:02 +0000 | [diff] [blame] | 35 | //These describe LDAx |
Andrew Lenharth | c051383 | 2005-03-29 19:24:04 +0000 | [diff] [blame] | 36 | static const int IMM_LOW = -32768; |
| 37 | static const int IMM_HIGH = 32767; |
Andrew Lenharth | 3ee6041 | 2005-03-05 15:30:33 +0000 | [diff] [blame] | 38 | static const int IMM_MULT = 65536; |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 39 | |
| 40 | static long getUpper16(long l) |
| 41 | { |
Andrew Lenharth | f69a98c | 2005-03-04 21:40:02 +0000 | [diff] [blame] | 42 | long y = l / IMM_MULT; |
| 43 | if (l % IMM_MULT > IMM_HIGH) |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 44 | ++y; |
| 45 | return y; |
| 46 | } |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 47 | |
Andrew Lenharth | f69a98c | 2005-03-04 21:40:02 +0000 | [diff] [blame] | 48 | static long getLower16(long l) |
| 49 | { |
| 50 | long h = getUpper16(l); |
| 51 | return l - h * IMM_MULT; |
| 52 | } |
| 53 | |
Evan Cheng | 7ce4578 | 2006-11-13 23:36:35 +0000 | [diff] [blame] | 54 | AlphaRegisterInfo::AlphaRegisterInfo(const TargetInstrInfo &tii) |
| 55 | : AlphaGenRegisterInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP), |
| 56 | TII(tii) |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 57 | { |
| 58 | } |
| 59 | |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 60 | void |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 61 | AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, |
| 62 | MachineBasicBlock::iterator MI, |
Chris Lattner | 97d5e64 | 2005-09-30 01:29:42 +0000 | [diff] [blame] | 63 | unsigned SrcReg, int FrameIdx, |
| 64 | const TargetRegisterClass *RC) const { |
Bill Wendling | f5da133 | 2006-12-07 22:21:48 +0000 | [diff] [blame] | 65 | //cerr << "Trying to store " << getPrettyName(SrcReg) << " to " |
| 66 | // << FrameIdx << "\n"; |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 67 | //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg); |
Andrew Lenharth | 5cefc5e | 2005-11-09 19:17:08 +0000 | [diff] [blame] | 68 | if (RC == Alpha::F4RCRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 69 | BuildMI(MBB, MI, TII.get(Alpha::STS)) |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 70 | .addReg(SrcReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); |
Andrew Lenharth | 5cefc5e | 2005-11-09 19:17:08 +0000 | [diff] [blame] | 71 | else if (RC == Alpha::F8RCRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 72 | BuildMI(MBB, MI, TII.get(Alpha::STT)) |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 73 | .addReg(SrcReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); |
Andrew Lenharth | 5cefc5e | 2005-11-09 19:17:08 +0000 | [diff] [blame] | 74 | else if (RC == Alpha::GPRCRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 75 | BuildMI(MBB, MI, TII.get(Alpha::STQ)) |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 76 | .addReg(SrcReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); |
Andrew Lenharth | 2a8fc23 | 2005-02-01 20:35:57 +0000 | [diff] [blame] | 77 | else |
| 78 | abort(); |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | void |
| 82 | AlphaRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, |
| 83 | MachineBasicBlock::iterator MI, |
Chris Lattner | 97d5e64 | 2005-09-30 01:29:42 +0000 | [diff] [blame] | 84 | unsigned DestReg, int FrameIdx, |
| 85 | const TargetRegisterClass *RC) const { |
Bill Wendling | f5da133 | 2006-12-07 22:21:48 +0000 | [diff] [blame] | 86 | //cerr << "Trying to load " << getPrettyName(DestReg) << " to " |
| 87 | // << FrameIdx << "\n"; |
Andrew Lenharth | 5cefc5e | 2005-11-09 19:17:08 +0000 | [diff] [blame] | 88 | if (RC == Alpha::F4RCRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 89 | BuildMI(MBB, MI, TII.get(Alpha::LDS), DestReg) |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 90 | .addFrameIndex(FrameIdx).addReg(Alpha::F31); |
Andrew Lenharth | 5cefc5e | 2005-11-09 19:17:08 +0000 | [diff] [blame] | 91 | else if (RC == Alpha::F8RCRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 92 | BuildMI(MBB, MI, TII.get(Alpha::LDT), DestReg) |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 93 | .addFrameIndex(FrameIdx).addReg(Alpha::F31); |
Andrew Lenharth | 5cefc5e | 2005-11-09 19:17:08 +0000 | [diff] [blame] | 94 | else if (RC == Alpha::GPRCRegisterClass) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 95 | BuildMI(MBB, MI, TII.get(Alpha::LDQ), DestReg) |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 96 | .addFrameIndex(FrameIdx).addReg(Alpha::F31); |
Andrew Lenharth | 2a8fc23 | 2005-02-01 20:35:57 +0000 | [diff] [blame] | 97 | else |
| 98 | abort(); |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 99 | } |
| 100 | |
Andrew Lenharth | 5cefc5e | 2005-11-09 19:17:08 +0000 | [diff] [blame] | 101 | MachineInstr *AlphaRegisterInfo::foldMemoryOperand(MachineInstr *MI, |
| 102 | unsigned OpNum, |
| 103 | int FrameIndex) const { |
Andrew Lenharth | 7a832da | 2006-01-01 22:13:54 +0000 | [diff] [blame] | 104 | // Make sure this is a reg-reg copy. |
| 105 | unsigned Opc = MI->getOpcode(); |
| 106 | |
Evan Cheng | 6ce7dc2 | 2006-11-15 20:58:11 +0000 | [diff] [blame] | 107 | MachineInstr *NewMI = NULL; |
Andrew Lenharth | 7a832da | 2006-01-01 22:13:54 +0000 | [diff] [blame] | 108 | switch(Opc) { |
| 109 | default: |
| 110 | break; |
Andrew Lenharth | 6bbf6b0 | 2006-10-31 23:46:56 +0000 | [diff] [blame] | 111 | case Alpha::BISr: |
Andrew Lenharth | 7a832da | 2006-01-01 22:13:54 +0000 | [diff] [blame] | 112 | case Alpha::CPYSS: |
| 113 | case Alpha::CPYST: |
| 114 | if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { |
| 115 | if (OpNum == 0) { // move -> store |
| 116 | unsigned InReg = MI->getOperand(1).getReg(); |
Andrew Lenharth | 6bbf6b0 | 2006-10-31 23:46:56 +0000 | [diff] [blame] | 117 | Opc = (Opc == Alpha::BISr) ? Alpha::STQ : |
Andrew Lenharth | 7a832da | 2006-01-01 22:13:54 +0000 | [diff] [blame] | 118 | ((Opc == Alpha::CPYSS) ? Alpha::STS : Alpha::STT); |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 119 | NewMI = BuildMI(TII.get(Opc)).addReg(InReg).addFrameIndex(FrameIndex) |
Andrew Lenharth | 7a832da | 2006-01-01 22:13:54 +0000 | [diff] [blame] | 120 | .addReg(Alpha::F31); |
| 121 | } else { // load -> move |
| 122 | unsigned OutReg = MI->getOperand(0).getReg(); |
Andrew Lenharth | 6bbf6b0 | 2006-10-31 23:46:56 +0000 | [diff] [blame] | 123 | Opc = (Opc == Alpha::BISr) ? Alpha::LDQ : |
Andrew Lenharth | 7a832da | 2006-01-01 22:13:54 +0000 | [diff] [blame] | 124 | ((Opc == Alpha::CPYSS) ? Alpha::LDS : Alpha::LDT); |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 125 | NewMI = BuildMI(TII.get(Opc), OutReg).addFrameIndex(FrameIndex) |
Andrew Lenharth | 7a832da | 2006-01-01 22:13:54 +0000 | [diff] [blame] | 126 | .addReg(Alpha::F31); |
| 127 | } |
| 128 | } |
| 129 | break; |
| 130 | } |
Evan Cheng | 6ce7dc2 | 2006-11-15 20:58:11 +0000 | [diff] [blame] | 131 | if (NewMI) |
| 132 | NewMI->copyKillDeadInfo(MI); |
Andrew Lenharth | 5cefc5e | 2005-11-09 19:17:08 +0000 | [diff] [blame] | 133 | return 0; |
| 134 | } |
| 135 | |
| 136 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 137 | void AlphaRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, |
| 138 | MachineBasicBlock::iterator MI, |
| 139 | unsigned DestReg, unsigned SrcReg, |
| 140 | const TargetRegisterClass *RC) const { |
Bill Wendling | f5da133 | 2006-12-07 22:21:48 +0000 | [diff] [blame] | 141 | //cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n"; |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 142 | if (RC == Alpha::GPRCRegisterClass) { |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 143 | BuildMI(MBB, MI, TII.get(Alpha::BISr), DestReg).addReg(SrcReg).addReg(SrcReg); |
Andrew Lenharth | 5cefc5e | 2005-11-09 19:17:08 +0000 | [diff] [blame] | 144 | } else if (RC == Alpha::F4RCRegisterClass) { |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 145 | BuildMI(MBB, MI, TII.get(Alpha::CPYSS), DestReg).addReg(SrcReg).addReg(SrcReg); |
Andrew Lenharth | 5cefc5e | 2005-11-09 19:17:08 +0000 | [diff] [blame] | 146 | } else if (RC == Alpha::F8RCRegisterClass) { |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 147 | BuildMI(MBB, MI, TII.get(Alpha::CPYST), DestReg).addReg(SrcReg).addReg(SrcReg); |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 148 | } else { |
Bill Wendling | f5da133 | 2006-12-07 22:21:48 +0000 | [diff] [blame] | 149 | cerr << "Attempt to copy register that is not GPR or FPR"; |
| 150 | abort(); |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 151 | } |
| 152 | } |
| 153 | |
Evan Cheng | c2b861d | 2007-01-02 21:33:40 +0000 | [diff] [blame^] | 154 | const unsigned* AlphaRegisterInfo::getCalleeSavedRegs() const { |
| 155 | static const unsigned CalleeSavedRegs[] = { |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 156 | Alpha::R9, Alpha::R10, |
| 157 | Alpha::R11, Alpha::R12, |
| 158 | Alpha::R13, Alpha::R14, |
| 159 | Alpha::F2, Alpha::F3, |
| 160 | Alpha::F4, Alpha::F5, |
| 161 | Alpha::F6, Alpha::F7, |
| 162 | Alpha::F8, Alpha::F9, 0 |
| 163 | }; |
Evan Cheng | c2b861d | 2007-01-02 21:33:40 +0000 | [diff] [blame^] | 164 | return CalleeSavedRegs; |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 165 | } |
| 166 | |
| 167 | const TargetRegisterClass* const* |
Evan Cheng | c2b861d | 2007-01-02 21:33:40 +0000 | [diff] [blame^] | 168 | AlphaRegisterInfo::getCalleeSavedRegClasses() const { |
| 169 | static const TargetRegisterClass * const CalleeSavedRegClasses[] = { |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 170 | &Alpha::GPRCRegClass, &Alpha::GPRCRegClass, |
| 171 | &Alpha::GPRCRegClass, &Alpha::GPRCRegClass, |
| 172 | &Alpha::GPRCRegClass, &Alpha::GPRCRegClass, |
| 173 | &Alpha::F8RCRegClass, &Alpha::F8RCRegClass, |
| 174 | &Alpha::F8RCRegClass, &Alpha::F8RCRegClass, |
| 175 | &Alpha::F8RCRegClass, &Alpha::F8RCRegClass, |
| 176 | &Alpha::F8RCRegClass, &Alpha::F8RCRegClass, 0 |
| 177 | }; |
Evan Cheng | c2b861d | 2007-01-02 21:33:40 +0000 | [diff] [blame^] | 178 | return CalleeSavedRegClasses; |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 179 | } |
| 180 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 181 | //===----------------------------------------------------------------------===// |
| 182 | // Stack Frame Processing methods |
| 183 | //===----------------------------------------------------------------------===// |
| 184 | |
| 185 | // hasFP - Return true if the specified function should have a dedicated frame |
| 186 | // pointer register. This is true if the function has variable sized allocas or |
| 187 | // if frame pointer elimination is disabled. |
| 188 | // |
Chris Lattner | 5ea64fd | 2006-08-17 22:00:08 +0000 | [diff] [blame] | 189 | static bool hasFP(const MachineFunction &MF) { |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 190 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
| 191 | return MFI->hasVarSizedObjects(); |
| 192 | } |
| 193 | |
| 194 | void AlphaRegisterInfo:: |
| 195 | eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, |
| 196 | MachineBasicBlock::iterator I) const { |
| 197 | if (hasFP(MF)) { |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 198 | // If we have a frame pointer, turn the adjcallstackup instruction into a |
| 199 | // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP, |
| 200 | // <amt>' |
| 201 | MachineInstr *Old = I; |
Andrew Lenharth | 65b889f | 2006-05-17 19:24:49 +0000 | [diff] [blame] | 202 | uint64_t Amount = Old->getOperand(0).getImmedValue(); |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 203 | if (Amount != 0) { |
| 204 | // We need to keep the stack aligned properly. To do this, we round the |
| 205 | // amount of space needed for the outgoing arguments up to the next |
| 206 | // alignment boundary. |
| 207 | unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); |
| 208 | Amount = (Amount+Align-1)/Align*Align; |
| 209 | |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 210 | MachineInstr *New; |
| 211 | if (Old->getOpcode() == Alpha::ADJUSTSTACKDOWN) { |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 212 | New=BuildMI(TII.get(Alpha::LDA), Alpha::R30) |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 213 | .addImm(-Amount).addReg(Alpha::R30); |
| 214 | } else { |
Misha Brukman | 7847fca | 2005-04-22 17:54:37 +0000 | [diff] [blame] | 215 | assert(Old->getOpcode() == Alpha::ADJUSTSTACKUP); |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 216 | New=BuildMI(TII.get(Alpha::LDA), Alpha::R30) |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 217 | .addImm(Amount).addReg(Alpha::R30); |
| 218 | } |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 219 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 220 | // Replace the pseudo instruction with a new instruction... |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 221 | MBB.insert(I, New); |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 222 | } |
| 223 | } |
| 224 | |
| 225 | MBB.erase(I); |
| 226 | } |
| 227 | |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 228 | //Alpha has a slightly funny stack: |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 229 | //Args |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 230 | //<- incoming SP |
| 231 | //fixed locals (and spills, callee saved, etc) |
| 232 | //<- FP |
| 233 | //variable locals |
| 234 | //<- SP |
| 235 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 236 | void |
| 237 | AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { |
Andrew Lenharth | 684f229 | 2005-01-30 00:35:27 +0000 | [diff] [blame] | 238 | unsigned i = 0; |
| 239 | MachineInstr &MI = *II; |
| 240 | MachineBasicBlock &MBB = *MI.getParent(); |
| 241 | MachineFunction &MF = *MBB.getParent(); |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 242 | bool FP = hasFP(MF); |
| 243 | |
Andrew Lenharth | 684f229 | 2005-01-30 00:35:27 +0000 | [diff] [blame] | 244 | while (!MI.getOperand(i).isFrameIndex()) { |
| 245 | ++i; |
| 246 | assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); |
| 247 | } |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 248 | |
Andrew Lenharth | 684f229 | 2005-01-30 00:35:27 +0000 | [diff] [blame] | 249 | int FrameIndex = MI.getOperand(i).getFrameIndex(); |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 250 | |
Andrew Lenharth | 684f229 | 2005-01-30 00:35:27 +0000 | [diff] [blame] | 251 | // Add the base register of R30 (SP) or R15 (FP). |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 252 | MI.getOperand(i + 1).ChangeToRegister(FP ? Alpha::R15 : Alpha::R30, false); |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 253 | |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 254 | // Now add the frame object offset to the offset from the virtual frame index. |
Andrew Lenharth | 684f229 | 2005-01-30 00:35:27 +0000 | [diff] [blame] | 255 | int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); |
| 256 | |
Bill Wendling | f5da133 | 2006-12-07 22:21:48 +0000 | [diff] [blame] | 257 | DOUT << "FI: " << FrameIndex << " Offset: " << Offset << "\n"; |
Andrew Lenharth | 684f229 | 2005-01-30 00:35:27 +0000 | [diff] [blame] | 258 | |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 259 | Offset += MF.getFrameInfo()->getStackSize(); |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 260 | |
Bill Wendling | f5da133 | 2006-12-07 22:21:48 +0000 | [diff] [blame] | 261 | DOUT << "Corrected Offset " << Offset |
| 262 | << " for stack size: " << MF.getFrameInfo()->getStackSize() << "\n"; |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 263 | |
Andrew Lenharth | f69a98c | 2005-03-04 21:40:02 +0000 | [diff] [blame] | 264 | if (Offset > IMM_HIGH || Offset < IMM_LOW) { |
Bill Wendling | f5da133 | 2006-12-07 22:21:48 +0000 | [diff] [blame] | 265 | DOUT << "Unconditionally using R28 for evil purposes Offset: " |
| 266 | << Offset << "\n"; |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 267 | //so in this case, we need to use a temporary register, and move the |
| 268 | //original inst off the SP/FP |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 269 | //fix up the old: |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 270 | MI.getOperand(i + 1).ChangeToRegister(Alpha::R28, false); |
Chris Lattner | e53f4a0 | 2006-05-04 17:52:23 +0000 | [diff] [blame] | 271 | MI.getOperand(i).ChangeToImmediate(getLower16(Offset)); |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 272 | //insert the new |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 273 | MachineInstr* nMI=BuildMI(TII.get(Alpha::LDAH), Alpha::R28) |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 274 | .addImm(getUpper16(Offset)).addReg(FP ? Alpha::R15 : Alpha::R30); |
Andrew Lenharth | 84e2dc2 | 2005-03-13 00:43:20 +0000 | [diff] [blame] | 275 | MBB.insert(II, nMI); |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 276 | } else { |
Chris Lattner | e53f4a0 | 2006-05-04 17:52:23 +0000 | [diff] [blame] | 277 | MI.getOperand(i).ChangeToImmediate(Offset); |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 278 | } |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 279 | } |
| 280 | |
| 281 | |
| 282 | void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const { |
| 283 | MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB |
| 284 | MachineBasicBlock::iterator MBBI = MBB.begin(); |
| 285 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 286 | bool FP = hasFP(MF); |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 287 | |
Andrew Lenharth | 0934ae0 | 2005-07-22 20:52:16 +0000 | [diff] [blame] | 288 | static int curgpdist = 0; |
| 289 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 290 | //handle GOP offset |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 291 | BuildMI(MBB, MBBI, TII.get(Alpha::LDAHg), Alpha::R29) |
Andrew Lenharth | 0934ae0 | 2005-07-22 20:52:16 +0000 | [diff] [blame] | 292 | .addGlobalAddress(const_cast<Function*>(MF.getFunction())) |
| 293 | .addReg(Alpha::R27).addImm(++curgpdist); |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 294 | BuildMI(MBB, MBBI, TII.get(Alpha::LDAg), Alpha::R29) |
Andrew Lenharth | 0934ae0 | 2005-07-22 20:52:16 +0000 | [diff] [blame] | 295 | .addGlobalAddress(const_cast<Function*>(MF.getFunction())) |
| 296 | .addReg(Alpha::R29).addImm(curgpdist); |
| 297 | |
Andrew Lenharth | c24b537 | 2005-04-13 17:17:28 +0000 | [diff] [blame] | 298 | //evil const_cast until MO stuff setup to handle const |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 299 | BuildMI(MBB, MBBI, TII.get(Alpha::ALTENT)) |
Chris Lattner | ea50fab | 2006-05-04 01:15:02 +0000 | [diff] [blame] | 300 | .addGlobalAddress(const_cast<Function*>(MF.getFunction())); |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 301 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 302 | // Get the number of bytes to allocate from the FrameInfo |
Andrew Lenharth | f69a98c | 2005-03-04 21:40:02 +0000 | [diff] [blame] | 303 | long NumBytes = MFI->getStackSize(); |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 304 | |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 305 | if (MFI->hasCalls() && !FP) { |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 306 | // We reserve argument space for call sites in the function immediately on |
| 307 | // entry to the current function. This eliminates the need for add/sub |
Andrew Lenharth | 684f229 | 2005-01-30 00:35:27 +0000 | [diff] [blame] | 308 | // brackets around call sites. |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 309 | //If there is a frame pointer, then we don't do this |
Andrew Lenharth | 684f229 | 2005-01-30 00:35:27 +0000 | [diff] [blame] | 310 | NumBytes += MFI->getMaxCallFrameSize(); |
Bill Wendling | f5da133 | 2006-12-07 22:21:48 +0000 | [diff] [blame] | 311 | DOUT << "Added " << MFI->getMaxCallFrameSize() |
| 312 | << " to the stack due to calls\n"; |
Andrew Lenharth | 684f229 | 2005-01-30 00:35:27 +0000 | [diff] [blame] | 313 | } |
| 314 | |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 315 | if (FP) |
| 316 | NumBytes += 8; //reserve space for the old FP |
| 317 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 318 | // Do we need to allocate space on the stack? |
| 319 | if (NumBytes == 0) return; |
| 320 | |
Andrew Lenharth | 2391897 | 2006-01-25 01:51:08 +0000 | [diff] [blame] | 321 | unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); |
| 322 | NumBytes = (NumBytes+Align-1)/Align*Align; |
| 323 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 324 | // Update frame info to pretend that this is part of the stack... |
| 325 | MFI->setStackSize(NumBytes); |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 326 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 327 | // adjust stack pointer: r30 -= numbytes |
Andrew Lenharth | f69a98c | 2005-03-04 21:40:02 +0000 | [diff] [blame] | 328 | NumBytes = -NumBytes; |
| 329 | if (NumBytes >= IMM_LOW) { |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 330 | BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes) |
Andrew Lenharth | a48f3ce | 2005-07-07 19:52:58 +0000 | [diff] [blame] | 331 | .addReg(Alpha::R30); |
Andrew Lenharth | f69a98c | 2005-03-04 21:40:02 +0000 | [diff] [blame] | 332 | } else if (getUpper16(NumBytes) >= IMM_LOW) { |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 333 | BuildMI(MBB, MBBI, TII.get(Alpha::LDAH), Alpha::R30).addImm(getUpper16(NumBytes)) |
Andrew Lenharth | a48f3ce | 2005-07-07 19:52:58 +0000 | [diff] [blame] | 334 | .addReg(Alpha::R30); |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 335 | BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30).addImm(getLower16(NumBytes)) |
Andrew Lenharth | a48f3ce | 2005-07-07 19:52:58 +0000 | [diff] [blame] | 336 | .addReg(Alpha::R30); |
Andrew Lenharth | 3e98fde | 2005-01-26 21:54:09 +0000 | [diff] [blame] | 337 | } else { |
Bill Wendling | f5da133 | 2006-12-07 22:21:48 +0000 | [diff] [blame] | 338 | cerr << "Too big a stack frame at " << NumBytes << "\n"; |
Andrew Lenharth | 3e98fde | 2005-01-26 21:54:09 +0000 | [diff] [blame] | 339 | abort(); |
| 340 | } |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 341 | |
| 342 | //now if we need to, save the old FP and set the new |
| 343 | if (FP) |
| 344 | { |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 345 | BuildMI(MBB, MBBI, TII.get(Alpha::STQ)) |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 346 | .addReg(Alpha::R15).addImm(0).addReg(Alpha::R30); |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 347 | //this must be the last instr in the prolog |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 348 | BuildMI(MBB, MBBI, TII.get(Alpha::BISr), Alpha::R15) |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 349 | .addReg(Alpha::R30).addReg(Alpha::R30); |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 350 | } |
| 351 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 352 | } |
| 353 | |
| 354 | void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF, |
| 355 | MachineBasicBlock &MBB) const { |
| 356 | const MachineFrameInfo *MFI = MF.getFrameInfo(); |
| 357 | MachineBasicBlock::iterator MBBI = prior(MBB.end()); |
Chris Lattner | 09e4606 | 2006-09-05 02:31:13 +0000 | [diff] [blame] | 358 | assert(MBBI->getOpcode() == Alpha::RETDAG || |
| 359 | MBBI->getOpcode() == Alpha::RETDAGp |
Misha Brukman | 7847fca | 2005-04-22 17:54:37 +0000 | [diff] [blame] | 360 | && "Can only insert epilog into returning blocks"); |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 361 | |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 362 | bool FP = hasFP(MF); |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 363 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 364 | // Get the number of bytes allocated from the FrameInfo... |
Andrew Lenharth | 3ee6041 | 2005-03-05 15:30:33 +0000 | [diff] [blame] | 365 | long NumBytes = MFI->getStackSize(); |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 366 | |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 367 | //now if we need to, restore the old FP |
| 368 | if (FP) |
| 369 | { |
Andrew Lenharth | 0169475 | 2005-02-24 18:36:32 +0000 | [diff] [blame] | 370 | //copy the FP into the SP (discards allocas) |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 371 | BuildMI(MBB, MBBI, TII.get(Alpha::BISr), Alpha::R30).addReg(Alpha::R15) |
Andrew Lenharth | a48f3ce | 2005-07-07 19:52:58 +0000 | [diff] [blame] | 372 | .addReg(Alpha::R15); |
Andrew Lenharth | 0169475 | 2005-02-24 18:36:32 +0000 | [diff] [blame] | 373 | //restore the FP |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 374 | BuildMI(MBB, MBBI, TII.get(Alpha::LDQ), Alpha::R15).addImm(0).addReg(Alpha::R15); |
Andrew Lenharth | 032f235 | 2005-02-22 21:59:48 +0000 | [diff] [blame] | 375 | } |
| 376 | |
Misha Brukman | 4633f1c | 2005-04-21 23:13:11 +0000 | [diff] [blame] | 377 | if (NumBytes != 0) |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 378 | { |
Andrew Lenharth | f69a98c | 2005-03-04 21:40:02 +0000 | [diff] [blame] | 379 | if (NumBytes <= IMM_HIGH) { |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 380 | BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes) |
Andrew Lenharth | a48f3ce | 2005-07-07 19:52:58 +0000 | [diff] [blame] | 381 | .addReg(Alpha::R30); |
Andrew Lenharth | f69a98c | 2005-03-04 21:40:02 +0000 | [diff] [blame] | 382 | } else if (getUpper16(NumBytes) <= IMM_HIGH) { |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 383 | BuildMI(MBB, MBBI, TII.get(Alpha::LDAH), Alpha::R30) |
Andrew Lenharth | a48f3ce | 2005-07-07 19:52:58 +0000 | [diff] [blame] | 384 | .addImm(getUpper16(NumBytes)).addReg(Alpha::R30); |
Evan Cheng | c0f64ff | 2006-11-27 23:37:22 +0000 | [diff] [blame] | 385 | BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30) |
Andrew Lenharth | a48f3ce | 2005-07-07 19:52:58 +0000 | [diff] [blame] | 386 | .addImm(getLower16(NumBytes)).addReg(Alpha::R30); |
Andrew Lenharth | 04c868e | 2005-01-27 08:31:19 +0000 | [diff] [blame] | 387 | } else { |
Bill Wendling | f5da133 | 2006-12-07 22:21:48 +0000 | [diff] [blame] | 388 | cerr << "Too big a stack frame at " << NumBytes << "\n"; |
Andrew Lenharth | 04c868e | 2005-01-27 08:31:19 +0000 | [diff] [blame] | 389 | abort(); |
| 390 | } |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 391 | } |
| 392 | } |
| 393 | |
Jim Laskey | 4188699 | 2006-04-07 16:34:46 +0000 | [diff] [blame] | 394 | unsigned AlphaRegisterInfo::getRARegister() const { |
| 395 | assert(0 && "What is the return address register"); |
| 396 | return 0; |
| 397 | } |
| 398 | |
Jim Laskey | a997918 | 2006-03-28 13:48:33 +0000 | [diff] [blame] | 399 | unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const { |
Jim Laskey | 4188699 | 2006-04-07 16:34:46 +0000 | [diff] [blame] | 400 | return hasFP(MF) ? Alpha::R15 : Alpha::R30; |
Jim Laskey | f1d78e8 | 2006-03-23 18:12:57 +0000 | [diff] [blame] | 401 | } |
| 402 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 403 | #include "AlphaGenRegisterInfo.inc" |
| 404 | |
Andrew Lenharth | 304d0f3 | 2005-01-22 23:41:55 +0000 | [diff] [blame] | 405 | std::string AlphaRegisterInfo::getPrettyName(unsigned reg) |
| 406 | { |
| 407 | std::string s(RegisterDescriptors[reg].Name); |
| 408 | return s; |
| 409 | } |