Chris Lattner | 128aff4 | 2002-12-28 20:32:54 +0000 | [diff] [blame] | 1 | //===- X86RegisterInfo.h - X86 Register Information Impl --------*- C++ -*-===// |
Misha Brukman | 0e0a7a45 | 2005-04-21 23:38:14 +0000 | [diff] [blame] | 2 | // |
John Criswell | 856ba76 | 2003-10-21 15:17:13 +0000 | [diff] [blame] | 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
Chris Lattner | 4ee451d | 2007-12-29 20:36:04 +0000 | [diff] [blame^] | 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
Misha Brukman | 0e0a7a45 | 2005-04-21 23:38:14 +0000 | [diff] [blame] | 7 | // |
John Criswell | 856ba76 | 2003-10-21 15:17:13 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// |
Chris Lattner | 7261408 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 9 | // |
| 10 | // This file contains the X86 implementation of the MRegisterInfo class. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef X86REGISTERINFO_H |
| 15 | #define X86REGISTERINFO_H |
| 16 | |
Evan Cheng | 7f3394f | 2007-10-01 23:44:33 +0000 | [diff] [blame] | 17 | #include "llvm/ADT/DenseMap.h" |
Evan Cheng | f4c3a59 | 2007-08-30 05:54:07 +0000 | [diff] [blame] | 18 | #include "llvm/ADT/SmallVector.h" |
Chris Lattner | 7261408 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 19 | #include "llvm/Target/MRegisterInfo.h" |
Chris Lattner | 7ad3e06 | 2003-08-03 15:48:14 +0000 | [diff] [blame] | 20 | #include "X86GenRegisterInfo.h.inc" |
| 21 | |
Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 22 | namespace llvm { |
Chris Lattner | 2926869 | 2006-09-05 02:12:02 +0000 | [diff] [blame] | 23 | class Type; |
| 24 | class TargetInstrInfo; |
Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 25 | class X86TargetMachine; |
Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 26 | |
Duncan Sands | ee46574 | 2007-08-29 19:01:20 +0000 | [diff] [blame] | 27 | /// N86 namespace - Native X86 register numbers |
| 28 | /// |
| 29 | namespace N86 { |
| 30 | enum { |
| 31 | EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7 |
| 32 | }; |
| 33 | } |
| 34 | |
Anton Korobeynikov | f191c80 | 2007-11-11 19:50:10 +0000 | [diff] [blame] | 35 | /// DWARFFlavour - Flavour of dwarf regnumbers |
| 36 | /// |
| 37 | namespace DWARFFlavour { |
| 38 | enum { |
| 39 | X86_64 = 0, X86_32_Darwin = 1, X86_32_ELF = 2 |
| 40 | }; |
| 41 | } |
| 42 | |
Jeff Cohen | d41b30d | 2006-11-05 19:31:28 +0000 | [diff] [blame] | 43 | class X86RegisterInfo : public X86GenRegisterInfo { |
| 44 | public: |
Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 45 | X86TargetMachine &TM; |
Chris Lattner | 2926869 | 2006-09-05 02:12:02 +0000 | [diff] [blame] | 46 | const TargetInstrInfo &TII; |
Jeff Cohen | d41b30d | 2006-11-05 19:31:28 +0000 | [diff] [blame] | 47 | |
Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 48 | private: |
| 49 | /// Is64Bit - Is the target 64-bits. |
Evan Cheng | 7f3394f | 2007-10-01 23:44:33 +0000 | [diff] [blame] | 50 | /// |
Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 51 | bool Is64Bit; |
| 52 | |
| 53 | /// SlotSize - Stack slot size in bytes. |
Evan Cheng | 7f3394f | 2007-10-01 23:44:33 +0000 | [diff] [blame] | 54 | /// |
Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 55 | unsigned SlotSize; |
| 56 | |
Evan Cheng | db807ed | 2007-11-05 07:30:01 +0000 | [diff] [blame] | 57 | /// StackAlign - Default stack alignment. |
| 58 | /// |
| 59 | unsigned StackAlign; |
| 60 | |
Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 61 | /// StackPtr - X86 physical register used as stack ptr. |
Evan Cheng | 7f3394f | 2007-10-01 23:44:33 +0000 | [diff] [blame] | 62 | /// |
Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 63 | unsigned StackPtr; |
| 64 | |
| 65 | /// FramePtr - X86 physical register used as frame ptr. |
Evan Cheng | 7f3394f | 2007-10-01 23:44:33 +0000 | [diff] [blame] | 66 | /// |
Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 67 | unsigned FramePtr; |
| 68 | |
Evan Cheng | 7f3394f | 2007-10-01 23:44:33 +0000 | [diff] [blame] | 69 | /// RegOp2MemOpTable2Addr, RegOp2MemOpTable0, RegOp2MemOpTable1, |
| 70 | /// RegOp2MemOpTable2 - Load / store folding opcode maps. |
| 71 | /// |
| 72 | DenseMap<unsigned*, unsigned> RegOp2MemOpTable2Addr; |
| 73 | DenseMap<unsigned*, unsigned> RegOp2MemOpTable0; |
| 74 | DenseMap<unsigned*, unsigned> RegOp2MemOpTable1; |
| 75 | DenseMap<unsigned*, unsigned> RegOp2MemOpTable2; |
| 76 | |
| 77 | /// MemOp2RegOpTable - Load / store unfolding opcode map. |
| 78 | /// |
Evan Cheng | 75b4e46 | 2007-10-05 01:34:55 +0000 | [diff] [blame] | 79 | DenseMap<unsigned*, std::pair<unsigned, unsigned> > MemOp2RegOpTable; |
Evan Cheng | 7f3394f | 2007-10-01 23:44:33 +0000 | [diff] [blame] | 80 | |
Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 81 | public: |
| 82 | X86RegisterInfo(X86TargetMachine &tm, const TargetInstrInfo &tii); |
Chris Lattner | 128aff4 | 2002-12-28 20:32:54 +0000 | [diff] [blame] | 83 | |
Duncan Sands | ee46574 | 2007-08-29 19:01:20 +0000 | [diff] [blame] | 84 | /// getX86RegNum - Returns the native X86 register number for the given LLVM |
| 85 | /// register identifier. |
| 86 | unsigned getX86RegNum(unsigned RegNo); |
| 87 | |
Dale Johannesen | 483ec21 | 2007-11-07 00:25:05 +0000 | [diff] [blame] | 88 | /// getDwarfRegNum - allows modification of X86GenRegisterInfo::getDwarfRegNum |
| 89 | /// (created by TableGen) for target dependencies. |
Dale Johannesen | b97aec6 | 2007-11-13 19:13:01 +0000 | [diff] [blame] | 90 | int getDwarfRegNum(unsigned RegNum, bool isEH) const; |
Dale Johannesen | 483ec21 | 2007-11-07 00:25:05 +0000 | [diff] [blame] | 91 | |
Chris Lattner | 128aff4 | 2002-12-28 20:32:54 +0000 | [diff] [blame] | 92 | /// Code Generation virtual methods... |
Evan Cheng | 7f3394f | 2007-10-01 23:44:33 +0000 | [diff] [blame] | 93 | /// |
Evan Cheng | 89d1659 | 2007-07-17 07:59:08 +0000 | [diff] [blame] | 94 | bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, |
| 95 | MachineBasicBlock::iterator MI, |
| 96 | const std::vector<CalleeSavedInfo> &CSI) const; |
| 97 | |
| 98 | bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, |
| 99 | MachineBasicBlock::iterator MI, |
| 100 | const std::vector<CalleeSavedInfo> &CSI) const; |
| 101 | |
Chris Lattner | 01d0efb | 2004-08-15 22:15:11 +0000 | [diff] [blame] | 102 | void storeRegToStackSlot(MachineBasicBlock &MBB, |
Alkis Evlogimenos | 024126e | 2004-02-12 08:11:04 +0000 | [diff] [blame] | 103 | MachineBasicBlock::iterator MI, |
Evan Cheng | d64b5c8 | 2007-12-05 03:14:33 +0000 | [diff] [blame] | 104 | unsigned SrcReg, bool isKill, int FrameIndex, |
Chris Lattner | 97d5e64 | 2005-09-30 01:29:42 +0000 | [diff] [blame] | 105 | const TargetRegisterClass *RC) const; |
Chris Lattner | 01d0efb | 2004-08-15 22:15:11 +0000 | [diff] [blame] | 106 | |
Evan Cheng | d64b5c8 | 2007-12-05 03:14:33 +0000 | [diff] [blame] | 107 | void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, |
Evan Cheng | f0a0cdd | 2007-10-18 22:40:57 +0000 | [diff] [blame] | 108 | SmallVectorImpl<MachineOperand> &Addr, |
Evan Cheng | 75b4e46 | 2007-10-05 01:34:55 +0000 | [diff] [blame] | 109 | const TargetRegisterClass *RC, |
Evan Cheng | 58184e6 | 2007-10-18 21:29:24 +0000 | [diff] [blame] | 110 | SmallVectorImpl<MachineInstr*> &NewMIs) const; |
Evan Cheng | 75b4e46 | 2007-10-05 01:34:55 +0000 | [diff] [blame] | 111 | |
Chris Lattner | 01d0efb | 2004-08-15 22:15:11 +0000 | [diff] [blame] | 112 | void loadRegFromStackSlot(MachineBasicBlock &MBB, |
| 113 | MachineBasicBlock::iterator MI, |
Chris Lattner | 97d5e64 | 2005-09-30 01:29:42 +0000 | [diff] [blame] | 114 | unsigned DestReg, int FrameIndex, |
| 115 | const TargetRegisterClass *RC) const; |
Misha Brukman | 0e0a7a45 | 2005-04-21 23:38:14 +0000 | [diff] [blame] | 116 | |
Evan Cheng | 75b4e46 | 2007-10-05 01:34:55 +0000 | [diff] [blame] | 117 | void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, |
Evan Cheng | f0a0cdd | 2007-10-18 22:40:57 +0000 | [diff] [blame] | 118 | SmallVectorImpl<MachineOperand> &Addr, |
Evan Cheng | 75b4e46 | 2007-10-05 01:34:55 +0000 | [diff] [blame] | 119 | const TargetRegisterClass *RC, |
Evan Cheng | 58184e6 | 2007-10-18 21:29:24 +0000 | [diff] [blame] | 120 | SmallVectorImpl<MachineInstr*> &NewMIs) const; |
Evan Cheng | 75b4e46 | 2007-10-05 01:34:55 +0000 | [diff] [blame] | 121 | |
Chris Lattner | 01d0efb | 2004-08-15 22:15:11 +0000 | [diff] [blame] | 122 | void copyRegToReg(MachineBasicBlock &MBB, |
| 123 | MachineBasicBlock::iterator MI, |
| 124 | unsigned DestReg, unsigned SrcReg, |
Evan Cheng | 9efce63 | 2007-09-26 06:25:56 +0000 | [diff] [blame] | 125 | const TargetRegisterClass *DestRC, |
| 126 | const TargetRegisterClass *SrcRC) const; |
Evan Cheng | bf2c8b3 | 2007-03-20 08:09:38 +0000 | [diff] [blame] | 127 | |
Evan Cheng | ff11026 | 2007-09-26 21:31:07 +0000 | [diff] [blame] | 128 | const TargetRegisterClass * |
| 129 | getCrossCopyRegClass(const TargetRegisterClass *RC) const; |
| 130 | |
Evan Cheng | bf2c8b3 | 2007-03-20 08:09:38 +0000 | [diff] [blame] | 131 | void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, |
| 132 | unsigned DestReg, const MachineInstr *Orig) const; |
Chris Lattner | 128aff4 | 2002-12-28 20:32:54 +0000 | [diff] [blame] | 133 | |
Chris Lattner | 5a051f6 | 2004-02-17 05:54:57 +0000 | [diff] [blame] | 134 | /// foldMemoryOperand - If this target supports it, fold a load or store of |
| 135 | /// the specified stack slot into the specified machine instruction for the |
Evan Cheng | aee4af6 | 2007-12-02 08:30:39 +0000 | [diff] [blame] | 136 | /// specified operand(s). If this is possible, the target should perform the |
Chris Lattner | 5a051f6 | 2004-02-17 05:54:57 +0000 | [diff] [blame] | 137 | /// folding and return true, otherwise it should return false. If it folds |
| 138 | /// the instruction, it is likely that the MachineInstruction the iterator |
| 139 | /// references has been changed. |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 140 | MachineInstr* foldMemoryOperand(MachineInstr* MI, |
Evan Cheng | aee4af6 | 2007-12-02 08:30:39 +0000 | [diff] [blame] | 141 | SmallVectorImpl<unsigned> &Ops, |
Evan Cheng | e62f97c | 2007-12-01 02:07:52 +0000 | [diff] [blame] | 142 | int FrameIndex) const; |
| 143 | |
Evan Cheng | f4c3a59 | 2007-08-30 05:54:07 +0000 | [diff] [blame] | 144 | /// foldMemoryOperand - Same as the previous version except it allows folding |
| 145 | /// of any load and store from / to any address, not just from a specific |
| 146 | /// stack slot. |
| 147 | MachineInstr* foldMemoryOperand(MachineInstr* MI, |
Evan Cheng | aee4af6 | 2007-12-02 08:30:39 +0000 | [diff] [blame] | 148 | SmallVectorImpl<unsigned> &Ops, |
Evan Cheng | e62f97c | 2007-12-01 02:07:52 +0000 | [diff] [blame] | 149 | MachineInstr* LoadMI) const; |
| 150 | |
Evan Cheng | d64b5c8 | 2007-12-05 03:14:33 +0000 | [diff] [blame] | 151 | /// canFoldMemoryOperand - Returns true if the specified load / store is |
| 152 | /// folding is possible. |
| 153 | bool canFoldMemoryOperand(MachineInstr*, SmallVectorImpl<unsigned> &) const; |
Evan Cheng | 66f7163 | 2007-10-19 21:23:22 +0000 | [diff] [blame] | 154 | |
Christopher Lamb | 91ee18c | 2007-10-18 19:28:55 +0000 | [diff] [blame] | 155 | /// unfoldMemoryOperand - Separate a single instruction which folded a load or |
Evan Cheng | 75b4e46 | 2007-10-05 01:34:55 +0000 | [diff] [blame] | 156 | /// a store or a load and a store into two or more instruction. If this is |
| 157 | /// possible, returns true as well as the new instructions by reference. |
| 158 | bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, |
Evan Cheng | 106e802 | 2007-10-13 02:35:06 +0000 | [diff] [blame] | 159 | unsigned Reg, bool UnfoldLoad, bool UnfoldStore, |
Evan Cheng | 58184e6 | 2007-10-18 21:29:24 +0000 | [diff] [blame] | 160 | SmallVectorImpl<MachineInstr*> &NewMIs) const; |
Evan Cheng | 75b4e46 | 2007-10-05 01:34:55 +0000 | [diff] [blame] | 161 | |
| 162 | bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, |
Evan Cheng | 58184e6 | 2007-10-18 21:29:24 +0000 | [diff] [blame] | 163 | SmallVectorImpl<SDNode*> &NewNodes) const; |
Evan Cheng | 75b4e46 | 2007-10-05 01:34:55 +0000 | [diff] [blame] | 164 | |
Evan Cheng | f0a0cdd | 2007-10-18 22:40:57 +0000 | [diff] [blame] | 165 | /// getOpcodeAfterMemoryUnfold - Returns the opcode of the would be new |
Evan Cheng | 66f7163 | 2007-10-19 21:23:22 +0000 | [diff] [blame] | 166 | /// instruction after load / store are unfolded from an instruction of the |
| 167 | /// specified opcode. It returns zero if the specified unfolding is not |
| 168 | /// possible. |
Evan Cheng | f0a0cdd | 2007-10-18 22:40:57 +0000 | [diff] [blame] | 169 | unsigned getOpcodeAfterMemoryUnfold(unsigned Opc, |
| 170 | bool UnfoldLoad, bool UnfoldStore) const; |
| 171 | |
Evan Cheng | c2b861d | 2007-01-02 21:33:40 +0000 | [diff] [blame] | 172 | /// getCalleeSavedRegs - Return a null-terminated list of all of the |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 173 | /// callee-save registers on this target. |
Anton Korobeynikov | 2365f51 | 2007-07-14 14:06:15 +0000 | [diff] [blame] | 174 | const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const; |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 175 | |
Evan Cheng | c2b861d | 2007-01-02 21:33:40 +0000 | [diff] [blame] | 176 | /// getCalleeSavedRegClasses - Return a null-terminated list of the preferred |
Evan Cheng | 0f3ac8d | 2006-05-18 00:12:58 +0000 | [diff] [blame] | 177 | /// register classes to spill each callee-saved register with. The order and |
Evan Cheng | c2b861d | 2007-01-02 21:33:40 +0000 | [diff] [blame] | 178 | /// length of this list match the getCalleeSavedRegs() list. |
Evan Cheng | 64d80e3 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 179 | const TargetRegisterClass* const* |
| 180 | getCalleeSavedRegClasses(const MachineFunction *MF = 0) const; |
Alkis Evlogimenos | b499866 | 2004-02-17 04:33:18 +0000 | [diff] [blame] | 181 | |
Evan Cheng | b371f45 | 2007-02-19 21:49:54 +0000 | [diff] [blame] | 182 | /// getReservedRegs - Returns a bitset indexed by physical register number |
| 183 | /// indicating if a register is a special register that has particular uses and |
| 184 | /// should be considered unavailable at all times, e.g. SP, RA. This is used by |
| 185 | /// register scavenger to determine what registers are free. |
| 186 | BitVector getReservedRegs(const MachineFunction &MF) const; |
| 187 | |
Evan Cheng | dc77540 | 2007-01-23 00:57:47 +0000 | [diff] [blame] | 188 | bool hasFP(const MachineFunction &MF) const; |
| 189 | |
Evan Cheng | 7e7bbf8 | 2007-07-19 00:42:05 +0000 | [diff] [blame] | 190 | bool hasReservedCallFrame(MachineFunction &MF) const; |
| 191 | |
Chris Lattner | bb07ef9 | 2004-02-14 19:49:54 +0000 | [diff] [blame] | 192 | void eliminateCallFramePseudoInstr(MachineFunction &MF, |
| 193 | MachineBasicBlock &MBB, |
| 194 | MachineBasicBlock::iterator MI) const; |
Chris Lattner | 128aff4 | 2002-12-28 20:32:54 +0000 | [diff] [blame] | 195 | |
Evan Cheng | 5e6df46 | 2007-02-28 00:21:17 +0000 | [diff] [blame] | 196 | void eliminateFrameIndex(MachineBasicBlock::iterator MI, |
Evan Cheng | 97de913 | 2007-05-01 09:13:03 +0000 | [diff] [blame] | 197 | int SPAdj, RegScavenger *RS = NULL) const; |
Chris Lattner | 128aff4 | 2002-12-28 20:32:54 +0000 | [diff] [blame] | 198 | |
Chris Lattner | bb07ef9 | 2004-02-14 19:49:54 +0000 | [diff] [blame] | 199 | void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; |
Chris Lattner | 128aff4 | 2002-12-28 20:32:54 +0000 | [diff] [blame] | 200 | |
Chris Lattner | bb07ef9 | 2004-02-14 19:49:54 +0000 | [diff] [blame] | 201 | void emitPrologue(MachineFunction &MF) const; |
| 202 | void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; |
Jim Laskey | f1d78e8 | 2006-03-23 18:12:57 +0000 | [diff] [blame] | 203 | |
Jim Laskey | a997918 | 2006-03-28 13:48:33 +0000 | [diff] [blame] | 204 | // Debug information queries. |
Jim Laskey | 4188699 | 2006-04-07 16:34:46 +0000 | [diff] [blame] | 205 | unsigned getRARegister() const; |
Jim Laskey | a997918 | 2006-03-28 13:48:33 +0000 | [diff] [blame] | 206 | unsigned getFrameRegister(MachineFunction &MF) const; |
Jim Laskey | 0e41094 | 2007-01-24 19:15:24 +0000 | [diff] [blame] | 207 | void getInitialFrameState(std::vector<MachineMove> &Moves) const; |
Jim Laskey | 62819f3 | 2007-02-21 22:54:50 +0000 | [diff] [blame] | 208 | |
| 209 | // Exception handling queries. |
| 210 | unsigned getEHExceptionRegister() const; |
| 211 | unsigned getEHHandlerRegister() const; |
Evan Cheng | f4c3a59 | 2007-08-30 05:54:07 +0000 | [diff] [blame] | 212 | |
| 213 | private: |
| 214 | MachineInstr* foldMemoryOperand(MachineInstr* MI, |
| 215 | unsigned OpNum, |
| 216 | SmallVector<MachineOperand,4> &MOs) const; |
Chris Lattner | 7261408 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 217 | }; |
| 218 | |
Evan Cheng | 8f7f712 | 2006-05-05 05:40:20 +0000 | [diff] [blame] | 219 | // getX86SubSuperRegister - X86 utility function. It returns the sub or super |
| 220 | // register of a specific X86 register. |
| 221 | // e.g. getX86SubSuperRegister(X86::EAX, MVT::i16) return X86:AX |
| 222 | unsigned getX86SubSuperRegister(unsigned, MVT::ValueType, bool High=false); |
| 223 | |
Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 224 | } // End llvm namespace |
| 225 | |
Chris Lattner | 7261408 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 226 | #endif |