Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 1 | //===- SparcV8RegisterInfo.cpp - SparcV8 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 SparcV8 implementation of the MRegisterInfo class. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #include "SparcV8.h" |
| 15 | #include "SparcV8RegisterInfo.h" |
Chris Lattner | e1274de | 2004-02-29 05:18:30 +0000 | [diff] [blame] | 16 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
| 17 | #include "llvm/CodeGen/MachineFunction.h" |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 18 | #include "llvm/CodeGen/MachineFrameInfo.h" |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 19 | #include "llvm/Type.h" |
Brian Gaeke | 74dfcf1 | 2004-09-02 02:37:43 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/STLExtras.h" |
Chris Lattner | 38343f6 | 2004-07-04 17:19:21 +0000 | [diff] [blame] | 21 | #include <iostream> |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 22 | using namespace llvm; |
| 23 | |
| 24 | SparcV8RegisterInfo::SparcV8RegisterInfo() |
Chris Lattner | 275f645 | 2004-02-28 19:37:18 +0000 | [diff] [blame] | 25 | : SparcV8GenRegisterInfo(V8::ADJCALLSTACKDOWN, |
| 26 | V8::ADJCALLSTACKUP) {} |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 27 | |
Chris Lattner | 01d0efb | 2004-08-15 22:15:11 +0000 | [diff] [blame] | 28 | void SparcV8RegisterInfo:: |
Chris Lattner | 57f1b67 | 2004-08-15 21:56:44 +0000 | [diff] [blame] | 29 | storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, |
| 30 | unsigned SrcReg, int FrameIdx) const { |
| 31 | const TargetRegisterClass *RC = getRegClass(SrcReg); |
| 32 | |
Brian Gaeke | 6713d98 | 2004-06-17 22:34:48 +0000 | [diff] [blame] | 33 | // On the order of operands here: think "[FrameIdx + 0] = SrcReg". |
Brian Gaeke | 6bd5551 | 2004-06-27 22:59:56 +0000 | [diff] [blame] | 34 | if (RC == SparcV8::IntRegsRegisterClass) |
| 35 | BuildMI (MBB, I, V8::ST, 3).addFrameIndex (FrameIdx).addSImm (0) |
| 36 | .addReg (SrcReg); |
| 37 | else if (RC == SparcV8::FPRegsRegisterClass) |
| 38 | BuildMI (MBB, I, V8::STFri, 3).addFrameIndex (FrameIdx).addSImm (0) |
| 39 | .addReg (SrcReg); |
| 40 | else if (RC == SparcV8::DFPRegsRegisterClass) |
| 41 | BuildMI (MBB, I, V8::STDFri, 3).addFrameIndex (FrameIdx).addSImm (0) |
| 42 | .addReg (SrcReg); |
| 43 | else |
| 44 | assert (0 && "Can't store this register to stack slot"); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 45 | } |
| 46 | |
Chris Lattner | 01d0efb | 2004-08-15 22:15:11 +0000 | [diff] [blame] | 47 | void SparcV8RegisterInfo:: |
Chris Lattner | 57f1b67 | 2004-08-15 21:56:44 +0000 | [diff] [blame] | 48 | loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, |
| 49 | unsigned DestReg, int FrameIdx) const { |
| 50 | const TargetRegisterClass *RC = getRegClass(DestReg); |
Brian Gaeke | 6bd5551 | 2004-06-27 22:59:56 +0000 | [diff] [blame] | 51 | if (RC == SparcV8::IntRegsRegisterClass) |
| 52 | BuildMI (MBB, I, V8::LD, 2, DestReg).addFrameIndex (FrameIdx).addSImm (0); |
| 53 | else if (RC == SparcV8::FPRegsRegisterClass) |
| 54 | BuildMI (MBB, I, V8::LDFri, 2, DestReg).addFrameIndex (FrameIdx) |
| 55 | .addSImm (0); |
| 56 | else if (RC == SparcV8::DFPRegsRegisterClass) |
| 57 | BuildMI (MBB, I, V8::LDDFri, 2, DestReg).addFrameIndex (FrameIdx) |
| 58 | .addSImm (0); |
| 59 | else |
Chris Lattner | 01d0efb | 2004-08-15 22:15:11 +0000 | [diff] [blame] | 60 | assert(0 && "Can't load this register from stack slot"); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 61 | } |
| 62 | |
Chris Lattner | 01d0efb | 2004-08-15 22:15:11 +0000 | [diff] [blame] | 63 | void SparcV8RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, |
| 64 | MachineBasicBlock::iterator I, |
| 65 | unsigned DestReg, unsigned SrcReg, |
| 66 | const TargetRegisterClass *RC) const { |
Brian Gaeke | 6bd5551 | 2004-06-27 22:59:56 +0000 | [diff] [blame] | 67 | if (RC == SparcV8::IntRegsRegisterClass) |
| 68 | BuildMI (MBB, I, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg); |
| 69 | else if (RC == SparcV8::FPRegsRegisterClass) |
| 70 | BuildMI (MBB, I, V8::FMOVS, 1, DestReg).addReg (SrcReg); |
Brian Gaeke | bcf2ad2 | 2004-09-29 03:27:30 +0000 | [diff] [blame] | 71 | else if (RC == SparcV8::DFPRegsRegisterClass) |
| 72 | BuildMI (MBB, I, V8::FpMOVD, 1, DestReg).addReg (SrcReg); |
Brian Gaeke | 6bd5551 | 2004-06-27 22:59:56 +0000 | [diff] [blame] | 73 | else |
| 74 | assert (0 && "Can't copy this register"); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | void SparcV8RegisterInfo:: |
| 78 | eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, |
| 79 | MachineBasicBlock::iterator I) const { |
Brian Gaeke | 85c0835 | 2004-10-10 19:57:21 +0000 | [diff] [blame^] | 80 | MachineInstr &MI = *I; |
| 81 | int size = MI.getOperand (0).getImmedValue (); |
| 82 | if (MI.getOpcode () == V8::ADJCALLSTACKDOWN) |
| 83 | size = -size; |
| 84 | BuildMI (MBB, I, V8::ADDri, 2, V8::SP).addReg (V8::SP).addSImm (size); |
| 85 | MBB.erase (I); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | void |
Chris Lattner | b8ce4c4 | 2004-08-14 22:57:22 +0000 | [diff] [blame] | 89 | SparcV8RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 90 | unsigned i = 0; |
| 91 | MachineInstr &MI = *II; |
| 92 | while (!MI.getOperand(i).isFrameIndex()) { |
| 93 | ++i; |
| 94 | assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); |
| 95 | } |
| 96 | |
| 97 | int FrameIndex = MI.getOperand(i).getFrameIndex(); |
| 98 | |
Brian Gaeke | 3a8ad62 | 2004-04-06 22:10:22 +0000 | [diff] [blame] | 99 | // Replace frame index with a frame pointer reference |
| 100 | MI.SetMachineOperandReg (i, V8::FP); |
| 101 | |
| 102 | // Addressable stack objects are accessed using neg. offsets from %fp |
Chris Lattner | b8ce4c4 | 2004-08-14 22:57:22 +0000 | [diff] [blame] | 103 | MachineFunction &MF = *MI.getParent()->getParent(); |
Brian Gaeke | 3a8ad62 | 2004-04-06 22:10:22 +0000 | [diff] [blame] | 104 | int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + |
| 105 | MI.getOperand(i+1).getImmedValue(); |
| 106 | // note: Offset < 0 |
| 107 | MI.SetMachineOperandConst (i+1, MachineOperand::MO_SignExtendedImmed, Offset); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 108 | } |
| 109 | |
Chris Lattner | e1274de | 2004-02-29 05:18:30 +0000 | [diff] [blame] | 110 | void SparcV8RegisterInfo:: |
| 111 | processFunctionBeforeFrameFinalized(MachineFunction &MF) const {} |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 112 | |
| 113 | void SparcV8RegisterInfo::emitPrologue(MachineFunction &MF) const { |
Chris Lattner | e1274de | 2004-02-29 05:18:30 +0000 | [diff] [blame] | 114 | MachineBasicBlock &MBB = MF.front(); |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 115 | MachineFrameInfo *MFI = MF.getFrameInfo(); |
Chris Lattner | e1274de | 2004-02-29 05:18:30 +0000 | [diff] [blame] | 116 | |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 117 | // Get the number of bytes to allocate from the FrameInfo |
Brian Gaeke | ef8e48a | 2004-04-13 18:28:37 +0000 | [diff] [blame] | 118 | int NumBytes = (int) MFI->getStackSize(); |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 119 | |
Brian Gaeke | 85c0835 | 2004-10-10 19:57:21 +0000 | [diff] [blame^] | 120 | // Emit the correct save instruction based on the number of bytes in |
| 121 | // the frame. Minimum stack frame size according to V8 ABI is: |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 122 | // 16 words for register window spill |
| 123 | // 1 word for address of returned aggregate-value |
| 124 | // + 6 words for passing parameters on the stack |
| 125 | // ---------- |
| 126 | // 23 words * 4 bytes per word = 92 bytes |
| 127 | NumBytes += 92; |
Brian Gaeke | 6713d98 | 2004-06-17 22:34:48 +0000 | [diff] [blame] | 128 | // Round up to next doubleword boundary -- a double-word boundary |
| 129 | // is required by the ABI. |
| 130 | NumBytes = (NumBytes + 7) & ~7; |
Brian Gaeke | 6c5526e | 2004-04-02 20:53:37 +0000 | [diff] [blame] | 131 | BuildMI(MBB, MBB.begin(), V8::SAVEri, 2, |
| 132 | V8::SP).addImm(-NumBytes).addReg(V8::SP); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 133 | } |
| 134 | |
| 135 | void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF, |
| 136 | MachineBasicBlock &MBB) const { |
Chris Lattner | e1274de | 2004-02-29 05:18:30 +0000 | [diff] [blame] | 137 | MachineBasicBlock::iterator MBBI = prior(MBB.end()); |
Brian Gaeke | d69b3c5 | 2004-03-06 05:31:21 +0000 | [diff] [blame] | 138 | assert(MBBI->getOpcode() == V8::RETL && |
| 139 | "Can only put epilog before 'retl' instruction!"); |
| 140 | BuildMI(MBB, MBBI, V8::RESTORErr, 2, V8::G0).addReg(V8::G0).addReg(V8::G0); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 141 | } |
| 142 | |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 143 | #include "SparcV8GenRegisterInfo.inc" |
| 144 | |
| 145 | const TargetRegisterClass* |
| 146 | SparcV8RegisterInfo::getRegClassForType(const Type* Ty) const { |
Chris Lattner | f70c22b | 2004-06-17 18:19:28 +0000 | [diff] [blame] | 147 | switch (Ty->getTypeID()) { |
Brian Gaeke | a98e051 | 2004-03-06 03:54:13 +0000 | [diff] [blame] | 148 | case Type::FloatTyID: return &FPRegsInstance; |
| 149 | case Type::DoubleTyID: return &DFPRegsInstance; |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 150 | case Type::LongTyID: |
Brian Gaeke | be81e82 | 2004-06-24 08:55:21 +0000 | [diff] [blame] | 151 | case Type::ULongTyID: assert(0 && "Long values do not fit in registers!"); |
Brian Gaeke | f54d912 | 2004-06-22 20:14:41 +0000 | [diff] [blame] | 152 | default: assert(0 && "Invalid type to getClass!"); |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 153 | case Type::BoolTyID: |
| 154 | case Type::SByteTyID: |
| 155 | case Type::UByteTyID: |
| 156 | case Type::ShortTyID: |
| 157 | case Type::UShortTyID: |
| 158 | case Type::IntTyID: |
| 159 | case Type::UIntTyID: |
Chris Lattner | 275f645 | 2004-02-28 19:37:18 +0000 | [diff] [blame] | 160 | case Type::PointerTyID: return &IntRegsInstance; |
Brian Gaeke | e785e53 | 2004-02-25 19:28:19 +0000 | [diff] [blame] | 161 | } |
| 162 | } |
| 163 | |