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