blob: ce4966dfdc7f47b136b7638f7750f0d066892860 [file] [log] [blame]
Misha Brukmancf2b9ac2002-11-22 22:43:47 +00001//===- X86RegisterInfo.cpp - X86 Register Information -----------*- C++ -*-===//
Alkis Evlogimenos39354c92004-03-14 07:19:51 +00002//
John Criswellb576c942003-10-20 19:43:21 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Alkis Evlogimenos39354c92004-03-14 07:19:51 +00007//
John Criswellb576c942003-10-20 19:43:21 +00008//===----------------------------------------------------------------------===//
Chris Lattner72614082002-10-25 22:55:53 +00009//
Dan Gohman6f0d0242008-02-10 18:45:23 +000010// This file contains the X86 implementation of the TargetRegisterInfo class.
11// This file is responsible for the frame pointer elimination optimization
12// on X86.
Chris Lattner72614082002-10-25 22:55:53 +000013//
14//===----------------------------------------------------------------------===//
15
Misha Brukmanb83b2862002-11-20 18:59:43 +000016#include "X86.h"
Chris Lattner72614082002-10-25 22:55:53 +000017#include "X86RegisterInfo.h"
Misha Brukmancf2b9ac2002-11-22 22:43:47 +000018#include "X86InstrBuilder.h"
Evan Chenge8bd0a32006-06-06 23:30:24 +000019#include "X86MachineFunctionInfo.h"
Evan Cheng25ab6902006-09-08 06:48:29 +000020#include "X86Subtarget.h"
Evan Chenge8bd0a32006-06-06 23:30:24 +000021#include "X86TargetMachine.h"
Misha Brukmanb83b2862002-11-20 18:59:43 +000022#include "llvm/Constants.h"
Evan Cheng3649b0e2006-06-02 22:38:37 +000023#include "llvm/Function.h"
Evan Cheng25ab6902006-09-08 06:48:29 +000024#include "llvm/Type.h"
Chris Lattnerc8c377d2003-07-29 05:14:16 +000025#include "llvm/CodeGen/ValueTypes.h"
Misha Brukmanb83b2862002-11-20 18:59:43 +000026#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner198ab642002-12-15 20:06:35 +000027#include "llvm/CodeGen/MachineFunction.h"
Dan Gohman2dad0252008-07-01 18:15:35 +000028#include "llvm/CodeGen/MachineFunctionPass.h"
Chris Lattneraa09b752002-12-28 21:08:28 +000029#include "llvm/CodeGen/MachineFrameInfo.h"
Jim Laskeyf1d78e82006-03-23 18:12:57 +000030#include "llvm/CodeGen/MachineLocation.h"
Chris Lattner84bc5422007-12-31 04:13:23 +000031#include "llvm/CodeGen/MachineModuleInfo.h"
32#include "llvm/CodeGen/MachineRegisterInfo.h"
Chris Lattneraf76e592009-08-22 20:48:53 +000033#include "llvm/MC/MCAsmInfo.h"
Chris Lattnerf158da22003-01-16 02:20:12 +000034#include "llvm/Target/TargetFrameInfo.h"
Evan Cheng51cdcd12006-12-07 01:21:59 +000035#include "llvm/Target/TargetInstrInfo.h"
Misha Brukman83eaa0b2004-06-21 21:10:24 +000036#include "llvm/Target/TargetMachine.h"
Chris Lattner0cf0c372004-07-11 04:17:10 +000037#include "llvm/Target/TargetOptions.h"
Evan Chengb371f452007-02-19 21:49:54 +000038#include "llvm/ADT/BitVector.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000039#include "llvm/ADT/STLExtras.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000040#include "llvm/Support/ErrorHandling.h"
Eric Christophere74a0882010-08-05 23:57:43 +000041#include "llvm/Support/CommandLine.h"
Chris Lattner300d0ed2004-02-14 06:00:36 +000042using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000043
Anton Korobeynikov33464912010-11-15 00:06:54 +000044cl::opt<bool>
Eric Christophere74a0882010-08-05 23:57:43 +000045ForceStackAlign("force-align-stack",
46 cl::desc("Force align the stack to the minimum alignment"
47 " needed for the function."),
48 cl::init(false), cl::Hidden);
49
Evan Cheng25ab6902006-09-08 06:48:29 +000050X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm,
51 const TargetInstrInfo &tii)
Dan Gohman6d4b0522008-10-01 18:28:06 +000052 : X86GenRegisterInfo(tm.getSubtarget<X86Subtarget>().is64Bit() ?
53 X86::ADJCALLSTACKDOWN64 :
54 X86::ADJCALLSTACKDOWN32,
55 tm.getSubtarget<X86Subtarget>().is64Bit() ?
56 X86::ADJCALLSTACKUP64 :
57 X86::ADJCALLSTACKUP32),
Evan Cheng25ab6902006-09-08 06:48:29 +000058 TM(tm), TII(tii) {
59 // Cache some information.
60 const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
61 Is64Bit = Subtarget->is64Bit();
Anton Korobeynikov1dcce212008-03-22 21:04:01 +000062 IsWin64 = Subtarget->isTargetWin64();
Evan Chengdb807ed2007-11-05 07:30:01 +000063 StackAlign = TM.getFrameInfo()->getStackAlignment();
Bill Wendling80c76432009-08-16 11:00:26 +000064
Evan Cheng25ab6902006-09-08 06:48:29 +000065 if (Is64Bit) {
66 SlotSize = 8;
67 StackPtr = X86::RSP;
68 FramePtr = X86::RBP;
69 } else {
70 SlotSize = 4;
71 StackPtr = X86::ESP;
72 FramePtr = X86::EBP;
73 }
74}
Chris Lattner7ad3e062003-08-03 15:48:14 +000075
Bill Wendling80c76432009-08-16 11:00:26 +000076/// getDwarfRegNum - This function maps LLVM register identifiers to the DWARF
77/// specific numbering, used in debug info and exception tables.
Dale Johannesenb97aec62007-11-13 19:13:01 +000078int X86RegisterInfo::getDwarfRegNum(unsigned RegNo, bool isEH) const {
Dale Johannesen483ec212007-11-07 00:25:05 +000079 const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
Anton Korobeynikovf191c802007-11-11 19:50:10 +000080 unsigned Flavour = DWARFFlavour::X86_64;
Bill Wendling80c76432009-08-16 11:00:26 +000081
Dale Johannesen7a42f242007-11-09 18:07:11 +000082 if (!Subtarget->is64Bit()) {
Anton Korobeynikovf191c802007-11-11 19:50:10 +000083 if (Subtarget->isTargetDarwin()) {
Anton Korobeynikov8eea3392008-01-25 00:34:13 +000084 if (isEH)
85 Flavour = DWARFFlavour::X86_32_DarwinEH;
86 else
87 Flavour = DWARFFlavour::X86_32_Generic;
Anton Korobeynikovf191c802007-11-11 19:50:10 +000088 } else if (Subtarget->isTargetCygMing()) {
89 // Unsupported by now, just quick fallback
Anton Korobeynikov8eea3392008-01-25 00:34:13 +000090 Flavour = DWARFFlavour::X86_32_Generic;
Anton Korobeynikovf191c802007-11-11 19:50:10 +000091 } else {
Anton Korobeynikov8eea3392008-01-25 00:34:13 +000092 Flavour = DWARFFlavour::X86_32_Generic;
Dale Johannesen7a42f242007-11-09 18:07:11 +000093 }
Dale Johannesen483ec212007-11-07 00:25:05 +000094 }
Anton Korobeynikovf191c802007-11-11 19:50:10 +000095
96 return X86GenRegisterInfo::getDwarfRegNumFull(RegNo, Flavour);
Dale Johannesen483ec212007-11-07 00:25:05 +000097}
98
Bill Wendling80c76432009-08-16 11:00:26 +000099/// getX86RegNum - This function maps LLVM register identifiers to their X86
100/// specific numbering, which is used in various places encoding instructions.
Nicolas Geoffray52e724a2008-04-16 20:10:13 +0000101unsigned X86RegisterInfo::getX86RegNum(unsigned RegNo) {
Duncan Sandsee465742007-08-29 19:01:20 +0000102 switch(RegNo) {
103 case X86::RAX: case X86::EAX: case X86::AX: case X86::AL: return N86::EAX;
104 case X86::RCX: case X86::ECX: case X86::CX: case X86::CL: return N86::ECX;
105 case X86::RDX: case X86::EDX: case X86::DX: case X86::DL: return N86::EDX;
106 case X86::RBX: case X86::EBX: case X86::BX: case X86::BL: return N86::EBX;
107 case X86::RSP: case X86::ESP: case X86::SP: case X86::SPL: case X86::AH:
108 return N86::ESP;
109 case X86::RBP: case X86::EBP: case X86::BP: case X86::BPL: case X86::CH:
110 return N86::EBP;
111 case X86::RSI: case X86::ESI: case X86::SI: case X86::SIL: case X86::DH:
112 return N86::ESI;
113 case X86::RDI: case X86::EDI: case X86::DI: case X86::DIL: case X86::BH:
114 return N86::EDI;
115
116 case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
117 return N86::EAX;
118 case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
119 return N86::ECX;
120 case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
121 return N86::EDX;
122 case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
123 return N86::EBX;
124 case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
125 return N86::ESP;
126 case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
127 return N86::EBP;
128 case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
129 return N86::ESI;
130 case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
131 return N86::EDI;
132
133 case X86::ST0: case X86::ST1: case X86::ST2: case X86::ST3:
134 case X86::ST4: case X86::ST5: case X86::ST6: case X86::ST7:
135 return RegNo-X86::ST0;
136
Bruno Cardoso Lopese86b01c2010-07-09 18:27:43 +0000137 case X86::XMM0: case X86::XMM8:
138 case X86::YMM0: case X86::YMM8: case X86::MM0:
Evan Chenge7c87542007-11-13 17:54:34 +0000139 return 0;
Bruno Cardoso Lopese86b01c2010-07-09 18:27:43 +0000140 case X86::XMM1: case X86::XMM9:
141 case X86::YMM1: case X86::YMM9: case X86::MM1:
Evan Chenge7c87542007-11-13 17:54:34 +0000142 return 1;
Bruno Cardoso Lopese86b01c2010-07-09 18:27:43 +0000143 case X86::XMM2: case X86::XMM10:
144 case X86::YMM2: case X86::YMM10: case X86::MM2:
Evan Chenge7c87542007-11-13 17:54:34 +0000145 return 2;
Bruno Cardoso Lopese86b01c2010-07-09 18:27:43 +0000146 case X86::XMM3: case X86::XMM11:
147 case X86::YMM3: case X86::YMM11: case X86::MM3:
Evan Chenge7c87542007-11-13 17:54:34 +0000148 return 3;
Bruno Cardoso Lopese86b01c2010-07-09 18:27:43 +0000149 case X86::XMM4: case X86::XMM12:
150 case X86::YMM4: case X86::YMM12: case X86::MM4:
Evan Chenge7c87542007-11-13 17:54:34 +0000151 return 4;
Bruno Cardoso Lopese86b01c2010-07-09 18:27:43 +0000152 case X86::XMM5: case X86::XMM13:
153 case X86::YMM5: case X86::YMM13: case X86::MM5:
Evan Chenge7c87542007-11-13 17:54:34 +0000154 return 5;
Bruno Cardoso Lopese86b01c2010-07-09 18:27:43 +0000155 case X86::XMM6: case X86::XMM14:
156 case X86::YMM6: case X86::YMM14: case X86::MM6:
Evan Chenge7c87542007-11-13 17:54:34 +0000157 return 6;
Bruno Cardoso Lopese86b01c2010-07-09 18:27:43 +0000158 case X86::XMM7: case X86::XMM15:
159 case X86::YMM7: case X86::YMM15: case X86::MM7:
Evan Chenge7c87542007-11-13 17:54:34 +0000160 return 7;
Duncan Sandsee465742007-08-29 19:01:20 +0000161
Chris Lattnerbc57c6d2010-09-22 05:29:50 +0000162 case X86::ES: return 0;
163 case X86::CS: return 1;
164 case X86::SS: return 2;
165 case X86::DS: return 3;
166 case X86::FS: return 4;
167 case X86::GS: return 5;
Kevin Enderbyb1065432010-05-26 20:10:45 +0000168
Chris Lattnerbc57c6d2010-09-22 05:29:50 +0000169 case X86::CR0: case X86::CR8 : case X86::DR0: return 0;
170 case X86::CR1: case X86::CR9 : case X86::DR1: return 1;
171 case X86::CR2: case X86::CR10: case X86::DR2: return 2;
172 case X86::CR3: case X86::CR11: case X86::DR3: return 3;
173 case X86::CR4: case X86::CR12: case X86::DR4: return 4;
174 case X86::CR5: case X86::CR13: case X86::DR5: return 5;
175 case X86::CR6: case X86::CR14: case X86::DR6: return 6;
176 case X86::CR7: case X86::CR15: case X86::DR7: return 7;
Kevin Enderby31b6c5b2010-05-28 19:01:27 +0000177
Bruno Cardoso Lopes3c8e1be2010-07-24 00:06:39 +0000178 // Pseudo index registers are equivalent to a "none"
179 // scaled index (See Intel Manual 2A, table 2-3)
180 case X86::EIZ:
181 case X86::RIZ:
182 return 4;
183
Duncan Sandsee465742007-08-29 19:01:20 +0000184 default:
185 assert(isVirtualRegister(RegNo) && "Unknown physical register!");
Torok Edwinc23197a2009-07-14 16:55:14 +0000186 llvm_unreachable("Register allocator hasn't allocated reg correctly yet!");
Duncan Sandsee465742007-08-29 19:01:20 +0000187 return 0;
188 }
189}
190
Evan Cheng52484682009-07-18 02:10:10 +0000191const TargetRegisterClass *
192X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
193 const TargetRegisterClass *B,
194 unsigned SubIdx) const {
195 switch (SubIdx) {
196 default: return 0;
Jakob Stoklund Olesen22c0e972010-05-25 17:04:16 +0000197 case X86::sub_8bit:
Evan Cheng52484682009-07-18 02:10:10 +0000198 if (B == &X86::GR8RegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000199 if (A->getSize() == 2 || A->getSize() == 4 || A->getSize() == 8)
200 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000201 } else if (B == &X86::GR8_ABCD_LRegClass || B == &X86::GR8_ABCD_HRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000202 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000203 A == &X86::GR64_NOREXRegClass ||
204 A == &X86::GR64_NOSPRegClass ||
205 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000206 return &X86::GR64_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000207 else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000208 A == &X86::GR32_NOREXRegClass ||
209 A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000210 return &X86::GR32_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000211 else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
212 A == &X86::GR16_NOREXRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000213 return &X86::GR16_ABCDRegClass;
214 } else if (B == &X86::GR8_NOREXRegClass) {
Dan Gohmana4714e02009-07-30 01:56:29 +0000215 if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
216 A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000217 return &X86::GR64_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000218 else if (A == &X86::GR64_ABCDRegClass)
219 return &X86::GR64_ABCDRegClass;
Dan Gohmana4714e02009-07-30 01:56:29 +0000220 else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass ||
221 A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000222 return &X86::GR32_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000223 else if (A == &X86::GR32_ABCDRegClass)
224 return &X86::GR32_ABCDRegClass;
Evan Cheng52484682009-07-18 02:10:10 +0000225 else if (A == &X86::GR16RegClass || A == &X86::GR16_NOREXRegClass)
226 return &X86::GR16_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000227 else if (A == &X86::GR16_ABCDRegClass)
228 return &X86::GR16_ABCDRegClass;
Evan Cheng52484682009-07-18 02:10:10 +0000229 }
230 break;
Jakob Stoklund Olesen22c0e972010-05-25 17:04:16 +0000231 case X86::sub_8bit_hi:
Evan Cheng52484682009-07-18 02:10:10 +0000232 if (B == &X86::GR8_ABCD_HRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000233 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000234 A == &X86::GR64_NOREXRegClass ||
235 A == &X86::GR64_NOSPRegClass ||
236 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000237 return &X86::GR64_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000238 else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000239 A == &X86::GR32_NOREXRegClass || A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000240 return &X86::GR32_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000241 else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
242 A == &X86::GR16_NOREXRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000243 return &X86::GR16_ABCDRegClass;
244 }
245 break;
Jakob Stoklund Olesen22c0e972010-05-25 17:04:16 +0000246 case X86::sub_16bit:
Evan Cheng52484682009-07-18 02:10:10 +0000247 if (B == &X86::GR16RegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000248 if (A->getSize() == 4 || A->getSize() == 8)
249 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000250 } else if (B == &X86::GR16_ABCDRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000251 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000252 A == &X86::GR64_NOREXRegClass ||
253 A == &X86::GR64_NOSPRegClass ||
254 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000255 return &X86::GR64_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000256 else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000257 A == &X86::GR32_NOREXRegClass || A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000258 return &X86::GR32_ABCDRegClass;
259 } else if (B == &X86::GR16_NOREXRegClass) {
Dan Gohmana4714e02009-07-30 01:56:29 +0000260 if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
261 A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000262 return &X86::GR64_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000263 else if (A == &X86::GR64_ABCDRegClass)
264 return &X86::GR64_ABCDRegClass;
Dan Gohmana4714e02009-07-30 01:56:29 +0000265 else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass ||
266 A == &X86::GR32_NOSPRegClass)
Evan Cheng753480a2009-07-20 19:47:55 +0000267 return &X86::GR32_NOREXRegClass;
268 else if (A == &X86::GR32_ABCDRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000269 return &X86::GR64_ABCDRegClass;
270 }
271 break;
Jakob Stoklund Olesen22c0e972010-05-25 17:04:16 +0000272 case X86::sub_32bit:
Jakob Stoklund Olesen8f42a192010-10-06 23:56:46 +0000273 if (B == &X86::GR32RegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000274 if (A->getSize() == 8)
275 return A;
Jakob Stoklund Olesen8f42a192010-10-06 23:56:46 +0000276 } else if (B == &X86::GR32_NOSPRegClass) {
Jakob Stoklund Olesen8456c4f2010-10-07 18:47:10 +0000277 if (A == &X86::GR64RegClass || A == &X86::GR64_NOSPRegClass)
Jakob Stoklund Olesen8f42a192010-10-06 23:56:46 +0000278 return &X86::GR64_NOSPRegClass;
279 if (A->getSize() == 8)
280 return getCommonSubClass(A, &X86::GR64_NOSPRegClass);
Evan Cheng52484682009-07-18 02:10:10 +0000281 } else if (B == &X86::GR32_ABCDRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000282 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000283 A == &X86::GR64_NOREXRegClass ||
284 A == &X86::GR64_NOSPRegClass ||
285 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000286 return &X86::GR64_ABCDRegClass;
287 } else if (B == &X86::GR32_NOREXRegClass) {
Dan Gohmana4714e02009-07-30 01:56:29 +0000288 if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
289 A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000290 return &X86::GR64_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000291 else if (A == &X86::GR64_ABCDRegClass)
292 return &X86::GR64_ABCDRegClass;
Evan Cheng52484682009-07-18 02:10:10 +0000293 }
294 break;
Jakob Stoklund Olesenb5398522010-05-25 19:49:40 +0000295 case X86::sub_ss:
296 if (B == &X86::FR32RegClass)
297 return A;
298 break;
299 case X86::sub_sd:
300 if (B == &X86::FR64RegClass)
301 return A;
302 break;
303 case X86::sub_xmm:
304 if (B == &X86::VR128RegClass)
305 return A;
306 break;
Evan Cheng52484682009-07-18 02:10:10 +0000307 }
308 return 0;
309}
310
Bill Wendling80c76432009-08-16 11:00:26 +0000311const TargetRegisterClass *
312X86RegisterInfo::getPointerRegClass(unsigned Kind) const {
Dan Gohmana4714e02009-07-30 01:56:29 +0000313 switch (Kind) {
314 default: llvm_unreachable("Unexpected Kind in getPointerRegClass!");
315 case 0: // Normal GPRs.
316 if (TM.getSubtarget<X86Subtarget>().is64Bit())
317 return &X86::GR64RegClass;
318 return &X86::GR32RegClass;
319 case 1: // Normal GRPs except the stack pointer (for encoding reasons).
Dan Gohman74f6f9a2009-08-05 17:40:24 +0000320 if (TM.getSubtarget<X86Subtarget>().is64Bit())
321 return &X86::GR64_NOSPRegClass;
322 return &X86::GR32_NOSPRegClass;
Dan Gohmana4714e02009-07-30 01:56:29 +0000323 }
Evan Cheng770bcc72009-02-06 17:43:24 +0000324}
325
Evan Chengff110262007-09-26 21:31:07 +0000326const TargetRegisterClass *
327X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
Anton Korobeynikov4aefd6b2008-02-20 12:07:57 +0000328 if (RC == &X86::CCRRegClass) {
Evan Cheng3f2d9ec2007-09-27 21:50:05 +0000329 if (Is64Bit)
330 return &X86::GR64RegClass;
331 else
332 return &X86::GR32RegClass;
Anton Korobeynikov4aefd6b2008-02-20 12:07:57 +0000333 }
Evan Chengff110262007-09-26 21:31:07 +0000334 return NULL;
335}
Evan Chengbf2c8b32007-03-20 08:09:38 +0000336
Evan Cheng64d80e32007-07-19 01:14:50 +0000337const unsigned *
338X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000339 bool callsEHReturn = false;
Chris Lattner29689432010-03-11 00:22:57 +0000340 bool ghcCall = false;
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000341
342 if (MF) {
Chris Lattnera267b002010-04-05 05:57:52 +0000343 callsEHReturn = MF->getMMI().callsEHReturn();
Chris Lattner29689432010-03-11 00:22:57 +0000344 const Function *F = MF->getFunction();
345 ghcCall = (F ? F->getCallingConv() == CallingConv::GHC : false);
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000346 }
347
Chris Lattner29689432010-03-11 00:22:57 +0000348 static const unsigned GhcCalleeSavedRegs[] = {
349 0
350 };
351
Evan Chengc2b861d2007-01-02 21:33:40 +0000352 static const unsigned CalleeSavedRegs32Bit[] = {
Evan Cheng0f3ac8d2006-05-18 00:12:58 +0000353 X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0
354 };
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000355
356 static const unsigned CalleeSavedRegs32EHRet[] = {
357 X86::EAX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0
358 };
359
Evan Chengc2b861d2007-01-02 21:33:40 +0000360 static const unsigned CalleeSavedRegs64Bit[] = {
Evan Cheng25ab6902006-09-08 06:48:29 +0000361 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
362 };
363
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000364 static const unsigned CalleeSavedRegs64EHRet[] = {
365 X86::RAX, X86::RDX, X86::RBX, X86::R12,
366 X86::R13, X86::R14, X86::R15, X86::RBP, 0
367 };
368
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000369 static const unsigned CalleeSavedRegsWin64[] = {
Anton Korobeynikov5979d712008-09-24 22:03:04 +0000370 X86::RBX, X86::RBP, X86::RDI, X86::RSI,
371 X86::R12, X86::R13, X86::R14, X86::R15,
372 X86::XMM6, X86::XMM7, X86::XMM8, X86::XMM9,
373 X86::XMM10, X86::XMM11, X86::XMM12, X86::XMM13,
374 X86::XMM14, X86::XMM15, 0
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000375 };
376
Chris Lattner29689432010-03-11 00:22:57 +0000377 if (ghcCall) {
378 return GhcCalleeSavedRegs;
379 } else if (Is64Bit) {
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000380 if (IsWin64)
381 return CalleeSavedRegsWin64;
382 else
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000383 return (callsEHReturn ? CalleeSavedRegs64EHRet : CalleeSavedRegs64Bit);
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000384 } else {
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000385 return (callsEHReturn ? CalleeSavedRegs32EHRet : CalleeSavedRegs32Bit);
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000386 }
Evan Cheng0f3ac8d2006-05-18 00:12:58 +0000387}
388
Evan Chengb371f452007-02-19 21:49:54 +0000389BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
390 BitVector Reserved(getNumRegs());
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000391 const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
392
Dan Gohmana32b7ac2008-12-18 01:05:09 +0000393 // Set the stack-pointer register and its aliases as reserved.
Evan Chengb371f452007-02-19 21:49:54 +0000394 Reserved.set(X86::RSP);
395 Reserved.set(X86::ESP);
396 Reserved.set(X86::SP);
397 Reserved.set(X86::SPL);
Bill Wendling80c76432009-08-16 11:00:26 +0000398
Jakob Stoklund Olesen52cd5482009-11-13 21:56:01 +0000399 // Set the instruction pointer register and its aliases as reserved.
400 Reserved.set(X86::RIP);
401 Reserved.set(X86::EIP);
402 Reserved.set(X86::IP);
403
Dan Gohmana32b7ac2008-12-18 01:05:09 +0000404 // Set the frame-pointer register and its aliases as reserved if needed.
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000405 if (TFI->hasFP(MF)) {
Evan Chengb371f452007-02-19 21:49:54 +0000406 Reserved.set(X86::RBP);
407 Reserved.set(X86::EBP);
408 Reserved.set(X86::BP);
409 Reserved.set(X86::BPL);
410 }
Bill Wendling80c76432009-08-16 11:00:26 +0000411
412 // Mark the x87 stack registers as reserved, since they don't behave normally
413 // with respect to liveness. We don't fully model the effects of x87 stack
414 // pushes and pops after stackification.
Dan Gohmana32b7ac2008-12-18 01:05:09 +0000415 Reserved.set(X86::ST0);
416 Reserved.set(X86::ST1);
417 Reserved.set(X86::ST2);
418 Reserved.set(X86::ST3);
419 Reserved.set(X86::ST4);
420 Reserved.set(X86::ST5);
421 Reserved.set(X86::ST6);
422 Reserved.set(X86::ST7);
Evan Chengb371f452007-02-19 21:49:54 +0000423 return Reserved;
424}
425
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000426//===----------------------------------------------------------------------===//
427// Stack Frame Processing methods
428//===----------------------------------------------------------------------===//
429
Jim Grosbache45ab8a2010-01-19 18:31:11 +0000430bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
431 const MachineFrameInfo *MFI = MF.getFrameInfo();
432 return (RealignStack &&
433 !MFI->hasVarSizedObjects());
434}
435
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000436bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
Nick Lewycky9c0f1462009-03-19 05:51:39 +0000437 const MachineFrameInfo *MFI = MF.getFrameInfo();
Charles Davis5dfa2672010-02-19 18:17:13 +0000438 const Function *F = MF.getFunction();
Eric Christopher697cba82010-07-17 00:33:04 +0000439 bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) ||
440 F->hasFnAttr(Attribute::StackAlignment));
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000441
Anton Korobeynikov35410a42008-04-23 18:16:43 +0000442 // FIXME: Currently we don't support stack realignment for functions with
Anton Korobeynikovb23f3aa2009-11-14 18:01:41 +0000443 // variable-sized allocas.
Eric Christopheracdb4b92010-07-17 00:25:41 +0000444 // FIXME: It's more complicated than this...
Anton Korobeynikovb23f3aa2009-11-14 18:01:41 +0000445 if (0 && requiresRealignment && MFI->hasVarSizedObjects())
Chris Lattner75361b62010-04-07 22:58:41 +0000446 report_fatal_error(
Anton Korobeynikov773943a2009-11-08 12:58:40 +0000447 "Stack realignment in presense of dynamic allocas is not supported");
Eric Christophere74a0882010-08-05 23:57:43 +0000448
449 // If we've requested that we force align the stack do so now.
450 if (ForceStackAlign)
451 return canRealignStack(MF);
452
Eric Christopheracdb4b92010-07-17 00:25:41 +0000453 return requiresRealignment && canRealignStack(MF);
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000454}
455
Eric Christopher72852a82010-07-20 06:52:21 +0000456bool X86RegisterInfo::hasReservedSpillSlot(const MachineFunction &MF,
457 unsigned Reg, int &FrameIdx) const {
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000458 const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
459
460 if (Reg == FramePtr && TFI->hasFP(MF)) {
Evan Cheng910139f2009-07-09 06:53:48 +0000461 FrameIdx = MF.getFrameInfo()->getObjectIndexBegin();
462 return true;
463 }
464 return false;
465}
466
Dan Gohman7c2e0392010-05-19 00:53:19 +0000467static unsigned getSUBriOpcode(unsigned is64Bit, int64_t Imm) {
468 if (is64Bit) {
469 if (isInt<8>(Imm))
470 return X86::SUB64ri8;
471 return X86::SUB64ri32;
472 } else {
473 if (isInt<8>(Imm))
474 return X86::SUB32ri8;
475 return X86::SUB32ri;
476 }
477}
478
479static unsigned getADDriOpcode(unsigned is64Bit, int64_t Imm) {
480 if (is64Bit) {
481 if (isInt<8>(Imm))
482 return X86::ADD64ri8;
483 return X86::ADD64ri32;
484 } else {
485 if (isInt<8>(Imm))
486 return X86::ADD32ri8;
487 return X86::ADD32ri;
488 }
489}
490
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000491void X86RegisterInfo::
492eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
493 MachineBasicBlock::iterator I) const {
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000494 const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
Evan Chenge4a2dd22010-12-23 23:54:17 +0000495 bool reseveCallFrame = TFI->hasReservedCallFrame(MF);
496 int Opcode = I->getOpcode();
497 bool isDestroy = Opcode == getCallFrameDestroyOpcode();
498 DebugLoc DL = I->getDebugLoc();
499 uint64_t Amount = !reseveCallFrame ? I->getOperand(0).getImm() : 0;
500 uint64_t CalleeAmt = isDestroy ? I->getOperand(1).getImm() : 0;
501 I = MBB.erase(I);
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000502
Evan Chenge4a2dd22010-12-23 23:54:17 +0000503 if (!reseveCallFrame) {
Evan Cheng7e7bbf82007-07-19 00:42:05 +0000504 // If the stack pointer can be changed after prologue, turn the
505 // adjcallstackup instruction into a 'sub ESP, <amt>' and the
506 // adjcallstackdown instruction into 'add ESP, <amt>'
507 // TODO: consider using push / pop instead of sub + store / add
Evan Chenge4a2dd22010-12-23 23:54:17 +0000508 if (Amount == 0)
509 return;
Chris Lattnerf158da22003-01-16 02:20:12 +0000510
Evan Chenge4a2dd22010-12-23 23:54:17 +0000511 // We need to keep the stack aligned properly. To do this, we round the
512 // amount of space needed for the outgoing arguments up to the next
513 // alignment boundary.
514 Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign;
Bill Wendling80c76432009-08-16 11:00:26 +0000515
Evan Chenge4a2dd22010-12-23 23:54:17 +0000516 MachineInstr *New = 0;
517 if (Opcode == getCallFrameSetupOpcode()) {
518 New = BuildMI(MF, DL, TII.get(getSUBriOpcode(Is64Bit, Amount)),
519 StackPtr)
520 .addReg(StackPtr)
521 .addImm(Amount);
522 } else {
523 assert(Opcode == getCallFrameDestroyOpcode());
524
525 // Factor out the amount the callee already popped.
526 Amount -= CalleeAmt;
Bill Wendling80c76432009-08-16 11:00:26 +0000527
528 if (Amount) {
Evan Chenge4a2dd22010-12-23 23:54:17 +0000529 unsigned Opc = getADDriOpcode(Is64Bit, Amount);
530 New = BuildMI(MF, DL, TII.get(Opc), StackPtr)
531 .addReg(StackPtr).addImm(Amount);
Dan Gohmand293e0d2009-02-11 19:50:24 +0000532 }
Chris Lattner3648c672005-05-13 21:44:04 +0000533 }
Evan Chenge4a2dd22010-12-23 23:54:17 +0000534
535 if (New) {
536 // The EFLAGS implicit def is dead.
537 New->getOperand(3).setIsDead();
538
539 // Replace the pseudo instruction with a new instruction.
540 MBB.insert(I, New);
541 }
542
543 return;
544 }
545
546 if (Opcode == getCallFrameDestroyOpcode() && CalleeAmt) {
Chris Lattner3648c672005-05-13 21:44:04 +0000547 // If we are performing frame pointer elimination and if the callee pops
548 // something off the stack pointer, add it back. We do this until we have
549 // more advanced stack pointer tracking ability.
Evan Chenge4a2dd22010-12-23 23:54:17 +0000550 unsigned Opc = getSUBriOpcode(Is64Bit, CalleeAmt);
551 MachineInstr *New = BuildMI(MF, DL, TII.get(Opc), StackPtr)
552 .addReg(StackPtr).addImm(CalleeAmt);
Bill Wendling80c76432009-08-16 11:00:26 +0000553
Evan Chenge4a2dd22010-12-23 23:54:17 +0000554 // The EFLAGS implicit def is dead.
555 New->getOperand(3).setIsDead();
556 MBB.insert(I, New);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000557 }
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000558}
559
Jim Grosbachfcb4a8e2010-08-26 23:32:16 +0000560void
Jim Grosbachb58f4982009-10-07 17:12:56 +0000561X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
Jim Grosbachfcb4a8e2010-08-26 23:32:16 +0000562 int SPAdj, RegScavenger *RS) const{
Evan Cheng97de9132007-05-01 09:13:03 +0000563 assert(SPAdj == 0 && "Unexpected");
564
Chris Lattnerd264bec2003-01-13 00:50:33 +0000565 unsigned i = 0;
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000566 MachineInstr &MI = *II;
Nate Begemanf8be5e92004-08-14 22:05:10 +0000567 MachineFunction &MF = *MI.getParent()->getParent();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000568 const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
Bill Wendling80c76432009-08-16 11:00:26 +0000569
Dan Gohmand735b802008-10-03 15:45:36 +0000570 while (!MI.getOperand(i).isFI()) {
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000571 ++i;
572 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
573 }
574
Chris Lattner8aa797a2007-12-30 23:10:15 +0000575 int FrameIndex = MI.getOperand(i).getIndex();
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000576 unsigned BasePtr;
Bill Wendling80c76432009-08-16 11:00:26 +0000577
Evan Cheng3f54c642010-04-29 05:08:22 +0000578 unsigned Opc = MI.getOpcode();
579 bool AfterFPPop = Opc == X86::TAILJMPm64 || Opc == X86::TAILJMPm;
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000580 if (needsStackRealignment(MF))
581 BasePtr = (FrameIndex < 0 ? FramePtr : StackPtr);
Evan Cheng3f54c642010-04-29 05:08:22 +0000582 else if (AfterFPPop)
583 BasePtr = StackPtr;
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000584 else
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000585 BasePtr = (TFI->hasFP(MF) ? FramePtr : StackPtr);
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000586
Chris Lattnerd264bec2003-01-13 00:50:33 +0000587 // This must be part of a four operand memory reference. Replace the
Evan Cheng25ab6902006-09-08 06:48:29 +0000588 // FrameIndex with base register with EBP. Add an offset to the offset.
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000589 MI.getOperand(i).ChangeToRegister(BasePtr, false);
Chris Lattnerd264bec2003-01-13 00:50:33 +0000590
Dan Gohman82779702008-12-24 00:27:51 +0000591 // Now add the frame object offset to the offset from EBP.
Evan Cheng3f54c642010-04-29 05:08:22 +0000592 int FIOffset;
593 if (AfterFPPop) {
594 // Tail call jmp happens after FP is popped.
Evan Cheng3f54c642010-04-29 05:08:22 +0000595 const MachineFrameInfo *MFI = MF.getFrameInfo();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000596 FIOffset = MFI->getObjectOffset(FrameIndex) - TFI->getOffsetOfLocalArea();
Evan Cheng3f54c642010-04-29 05:08:22 +0000597 } else
Anton Korobeynikov82f58742010-11-20 15:59:32 +0000598 FIOffset = TFI->getFrameIndexOffset(MF, FrameIndex);
Evan Cheng3f54c642010-04-29 05:08:22 +0000599
Dan Gohman82779702008-12-24 00:27:51 +0000600 if (MI.getOperand(i+3).isImm()) {
601 // Offset is a 32-bit integer.
Evan Cheng3f54c642010-04-29 05:08:22 +0000602 int Offset = FIOffset + (int)(MI.getOperand(i + 3).getImm());
David Greene3f2bf852009-11-12 20:49:22 +0000603 MI.getOperand(i + 3).ChangeToImmediate(Offset);
Dan Gohman82779702008-12-24 00:27:51 +0000604 } else {
605 // Offset is symbolic. This is extremely rare.
Evan Cheng3f54c642010-04-29 05:08:22 +0000606 uint64_t Offset = FIOffset + (uint64_t)MI.getOperand(i+3).getOffset();
Dan Gohman82779702008-12-24 00:27:51 +0000607 MI.getOperand(i+3).setOffset(Offset);
608 }
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000609}
610
Jim Laskey41886992006-04-07 16:34:46 +0000611unsigned X86RegisterInfo::getRARegister() const {
Bill Wendling80c76432009-08-16 11:00:26 +0000612 return Is64Bit ? X86::RIP // Should have dwarf #16.
613 : X86::EIP; // Should have dwarf #8.
Jim Laskey41886992006-04-07 16:34:46 +0000614}
615
David Greene3f2bf852009-11-12 20:49:22 +0000616unsigned X86RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000617 const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
618 return TFI->hasFP(MF) ? FramePtr : StackPtr;
Jim Laskeyf1d78e82006-03-23 18:12:57 +0000619}
620
Jim Laskey62819f32007-02-21 22:54:50 +0000621unsigned X86RegisterInfo::getEHExceptionRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +0000622 llvm_unreachable("What is the exception register");
Jim Laskey62819f32007-02-21 22:54:50 +0000623 return 0;
624}
625
626unsigned X86RegisterInfo::getEHHandlerRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +0000627 llvm_unreachable("What is the exception handler register");
Jim Laskey62819f32007-02-21 22:54:50 +0000628 return 0;
629}
630
Evan Cheng8f7f7122006-05-05 05:40:20 +0000631namespace llvm {
Owen Andersone50ed302009-08-10 22:56:29 +0000632unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) {
Owen Anderson825b72b2009-08-11 20:47:22 +0000633 switch (VT.getSimpleVT().SimpleTy) {
Evan Cheng8f7f7122006-05-05 05:40:20 +0000634 default: return Reg;
Owen Anderson825b72b2009-08-11 20:47:22 +0000635 case MVT::i8:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000636 if (High) {
637 switch (Reg) {
Evan Cheng25ab6902006-09-08 06:48:29 +0000638 default: return 0;
639 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000640 return X86::AH;
Evan Cheng25ab6902006-09-08 06:48:29 +0000641 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000642 return X86::DH;
Evan Cheng25ab6902006-09-08 06:48:29 +0000643 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000644 return X86::CH;
Evan Cheng25ab6902006-09-08 06:48:29 +0000645 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000646 return X86::BH;
647 }
648 } else {
649 switch (Reg) {
Evan Cheng25ab6902006-09-08 06:48:29 +0000650 default: return 0;
651 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000652 return X86::AL;
Evan Cheng25ab6902006-09-08 06:48:29 +0000653 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000654 return X86::DL;
Evan Cheng25ab6902006-09-08 06:48:29 +0000655 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000656 return X86::CL;
Evan Cheng25ab6902006-09-08 06:48:29 +0000657 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000658 return X86::BL;
Evan Cheng25ab6902006-09-08 06:48:29 +0000659 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
660 return X86::SIL;
661 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
662 return X86::DIL;
663 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
664 return X86::BPL;
665 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
666 return X86::SPL;
667 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
668 return X86::R8B;
669 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
670 return X86::R9B;
671 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
672 return X86::R10B;
673 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
674 return X86::R11B;
675 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
676 return X86::R12B;
677 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
678 return X86::R13B;
679 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
680 return X86::R14B;
681 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
682 return X86::R15B;
Evan Cheng8f7f7122006-05-05 05:40:20 +0000683 }
684 }
Owen Anderson825b72b2009-08-11 20:47:22 +0000685 case MVT::i16:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000686 switch (Reg) {
687 default: return Reg;
Evan Cheng25ab6902006-09-08 06:48:29 +0000688 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000689 return X86::AX;
Evan Cheng25ab6902006-09-08 06:48:29 +0000690 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000691 return X86::DX;
Evan Cheng25ab6902006-09-08 06:48:29 +0000692 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000693 return X86::CX;
Evan Cheng25ab6902006-09-08 06:48:29 +0000694 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000695 return X86::BX;
Evan Cheng25ab6902006-09-08 06:48:29 +0000696 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000697 return X86::SI;
Evan Cheng25ab6902006-09-08 06:48:29 +0000698 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000699 return X86::DI;
Evan Cheng25ab6902006-09-08 06:48:29 +0000700 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000701 return X86::BP;
Evan Cheng25ab6902006-09-08 06:48:29 +0000702 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000703 return X86::SP;
Evan Cheng25ab6902006-09-08 06:48:29 +0000704 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
705 return X86::R8W;
706 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
707 return X86::R9W;
708 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
709 return X86::R10W;
710 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
711 return X86::R11W;
712 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
713 return X86::R12W;
714 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
715 return X86::R13W;
716 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
717 return X86::R14W;
718 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
719 return X86::R15W;
Evan Cheng8f7f7122006-05-05 05:40:20 +0000720 }
Owen Anderson825b72b2009-08-11 20:47:22 +0000721 case MVT::i32:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000722 switch (Reg) {
Evan Cheng25ab6902006-09-08 06:48:29 +0000723 default: return Reg;
724 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000725 return X86::EAX;
Evan Cheng25ab6902006-09-08 06:48:29 +0000726 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000727 return X86::EDX;
Evan Cheng25ab6902006-09-08 06:48:29 +0000728 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000729 return X86::ECX;
Evan Cheng25ab6902006-09-08 06:48:29 +0000730 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000731 return X86::EBX;
Evan Cheng25ab6902006-09-08 06:48:29 +0000732 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000733 return X86::ESI;
Evan Cheng25ab6902006-09-08 06:48:29 +0000734 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000735 return X86::EDI;
Evan Cheng25ab6902006-09-08 06:48:29 +0000736 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000737 return X86::EBP;
Evan Cheng25ab6902006-09-08 06:48:29 +0000738 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
Evan Cheng8f7f7122006-05-05 05:40:20 +0000739 return X86::ESP;
Evan Cheng25ab6902006-09-08 06:48:29 +0000740 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
741 return X86::R8D;
742 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
743 return X86::R9D;
744 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
745 return X86::R10D;
746 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
747 return X86::R11D;
748 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
749 return X86::R12D;
750 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
751 return X86::R13D;
752 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
753 return X86::R14D;
754 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
755 return X86::R15D;
756 }
Owen Anderson825b72b2009-08-11 20:47:22 +0000757 case MVT::i64:
Evan Cheng25ab6902006-09-08 06:48:29 +0000758 switch (Reg) {
759 default: return Reg;
760 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
761 return X86::RAX;
762 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
763 return X86::RDX;
764 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
765 return X86::RCX;
766 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
767 return X86::RBX;
768 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
769 return X86::RSI;
770 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
771 return X86::RDI;
772 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
773 return X86::RBP;
774 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
775 return X86::RSP;
776 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
777 return X86::R8;
778 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
779 return X86::R9;
780 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
781 return X86::R10;
782 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
783 return X86::R11;
784 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
785 return X86::R12;
786 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
787 return X86::R13;
788 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
789 return X86::R14;
790 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
791 return X86::R15;
Evan Cheng8f7f7122006-05-05 05:40:20 +0000792 }
793 }
794
795 return Reg;
796}
797}
798
Chris Lattner7ad3e062003-08-03 15:48:14 +0000799#include "X86GenRegisterInfo.inc"
Jim Grosbachfa85eb62010-04-06 20:26:37 +0000800
801namespace {
802 struct MSAH : public MachineFunctionPass {
803 static char ID;
Owen Anderson90c579d2010-08-06 18:33:48 +0000804 MSAH() : MachineFunctionPass(ID) {}
Jim Grosbachfa85eb62010-04-06 20:26:37 +0000805
806 virtual bool runOnMachineFunction(MachineFunction &MF) {
807 const X86TargetMachine *TM =
808 static_cast<const X86TargetMachine *>(&MF.getTarget());
809 const X86RegisterInfo *X86RI = TM->getRegisterInfo();
810 MachineRegisterInfo &RI = MF.getRegInfo();
811 X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
812 unsigned StackAlignment = X86RI->getStackAlignment();
813
814 // Be over-conservative: scan over all vreg defs and find whether vector
815 // registers are used. If yes, there is a possibility that vector register
816 // will be spilled and thus require dynamic stack realignment.
Jakob Stoklund Olesenb2581352011-01-08 23:11:11 +0000817 for (unsigned i = 0, e = RI.getNumVirtRegs(); i != e; ++i) {
818 unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
819 if (RI.getRegClass(Reg)->getAlignment() > StackAlignment) {
Jim Grosbachfa85eb62010-04-06 20:26:37 +0000820 FuncInfo->setReserveFP(true);
821 return true;
822 }
Jakob Stoklund Olesenb2581352011-01-08 23:11:11 +0000823 }
Jim Grosbachfa85eb62010-04-06 20:26:37 +0000824 // Nothing to do
825 return false;
826 }
827
828 virtual const char *getPassName() const {
829 return "X86 Maximal Stack Alignment Check";
830 }
831
832 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
833 AU.setPreservesCFG();
834 MachineFunctionPass::getAnalysisUsage(AU);
835 }
836 };
837
838 char MSAH::ID = 0;
839}
840
841FunctionPass*
842llvm::createX86MaxStackAlignmentHeuristicPass() { return new MSAH(); }