blob: abb9aca78e9c70a7e477a749b801ad66286c614f [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"
Dan Gohmana4714e02009-07-30 01:56:29 +000040#include "llvm/Support/CommandLine.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000041#include "llvm/Support/ErrorHandling.h"
Chris Lattner300d0ed2004-02-14 06:00:36 +000042using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000043
Evan Cheng25ab6902006-09-08 06:48:29 +000044X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm,
45 const TargetInstrInfo &tii)
Dan Gohman6d4b0522008-10-01 18:28:06 +000046 : X86GenRegisterInfo(tm.getSubtarget<X86Subtarget>().is64Bit() ?
47 X86::ADJCALLSTACKDOWN64 :
48 X86::ADJCALLSTACKDOWN32,
49 tm.getSubtarget<X86Subtarget>().is64Bit() ?
50 X86::ADJCALLSTACKUP64 :
51 X86::ADJCALLSTACKUP32),
Evan Cheng25ab6902006-09-08 06:48:29 +000052 TM(tm), TII(tii) {
53 // Cache some information.
54 const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
55 Is64Bit = Subtarget->is64Bit();
Anton Korobeynikov1dcce212008-03-22 21:04:01 +000056 IsWin64 = Subtarget->isTargetWin64();
Evan Chengdb807ed2007-11-05 07:30:01 +000057 StackAlign = TM.getFrameInfo()->getStackAlignment();
Bill Wendling80c76432009-08-16 11:00:26 +000058
Evan Cheng25ab6902006-09-08 06:48:29 +000059 if (Is64Bit) {
60 SlotSize = 8;
61 StackPtr = X86::RSP;
62 FramePtr = X86::RBP;
63 } else {
64 SlotSize = 4;
65 StackPtr = X86::ESP;
66 FramePtr = X86::EBP;
67 }
68}
Chris Lattner7ad3e062003-08-03 15:48:14 +000069
Bill Wendling80c76432009-08-16 11:00:26 +000070/// getDwarfRegNum - This function maps LLVM register identifiers to the DWARF
71/// specific numbering, used in debug info and exception tables.
Dale Johannesenb97aec62007-11-13 19:13:01 +000072int X86RegisterInfo::getDwarfRegNum(unsigned RegNo, bool isEH) const {
Dale Johannesen483ec212007-11-07 00:25:05 +000073 const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
Anton Korobeynikovf191c802007-11-11 19:50:10 +000074 unsigned Flavour = DWARFFlavour::X86_64;
Bill Wendling80c76432009-08-16 11:00:26 +000075
Dale Johannesen7a42f242007-11-09 18:07:11 +000076 if (!Subtarget->is64Bit()) {
Anton Korobeynikovf191c802007-11-11 19:50:10 +000077 if (Subtarget->isTargetDarwin()) {
Anton Korobeynikov8eea3392008-01-25 00:34:13 +000078 if (isEH)
79 Flavour = DWARFFlavour::X86_32_DarwinEH;
80 else
81 Flavour = DWARFFlavour::X86_32_Generic;
Anton Korobeynikovf191c802007-11-11 19:50:10 +000082 } else if (Subtarget->isTargetCygMing()) {
83 // Unsupported by now, just quick fallback
Anton Korobeynikov8eea3392008-01-25 00:34:13 +000084 Flavour = DWARFFlavour::X86_32_Generic;
Anton Korobeynikovf191c802007-11-11 19:50:10 +000085 } else {
Anton Korobeynikov8eea3392008-01-25 00:34:13 +000086 Flavour = DWARFFlavour::X86_32_Generic;
Dale Johannesen7a42f242007-11-09 18:07:11 +000087 }
Dale Johannesen483ec212007-11-07 00:25:05 +000088 }
Anton Korobeynikovf191c802007-11-11 19:50:10 +000089
90 return X86GenRegisterInfo::getDwarfRegNumFull(RegNo, Flavour);
Dale Johannesen483ec212007-11-07 00:25:05 +000091}
92
Bill Wendling80c76432009-08-16 11:00:26 +000093/// getX86RegNum - This function maps LLVM register identifiers to their X86
94/// specific numbering, which is used in various places encoding instructions.
Nicolas Geoffray52e724a2008-04-16 20:10:13 +000095unsigned X86RegisterInfo::getX86RegNum(unsigned RegNo) {
Duncan Sandsee465742007-08-29 19:01:20 +000096 switch(RegNo) {
97 case X86::RAX: case X86::EAX: case X86::AX: case X86::AL: return N86::EAX;
98 case X86::RCX: case X86::ECX: case X86::CX: case X86::CL: return N86::ECX;
99 case X86::RDX: case X86::EDX: case X86::DX: case X86::DL: return N86::EDX;
100 case X86::RBX: case X86::EBX: case X86::BX: case X86::BL: return N86::EBX;
101 case X86::RSP: case X86::ESP: case X86::SP: case X86::SPL: case X86::AH:
102 return N86::ESP;
103 case X86::RBP: case X86::EBP: case X86::BP: case X86::BPL: case X86::CH:
104 return N86::EBP;
105 case X86::RSI: case X86::ESI: case X86::SI: case X86::SIL: case X86::DH:
106 return N86::ESI;
107 case X86::RDI: case X86::EDI: case X86::DI: case X86::DIL: case X86::BH:
108 return N86::EDI;
109
110 case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
111 return N86::EAX;
112 case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
113 return N86::ECX;
114 case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
115 return N86::EDX;
116 case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
117 return N86::EBX;
118 case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
119 return N86::ESP;
120 case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
121 return N86::EBP;
122 case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
123 return N86::ESI;
124 case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
125 return N86::EDI;
126
127 case X86::ST0: case X86::ST1: case X86::ST2: case X86::ST3:
128 case X86::ST4: case X86::ST5: case X86::ST6: case X86::ST7:
129 return RegNo-X86::ST0;
130
Nate Begeman6e041c22007-12-11 18:06:14 +0000131 case X86::XMM0: case X86::XMM8: case X86::MM0:
Evan Chenge7c87542007-11-13 17:54:34 +0000132 return 0;
Nate Begeman6e041c22007-12-11 18:06:14 +0000133 case X86::XMM1: case X86::XMM9: case X86::MM1:
Evan Chenge7c87542007-11-13 17:54:34 +0000134 return 1;
Nate Begeman6e041c22007-12-11 18:06:14 +0000135 case X86::XMM2: case X86::XMM10: case X86::MM2:
Evan Chenge7c87542007-11-13 17:54:34 +0000136 return 2;
Nate Begeman6e041c22007-12-11 18:06:14 +0000137 case X86::XMM3: case X86::XMM11: case X86::MM3:
Evan Chenge7c87542007-11-13 17:54:34 +0000138 return 3;
Nate Begeman6e041c22007-12-11 18:06:14 +0000139 case X86::XMM4: case X86::XMM12: case X86::MM4:
Evan Chenge7c87542007-11-13 17:54:34 +0000140 return 4;
Nate Begeman6e041c22007-12-11 18:06:14 +0000141 case X86::XMM5: case X86::XMM13: case X86::MM5:
Evan Chenge7c87542007-11-13 17:54:34 +0000142 return 5;
Nate Begeman6e041c22007-12-11 18:06:14 +0000143 case X86::XMM6: case X86::XMM14: case X86::MM6:
Evan Chenge7c87542007-11-13 17:54:34 +0000144 return 6;
Nate Begeman6e041c22007-12-11 18:06:14 +0000145 case X86::XMM7: case X86::XMM15: case X86::MM7:
Evan Chenge7c87542007-11-13 17:54:34 +0000146 return 7;
Duncan Sandsee465742007-08-29 19:01:20 +0000147
148 default:
149 assert(isVirtualRegister(RegNo) && "Unknown physical register!");
Torok Edwinc23197a2009-07-14 16:55:14 +0000150 llvm_unreachable("Register allocator hasn't allocated reg correctly yet!");
Duncan Sandsee465742007-08-29 19:01:20 +0000151 return 0;
152 }
153}
154
Evan Cheng52484682009-07-18 02:10:10 +0000155const TargetRegisterClass *
156X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
157 const TargetRegisterClass *B,
158 unsigned SubIdx) const {
159 switch (SubIdx) {
160 default: return 0;
161 case 1:
162 // 8-bit
163 if (B == &X86::GR8RegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000164 if (A->getSize() == 2 || A->getSize() == 4 || A->getSize() == 8)
165 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000166 } else if (B == &X86::GR8_ABCD_LRegClass || B == &X86::GR8_ABCD_HRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000167 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000168 A == &X86::GR64_NOREXRegClass ||
169 A == &X86::GR64_NOSPRegClass ||
170 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000171 return &X86::GR64_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000172 else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000173 A == &X86::GR32_NOREXRegClass ||
174 A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000175 return &X86::GR32_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000176 else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
177 A == &X86::GR16_NOREXRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000178 return &X86::GR16_ABCDRegClass;
179 } else if (B == &X86::GR8_NOREXRegClass) {
Dan Gohmana4714e02009-07-30 01:56:29 +0000180 if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
181 A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000182 return &X86::GR64_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000183 else if (A == &X86::GR64_ABCDRegClass)
184 return &X86::GR64_ABCDRegClass;
Dan Gohmana4714e02009-07-30 01:56:29 +0000185 else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass ||
186 A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000187 return &X86::GR32_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000188 else if (A == &X86::GR32_ABCDRegClass)
189 return &X86::GR32_ABCDRegClass;
Evan Cheng52484682009-07-18 02:10:10 +0000190 else if (A == &X86::GR16RegClass || A == &X86::GR16_NOREXRegClass)
191 return &X86::GR16_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000192 else if (A == &X86::GR16_ABCDRegClass)
193 return &X86::GR16_ABCDRegClass;
Dan Gohman874cada2010-02-28 00:17:42 +0000194 } else if (B == &X86::FR32RegClass) {
195 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000196 }
197 break;
198 case 2:
199 // 8-bit hi
200 if (B == &X86::GR8_ABCD_HRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000201 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000202 A == &X86::GR64_NOREXRegClass ||
203 A == &X86::GR64_NOSPRegClass ||
204 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000205 return &X86::GR64_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000206 else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000207 A == &X86::GR32_NOREXRegClass || A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000208 return &X86::GR32_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000209 else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
210 A == &X86::GR16_NOREXRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000211 return &X86::GR16_ABCDRegClass;
Dan Gohman874cada2010-02-28 00:17:42 +0000212 } else if (B == &X86::FR64RegClass) {
213 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000214 }
215 break;
216 case 3:
217 // 16-bit
218 if (B == &X86::GR16RegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000219 if (A->getSize() == 4 || A->getSize() == 8)
220 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000221 } else if (B == &X86::GR16_ABCDRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000222 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000223 A == &X86::GR64_NOREXRegClass ||
224 A == &X86::GR64_NOSPRegClass ||
225 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000226 return &X86::GR64_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000227 else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000228 A == &X86::GR32_NOREXRegClass || A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000229 return &X86::GR32_ABCDRegClass;
230 } else if (B == &X86::GR16_NOREXRegClass) {
Dan Gohmana4714e02009-07-30 01:56:29 +0000231 if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
232 A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000233 return &X86::GR64_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000234 else if (A == &X86::GR64_ABCDRegClass)
235 return &X86::GR64_ABCDRegClass;
Dan Gohmana4714e02009-07-30 01:56:29 +0000236 else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass ||
237 A == &X86::GR32_NOSPRegClass)
Evan Cheng753480a2009-07-20 19:47:55 +0000238 return &X86::GR32_NOREXRegClass;
239 else if (A == &X86::GR32_ABCDRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000240 return &X86::GR64_ABCDRegClass;
Dan Gohman874cada2010-02-28 00:17:42 +0000241 } else if (B == &X86::VR128RegClass) {
242 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000243 }
244 break;
245 case 4:
246 // 32-bit
Dan Gohmana4714e02009-07-30 01:56:29 +0000247 if (B == &X86::GR32RegClass || B == &X86::GR32_NOSPRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000248 if (A->getSize() == 8)
249 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000250 } else if (B == &X86::GR32_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;
256 } else if (B == &X86::GR32_NOREXRegClass) {
Dan Gohmana4714e02009-07-30 01:56:29 +0000257 if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
258 A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000259 return &X86::GR64_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000260 else if (A == &X86::GR64_ABCDRegClass)
261 return &X86::GR64_ABCDRegClass;
Evan Cheng52484682009-07-18 02:10:10 +0000262 }
263 break;
264 }
265 return 0;
266}
267
Bill Wendling80c76432009-08-16 11:00:26 +0000268const TargetRegisterClass *
269X86RegisterInfo::getPointerRegClass(unsigned Kind) const {
Dan Gohmana4714e02009-07-30 01:56:29 +0000270 switch (Kind) {
271 default: llvm_unreachable("Unexpected Kind in getPointerRegClass!");
272 case 0: // Normal GPRs.
273 if (TM.getSubtarget<X86Subtarget>().is64Bit())
274 return &X86::GR64RegClass;
275 return &X86::GR32RegClass;
276 case 1: // Normal GRPs except the stack pointer (for encoding reasons).
Dan Gohman74f6f9a2009-08-05 17:40:24 +0000277 if (TM.getSubtarget<X86Subtarget>().is64Bit())
278 return &X86::GR64_NOSPRegClass;
279 return &X86::GR32_NOSPRegClass;
Dan Gohmana4714e02009-07-30 01:56:29 +0000280 }
Evan Cheng770bcc72009-02-06 17:43:24 +0000281}
282
Evan Chengff110262007-09-26 21:31:07 +0000283const TargetRegisterClass *
284X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
Anton Korobeynikov4aefd6b2008-02-20 12:07:57 +0000285 if (RC == &X86::CCRRegClass) {
Evan Cheng3f2d9ec2007-09-27 21:50:05 +0000286 if (Is64Bit)
287 return &X86::GR64RegClass;
288 else
289 return &X86::GR32RegClass;
Anton Korobeynikov4aefd6b2008-02-20 12:07:57 +0000290 }
Evan Chengff110262007-09-26 21:31:07 +0000291 return NULL;
292}
Evan Chengbf2c8b32007-03-20 08:09:38 +0000293
Evan Cheng64d80e32007-07-19 01:14:50 +0000294const unsigned *
295X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000296 bool callsEHReturn = false;
Chris Lattner29689432010-03-11 00:22:57 +0000297 bool ghcCall = false;
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000298
299 if (MF) {
Chris Lattnera267b002010-04-05 05:57:52 +0000300 callsEHReturn = MF->getMMI().callsEHReturn();
Chris Lattner29689432010-03-11 00:22:57 +0000301 const Function *F = MF->getFunction();
302 ghcCall = (F ? F->getCallingConv() == CallingConv::GHC : false);
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000303 }
304
Chris Lattner29689432010-03-11 00:22:57 +0000305 static const unsigned GhcCalleeSavedRegs[] = {
306 0
307 };
308
Evan Chengc2b861d2007-01-02 21:33:40 +0000309 static const unsigned CalleeSavedRegs32Bit[] = {
Evan Cheng0f3ac8d2006-05-18 00:12:58 +0000310 X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0
311 };
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000312
313 static const unsigned CalleeSavedRegs32EHRet[] = {
314 X86::EAX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0
315 };
316
Evan Chengc2b861d2007-01-02 21:33:40 +0000317 static const unsigned CalleeSavedRegs64Bit[] = {
Evan Cheng25ab6902006-09-08 06:48:29 +0000318 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
319 };
320
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000321 static const unsigned CalleeSavedRegs64EHRet[] = {
322 X86::RAX, X86::RDX, X86::RBX, X86::R12,
323 X86::R13, X86::R14, X86::R15, X86::RBP, 0
324 };
325
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000326 static const unsigned CalleeSavedRegsWin64[] = {
Anton Korobeynikov5979d712008-09-24 22:03:04 +0000327 X86::RBX, X86::RBP, X86::RDI, X86::RSI,
328 X86::R12, X86::R13, X86::R14, X86::R15,
329 X86::XMM6, X86::XMM7, X86::XMM8, X86::XMM9,
330 X86::XMM10, X86::XMM11, X86::XMM12, X86::XMM13,
331 X86::XMM14, X86::XMM15, 0
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000332 };
333
Chris Lattner29689432010-03-11 00:22:57 +0000334 if (ghcCall) {
335 return GhcCalleeSavedRegs;
336 } else if (Is64Bit) {
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000337 if (IsWin64)
338 return CalleeSavedRegsWin64;
339 else
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000340 return (callsEHReturn ? CalleeSavedRegs64EHRet : CalleeSavedRegs64Bit);
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000341 } else {
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000342 return (callsEHReturn ? CalleeSavedRegs32EHRet : CalleeSavedRegs32Bit);
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000343 }
Evan Cheng0f3ac8d2006-05-18 00:12:58 +0000344}
345
346const TargetRegisterClass* const*
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000347X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000348 bool callsEHReturn = false;
Chris Lattnera267b002010-04-05 05:57:52 +0000349 if (MF)
350 callsEHReturn = MF->getMMI().callsEHReturn();
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000351
Evan Chengc2b861d2007-01-02 21:33:40 +0000352 static const TargetRegisterClass * const CalleeSavedRegClasses32Bit[] = {
Evan Cheng0f3ac8d2006-05-18 00:12:58 +0000353 &X86::GR32RegClass, &X86::GR32RegClass,
354 &X86::GR32RegClass, &X86::GR32RegClass, 0
355 };
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000356 static const TargetRegisterClass * const CalleeSavedRegClasses32EHRet[] = {
357 &X86::GR32RegClass, &X86::GR32RegClass,
358 &X86::GR32RegClass, &X86::GR32RegClass,
359 &X86::GR32RegClass, &X86::GR32RegClass, 0
360 };
Evan Chengc2b861d2007-01-02 21:33:40 +0000361 static const TargetRegisterClass * const CalleeSavedRegClasses64Bit[] = {
Evan Cheng25ab6902006-09-08 06:48:29 +0000362 &X86::GR64RegClass, &X86::GR64RegClass,
363 &X86::GR64RegClass, &X86::GR64RegClass,
364 &X86::GR64RegClass, &X86::GR64RegClass, 0
365 };
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000366 static const TargetRegisterClass * const CalleeSavedRegClasses64EHRet[] = {
367 &X86::GR64RegClass, &X86::GR64RegClass,
368 &X86::GR64RegClass, &X86::GR64RegClass,
369 &X86::GR64RegClass, &X86::GR64RegClass,
370 &X86::GR64RegClass, &X86::GR64RegClass, 0
371 };
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000372 static const TargetRegisterClass * const CalleeSavedRegClassesWin64[] = {
Anton Korobeynikov5979d712008-09-24 22:03:04 +0000373 &X86::GR64RegClass, &X86::GR64RegClass,
374 &X86::GR64RegClass, &X86::GR64RegClass,
375 &X86::GR64RegClass, &X86::GR64RegClass,
376 &X86::GR64RegClass, &X86::GR64RegClass,
377 &X86::VR128RegClass, &X86::VR128RegClass,
378 &X86::VR128RegClass, &X86::VR128RegClass,
379 &X86::VR128RegClass, &X86::VR128RegClass,
380 &X86::VR128RegClass, &X86::VR128RegClass,
381 &X86::VR128RegClass, &X86::VR128RegClass, 0
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000382 };
Evan Cheng25ab6902006-09-08 06:48:29 +0000383
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000384 if (Is64Bit) {
385 if (IsWin64)
386 return CalleeSavedRegClassesWin64;
387 else
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000388 return (callsEHReturn ?
389 CalleeSavedRegClasses64EHRet : CalleeSavedRegClasses64Bit);
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000390 } else {
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000391 return (callsEHReturn ?
392 CalleeSavedRegClasses32EHRet : CalleeSavedRegClasses32Bit);
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000393 }
Evan Cheng0f3ac8d2006-05-18 00:12:58 +0000394}
395
Evan Chengb371f452007-02-19 21:49:54 +0000396BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
397 BitVector Reserved(getNumRegs());
Dan Gohmana32b7ac2008-12-18 01:05:09 +0000398 // Set the stack-pointer register and its aliases as reserved.
Evan Chengb371f452007-02-19 21:49:54 +0000399 Reserved.set(X86::RSP);
400 Reserved.set(X86::ESP);
401 Reserved.set(X86::SP);
402 Reserved.set(X86::SPL);
Bill Wendling80c76432009-08-16 11:00:26 +0000403
Jakob Stoklund Olesen52cd5482009-11-13 21:56:01 +0000404 // Set the instruction pointer register and its aliases as reserved.
405 Reserved.set(X86::RIP);
406 Reserved.set(X86::EIP);
407 Reserved.set(X86::IP);
408
Dan Gohmana32b7ac2008-12-18 01:05:09 +0000409 // Set the frame-pointer register and its aliases as reserved if needed.
Evan Chengb371f452007-02-19 21:49:54 +0000410 if (hasFP(MF)) {
411 Reserved.set(X86::RBP);
412 Reserved.set(X86::EBP);
413 Reserved.set(X86::BP);
414 Reserved.set(X86::BPL);
415 }
Bill Wendling80c76432009-08-16 11:00:26 +0000416
417 // Mark the x87 stack registers as reserved, since they don't behave normally
418 // with respect to liveness. We don't fully model the effects of x87 stack
419 // pushes and pops after stackification.
Dan Gohmana32b7ac2008-12-18 01:05:09 +0000420 Reserved.set(X86::ST0);
421 Reserved.set(X86::ST1);
422 Reserved.set(X86::ST2);
423 Reserved.set(X86::ST3);
424 Reserved.set(X86::ST4);
425 Reserved.set(X86::ST5);
426 Reserved.set(X86::ST6);
427 Reserved.set(X86::ST7);
Evan Chengb371f452007-02-19 21:49:54 +0000428 return Reserved;
429}
430
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000431//===----------------------------------------------------------------------===//
432// Stack Frame Processing methods
433//===----------------------------------------------------------------------===//
434
Bill Wendling80c76432009-08-16 11:00:26 +0000435/// hasFP - Return true if the specified function should have a dedicated frame
436/// pointer register. This is true if the function has variable sized allocas
437/// or if frame pointer elimination is disabled.
Evan Chengdc775402007-01-23 00:57:47 +0000438bool X86RegisterInfo::hasFP(const MachineFunction &MF) const {
Dan Gohman8e5f2c62008-07-07 23:14:23 +0000439 const MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattnera267b002010-04-05 05:57:52 +0000440 const MachineModuleInfo &MMI = MF.getMMI();
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000441
Anton Korobeynikove2011902008-04-23 18:15:11 +0000442 return (NoFramePointerElim ||
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000443 needsStackRealignment(MF) ||
Evan Cheng7e7bbf82007-07-19 00:42:05 +0000444 MFI->hasVarSizedObjects() ||
Evan Cheng184793f2008-09-27 01:56:22 +0000445 MFI->isFrameAddressTaken() ||
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000446 MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() ||
Chris Lattnera267b002010-04-05 05:57:52 +0000447 MMI.callsUnwindInit());
Misha Brukman03c6faf2002-12-03 23:11:21 +0000448}
Misha Brukman2adb3952002-12-04 23:57:03 +0000449
Jim Grosbache45ab8a2010-01-19 18:31:11 +0000450bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
451 const MachineFrameInfo *MFI = MF.getFrameInfo();
452 return (RealignStack &&
453 !MFI->hasVarSizedObjects());
454}
455
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000456bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
Nick Lewycky9c0f1462009-03-19 05:51:39 +0000457 const MachineFrameInfo *MFI = MF.getFrameInfo();
Charles Davis5dfa2672010-02-19 18:17:13 +0000458 const Function *F = MF.getFunction();
Anton Korobeynikov773943a2009-11-08 12:58:40 +0000459 bool requiresRealignment =
Charles Davis5dfa2672010-02-19 18:17:13 +0000460 RealignStack && ((MFI->getMaxAlignment() > StackAlign) ||
461 F->hasFnAttr(Attribute::StackAlignment));
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000462
Anton Korobeynikov35410a42008-04-23 18:16:43 +0000463 // FIXME: Currently we don't support stack realignment for functions with
Anton Korobeynikovb23f3aa2009-11-14 18:01:41 +0000464 // variable-sized allocas.
465 // FIXME: Temporary disable the error - it seems to be too conservative.
466 if (0 && requiresRealignment && MFI->hasVarSizedObjects())
Chris Lattner75361b62010-04-07 22:58:41 +0000467 report_fatal_error(
Anton Korobeynikov773943a2009-11-08 12:58:40 +0000468 "Stack realignment in presense of dynamic allocas is not supported");
469
Anton Korobeynikovb23f3aa2009-11-14 18:01:41 +0000470 return (requiresRealignment && !MFI->hasVarSizedObjects());
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000471}
472
Evan Cheng7e7bbf82007-07-19 00:42:05 +0000473bool X86RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
474 return !MF.getFrameInfo()->hasVarSizedObjects();
475}
476
Evan Cheng910139f2009-07-09 06:53:48 +0000477bool X86RegisterInfo::hasReservedSpillSlot(MachineFunction &MF, unsigned Reg,
478 int &FrameIdx) const {
479 if (Reg == FramePtr && hasFP(MF)) {
480 FrameIdx = MF.getFrameInfo()->getObjectIndexBegin();
481 return true;
482 }
483 return false;
484}
485
Anton Korobeynikov82751e32008-04-23 18:18:36 +0000486int
Chris Lattner30c6b752010-01-26 23:15:09 +0000487X86RegisterInfo::getFrameIndexOffset(const MachineFunction &MF, int FI) const {
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000488 const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
Chris Lattner30c6b752010-01-26 23:15:09 +0000489 const MachineFrameInfo *MFI = MF.getFrameInfo();
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000490 int Offset = MFI->getObjectOffset(FI) - TFI.getOffsetOfLocalArea();
491 uint64_t StackSize = MFI->getStackSize();
Anton Korobeynikov82751e32008-04-23 18:18:36 +0000492
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000493 if (needsStackRealignment(MF)) {
Bill Wendling80c76432009-08-16 11:00:26 +0000494 if (FI < 0) {
495 // Skip the saved EBP.
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000496 Offset += SlotSize;
Bill Wendling80c76432009-08-16 11:00:26 +0000497 } else {
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000498 unsigned Align = MFI->getObjectAlignment(FI);
Evan Cheng7545f492010-02-13 01:56:41 +0000499 assert((-(Offset + StackSize)) % Align == 0);
Devang Patelfd1c6c32008-12-23 21:56:28 +0000500 Align = 0;
Dale Johannesenb5dae002008-06-26 01:51:13 +0000501 return Offset + StackSize;
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000502 }
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000503 // FIXME: Support tail calls
504 } else {
505 if (!hasFP(MF))
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000506 return Offset + StackSize;
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000507
Bill Wendling80c76432009-08-16 11:00:26 +0000508 // Skip the saved EBP.
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000509 Offset += SlotSize;
510
511 // Skip the RETADDR move area
Chris Lattner30c6b752010-01-26 23:15:09 +0000512 const X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000513 int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
Bill Wendling80c76432009-08-16 11:00:26 +0000514 if (TailCallReturnAddrDelta < 0)
515 Offset -= TailCallReturnAddrDelta;
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000516 }
517
Anton Korobeynikov82751e32008-04-23 18:18:36 +0000518 return Offset;
519}
520
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000521void X86RegisterInfo::
522eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
523 MachineBasicBlock::iterator I) const {
Evan Cheng7e7bbf82007-07-19 00:42:05 +0000524 if (!hasReservedCallFrame(MF)) {
525 // If the stack pointer can be changed after prologue, turn the
526 // adjcallstackup instruction into a 'sub ESP, <amt>' and the
527 // adjcallstackdown instruction into 'add ESP, <amt>'
528 // TODO: consider using push / pop instead of sub + store / add
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000529 MachineInstr *Old = I;
Chris Lattner61807802007-04-25 04:25:10 +0000530 uint64_t Amount = Old->getOperand(0).getImm();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000531 if (Amount != 0) {
Chris Lattnerf158da22003-01-16 02:20:12 +0000532 // We need to keep the stack aligned properly. To do this, we round the
533 // amount of space needed for the outgoing arguments up to the next
534 // alignment boundary.
Bill Wendling80c76432009-08-16 11:00:26 +0000535 Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign;
Chris Lattnerf158da22003-01-16 02:20:12 +0000536
Chris Lattner3648c672005-05-13 21:44:04 +0000537 MachineInstr *New = 0;
Dan Gohman6d4b0522008-10-01 18:28:06 +0000538 if (Old->getOpcode() == getCallFrameSetupOpcode()) {
Dale Johannesen21b55412009-02-12 23:08:38 +0000539 New = BuildMI(MF, Old->getDebugLoc(),
540 TII.get(Is64Bit ? X86::SUB64ri32 : X86::SUB32ri),
Bill Wendling80c76432009-08-16 11:00:26 +0000541 StackPtr)
542 .addReg(StackPtr)
543 .addImm(Amount);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000544 } else {
Dan Gohman6d4b0522008-10-01 18:28:06 +0000545 assert(Old->getOpcode() == getCallFrameDestroyOpcode());
Bill Wendling80c76432009-08-16 11:00:26 +0000546
547 // Factor out the amount the callee already popped.
Chris Lattner61807802007-04-25 04:25:10 +0000548 uint64_t CalleeAmt = Old->getOperand(1).getImm();
Chris Lattner3648c672005-05-13 21:44:04 +0000549 Amount -= CalleeAmt;
Bill Wendling80c76432009-08-16 11:00:26 +0000550
551 if (Amount) {
Evan Cheng25ab6902006-09-08 06:48:29 +0000552 unsigned Opc = (Amount < 128) ?
553 (Is64Bit ? X86::ADD64ri8 : X86::ADD32ri8) :
554 (Is64Bit ? X86::ADD64ri32 : X86::ADD32ri);
Dale Johannesen21b55412009-02-12 23:08:38 +0000555 New = BuildMI(MF, Old->getDebugLoc(), TII.get(Opc), StackPtr)
Bill Wendling80c76432009-08-16 11:00:26 +0000556 .addReg(StackPtr)
557 .addImm(Amount);
Chris Lattnerd77525d2006-02-03 18:20:04 +0000558 }
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000559 }
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000560
Dan Gohmand293e0d2009-02-11 19:50:24 +0000561 if (New) {
562 // The EFLAGS implicit def is dead.
563 New->getOperand(3).setIsDead();
Dan Gohmanbfd23c92008-12-18 22:03:42 +0000564
Bill Wendling80c76432009-08-16 11:00:26 +0000565 // Replace the pseudo instruction with a new instruction.
Dan Gohmand293e0d2009-02-11 19:50:24 +0000566 MBB.insert(I, New);
567 }
Chris Lattner3648c672005-05-13 21:44:04 +0000568 }
Dan Gohman6d4b0522008-10-01 18:28:06 +0000569 } else if (I->getOpcode() == getCallFrameDestroyOpcode()) {
Chris Lattner3648c672005-05-13 21:44:04 +0000570 // If we are performing frame pointer elimination and if the callee pops
571 // something off the stack pointer, add it back. We do this until we have
572 // more advanced stack pointer tracking ability.
Chris Lattner61807802007-04-25 04:25:10 +0000573 if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
Evan Cheng25ab6902006-09-08 06:48:29 +0000574 unsigned Opc = (CalleeAmt < 128) ?
575 (Is64Bit ? X86::SUB64ri8 : X86::SUB32ri8) :
576 (Is64Bit ? X86::SUB64ri32 : X86::SUB32ri);
Dale Johannesen21b55412009-02-12 23:08:38 +0000577 MachineInstr *Old = I;
Jeff Cohen00b168892005-07-27 06:12:32 +0000578 MachineInstr *New =
Dale Johannesen21b55412009-02-12 23:08:38 +0000579 BuildMI(MF, Old->getDebugLoc(), TII.get(Opc),
Bill Wendling80c76432009-08-16 11:00:26 +0000580 StackPtr)
581 .addReg(StackPtr)
582 .addImm(CalleeAmt);
583
Dan Gohmanbfd23c92008-12-18 22:03:42 +0000584 // The EFLAGS implicit def is dead.
585 New->getOperand(3).setIsDead();
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000586 MBB.insert(I, New);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000587 }
588 }
589
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000590 MBB.erase(I);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000591}
592
Jim Grosbachb58f4982009-10-07 17:12:56 +0000593unsigned
594X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
Jim Grosbachdff4b4c2010-03-09 21:45:49 +0000595 int SPAdj, FrameIndexValue *Value,
Jim Grosbachb58f4982009-10-07 17:12:56 +0000596 RegScavenger *RS) const{
Evan Cheng97de9132007-05-01 09:13:03 +0000597 assert(SPAdj == 0 && "Unexpected");
598
Chris Lattnerd264bec2003-01-13 00:50:33 +0000599 unsigned i = 0;
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000600 MachineInstr &MI = *II;
Nate Begemanf8be5e92004-08-14 22:05:10 +0000601 MachineFunction &MF = *MI.getParent()->getParent();
Bill Wendling80c76432009-08-16 11:00:26 +0000602
Dan Gohmand735b802008-10-03 15:45:36 +0000603 while (!MI.getOperand(i).isFI()) {
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000604 ++i;
605 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
606 }
607
Chris Lattner8aa797a2007-12-30 23:10:15 +0000608 int FrameIndex = MI.getOperand(i).getIndex();
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000609 unsigned BasePtr;
Bill Wendling80c76432009-08-16 11:00:26 +0000610
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000611 if (needsStackRealignment(MF))
612 BasePtr = (FrameIndex < 0 ? FramePtr : StackPtr);
613 else
614 BasePtr = (hasFP(MF) ? FramePtr : StackPtr);
615
Chris Lattnerd264bec2003-01-13 00:50:33 +0000616 // This must be part of a four operand memory reference. Replace the
Evan Cheng25ab6902006-09-08 06:48:29 +0000617 // FrameIndex with base register with EBP. Add an offset to the offset.
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000618 MI.getOperand(i).ChangeToRegister(BasePtr, false);
Chris Lattnerd264bec2003-01-13 00:50:33 +0000619
Dan Gohman82779702008-12-24 00:27:51 +0000620 // Now add the frame object offset to the offset from EBP.
621 if (MI.getOperand(i+3).isImm()) {
622 // Offset is a 32-bit integer.
623 int Offset = getFrameIndexOffset(MF, FrameIndex) +
Bill Wendling80c76432009-08-16 11:00:26 +0000624 (int)(MI.getOperand(i + 3).getImm());
David Greene3f2bf852009-11-12 20:49:22 +0000625
626 MI.getOperand(i + 3).ChangeToImmediate(Offset);
Dan Gohman82779702008-12-24 00:27:51 +0000627 } else {
628 // Offset is symbolic. This is extremely rare.
629 uint64_t Offset = getFrameIndexOffset(MF, FrameIndex) +
630 (uint64_t)MI.getOperand(i+3).getOffset();
631 MI.getOperand(i+3).setOffset(Offset);
632 }
Jim Grosbachb58f4982009-10-07 17:12:56 +0000633 return 0;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000634}
635
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000636void
Anton Korobeynikovb51dce32008-04-23 18:20:17 +0000637X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
638 RegScavenger *RS) const {
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000639 MachineFrameInfo *MFI = MF.getFrameInfo();
Anton Korobeynikovb51dce32008-04-23 18:20:17 +0000640
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000641 X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
642 int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
Bill Wendling80c76432009-08-16 11:00:26 +0000643
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000644 if (TailCallReturnAddrDelta < 0) {
645 // create RETURNADDR area
646 // arg
647 // arg
648 // RETADDR
649 // { ...
650 // RETADDR area
651 // ...
652 // }
653 // [EBP]
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000654 MFI->CreateFixedObject(-TailCallReturnAddrDelta,
David Greene3f2bf852009-11-12 20:49:22 +0000655 (-1U*SlotSize)+TailCallReturnAddrDelta,
656 true, false);
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000657 }
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000658
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000659 if (hasFP(MF)) {
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000660 assert((TailCallReturnAddrDelta <= 0) &&
661 "The Delta should always be zero or negative");
Anton Korobeynikovdd93f5e2009-08-03 08:14:30 +0000662 const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
Bill Wendling80c76432009-08-16 11:00:26 +0000663
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000664 // Create a frame entry for the EBP register that must be saved.
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000665 int FrameIdx = MFI->CreateFixedObject(SlotSize,
Anton Korobeynikovdd93f5e2009-08-03 08:14:30 +0000666 -(int)SlotSize +
667 TFI.getOffsetOfLocalArea() +
David Greene3f2bf852009-11-12 20:49:22 +0000668 TailCallReturnAddrDelta,
669 true, false);
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000670 assert(FrameIdx == MFI->getObjectIndexBegin() &&
Chris Lattner96c3d2e2004-02-15 00:15:37 +0000671 "Slot for EBP register must be last in order to be found!");
Devang Patelfd1c6c32008-12-23 21:56:28 +0000672 FrameIdx = 0;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000673 }
674}
675
Evan Chenga24dddd2007-04-26 01:09:28 +0000676/// emitSPUpdate - Emit a series of instructions to increment / decrement the
677/// stack pointer by a constant value.
678static
679void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
680 unsigned StackPtr, int64_t NumBytes, bool Is64Bit,
681 const TargetInstrInfo &TII) {
682 bool isSub = NumBytes < 0;
683 uint64_t Offset = isSub ? -NumBytes : NumBytes;
684 unsigned Opc = isSub
685 ? ((Offset < 128) ?
686 (Is64Bit ? X86::SUB64ri8 : X86::SUB32ri8) :
687 (Is64Bit ? X86::SUB64ri32 : X86::SUB32ri))
688 : ((Offset < 128) ?
689 (Is64Bit ? X86::ADD64ri8 : X86::ADD32ri8) :
690 (Is64Bit ? X86::ADD64ri32 : X86::ADD32ri));
691 uint64_t Chunk = (1LL << 31) - 1;
Dale Johannesen73e884b2010-01-20 21:36:02 +0000692 DebugLoc DL = MBB.findDebugLoc(MBBI);
Evan Chenga24dddd2007-04-26 01:09:28 +0000693
694 while (Offset) {
695 uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
Dan Gohmanbfd23c92008-12-18 22:03:42 +0000696 MachineInstr *MI =
Dale Johannesen8d13f8f2009-02-13 02:33:27 +0000697 BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr)
Bill Wendling3f5bb162009-08-15 21:27:32 +0000698 .addReg(StackPtr)
699 .addImm(ThisVal);
700 MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
Evan Chenga24dddd2007-04-26 01:09:28 +0000701 Offset -= ThisVal;
702 }
703}
704
Bill Wendling80c76432009-08-16 11:00:26 +0000705/// mergeSPUpdatesUp - Merge two stack-manipulating instructions upper iterator.
Anton Korobeynikov4f1c33f2007-10-06 16:17:49 +0000706static
707void mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
708 unsigned StackPtr, uint64_t *NumBytes = NULL) {
Chris Lattnereac93852007-10-07 21:53:12 +0000709 if (MBBI == MBB.begin()) return;
Anton Korobeynikove2011902008-04-23 18:15:11 +0000710
Chris Lattnereac93852007-10-07 21:53:12 +0000711 MachineBasicBlock::iterator PI = prior(MBBI);
712 unsigned Opc = PI->getOpcode();
713 if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
714 Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
715 PI->getOperand(0).getReg() == StackPtr) {
716 if (NumBytes)
717 *NumBytes += PI->getOperand(2).getImm();
718 MBB.erase(PI);
719 } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
720 Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
721 PI->getOperand(0).getReg() == StackPtr) {
722 if (NumBytes)
723 *NumBytes -= PI->getOperand(2).getImm();
724 MBB.erase(PI);
Anton Korobeynikov4f1c33f2007-10-06 16:17:49 +0000725 }
726}
727
Bill Wendling80c76432009-08-16 11:00:26 +0000728/// mergeSPUpdatesUp - Merge two stack-manipulating instructions lower iterator.
Anton Korobeynikov25083722007-10-06 16:39:43 +0000729static
Chris Lattnereac93852007-10-07 21:53:12 +0000730void mergeSPUpdatesDown(MachineBasicBlock &MBB,
731 MachineBasicBlock::iterator &MBBI,
Anton Korobeynikov25083722007-10-06 16:39:43 +0000732 unsigned StackPtr, uint64_t *NumBytes = NULL) {
Bill Wendling3f5bb162009-08-15 21:27:32 +0000733 // FIXME: THIS ISN'T RUN!!!
Chris Lattnerf443ba72007-10-07 22:00:31 +0000734 return;
Anton Korobeynikove2011902008-04-23 18:15:11 +0000735
Chris Lattnereac93852007-10-07 21:53:12 +0000736 if (MBBI == MBB.end()) return;
Anton Korobeynikove2011902008-04-23 18:15:11 +0000737
Chris Lattner7896c9f2009-12-03 00:50:42 +0000738 MachineBasicBlock::iterator NI = llvm::next(MBBI);
Chris Lattnereac93852007-10-07 21:53:12 +0000739 if (NI == MBB.end()) return;
Anton Korobeynikove2011902008-04-23 18:15:11 +0000740
Chris Lattnereac93852007-10-07 21:53:12 +0000741 unsigned Opc = NI->getOpcode();
742 if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
743 Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
744 NI->getOperand(0).getReg() == StackPtr) {
745 if (NumBytes)
746 *NumBytes -= NI->getOperand(2).getImm();
747 MBB.erase(NI);
748 MBBI = NI;
749 } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
750 Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
751 NI->getOperand(0).getReg() == StackPtr) {
752 if (NumBytes)
753 *NumBytes += NI->getOperand(2).getImm();
754 MBB.erase(NI);
755 MBBI = NI;
Anton Korobeynikov25083722007-10-06 16:39:43 +0000756 }
757}
758
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000759/// mergeSPUpdates - Checks the instruction before/after the passed
Bill Wendling80c76432009-08-16 11:00:26 +0000760/// instruction. If it is an ADD/SUB instruction it is deleted argument and the
761/// stack adjustment is returned as a positive value for ADD and a negative for
762/// SUB.
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000763static int mergeSPUpdates(MachineBasicBlock &MBB,
764 MachineBasicBlock::iterator &MBBI,
Anton Korobeynikove2011902008-04-23 18:15:11 +0000765 unsigned StackPtr,
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000766 bool doMergeWithPrevious) {
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000767 if ((doMergeWithPrevious && MBBI == MBB.begin()) ||
768 (!doMergeWithPrevious && MBBI == MBB.end()))
769 return 0;
770
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000771 MachineBasicBlock::iterator PI = doMergeWithPrevious ? prior(MBBI) : MBBI;
Chris Lattner7896c9f2009-12-03 00:50:42 +0000772 MachineBasicBlock::iterator NI = doMergeWithPrevious ? 0 : llvm::next(MBBI);
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000773 unsigned Opc = PI->getOpcode();
Bill Wendling80c76432009-08-16 11:00:26 +0000774 int Offset = 0;
775
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000776 if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
777 Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
778 PI->getOperand(0).getReg() == StackPtr){
779 Offset += PI->getOperand(2).getImm();
780 MBB.erase(PI);
781 if (!doMergeWithPrevious) MBBI = NI;
782 } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
783 Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
784 PI->getOperand(0).getReg() == StackPtr) {
785 Offset -= PI->getOperand(2).getImm();
786 MBB.erase(PI);
787 if (!doMergeWithPrevious) MBBI = NI;
Anton Korobeynikove2011902008-04-23 18:15:11 +0000788 }
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000789
790 return Offset;
791}
792
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000793void X86RegisterInfo::emitCalleeSavedFrameMoves(MachineFunction &MF,
Chris Lattner2e9919a2010-03-14 08:12:40 +0000794 MCSymbol *Label,
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000795 unsigned FramePtr) const {
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000796 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattnera267b002010-04-05 05:57:52 +0000797 MachineModuleInfo &MMI = MF.getMMI();
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000798
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000799 // Add callee saved registers to move list.
800 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
801 if (CSI.empty()) return;
802
Chris Lattnera267b002010-04-05 05:57:52 +0000803 std::vector<MachineMove> &Moves = MMI.getFrameMoves();
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000804 const TargetData *TD = MF.getTarget().getTargetData();
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000805 bool HasFP = hasFP(MF);
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000806
Bill Wendling80c76432009-08-16 11:00:26 +0000807 // Calculate amount of bytes used for return address storing.
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000808 int stackGrowth =
809 (MF.getTarget().getFrameInfo()->getStackGrowthDirection() ==
810 TargetFrameInfo::StackGrowsUp ?
811 TD->getPointerSize() : -TD->getPointerSize());
812
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000813 // FIXME: This is dirty hack. The code itself is pretty mess right now.
814 // It should be rewritten from scratch and generalized sometimes.
815
Bill Wendling80c76432009-08-16 11:00:26 +0000816 // Determine maximum offset (minumum due to stack growth).
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000817 int64_t MaxOffset = 0;
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000818 for (std::vector<CalleeSavedInfo>::const_iterator
819 I = CSI.begin(), E = CSI.end(); I != E; ++I)
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000820 MaxOffset = std::min(MaxOffset,
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000821 MFI->getObjectOffset(I->getFrameIdx()));
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000822
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000823 // Calculate offsets.
824 int64_t saveAreaOffset = (HasFP ? 3 : 2) * stackGrowth;
825 for (std::vector<CalleeSavedInfo>::const_iterator
826 I = CSI.begin(), E = CSI.end(); I != E; ++I) {
827 int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
828 unsigned Reg = I->getReg();
829 Offset = MaxOffset - Offset + saveAreaOffset;
830
Duncan Sandsdaf22122009-07-23 19:00:02 +0000831 // Don't output a new machine move if we're re-saving the frame
832 // pointer. This happens when the PrologEpilogInserter has inserted an extra
833 // "PUSH" of the frame pointer -- the "emitPrologue" method automatically
834 // generates one when frame pointers are used. If we generate a "machine
835 // move" for this extra "PUSH", the linker will lose track of the fact that
836 // the frame pointer should have the value of the first "PUSH" when it's
837 // trying to unwind.
838 //
839 // FIXME: This looks inelegant. It's possibly correct, but it's covering up
840 // another bug. I.e., one where we generate a prolog like this:
841 //
842 // pushl %ebp
843 // movl %esp, %ebp
844 // pushl %ebp
845 // pushl %esi
846 // ...
847 //
848 // The immediate re-push of EBP is unnecessary. At the least, it's an
849 // optimization bug. EBP can be used as a scratch register in certain
850 // cases, but probably not when we have a frame pointer.
851 if (HasFP && FramePtr == Reg)
852 continue;
853
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000854 MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
855 MachineLocation CSSrc(Reg);
Chris Lattner2e9919a2010-03-14 08:12:40 +0000856 Moves.push_back(MachineMove(Label, CSDst, CSSrc));
Bill Wendlingfe7f2942009-06-16 04:12:45 +0000857 }
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000858}
859
Bill Wendling3f5bb162009-08-15 21:27:32 +0000860/// emitPrologue - Push callee-saved registers onto the stack, which
861/// automatically adjust the stack pointer. Adjust the stack pointer to allocate
862/// space for local variables. Also emit labels used by the exception handler to
863/// generate the exception handling frames.
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000864void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
Bill Wendling3f5bb162009-08-15 21:27:32 +0000865 MachineBasicBlock &MBB = MF.front(); // Prologue goes in entry BB.
866 MachineBasicBlock::iterator MBBI = MBB.begin();
Chris Lattnereafa4232003-01-15 22:57:35 +0000867 MachineFrameInfo *MFI = MF.getFrameInfo();
Bill Wendling3f5bb162009-08-15 21:27:32 +0000868 const Function *Fn = MF.getFunction();
869 const X86Subtarget *Subtarget = &MF.getTarget().getSubtarget<X86Subtarget>();
Chris Lattnera267b002010-04-05 05:57:52 +0000870 MachineModuleInfo &MMI = MF.getMMI();
Evan Cheng89d16592007-07-17 07:59:08 +0000871 X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
Chris Lattnera267b002010-04-05 05:57:52 +0000872 bool needsFrameMoves = MMI.hasDebugInfo() ||
Bill Wendling3f5bb162009-08-15 21:27:32 +0000873 !Fn->doesNotThrow() || UnwindTablesMandatory;
874 uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment.
875 uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate.
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000876 bool HasFP = hasFP(MF);
Devang Patel369de262009-06-17 00:48:26 +0000877 DebugLoc DL;
Bill Wendling3d2445f2009-02-21 00:43:56 +0000878
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000879 // Add RETADDR move area to callee saved frame size.
880 int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
Anton Korobeynikove2011902008-04-23 18:15:11 +0000881 if (TailCallReturnAddrDelta < 0)
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000882 X86FI->setCalleeSavedFrameSize(
Bill Wendling3f5bb162009-08-15 21:27:32 +0000883 X86FI->getCalleeSavedFrameSize() - TailCallReturnAddrDelta);
Evan Chengd9245ca2006-04-14 07:26:43 +0000884
Dan Gohman336b6362009-01-27 00:40:06 +0000885 // If this is x86-64 and the Red Zone is not disabled, if we are a leaf
886 // function, and use up to 128 bytes of stack space, don't have a frame
887 // pointer, calls, or dynamic alloca then we do not need to adjust the
888 // stack pointer (we fit in the Red Zone).
Bill Wendling3f5bb162009-08-15 21:27:32 +0000889 if (Is64Bit && !Fn->hasFnAttr(Attribute::NoRedZone) &&
Dan Gohman336b6362009-01-27 00:40:06 +0000890 !needsStackRealignment(MF) &&
891 !MFI->hasVarSizedObjects() && // No dynamic alloca.
Eli Friedman9a417122009-06-04 02:02:01 +0000892 !MFI->hasCalls() && // No calls.
893 !Subtarget->isTargetWin64()) { // Win64 has no Red Zone
Dan Gohman336b6362009-01-27 00:40:06 +0000894 uint64_t MinSize = X86FI->getCalleeSavedFrameSize();
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000895 if (HasFP) MinSize += SlotSize;
Bill Wendling3f5bb162009-08-15 21:27:32 +0000896 StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0);
Dan Gohman336b6362009-01-27 00:40:06 +0000897 MFI->setStackSize(StackSize);
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000898 } else if (Subtarget->isTargetWin64()) {
899 // We need to always allocate 32 bytes as register spill area.
Bill Wendling3f5bb162009-08-15 21:27:32 +0000900 // FIXME: We might reuse these 32 bytes for leaf functions.
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000901 StackSize += 32;
902 MFI->setStackSize(StackSize);
Dan Gohman336b6362009-01-27 00:40:06 +0000903 }
904
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000905 // Insert stack pointer adjustment for later moving of return addr. Only
906 // applies to tail call optimized functions where the callee argument stack
907 // size is bigger than the callers.
908 if (TailCallReturnAddrDelta < 0) {
Dan Gohmanbfd23c92008-12-18 22:03:42 +0000909 MachineInstr *MI =
Dale Johannesen21b55412009-02-12 23:08:38 +0000910 BuildMI(MBB, MBBI, DL, TII.get(Is64Bit? X86::SUB64ri32 : X86::SUB32ri),
Bill Wendling3f5bb162009-08-15 21:27:32 +0000911 StackPtr)
912 .addReg(StackPtr)
913 .addImm(-TailCallReturnAddrDelta);
914 MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000915 }
916
Bill Wendling3f5bb162009-08-15 21:27:32 +0000917 // Mapping for machine moves:
918 //
919 // DST: VirtualFP AND
920 // SRC: VirtualFP => DW_CFA_def_cfa_offset
921 // ELSE => DW_CFA_def_cfa
922 //
923 // SRC: VirtualFP AND
924 // DST: Register => DW_CFA_def_cfa_register
925 //
926 // ELSE
927 // OFFSET < 0 => DW_CFA_offset_extended_sf
928 // REG < 64 => DW_CFA_offset + Reg
929 // ELSE => DW_CFA_offset_extended
930
Chris Lattnera267b002010-04-05 05:57:52 +0000931 std::vector<MachineMove> &Moves = MMI.getFrameMoves();
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000932 const TargetData *TD = MF.getTarget().getTargetData();
Bill Wendling3f5bb162009-08-15 21:27:32 +0000933 uint64_t NumBytes = 0;
Chris Lattner464bee12010-03-13 08:04:35 +0000934 int stackGrowth = -TD->getPointerSize();
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000935
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000936 if (HasFP) {
Bill Wendling3f5bb162009-08-15 21:27:32 +0000937 // Calculate required stack adjustment.
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000938 uint64_t FrameSize = StackSize - SlotSize;
939 if (needsStackRealignment(MF))
Bill Wendling3f5bb162009-08-15 21:27:32 +0000940 FrameSize = (FrameSize + MaxAlign - 1) / MaxAlign * MaxAlign;
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000941
942 NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize();
943
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000944 // Get the offset of the stack slot for the EBP register, which is
Evan Cheng89d16592007-07-17 07:59:08 +0000945 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
946 // Update the frame offset adjustment.
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000947 MFI->setOffsetAdjustment(-NumBytes);
Evan Cheng89d16592007-07-17 07:59:08 +0000948
Bill Wendling3f5bb162009-08-15 21:27:32 +0000949 // Save EBP/RBP into the appropriate stack slot.
Dale Johannesen21b55412009-02-12 23:08:38 +0000950 BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
Bill Wendling587daed2009-05-13 21:33:08 +0000951 .addReg(FramePtr, RegState::Kill);
Evan Cheng89d16592007-07-17 07:59:08 +0000952
Bill Wendling92c1e122009-02-13 02:16:35 +0000953 if (needsFrameMoves) {
Bill Wendling3f5bb162009-08-15 21:27:32 +0000954 // Mark the place where EBP/RBP was saved.
Chris Lattnera267b002010-04-05 05:57:52 +0000955 MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
Chris Lattner2e9919a2010-03-14 08:12:40 +0000956 BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(FrameLabel);
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000957
958 // Define the current CFA rule to use the provided offset.
959 if (StackSize) {
960 MachineLocation SPDst(MachineLocation::VirtualFP);
Bill Wendling80c76432009-08-16 11:00:26 +0000961 MachineLocation SPSrc(MachineLocation::VirtualFP, 2 * stackGrowth);
Chris Lattner2e9919a2010-03-14 08:12:40 +0000962 Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000963 } else {
964 // FIXME: Verify & implement for FP
965 MachineLocation SPDst(StackPtr);
966 MachineLocation SPSrc(StackPtr, stackGrowth);
Chris Lattner2e9919a2010-03-14 08:12:40 +0000967 Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000968 }
969
970 // Change the rule for the FramePtr to be an "offset" rule.
Chris Lattner464bee12010-03-13 08:04:35 +0000971 MachineLocation FPDst(MachineLocation::VirtualFP, 2 * stackGrowth);
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000972 MachineLocation FPSrc(FramePtr);
Chris Lattner2e9919a2010-03-14 08:12:40 +0000973 Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc));
Bill Wendling92c1e122009-02-13 02:16:35 +0000974 }
975
Evan Cheng89d16592007-07-17 07:59:08 +0000976 // Update EBP with the new base value...
Dale Johannesen21b55412009-02-12 23:08:38 +0000977 BuildMI(MBB, MBBI, DL,
978 TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr)
979 .addReg(StackPtr);
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000980
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000981 if (needsFrameMoves) {
Bill Wendling3f5bb162009-08-15 21:27:32 +0000982 // Mark effective beginning of when frame pointer becomes valid.
Chris Lattnera267b002010-04-05 05:57:52 +0000983 MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
Chris Lattner2e9919a2010-03-14 08:12:40 +0000984 BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(FrameLabel);
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000985
986 // Define the current CFA to use the EBP/RBP register.
987 MachineLocation FPDst(FramePtr);
988 MachineLocation FPSrc(MachineLocation::VirtualFP);
Chris Lattner2e9919a2010-03-14 08:12:40 +0000989 Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc));
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000990 }
991
Dan Gohman34d6ad72008-12-18 22:01:52 +0000992 // Mark the FramePtr as live-in in every block except the entry.
Chris Lattner7896c9f2009-12-03 00:50:42 +0000993 for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
Dan Gohman34d6ad72008-12-18 22:01:52 +0000994 I != E; ++I)
995 I->addLiveIn(FramePtr);
996
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000997 // Realign stack
Dan Gohmanbfd23c92008-12-18 22:03:42 +0000998 if (needsStackRealignment(MF)) {
999 MachineInstr *MI =
Dale Johannesen21b55412009-02-12 23:08:38 +00001000 BuildMI(MBB, MBBI, DL,
Dan Gohmanbfd23c92008-12-18 22:03:42 +00001001 TII.get(Is64Bit ? X86::AND64ri32 : X86::AND32ri),
1002 StackPtr).addReg(StackPtr).addImm(-MaxAlign);
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001003
Dan Gohmanbfd23c92008-12-18 22:03:42 +00001004 // The EFLAGS implicit def is dead.
1005 MI->getOperand(3).setIsDead();
1006 }
Bill Wendling3d2445f2009-02-21 00:43:56 +00001007 } else {
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001008 NumBytes = StackSize - X86FI->getCalleeSavedFrameSize();
Bill Wendling3d2445f2009-02-21 00:43:56 +00001009 }
Anton Korobeynikove2011902008-04-23 18:15:11 +00001010
Evan Cheng89d16592007-07-17 07:59:08 +00001011 // Skip the callee-saved push instructions.
Bill Wendling3f5bb162009-08-15 21:27:32 +00001012 bool PushedRegs = false;
1013 int StackOffset = 2 * stackGrowth;
1014
Evan Cheng89d16592007-07-17 07:59:08 +00001015 while (MBBI != MBB.end() &&
1016 (MBBI->getOpcode() == X86::PUSH32r ||
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001017 MBBI->getOpcode() == X86::PUSH64r)) {
Bill Wendling3f5bb162009-08-15 21:27:32 +00001018 PushedRegs = true;
Evan Cheng89d16592007-07-17 07:59:08 +00001019 ++MBBI;
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001020
Bill Wendling3f5bb162009-08-15 21:27:32 +00001021 if (!HasFP && needsFrameMoves) {
1022 // Mark callee-saved push instruction.
Chris Lattnera267b002010-04-05 05:57:52 +00001023 MCSymbol *Label = MMI.getContext().CreateTempSymbol();
Chris Lattner2e9919a2010-03-14 08:12:40 +00001024 BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(Label);
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001025
Bill Wendling3f5bb162009-08-15 21:27:32 +00001026 // Define the current CFA rule to use the provided offset.
1027 unsigned Ptr = StackSize ?
1028 MachineLocation::VirtualFP : StackPtr;
1029 MachineLocation SPDst(Ptr);
1030 MachineLocation SPSrc(Ptr, StackOffset);
Chris Lattner2e9919a2010-03-14 08:12:40 +00001031 Moves.push_back(MachineMove(Label, SPDst, SPSrc));
Bill Wendling3f5bb162009-08-15 21:27:32 +00001032 StackOffset += stackGrowth;
1033 }
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001034 }
Evan Cheng89d16592007-07-17 07:59:08 +00001035
Dale Johannesen73e884b2010-01-20 21:36:02 +00001036 DL = MBB.findDebugLoc(MBBI);
Bill Wendling3d2445f2009-02-21 00:43:56 +00001037
Bill Wendling3ae67f52009-06-09 20:08:51 +00001038 // Adjust stack pointer: ESP -= numbytes.
1039 if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) {
1040 // Check, whether EAX is livein for this function.
1041 bool isEAXAlive = false;
1042 for (MachineRegisterInfo::livein_iterator
Chris Lattner84bc5422007-12-31 04:13:23 +00001043 II = MF.getRegInfo().livein_begin(),
1044 EE = MF.getRegInfo().livein_end(); (II != EE) && !isEAXAlive; ++II) {
Bill Wendling3ae67f52009-06-09 20:08:51 +00001045 unsigned Reg = II->first;
1046 isEAXAlive = (Reg == X86::EAX || Reg == X86::AX ||
1047 Reg == X86::AH || Reg == X86::AL);
Evan Cheng004fb922006-06-13 05:14:44 +00001048 }
Bill Wendling3ae67f52009-06-09 20:08:51 +00001049
1050 // Function prologue calls _alloca to probe the stack when allocating more
1051 // than 4k bytes in one go. Touching the stack at 4K increments is necessary
1052 // to ensure that the guard pages used by the OS virtual memory manager are
1053 // allocated in correct sequence.
1054 if (!isEAXAlive) {
1055 BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
1056 .addImm(NumBytes);
1057 BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
Anton Korobeynikov043f3c22010-03-06 19:32:29 +00001058 .addExternalSymbol("_alloca")
1059 .addReg(StackPtr, RegState::Define | RegState::Implicit);
Bill Wendling3ae67f52009-06-09 20:08:51 +00001060 } else {
1061 // Save EAX
1062 BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r))
1063 .addReg(X86::EAX, RegState::Kill);
1064
1065 // Allocate NumBytes-4 bytes on stack. We'll also use 4 already
1066 // allocated bytes for EAX.
1067 BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
1068 .addImm(NumBytes - 4);
1069 BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
Anton Korobeynikov043f3c22010-03-06 19:32:29 +00001070 .addExternalSymbol("_alloca")
1071 .addReg(StackPtr, RegState::Define | RegState::Implicit);
Bill Wendling3ae67f52009-06-09 20:08:51 +00001072
1073 // Restore EAX
1074 MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm),
1075 X86::EAX),
1076 StackPtr, false, NumBytes - 4);
1077 MBB.insert(MBBI, MI);
1078 }
1079 } else if (NumBytes) {
1080 // If there is an SUB32ri of ESP immediately before this instruction, merge
1081 // the two. This can be the case when tail call elimination is enabled and
1082 // the callee has more arguments then the caller.
1083 NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true);
1084
1085 // If there is an ADD32ri or SUB32ri of ESP immediately after this
1086 // instruction, merge the two instructions.
1087 mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes);
1088
1089 if (NumBytes)
1090 emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII);
Evan Chengd9245ca2006-04-14 07:26:43 +00001091 }
Bill Wendlingd15f45f2009-07-09 22:30:02 +00001092
Bill Wendlingeb3a7662009-09-03 22:19:22 +00001093 if ((NumBytes || PushedRegs) && needsFrameMoves) {
Bill Wendlingd15f45f2009-07-09 22:30:02 +00001094 // Mark end of stack pointer adjustment.
Chris Lattnera267b002010-04-05 05:57:52 +00001095 MCSymbol *Label = MMI.getContext().CreateTempSymbol();
Chris Lattner2e9919a2010-03-14 08:12:40 +00001096 BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(Label);
Bill Wendlingd15f45f2009-07-09 22:30:02 +00001097
Bill Wendlingeb3a7662009-09-03 22:19:22 +00001098 if (!HasFP && NumBytes) {
Bill Wendling3f5bb162009-08-15 21:27:32 +00001099 // Define the current CFA rule to use the provided offset.
1100 if (StackSize) {
1101 MachineLocation SPDst(MachineLocation::VirtualFP);
1102 MachineLocation SPSrc(MachineLocation::VirtualFP,
1103 -StackSize + stackGrowth);
Chris Lattner2e9919a2010-03-14 08:12:40 +00001104 Moves.push_back(MachineMove(Label, SPDst, SPSrc));
Bill Wendling3f5bb162009-08-15 21:27:32 +00001105 } else {
1106 // FIXME: Verify & implement for FP
1107 MachineLocation SPDst(StackPtr);
1108 MachineLocation SPSrc(StackPtr, stackGrowth);
Chris Lattner2e9919a2010-03-14 08:12:40 +00001109 Moves.push_back(MachineMove(Label, SPDst, SPSrc));
Bill Wendling3f5bb162009-08-15 21:27:32 +00001110 }
Bill Wendlingd15f45f2009-07-09 22:30:02 +00001111 }
Bill Wendling3f5bb162009-08-15 21:27:32 +00001112
1113 // Emit DWARF info specifying the offsets of the callee-saved registers.
1114 if (PushedRegs)
Chris Lattner2e9919a2010-03-14 08:12:40 +00001115 emitCalleeSavedFrameMoves(MF, Label, HasFP ? FramePtr : StackPtr);
Bill Wendlingd15f45f2009-07-09 22:30:02 +00001116 }
Misha Brukman2adb3952002-12-04 23:57:03 +00001117}
1118
Chris Lattnerbb07ef92004-02-14 19:49:54 +00001119void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
1120 MachineBasicBlock &MBB) const {
Chris Lattneraa09b752002-12-28 21:08:28 +00001121 const MachineFrameInfo *MFI = MF.getFrameInfo();
Evan Cheng89d16592007-07-17 07:59:08 +00001122 X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
Alkis Evlogimenosf81af212004-02-14 01:18:34 +00001123 MachineBasicBlock::iterator MBBI = prior(MBB.end());
Anton Korobeynikov2365f512007-07-14 14:06:15 +00001124 unsigned RetOpcode = MBBI->getOpcode();
Bill Wendling2625f9b2009-02-21 00:32:08 +00001125 DebugLoc DL = MBBI->getDebugLoc();
Chris Lattner2b3d56e2005-05-14 23:35:21 +00001126
Anton Korobeynikov2365f512007-07-14 14:06:15 +00001127 switch (RetOpcode) {
Bill Wendling80c76432009-08-16 11:00:26 +00001128 default:
1129 llvm_unreachable("Can only insert epilog into returning blocks");
Chris Lattner2b3d56e2005-05-14 23:35:21 +00001130 case X86::RET:
1131 case X86::RETI:
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001132 case X86::TCRETURNdi:
1133 case X86::TCRETURNri:
Evan Chengf48ef032010-03-14 03:48:46 +00001134 case X86::TCRETURNmi:
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001135 case X86::TCRETURNdi64:
Evan Chengf48ef032010-03-14 03:48:46 +00001136 case X86::TCRETURNri64:
1137 case X86::TCRETURNmi64:
Anton Korobeynikov2365f512007-07-14 14:06:15 +00001138 case X86::EH_RETURN:
Anton Korobeynikovb84c1672008-09-08 21:12:47 +00001139 case X86::EH_RETURN64:
Bill Wendling80c76432009-08-16 11:00:26 +00001140 break; // These are ok
Chris Lattner2b3d56e2005-05-14 23:35:21 +00001141 }
Misha Brukman2adb3952002-12-04 23:57:03 +00001142
Bill Wendling80c76432009-08-16 11:00:26 +00001143 // Get the number of bytes to allocate from the FrameInfo.
Evan Cheng89d16592007-07-17 07:59:08 +00001144 uint64_t StackSize = MFI->getStackSize();
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001145 uint64_t MaxAlign = MFI->getMaxAlignment();
Evan Cheng89d16592007-07-17 07:59:08 +00001146 unsigned CSSize = X86FI->getCalleeSavedFrameSize();
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001147 uint64_t NumBytes = 0;
Evan Cheng89d16592007-07-17 07:59:08 +00001148
Chris Lattner3c1c03d2002-12-28 20:32:28 +00001149 if (hasFP(MF)) {
Bill Wendling80c76432009-08-16 11:00:26 +00001150 // Calculate required stack adjustment.
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001151 uint64_t FrameSize = StackSize - SlotSize;
1152 if (needsStackRealignment(MF))
1153 FrameSize = (FrameSize + MaxAlign - 1)/MaxAlign*MaxAlign;
1154
1155 NumBytes = FrameSize - CSSize;
1156
Bill Wendling80c76432009-08-16 11:00:26 +00001157 // Pop EBP.
Bill Wendling3d2445f2009-02-21 00:43:56 +00001158 BuildMI(MBB, MBBI, DL,
Dale Johannesen21b55412009-02-12 23:08:38 +00001159 TII.get(Is64Bit ? X86::POP64r : X86::POP32r), FramePtr);
Bill Wendling2625f9b2009-02-21 00:32:08 +00001160 } else {
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001161 NumBytes = StackSize - CSSize;
Bill Wendling2625f9b2009-02-21 00:32:08 +00001162 }
Anton Korobeynikov2365f512007-07-14 14:06:15 +00001163
Evan Chengf27795d2007-07-17 18:03:34 +00001164 // Skip the callee-saved pop instructions.
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001165 MachineBasicBlock::iterator LastCSPop = MBBI;
Evan Chengf27795d2007-07-17 18:03:34 +00001166 while (MBBI != MBB.begin()) {
Evan Chengfcc87932007-07-26 17:45:41 +00001167 MachineBasicBlock::iterator PI = prior(MBBI);
1168 unsigned Opc = PI->getOpcode();
Bill Wendling80c76432009-08-16 11:00:26 +00001169
Bill Wendlingf7c09402008-10-31 18:30:19 +00001170 if (Opc != X86::POP32r && Opc != X86::POP64r &&
1171 !PI->getDesc().isTerminator())
Evan Chengf27795d2007-07-17 18:03:34 +00001172 break;
Bill Wendling80c76432009-08-16 11:00:26 +00001173
Evan Chengf27795d2007-07-17 18:03:34 +00001174 --MBBI;
1175 }
1176
Bill Wendling3d2445f2009-02-21 00:43:56 +00001177 DL = MBBI->getDebugLoc();
1178
Anton Korobeynikov4f1c33f2007-10-06 16:17:49 +00001179 // If there is an ADD32ri or SUB32ri of ESP immediately before this
1180 // instruction, merge the two instructions.
1181 if (NumBytes || MFI->hasVarSizedObjects())
1182 mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
Evan Cheng5b3332c2007-07-17 18:40:47 +00001183
Anton Korobeynikov4f1c33f2007-10-06 16:17:49 +00001184 // If dynamic alloca is used, then reset esp to point to the last callee-saved
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001185 // slot before popping them off! Same applies for the case, when stack was
Bill Wendling80c76432009-08-16 11:00:26 +00001186 // realigned.
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001187 if (needsStackRealignment(MF)) {
1188 // We cannot use LEA here, because stack pointer was realigned. We need to
Bill Wendling80c76432009-08-16 11:00:26 +00001189 // deallocate local frame back.
Evan Cheng3c46eef2007-07-18 21:26:06 +00001190 if (CSSize) {
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001191 emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII);
1192 MBBI = prior(LastCSPop);
1193 }
1194
Dale Johannesen21b55412009-02-12 23:08:38 +00001195 BuildMI(MBB, MBBI, DL,
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001196 TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
1197 StackPtr).addReg(FramePtr);
1198 } else if (MFI->hasVarSizedObjects()) {
1199 if (CSSize) {
1200 unsigned Opc = Is64Bit ? X86::LEA64r : X86::LEA32r;
Bill Wendling80c76432009-08-16 11:00:26 +00001201 MachineInstr *MI =
1202 addLeaRegOffset(BuildMI(MF, DL, TII.get(Opc), StackPtr),
1203 FramePtr, false, -CSSize);
Evan Cheng3c46eef2007-07-18 21:26:06 +00001204 MBB.insert(MBBI, MI);
Bill Wendling80c76432009-08-16 11:00:26 +00001205 } else {
1206 BuildMI(MBB, MBBI, DL,
1207 TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), StackPtr)
1208 .addReg(FramePtr);
1209 }
1210 } else if (NumBytes) {
1211 // Adjust stack pointer back: ESP += numbytes.
1212 emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII);
Evan Cheng3c46eef2007-07-18 21:26:06 +00001213 }
1214
Evan Cheng5b3332c2007-07-17 18:40:47 +00001215 // We're returning from function via eh_return.
Anton Korobeynikovb84c1672008-09-08 21:12:47 +00001216 if (RetOpcode == X86::EH_RETURN || RetOpcode == X86::EH_RETURN64) {
Evan Cheng5b3332c2007-07-17 18:40:47 +00001217 MBBI = prior(MBB.end());
1218 MachineOperand &DestAddr = MBBI->getOperand(0);
Dan Gohmand735b802008-10-03 15:45:36 +00001219 assert(DestAddr.isReg() && "Offset should be in register!");
Dale Johannesen21b55412009-02-12 23:08:38 +00001220 BuildMI(MBB, MBBI, DL,
Anton Korobeynikovb84c1672008-09-08 21:12:47 +00001221 TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
1222 StackPtr).addReg(DestAddr.getReg());
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001223 } else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi ||
Evan Chengf48ef032010-03-14 03:48:46 +00001224 RetOpcode == X86::TCRETURNmi ||
1225 RetOpcode == X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64 ||
1226 RetOpcode == X86::TCRETURNmi64) {
1227 bool isMem = RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64;
Bill Wendling80c76432009-08-16 11:00:26 +00001228 // Tail call return: adjust the stack pointer and jump to callee.
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001229 MBBI = prior(MBB.end());
1230 MachineOperand &JumpTarget = MBBI->getOperand(0);
Evan Chengf48ef032010-03-14 03:48:46 +00001231 MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 5 : 1);
Dan Gohmand735b802008-10-03 15:45:36 +00001232 assert(StackAdjust.isImm() && "Expecting immediate value.");
Anton Korobeynikove2011902008-04-23 18:15:11 +00001233
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001234 // Adjust stack pointer.
1235 int StackAdj = StackAdjust.getImm();
1236 int MaxTCDelta = X86FI->getTCReturnAddrDelta();
1237 int Offset = 0;
1238 assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive");
Bill Wendling80c76432009-08-16 11:00:26 +00001239
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001240 // Incoporate the retaddr area.
1241 Offset = StackAdj-MaxTCDelta;
1242 assert(Offset >= 0 && "Offset should never be negative");
Bill Wendling3d2445f2009-02-21 00:43:56 +00001243
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001244 if (Offset) {
1245 // Check for possible merge with preceeding ADD instruction.
1246 Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true);
1247 emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII);
Anton Korobeynikove2011902008-04-23 18:15:11 +00001248 }
Bill Wendling3d2445f2009-02-21 00:43:56 +00001249
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001250 // Jump to label or value in register.
Evan Chengf48ef032010-03-14 03:48:46 +00001251 if (RetOpcode == X86::TCRETURNdi || RetOpcode == X86::TCRETURNdi64) {
1252 BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNdi)
1253 ? X86::TAILJMPd : X86::TAILJMPd64)).
Evan Cheng1d885c02010-01-30 01:16:15 +00001254 addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
1255 JumpTarget.getTargetFlags());
Evan Chengf48ef032010-03-14 03:48:46 +00001256 } else if (RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64) {
1257 MachineInstrBuilder MIB =
1258 BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNmi)
1259 ? X86::TAILJMPm : X86::TAILJMPm64));
1260 for (unsigned i = 0; i != 5; ++i)
1261 MIB.addOperand(MBBI->getOperand(i));
Evan Chengaa92bec2010-01-31 07:28:44 +00001262 } else if (RetOpcode == X86::TCRETURNri64) {
Dale Johannesen21b55412009-02-12 23:08:38 +00001263 BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr64), JumpTarget.getReg());
Evan Chengaa92bec2010-01-31 07:28:44 +00001264 } else {
Dan Gohman39a1fab2009-11-30 23:33:53 +00001265 BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr), JumpTarget.getReg());
Evan Chengaa92bec2010-01-31 07:28:44 +00001266 }
1267
1268 MachineInstr *NewMI = prior(MBBI);
1269 for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i)
1270 NewMI->addOperand(MBBI->getOperand(i));
Bill Wendling3d2445f2009-02-21 00:43:56 +00001271
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001272 // Delete the pseudo instruction TCRETURN.
1273 MBB.erase(MBBI);
Anton Korobeynikove2011902008-04-23 18:15:11 +00001274 } else if ((RetOpcode == X86::RET || RetOpcode == X86::RETI) &&
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001275 (X86FI->getTCReturnAddrDelta() < 0)) {
1276 // Add the return addr area delta back since we are not tail calling.
1277 int delta = -1*X86FI->getTCReturnAddrDelta();
1278 MBBI = prior(MBB.end());
Bill Wendling80c76432009-08-16 11:00:26 +00001279
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001280 // Check for possible merge with preceeding ADD instruction.
1281 delta += mergeSPUpdates(MBB, MBBI, StackPtr, true);
1282 emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, TII);
Evan Cheng5b3332c2007-07-17 18:40:47 +00001283 }
Chris Lattner3c1c03d2002-12-28 20:32:28 +00001284}
1285
Jim Laskey41886992006-04-07 16:34:46 +00001286unsigned X86RegisterInfo::getRARegister() const {
Bill Wendling80c76432009-08-16 11:00:26 +00001287 return Is64Bit ? X86::RIP // Should have dwarf #16.
1288 : X86::EIP; // Should have dwarf #8.
Jim Laskey41886992006-04-07 16:34:46 +00001289}
1290
David Greene3f2bf852009-11-12 20:49:22 +00001291unsigned X86RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
Evan Cheng25ab6902006-09-08 06:48:29 +00001292 return hasFP(MF) ? FramePtr : StackPtr;
Jim Laskeyf1d78e82006-03-23 18:12:57 +00001293}
1294
Bill Wendling80c76432009-08-16 11:00:26 +00001295void
1296X86RegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves) const {
Anton Korobeynikov0ff3ca42007-05-12 22:36:25 +00001297 // Calculate amount of bytes used for return address storing
1298 int stackGrowth = (Is64Bit ? -8 : -4);
1299
1300 // Initial state of the frame pointer is esp+4.
Jim Laskey0e410942007-01-24 19:15:24 +00001301 MachineLocation Dst(MachineLocation::VirtualFP);
Anton Korobeynikov0ff3ca42007-05-12 22:36:25 +00001302 MachineLocation Src(StackPtr, stackGrowth);
Jim Laskey0e410942007-01-24 19:15:24 +00001303 Moves.push_back(MachineMove(0, Dst, Src));
Anton Korobeynikov0ff3ca42007-05-12 22:36:25 +00001304
1305 // Add return address to move list
1306 MachineLocation CSDst(StackPtr, stackGrowth);
1307 MachineLocation CSSrc(getRARegister());
1308 Moves.push_back(MachineMove(0, CSDst, CSSrc));
Jim Laskey0e410942007-01-24 19:15:24 +00001309}
1310
Jim Laskey62819f32007-02-21 22:54:50 +00001311unsigned X86RegisterInfo::getEHExceptionRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +00001312 llvm_unreachable("What is the exception register");
Jim Laskey62819f32007-02-21 22:54:50 +00001313 return 0;
1314}
1315
1316unsigned X86RegisterInfo::getEHHandlerRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +00001317 llvm_unreachable("What is the exception handler register");
Jim Laskey62819f32007-02-21 22:54:50 +00001318 return 0;
1319}
1320
Evan Cheng8f7f7122006-05-05 05:40:20 +00001321namespace llvm {
Owen Andersone50ed302009-08-10 22:56:29 +00001322unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) {
Owen Anderson825b72b2009-08-11 20:47:22 +00001323 switch (VT.getSimpleVT().SimpleTy) {
Evan Cheng8f7f7122006-05-05 05:40:20 +00001324 default: return Reg;
Owen Anderson825b72b2009-08-11 20:47:22 +00001325 case MVT::i8:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001326 if (High) {
1327 switch (Reg) {
Evan Cheng25ab6902006-09-08 06:48:29 +00001328 default: return 0;
1329 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001330 return X86::AH;
Evan Cheng25ab6902006-09-08 06:48:29 +00001331 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001332 return X86::DH;
Evan Cheng25ab6902006-09-08 06:48:29 +00001333 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001334 return X86::CH;
Evan Cheng25ab6902006-09-08 06:48:29 +00001335 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001336 return X86::BH;
1337 }
1338 } else {
1339 switch (Reg) {
Evan Cheng25ab6902006-09-08 06:48:29 +00001340 default: return 0;
1341 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001342 return X86::AL;
Evan Cheng25ab6902006-09-08 06:48:29 +00001343 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001344 return X86::DL;
Evan Cheng25ab6902006-09-08 06:48:29 +00001345 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001346 return X86::CL;
Evan Cheng25ab6902006-09-08 06:48:29 +00001347 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001348 return X86::BL;
Evan Cheng25ab6902006-09-08 06:48:29 +00001349 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
1350 return X86::SIL;
1351 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
1352 return X86::DIL;
1353 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
1354 return X86::BPL;
1355 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
1356 return X86::SPL;
1357 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
1358 return X86::R8B;
1359 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
1360 return X86::R9B;
1361 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
1362 return X86::R10B;
1363 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
1364 return X86::R11B;
1365 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
1366 return X86::R12B;
1367 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
1368 return X86::R13B;
1369 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
1370 return X86::R14B;
1371 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
1372 return X86::R15B;
Evan Cheng8f7f7122006-05-05 05:40:20 +00001373 }
1374 }
Owen Anderson825b72b2009-08-11 20:47:22 +00001375 case MVT::i16:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001376 switch (Reg) {
1377 default: return Reg;
Evan Cheng25ab6902006-09-08 06:48:29 +00001378 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001379 return X86::AX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001380 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001381 return X86::DX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001382 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001383 return X86::CX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001384 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001385 return X86::BX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001386 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001387 return X86::SI;
Evan Cheng25ab6902006-09-08 06:48:29 +00001388 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001389 return X86::DI;
Evan Cheng25ab6902006-09-08 06:48:29 +00001390 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001391 return X86::BP;
Evan Cheng25ab6902006-09-08 06:48:29 +00001392 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001393 return X86::SP;
Evan Cheng25ab6902006-09-08 06:48:29 +00001394 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
1395 return X86::R8W;
1396 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
1397 return X86::R9W;
1398 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
1399 return X86::R10W;
1400 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
1401 return X86::R11W;
1402 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
1403 return X86::R12W;
1404 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
1405 return X86::R13W;
1406 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
1407 return X86::R14W;
1408 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
1409 return X86::R15W;
Evan Cheng8f7f7122006-05-05 05:40:20 +00001410 }
Owen Anderson825b72b2009-08-11 20:47:22 +00001411 case MVT::i32:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001412 switch (Reg) {
Evan Cheng25ab6902006-09-08 06:48:29 +00001413 default: return Reg;
1414 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001415 return X86::EAX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001416 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001417 return X86::EDX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001418 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001419 return X86::ECX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001420 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001421 return X86::EBX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001422 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001423 return X86::ESI;
Evan Cheng25ab6902006-09-08 06:48:29 +00001424 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001425 return X86::EDI;
Evan Cheng25ab6902006-09-08 06:48:29 +00001426 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001427 return X86::EBP;
Evan Cheng25ab6902006-09-08 06:48:29 +00001428 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001429 return X86::ESP;
Evan Cheng25ab6902006-09-08 06:48:29 +00001430 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
1431 return X86::R8D;
1432 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
1433 return X86::R9D;
1434 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
1435 return X86::R10D;
1436 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
1437 return X86::R11D;
1438 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
1439 return X86::R12D;
1440 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
1441 return X86::R13D;
1442 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
1443 return X86::R14D;
1444 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
1445 return X86::R15D;
1446 }
Owen Anderson825b72b2009-08-11 20:47:22 +00001447 case MVT::i64:
Evan Cheng25ab6902006-09-08 06:48:29 +00001448 switch (Reg) {
1449 default: return Reg;
1450 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
1451 return X86::RAX;
1452 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
1453 return X86::RDX;
1454 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
1455 return X86::RCX;
1456 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
1457 return X86::RBX;
1458 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
1459 return X86::RSI;
1460 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
1461 return X86::RDI;
1462 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
1463 return X86::RBP;
1464 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
1465 return X86::RSP;
1466 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
1467 return X86::R8;
1468 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
1469 return X86::R9;
1470 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
1471 return X86::R10;
1472 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
1473 return X86::R11;
1474 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
1475 return X86::R12;
1476 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
1477 return X86::R13;
1478 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
1479 return X86::R14;
1480 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
1481 return X86::R15;
Evan Cheng8f7f7122006-05-05 05:40:20 +00001482 }
1483 }
1484
1485 return Reg;
1486}
1487}
1488
Chris Lattner7ad3e062003-08-03 15:48:14 +00001489#include "X86GenRegisterInfo.inc"
Jim Grosbachfa85eb62010-04-06 20:26:37 +00001490
1491namespace {
1492 struct MSAH : public MachineFunctionPass {
1493 static char ID;
1494 MSAH() : MachineFunctionPass(&ID) {}
1495
1496 virtual bool runOnMachineFunction(MachineFunction &MF) {
1497 const X86TargetMachine *TM =
1498 static_cast<const X86TargetMachine *>(&MF.getTarget());
1499 const X86RegisterInfo *X86RI = TM->getRegisterInfo();
1500 MachineRegisterInfo &RI = MF.getRegInfo();
1501 X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
1502 unsigned StackAlignment = X86RI->getStackAlignment();
1503
1504 // Be over-conservative: scan over all vreg defs and find whether vector
1505 // registers are used. If yes, there is a possibility that vector register
1506 // will be spilled and thus require dynamic stack realignment.
1507 for (unsigned RegNum = TargetRegisterInfo::FirstVirtualRegister;
1508 RegNum < RI.getLastVirtReg(); ++RegNum)
1509 if (RI.getRegClass(RegNum)->getAlignment() > StackAlignment) {
1510 FuncInfo->setReserveFP(true);
1511 return true;
1512 }
1513
1514 // Nothing to do
1515 return false;
1516 }
1517
1518 virtual const char *getPassName() const {
1519 return "X86 Maximal Stack Alignment Check";
1520 }
1521
1522 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1523 AU.setPreservesCFG();
1524 MachineFunctionPass::getAnalysisUsage(AU);
1525 }
1526 };
1527
1528 char MSAH::ID = 0;
1529}
1530
1531FunctionPass*
1532llvm::createX86MaxStackAlignmentHeuristicPass() { return new MSAH(); }