blob: fac85c75d391cd548844d7c7637f5c5ad9062015 [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"
Chris Lattner300d0ed2004-02-14 06:00:36 +000041using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000042
Evan Cheng25ab6902006-09-08 06:48:29 +000043X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm,
44 const TargetInstrInfo &tii)
Dan Gohman6d4b0522008-10-01 18:28:06 +000045 : X86GenRegisterInfo(tm.getSubtarget<X86Subtarget>().is64Bit() ?
46 X86::ADJCALLSTACKDOWN64 :
47 X86::ADJCALLSTACKDOWN32,
48 tm.getSubtarget<X86Subtarget>().is64Bit() ?
49 X86::ADJCALLSTACKUP64 :
50 X86::ADJCALLSTACKUP32),
Evan Cheng25ab6902006-09-08 06:48:29 +000051 TM(tm), TII(tii) {
52 // Cache some information.
53 const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
54 Is64Bit = Subtarget->is64Bit();
Anton Korobeynikov1dcce212008-03-22 21:04:01 +000055 IsWin64 = Subtarget->isTargetWin64();
Evan Chengdb807ed2007-11-05 07:30:01 +000056 StackAlign = TM.getFrameInfo()->getStackAlignment();
Bill Wendling80c76432009-08-16 11:00:26 +000057
Evan Cheng25ab6902006-09-08 06:48:29 +000058 if (Is64Bit) {
59 SlotSize = 8;
60 StackPtr = X86::RSP;
61 FramePtr = X86::RBP;
62 } else {
63 SlotSize = 4;
64 StackPtr = X86::ESP;
65 FramePtr = X86::EBP;
66 }
67}
Chris Lattner7ad3e062003-08-03 15:48:14 +000068
Bill Wendling80c76432009-08-16 11:00:26 +000069/// getDwarfRegNum - This function maps LLVM register identifiers to the DWARF
70/// specific numbering, used in debug info and exception tables.
Dale Johannesenb97aec62007-11-13 19:13:01 +000071int X86RegisterInfo::getDwarfRegNum(unsigned RegNo, bool isEH) const {
Dale Johannesen483ec212007-11-07 00:25:05 +000072 const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
Anton Korobeynikovf191c802007-11-11 19:50:10 +000073 unsigned Flavour = DWARFFlavour::X86_64;
Bill Wendling80c76432009-08-16 11:00:26 +000074
Dale Johannesen7a42f242007-11-09 18:07:11 +000075 if (!Subtarget->is64Bit()) {
Anton Korobeynikovf191c802007-11-11 19:50:10 +000076 if (Subtarget->isTargetDarwin()) {
Anton Korobeynikov8eea3392008-01-25 00:34:13 +000077 if (isEH)
78 Flavour = DWARFFlavour::X86_32_DarwinEH;
79 else
80 Flavour = DWARFFlavour::X86_32_Generic;
Anton Korobeynikovf191c802007-11-11 19:50:10 +000081 } else if (Subtarget->isTargetCygMing()) {
82 // Unsupported by now, just quick fallback
Anton Korobeynikov8eea3392008-01-25 00:34:13 +000083 Flavour = DWARFFlavour::X86_32_Generic;
Anton Korobeynikovf191c802007-11-11 19:50:10 +000084 } else {
Anton Korobeynikov8eea3392008-01-25 00:34:13 +000085 Flavour = DWARFFlavour::X86_32_Generic;
Dale Johannesen7a42f242007-11-09 18:07:11 +000086 }
Dale Johannesen483ec212007-11-07 00:25:05 +000087 }
Anton Korobeynikovf191c802007-11-11 19:50:10 +000088
89 return X86GenRegisterInfo::getDwarfRegNumFull(RegNo, Flavour);
Dale Johannesen483ec212007-11-07 00:25:05 +000090}
91
Bill Wendling80c76432009-08-16 11:00:26 +000092/// getX86RegNum - This function maps LLVM register identifiers to their X86
93/// specific numbering, which is used in various places encoding instructions.
Nicolas Geoffray52e724a2008-04-16 20:10:13 +000094unsigned X86RegisterInfo::getX86RegNum(unsigned RegNo) {
Duncan Sandsee465742007-08-29 19:01:20 +000095 switch(RegNo) {
96 case X86::RAX: case X86::EAX: case X86::AX: case X86::AL: return N86::EAX;
97 case X86::RCX: case X86::ECX: case X86::CX: case X86::CL: return N86::ECX;
98 case X86::RDX: case X86::EDX: case X86::DX: case X86::DL: return N86::EDX;
99 case X86::RBX: case X86::EBX: case X86::BX: case X86::BL: return N86::EBX;
100 case X86::RSP: case X86::ESP: case X86::SP: case X86::SPL: case X86::AH:
101 return N86::ESP;
102 case X86::RBP: case X86::EBP: case X86::BP: case X86::BPL: case X86::CH:
103 return N86::EBP;
104 case X86::RSI: case X86::ESI: case X86::SI: case X86::SIL: case X86::DH:
105 return N86::ESI;
106 case X86::RDI: case X86::EDI: case X86::DI: case X86::DIL: case X86::BH:
107 return N86::EDI;
108
109 case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
110 return N86::EAX;
111 case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
112 return N86::ECX;
113 case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
114 return N86::EDX;
115 case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
116 return N86::EBX;
117 case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
118 return N86::ESP;
119 case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
120 return N86::EBP;
121 case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
122 return N86::ESI;
123 case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
124 return N86::EDI;
125
126 case X86::ST0: case X86::ST1: case X86::ST2: case X86::ST3:
127 case X86::ST4: case X86::ST5: case X86::ST6: case X86::ST7:
128 return RegNo-X86::ST0;
129
Nate Begeman6e041c22007-12-11 18:06:14 +0000130 case X86::XMM0: case X86::XMM8: case X86::MM0:
Evan Chenge7c87542007-11-13 17:54:34 +0000131 return 0;
Nate Begeman6e041c22007-12-11 18:06:14 +0000132 case X86::XMM1: case X86::XMM9: case X86::MM1:
Evan Chenge7c87542007-11-13 17:54:34 +0000133 return 1;
Nate Begeman6e041c22007-12-11 18:06:14 +0000134 case X86::XMM2: case X86::XMM10: case X86::MM2:
Evan Chenge7c87542007-11-13 17:54:34 +0000135 return 2;
Nate Begeman6e041c22007-12-11 18:06:14 +0000136 case X86::XMM3: case X86::XMM11: case X86::MM3:
Evan Chenge7c87542007-11-13 17:54:34 +0000137 return 3;
Nate Begeman6e041c22007-12-11 18:06:14 +0000138 case X86::XMM4: case X86::XMM12: case X86::MM4:
Evan Chenge7c87542007-11-13 17:54:34 +0000139 return 4;
Nate Begeman6e041c22007-12-11 18:06:14 +0000140 case X86::XMM5: case X86::XMM13: case X86::MM5:
Evan Chenge7c87542007-11-13 17:54:34 +0000141 return 5;
Nate Begeman6e041c22007-12-11 18:06:14 +0000142 case X86::XMM6: case X86::XMM14: case X86::MM6:
Evan Chenge7c87542007-11-13 17:54:34 +0000143 return 6;
Nate Begeman6e041c22007-12-11 18:06:14 +0000144 case X86::XMM7: case X86::XMM15: case X86::MM7:
Evan Chenge7c87542007-11-13 17:54:34 +0000145 return 7;
Duncan Sandsee465742007-08-29 19:01:20 +0000146
147 default:
148 assert(isVirtualRegister(RegNo) && "Unknown physical register!");
Torok Edwinc23197a2009-07-14 16:55:14 +0000149 llvm_unreachable("Register allocator hasn't allocated reg correctly yet!");
Duncan Sandsee465742007-08-29 19:01:20 +0000150 return 0;
151 }
152}
153
Evan Cheng52484682009-07-18 02:10:10 +0000154const TargetRegisterClass *
155X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
156 const TargetRegisterClass *B,
157 unsigned SubIdx) const {
158 switch (SubIdx) {
159 default: return 0;
160 case 1:
161 // 8-bit
162 if (B == &X86::GR8RegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000163 if (A->getSize() == 2 || A->getSize() == 4 || A->getSize() == 8)
164 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000165 } else if (B == &X86::GR8_ABCD_LRegClass || B == &X86::GR8_ABCD_HRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000166 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000167 A == &X86::GR64_NOREXRegClass ||
168 A == &X86::GR64_NOSPRegClass ||
169 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000170 return &X86::GR64_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000171 else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000172 A == &X86::GR32_NOREXRegClass ||
173 A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000174 return &X86::GR32_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000175 else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
176 A == &X86::GR16_NOREXRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000177 return &X86::GR16_ABCDRegClass;
178 } else if (B == &X86::GR8_NOREXRegClass) {
Dan Gohmana4714e02009-07-30 01:56:29 +0000179 if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
180 A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000181 return &X86::GR64_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000182 else if (A == &X86::GR64_ABCDRegClass)
183 return &X86::GR64_ABCDRegClass;
Dan Gohmana4714e02009-07-30 01:56:29 +0000184 else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass ||
185 A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000186 return &X86::GR32_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000187 else if (A == &X86::GR32_ABCDRegClass)
188 return &X86::GR32_ABCDRegClass;
Evan Cheng52484682009-07-18 02:10:10 +0000189 else if (A == &X86::GR16RegClass || A == &X86::GR16_NOREXRegClass)
190 return &X86::GR16_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000191 else if (A == &X86::GR16_ABCDRegClass)
192 return &X86::GR16_ABCDRegClass;
Dan Gohman874cada2010-02-28 00:17:42 +0000193 } else if (B == &X86::FR32RegClass) {
194 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000195 }
196 break;
197 case 2:
198 // 8-bit hi
199 if (B == &X86::GR8_ABCD_HRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000200 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000201 A == &X86::GR64_NOREXRegClass ||
202 A == &X86::GR64_NOSPRegClass ||
203 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000204 return &X86::GR64_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000205 else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000206 A == &X86::GR32_NOREXRegClass || A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000207 return &X86::GR32_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000208 else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
209 A == &X86::GR16_NOREXRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000210 return &X86::GR16_ABCDRegClass;
Dan Gohman874cada2010-02-28 00:17:42 +0000211 } else if (B == &X86::FR64RegClass) {
212 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000213 }
214 break;
215 case 3:
216 // 16-bit
217 if (B == &X86::GR16RegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000218 if (A->getSize() == 4 || A->getSize() == 8)
219 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000220 } else if (B == &X86::GR16_ABCDRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000221 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000222 A == &X86::GR64_NOREXRegClass ||
223 A == &X86::GR64_NOSPRegClass ||
224 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000225 return &X86::GR64_ABCDRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000226 else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000227 A == &X86::GR32_NOREXRegClass || A == &X86::GR32_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000228 return &X86::GR32_ABCDRegClass;
229 } else if (B == &X86::GR16_NOREXRegClass) {
Dan Gohmana4714e02009-07-30 01:56:29 +0000230 if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
231 A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000232 return &X86::GR64_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000233 else if (A == &X86::GR64_ABCDRegClass)
234 return &X86::GR64_ABCDRegClass;
Dan Gohmana4714e02009-07-30 01:56:29 +0000235 else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass ||
236 A == &X86::GR32_NOSPRegClass)
Evan Cheng753480a2009-07-20 19:47:55 +0000237 return &X86::GR32_NOREXRegClass;
238 else if (A == &X86::GR32_ABCDRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000239 return &X86::GR64_ABCDRegClass;
Dan Gohman874cada2010-02-28 00:17:42 +0000240 } else if (B == &X86::VR128RegClass) {
241 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000242 }
243 break;
244 case 4:
245 // 32-bit
Dan Gohmana4714e02009-07-30 01:56:29 +0000246 if (B == &X86::GR32RegClass || B == &X86::GR32_NOSPRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000247 if (A->getSize() == 8)
248 return A;
Evan Cheng52484682009-07-18 02:10:10 +0000249 } else if (B == &X86::GR32_ABCDRegClass) {
Evan Cheng753480a2009-07-20 19:47:55 +0000250 if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
Dan Gohmana4714e02009-07-30 01:56:29 +0000251 A == &X86::GR64_NOREXRegClass ||
252 A == &X86::GR64_NOSPRegClass ||
253 A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000254 return &X86::GR64_ABCDRegClass;
255 } else if (B == &X86::GR32_NOREXRegClass) {
Dan Gohmana4714e02009-07-30 01:56:29 +0000256 if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
257 A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
Evan Cheng52484682009-07-18 02:10:10 +0000258 return &X86::GR64_NOREXRegClass;
Evan Cheng753480a2009-07-20 19:47:55 +0000259 else if (A == &X86::GR64_ABCDRegClass)
260 return &X86::GR64_ABCDRegClass;
Evan Cheng52484682009-07-18 02:10:10 +0000261 }
262 break;
263 }
264 return 0;
265}
266
Bill Wendling80c76432009-08-16 11:00:26 +0000267const TargetRegisterClass *
268X86RegisterInfo::getPointerRegClass(unsigned Kind) const {
Dan Gohmana4714e02009-07-30 01:56:29 +0000269 switch (Kind) {
270 default: llvm_unreachable("Unexpected Kind in getPointerRegClass!");
271 case 0: // Normal GPRs.
272 if (TM.getSubtarget<X86Subtarget>().is64Bit())
273 return &X86::GR64RegClass;
274 return &X86::GR32RegClass;
275 case 1: // Normal GRPs except the stack pointer (for encoding reasons).
Dan Gohman74f6f9a2009-08-05 17:40:24 +0000276 if (TM.getSubtarget<X86Subtarget>().is64Bit())
277 return &X86::GR64_NOSPRegClass;
278 return &X86::GR32_NOSPRegClass;
Dan Gohmana4714e02009-07-30 01:56:29 +0000279 }
Evan Cheng770bcc72009-02-06 17:43:24 +0000280}
281
Evan Chengff110262007-09-26 21:31:07 +0000282const TargetRegisterClass *
283X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
Anton Korobeynikov4aefd6b2008-02-20 12:07:57 +0000284 if (RC == &X86::CCRRegClass) {
Evan Cheng3f2d9ec2007-09-27 21:50:05 +0000285 if (Is64Bit)
286 return &X86::GR64RegClass;
287 else
288 return &X86::GR32RegClass;
Anton Korobeynikov4aefd6b2008-02-20 12:07:57 +0000289 }
Evan Chengff110262007-09-26 21:31:07 +0000290 return NULL;
291}
Evan Chengbf2c8b32007-03-20 08:09:38 +0000292
Evan Cheng64d80e32007-07-19 01:14:50 +0000293const unsigned *
294X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000295 bool callsEHReturn = false;
Chris Lattner29689432010-03-11 00:22:57 +0000296 bool ghcCall = false;
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000297
298 if (MF) {
Chris Lattnera267b002010-04-05 05:57:52 +0000299 callsEHReturn = MF->getMMI().callsEHReturn();
Chris Lattner29689432010-03-11 00:22:57 +0000300 const Function *F = MF->getFunction();
301 ghcCall = (F ? F->getCallingConv() == CallingConv::GHC : false);
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000302 }
303
Chris Lattner29689432010-03-11 00:22:57 +0000304 static const unsigned GhcCalleeSavedRegs[] = {
305 0
306 };
307
Evan Chengc2b861d2007-01-02 21:33:40 +0000308 static const unsigned CalleeSavedRegs32Bit[] = {
Evan Cheng0f3ac8d2006-05-18 00:12:58 +0000309 X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0
310 };
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000311
312 static const unsigned CalleeSavedRegs32EHRet[] = {
313 X86::EAX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0
314 };
315
Evan Chengc2b861d2007-01-02 21:33:40 +0000316 static const unsigned CalleeSavedRegs64Bit[] = {
Evan Cheng25ab6902006-09-08 06:48:29 +0000317 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
318 };
319
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000320 static const unsigned CalleeSavedRegs64EHRet[] = {
321 X86::RAX, X86::RDX, X86::RBX, X86::R12,
322 X86::R13, X86::R14, X86::R15, X86::RBP, 0
323 };
324
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000325 static const unsigned CalleeSavedRegsWin64[] = {
Anton Korobeynikov5979d712008-09-24 22:03:04 +0000326 X86::RBX, X86::RBP, X86::RDI, X86::RSI,
327 X86::R12, X86::R13, X86::R14, X86::R15,
328 X86::XMM6, X86::XMM7, X86::XMM8, X86::XMM9,
329 X86::XMM10, X86::XMM11, X86::XMM12, X86::XMM13,
330 X86::XMM14, X86::XMM15, 0
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000331 };
332
Chris Lattner29689432010-03-11 00:22:57 +0000333 if (ghcCall) {
334 return GhcCalleeSavedRegs;
335 } else if (Is64Bit) {
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000336 if (IsWin64)
337 return CalleeSavedRegsWin64;
338 else
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000339 return (callsEHReturn ? CalleeSavedRegs64EHRet : CalleeSavedRegs64Bit);
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000340 } else {
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000341 return (callsEHReturn ? CalleeSavedRegs32EHRet : CalleeSavedRegs32Bit);
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000342 }
Evan Cheng0f3ac8d2006-05-18 00:12:58 +0000343}
344
345const TargetRegisterClass* const*
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000346X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000347 bool callsEHReturn = false;
Chris Lattnera267b002010-04-05 05:57:52 +0000348 if (MF)
349 callsEHReturn = MF->getMMI().callsEHReturn();
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000350
Evan Chengc2b861d2007-01-02 21:33:40 +0000351 static const TargetRegisterClass * const CalleeSavedRegClasses32Bit[] = {
Evan Cheng0f3ac8d2006-05-18 00:12:58 +0000352 &X86::GR32RegClass, &X86::GR32RegClass,
353 &X86::GR32RegClass, &X86::GR32RegClass, 0
354 };
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000355 static const TargetRegisterClass * const CalleeSavedRegClasses32EHRet[] = {
356 &X86::GR32RegClass, &X86::GR32RegClass,
357 &X86::GR32RegClass, &X86::GR32RegClass,
358 &X86::GR32RegClass, &X86::GR32RegClass, 0
359 };
Evan Chengc2b861d2007-01-02 21:33:40 +0000360 static const TargetRegisterClass * const CalleeSavedRegClasses64Bit[] = {
Evan Cheng25ab6902006-09-08 06:48:29 +0000361 &X86::GR64RegClass, &X86::GR64RegClass,
362 &X86::GR64RegClass, &X86::GR64RegClass,
363 &X86::GR64RegClass, &X86::GR64RegClass, 0
364 };
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000365 static const TargetRegisterClass * const CalleeSavedRegClasses64EHRet[] = {
366 &X86::GR64RegClass, &X86::GR64RegClass,
367 &X86::GR64RegClass, &X86::GR64RegClass,
368 &X86::GR64RegClass, &X86::GR64RegClass,
369 &X86::GR64RegClass, &X86::GR64RegClass, 0
370 };
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000371 static const TargetRegisterClass * const CalleeSavedRegClassesWin64[] = {
Anton Korobeynikov5979d712008-09-24 22:03:04 +0000372 &X86::GR64RegClass, &X86::GR64RegClass,
373 &X86::GR64RegClass, &X86::GR64RegClass,
374 &X86::GR64RegClass, &X86::GR64RegClass,
375 &X86::GR64RegClass, &X86::GR64RegClass,
376 &X86::VR128RegClass, &X86::VR128RegClass,
377 &X86::VR128RegClass, &X86::VR128RegClass,
378 &X86::VR128RegClass, &X86::VR128RegClass,
379 &X86::VR128RegClass, &X86::VR128RegClass,
380 &X86::VR128RegClass, &X86::VR128RegClass, 0
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000381 };
Evan Cheng25ab6902006-09-08 06:48:29 +0000382
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000383 if (Is64Bit) {
384 if (IsWin64)
385 return CalleeSavedRegClassesWin64;
386 else
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000387 return (callsEHReturn ?
388 CalleeSavedRegClasses64EHRet : CalleeSavedRegClasses64Bit);
Anton Korobeynikov1dcce212008-03-22 21:04:01 +0000389 } else {
Anton Korobeynikovb84c1672008-09-08 21:12:47 +0000390 return (callsEHReturn ?
391 CalleeSavedRegClasses32EHRet : CalleeSavedRegClasses32Bit);
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000392 }
Evan Cheng0f3ac8d2006-05-18 00:12:58 +0000393}
394
Evan Chengb371f452007-02-19 21:49:54 +0000395BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
396 BitVector Reserved(getNumRegs());
Dan Gohmana32b7ac2008-12-18 01:05:09 +0000397 // Set the stack-pointer register and its aliases as reserved.
Evan Chengb371f452007-02-19 21:49:54 +0000398 Reserved.set(X86::RSP);
399 Reserved.set(X86::ESP);
400 Reserved.set(X86::SP);
401 Reserved.set(X86::SPL);
Bill Wendling80c76432009-08-16 11:00:26 +0000402
Jakob Stoklund Olesen52cd5482009-11-13 21:56:01 +0000403 // Set the instruction pointer register and its aliases as reserved.
404 Reserved.set(X86::RIP);
405 Reserved.set(X86::EIP);
406 Reserved.set(X86::IP);
407
Dan Gohmana32b7ac2008-12-18 01:05:09 +0000408 // Set the frame-pointer register and its aliases as reserved if needed.
Evan Chengb371f452007-02-19 21:49:54 +0000409 if (hasFP(MF)) {
410 Reserved.set(X86::RBP);
411 Reserved.set(X86::EBP);
412 Reserved.set(X86::BP);
413 Reserved.set(X86::BPL);
414 }
Bill Wendling80c76432009-08-16 11:00:26 +0000415
416 // Mark the x87 stack registers as reserved, since they don't behave normally
417 // with respect to liveness. We don't fully model the effects of x87 stack
418 // pushes and pops after stackification.
Dan Gohmana32b7ac2008-12-18 01:05:09 +0000419 Reserved.set(X86::ST0);
420 Reserved.set(X86::ST1);
421 Reserved.set(X86::ST2);
422 Reserved.set(X86::ST3);
423 Reserved.set(X86::ST4);
424 Reserved.set(X86::ST5);
425 Reserved.set(X86::ST6);
426 Reserved.set(X86::ST7);
Evan Chengb371f452007-02-19 21:49:54 +0000427 return Reserved;
428}
429
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000430//===----------------------------------------------------------------------===//
431// Stack Frame Processing methods
432//===----------------------------------------------------------------------===//
433
Bill Wendling80c76432009-08-16 11:00:26 +0000434/// hasFP - Return true if the specified function should have a dedicated frame
435/// pointer register. This is true if the function has variable sized allocas
436/// or if frame pointer elimination is disabled.
Evan Chengdc775402007-01-23 00:57:47 +0000437bool X86RegisterInfo::hasFP(const MachineFunction &MF) const {
Dan Gohman8e5f2c62008-07-07 23:14:23 +0000438 const MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattnera267b002010-04-05 05:57:52 +0000439 const MachineModuleInfo &MMI = MF.getMMI();
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000440
Evan Chenge5667632010-04-21 03:18:23 +0000441 return (DisableFramePointerElim(MF) ||
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000442 needsStackRealignment(MF) ||
Evan Cheng7e7bbf82007-07-19 00:42:05 +0000443 MFI->hasVarSizedObjects() ||
Evan Cheng184793f2008-09-27 01:56:22 +0000444 MFI->isFrameAddressTaken() ||
Anton Korobeynikov2365f512007-07-14 14:06:15 +0000445 MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() ||
Chris Lattnera267b002010-04-05 05:57:52 +0000446 MMI.callsUnwindInit());
Misha Brukman03c6faf2002-12-03 23:11:21 +0000447}
Misha Brukman2adb3952002-12-04 23:57:03 +0000448
Jim Grosbache45ab8a2010-01-19 18:31:11 +0000449bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
450 const MachineFrameInfo *MFI = MF.getFrameInfo();
451 return (RealignStack &&
452 !MFI->hasVarSizedObjects());
453}
454
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000455bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
Nick Lewycky9c0f1462009-03-19 05:51:39 +0000456 const MachineFrameInfo *MFI = MF.getFrameInfo();
Charles Davis5dfa2672010-02-19 18:17:13 +0000457 const Function *F = MF.getFunction();
Anton Korobeynikov773943a2009-11-08 12:58:40 +0000458 bool requiresRealignment =
Charles Davis5dfa2672010-02-19 18:17:13 +0000459 RealignStack && ((MFI->getMaxAlignment() > StackAlign) ||
460 F->hasFnAttr(Attribute::StackAlignment));
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000461
Anton Korobeynikov35410a42008-04-23 18:16:43 +0000462 // FIXME: Currently we don't support stack realignment for functions with
Anton Korobeynikovb23f3aa2009-11-14 18:01:41 +0000463 // variable-sized allocas.
464 // FIXME: Temporary disable the error - it seems to be too conservative.
465 if (0 && requiresRealignment && MFI->hasVarSizedObjects())
Chris Lattner75361b62010-04-07 22:58:41 +0000466 report_fatal_error(
Anton Korobeynikov773943a2009-11-08 12:58:40 +0000467 "Stack realignment in presense of dynamic allocas is not supported");
468
Anton Korobeynikovb23f3aa2009-11-14 18:01:41 +0000469 return (requiresRealignment && !MFI->hasVarSizedObjects());
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000470}
471
Evan Cheng7e7bbf82007-07-19 00:42:05 +0000472bool X86RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
473 return !MF.getFrameInfo()->hasVarSizedObjects();
474}
475
Evan Cheng910139f2009-07-09 06:53:48 +0000476bool X86RegisterInfo::hasReservedSpillSlot(MachineFunction &MF, unsigned Reg,
477 int &FrameIdx) const {
478 if (Reg == FramePtr && hasFP(MF)) {
479 FrameIdx = MF.getFrameInfo()->getObjectIndexBegin();
480 return true;
481 }
482 return false;
483}
484
Anton Korobeynikov82751e32008-04-23 18:18:36 +0000485int
Chris Lattner30c6b752010-01-26 23:15:09 +0000486X86RegisterInfo::getFrameIndexOffset(const MachineFunction &MF, int FI) const {
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000487 const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
Chris Lattner30c6b752010-01-26 23:15:09 +0000488 const MachineFrameInfo *MFI = MF.getFrameInfo();
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000489 int Offset = MFI->getObjectOffset(FI) - TFI.getOffsetOfLocalArea();
490 uint64_t StackSize = MFI->getStackSize();
Anton Korobeynikov82751e32008-04-23 18:18:36 +0000491
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000492 if (needsStackRealignment(MF)) {
Bill Wendling80c76432009-08-16 11:00:26 +0000493 if (FI < 0) {
494 // Skip the saved EBP.
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000495 Offset += SlotSize;
Bill Wendling80c76432009-08-16 11:00:26 +0000496 } else {
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000497 unsigned Align = MFI->getObjectAlignment(FI);
Evan Cheng7545f492010-02-13 01:56:41 +0000498 assert((-(Offset + StackSize)) % Align == 0);
Devang Patelfd1c6c32008-12-23 21:56:28 +0000499 Align = 0;
Dale Johannesenb5dae002008-06-26 01:51:13 +0000500 return Offset + StackSize;
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000501 }
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000502 // FIXME: Support tail calls
503 } else {
504 if (!hasFP(MF))
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000505 return Offset + StackSize;
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000506
Bill Wendling80c76432009-08-16 11:00:26 +0000507 // Skip the saved EBP.
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000508 Offset += SlotSize;
509
510 // Skip the RETADDR move area
Chris Lattner30c6b752010-01-26 23:15:09 +0000511 const X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000512 int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
Bill Wendling80c76432009-08-16 11:00:26 +0000513 if (TailCallReturnAddrDelta < 0)
514 Offset -= TailCallReturnAddrDelta;
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000515 }
516
Anton Korobeynikov82751e32008-04-23 18:18:36 +0000517 return Offset;
518}
519
Dan Gohman7c2e0392010-05-19 00:53:19 +0000520static unsigned getSUBriOpcode(unsigned is64Bit, int64_t Imm) {
521 if (is64Bit) {
522 if (isInt<8>(Imm))
523 return X86::SUB64ri8;
524 return X86::SUB64ri32;
525 } else {
526 if (isInt<8>(Imm))
527 return X86::SUB32ri8;
528 return X86::SUB32ri;
529 }
530}
531
532static unsigned getADDriOpcode(unsigned is64Bit, int64_t Imm) {
533 if (is64Bit) {
534 if (isInt<8>(Imm))
535 return X86::ADD64ri8;
536 return X86::ADD64ri32;
537 } else {
538 if (isInt<8>(Imm))
539 return X86::ADD32ri8;
540 return X86::ADD32ri;
541 }
542}
543
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000544void X86RegisterInfo::
545eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
546 MachineBasicBlock::iterator I) const {
Evan Cheng7e7bbf82007-07-19 00:42:05 +0000547 if (!hasReservedCallFrame(MF)) {
548 // If the stack pointer can be changed after prologue, turn the
549 // adjcallstackup instruction into a 'sub ESP, <amt>' and the
550 // adjcallstackdown instruction into 'add ESP, <amt>'
551 // TODO: consider using push / pop instead of sub + store / add
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000552 MachineInstr *Old = I;
Chris Lattner61807802007-04-25 04:25:10 +0000553 uint64_t Amount = Old->getOperand(0).getImm();
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000554 if (Amount != 0) {
Chris Lattnerf158da22003-01-16 02:20:12 +0000555 // We need to keep the stack aligned properly. To do this, we round the
556 // amount of space needed for the outgoing arguments up to the next
557 // alignment boundary.
Bill Wendling80c76432009-08-16 11:00:26 +0000558 Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign;
Chris Lattnerf158da22003-01-16 02:20:12 +0000559
Chris Lattner3648c672005-05-13 21:44:04 +0000560 MachineInstr *New = 0;
Dan Gohman6d4b0522008-10-01 18:28:06 +0000561 if (Old->getOpcode() == getCallFrameSetupOpcode()) {
Dale Johannesen21b55412009-02-12 23:08:38 +0000562 New = BuildMI(MF, Old->getDebugLoc(),
Dan Gohman7c2e0392010-05-19 00:53:19 +0000563 TII.get(getSUBriOpcode(Is64Bit, Amount)),
Bill Wendling80c76432009-08-16 11:00:26 +0000564 StackPtr)
565 .addReg(StackPtr)
566 .addImm(Amount);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000567 } else {
Dan Gohman6d4b0522008-10-01 18:28:06 +0000568 assert(Old->getOpcode() == getCallFrameDestroyOpcode());
Bill Wendling80c76432009-08-16 11:00:26 +0000569
570 // Factor out the amount the callee already popped.
Chris Lattner61807802007-04-25 04:25:10 +0000571 uint64_t CalleeAmt = Old->getOperand(1).getImm();
Chris Lattner3648c672005-05-13 21:44:04 +0000572 Amount -= CalleeAmt;
Bill Wendling80c76432009-08-16 11:00:26 +0000573
574 if (Amount) {
Dan Gohman7c2e0392010-05-19 00:53:19 +0000575 unsigned Opc = getADDriOpcode(Is64Bit, Amount);
Dale Johannesen21b55412009-02-12 23:08:38 +0000576 New = BuildMI(MF, Old->getDebugLoc(), TII.get(Opc), StackPtr)
Bill Wendling80c76432009-08-16 11:00:26 +0000577 .addReg(StackPtr)
578 .addImm(Amount);
Chris Lattnerd77525d2006-02-03 18:20:04 +0000579 }
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000580 }
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000581
Dan Gohmand293e0d2009-02-11 19:50:24 +0000582 if (New) {
583 // The EFLAGS implicit def is dead.
584 New->getOperand(3).setIsDead();
Dan Gohmanbfd23c92008-12-18 22:03:42 +0000585
Bill Wendling80c76432009-08-16 11:00:26 +0000586 // Replace the pseudo instruction with a new instruction.
Dan Gohmand293e0d2009-02-11 19:50:24 +0000587 MBB.insert(I, New);
588 }
Chris Lattner3648c672005-05-13 21:44:04 +0000589 }
Dan Gohman6d4b0522008-10-01 18:28:06 +0000590 } else if (I->getOpcode() == getCallFrameDestroyOpcode()) {
Chris Lattner3648c672005-05-13 21:44:04 +0000591 // If we are performing frame pointer elimination and if the callee pops
592 // something off the stack pointer, add it back. We do this until we have
593 // more advanced stack pointer tracking ability.
Chris Lattner61807802007-04-25 04:25:10 +0000594 if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
Dan Gohman7c2e0392010-05-19 00:53:19 +0000595 unsigned Opc = getSUBriOpcode(Is64Bit, CalleeAmt);
Dale Johannesen21b55412009-02-12 23:08:38 +0000596 MachineInstr *Old = I;
Jeff Cohen00b168892005-07-27 06:12:32 +0000597 MachineInstr *New =
Dale Johannesen21b55412009-02-12 23:08:38 +0000598 BuildMI(MF, Old->getDebugLoc(), TII.get(Opc),
Bill Wendling80c76432009-08-16 11:00:26 +0000599 StackPtr)
600 .addReg(StackPtr)
601 .addImm(CalleeAmt);
602
Dan Gohmanbfd23c92008-12-18 22:03:42 +0000603 // The EFLAGS implicit def is dead.
604 New->getOperand(3).setIsDead();
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000605 MBB.insert(I, New);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000606 }
607 }
608
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000609 MBB.erase(I);
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000610}
611
Jim Grosbachb58f4982009-10-07 17:12:56 +0000612unsigned
613X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
Jim Grosbachdff4b4c2010-03-09 21:45:49 +0000614 int SPAdj, FrameIndexValue *Value,
Jim Grosbachb58f4982009-10-07 17:12:56 +0000615 RegScavenger *RS) const{
Evan Cheng97de9132007-05-01 09:13:03 +0000616 assert(SPAdj == 0 && "Unexpected");
617
Chris Lattnerd264bec2003-01-13 00:50:33 +0000618 unsigned i = 0;
Alkis Evlogimenosc0b9dc52004-02-12 02:27:10 +0000619 MachineInstr &MI = *II;
Nate Begemanf8be5e92004-08-14 22:05:10 +0000620 MachineFunction &MF = *MI.getParent()->getParent();
Bill Wendling80c76432009-08-16 11:00:26 +0000621
Dan Gohmand735b802008-10-03 15:45:36 +0000622 while (!MI.getOperand(i).isFI()) {
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000623 ++i;
624 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
625 }
626
Chris Lattner8aa797a2007-12-30 23:10:15 +0000627 int FrameIndex = MI.getOperand(i).getIndex();
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000628 unsigned BasePtr;
Bill Wendling80c76432009-08-16 11:00:26 +0000629
Evan Cheng3f54c642010-04-29 05:08:22 +0000630 unsigned Opc = MI.getOpcode();
631 bool AfterFPPop = Opc == X86::TAILJMPm64 || Opc == X86::TAILJMPm;
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000632 if (needsStackRealignment(MF))
633 BasePtr = (FrameIndex < 0 ? FramePtr : StackPtr);
Evan Cheng3f54c642010-04-29 05:08:22 +0000634 else if (AfterFPPop)
635 BasePtr = StackPtr;
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000636 else
637 BasePtr = (hasFP(MF) ? FramePtr : StackPtr);
638
Chris Lattnerd264bec2003-01-13 00:50:33 +0000639 // This must be part of a four operand memory reference. Replace the
Evan Cheng25ab6902006-09-08 06:48:29 +0000640 // FrameIndex with base register with EBP. Add an offset to the offset.
Anton Korobeynikov8e91ec52008-04-23 18:21:02 +0000641 MI.getOperand(i).ChangeToRegister(BasePtr, false);
Chris Lattnerd264bec2003-01-13 00:50:33 +0000642
Dan Gohman82779702008-12-24 00:27:51 +0000643 // Now add the frame object offset to the offset from EBP.
Evan Cheng3f54c642010-04-29 05:08:22 +0000644 int FIOffset;
645 if (AfterFPPop) {
646 // Tail call jmp happens after FP is popped.
647 const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
648 const MachineFrameInfo *MFI = MF.getFrameInfo();
649 FIOffset = MFI->getObjectOffset(FrameIndex) - TFI.getOffsetOfLocalArea();
650 } else
651 FIOffset = getFrameIndexOffset(MF, FrameIndex);
652
Dan Gohman82779702008-12-24 00:27:51 +0000653 if (MI.getOperand(i+3).isImm()) {
654 // Offset is a 32-bit integer.
Evan Cheng3f54c642010-04-29 05:08:22 +0000655 int Offset = FIOffset + (int)(MI.getOperand(i + 3).getImm());
David Greene3f2bf852009-11-12 20:49:22 +0000656 MI.getOperand(i + 3).ChangeToImmediate(Offset);
Dan Gohman82779702008-12-24 00:27:51 +0000657 } else {
658 // Offset is symbolic. This is extremely rare.
Evan Cheng3f54c642010-04-29 05:08:22 +0000659 uint64_t Offset = FIOffset + (uint64_t)MI.getOperand(i+3).getOffset();
Dan Gohman82779702008-12-24 00:27:51 +0000660 MI.getOperand(i+3).setOffset(Offset);
661 }
Jim Grosbachb58f4982009-10-07 17:12:56 +0000662 return 0;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000663}
664
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000665void
Anton Korobeynikovb51dce32008-04-23 18:20:17 +0000666X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
667 RegScavenger *RS) const {
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000668 MachineFrameInfo *MFI = MF.getFrameInfo();
Anton Korobeynikovb51dce32008-04-23 18:20:17 +0000669
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000670 X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
671 int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
Bill Wendling80c76432009-08-16 11:00:26 +0000672
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000673 if (TailCallReturnAddrDelta < 0) {
674 // create RETURNADDR area
675 // arg
676 // arg
677 // RETADDR
678 // { ...
679 // RETADDR area
680 // ...
681 // }
682 // [EBP]
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000683 MFI->CreateFixedObject(-TailCallReturnAddrDelta,
David Greene3f2bf852009-11-12 20:49:22 +0000684 (-1U*SlotSize)+TailCallReturnAddrDelta,
685 true, false);
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000686 }
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000687
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000688 if (hasFP(MF)) {
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000689 assert((TailCallReturnAddrDelta <= 0) &&
690 "The Delta should always be zero or negative");
Anton Korobeynikovdd93f5e2009-08-03 08:14:30 +0000691 const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
Bill Wendling80c76432009-08-16 11:00:26 +0000692
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000693 // Create a frame entry for the EBP register that must be saved.
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000694 int FrameIdx = MFI->CreateFixedObject(SlotSize,
Anton Korobeynikovdd93f5e2009-08-03 08:14:30 +0000695 -(int)SlotSize +
696 TFI.getOffsetOfLocalArea() +
David Greene3f2bf852009-11-12 20:49:22 +0000697 TailCallReturnAddrDelta,
698 true, false);
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000699 assert(FrameIdx == MFI->getObjectIndexBegin() &&
Chris Lattner96c3d2e2004-02-15 00:15:37 +0000700 "Slot for EBP register must be last in order to be found!");
Devang Patelfd1c6c32008-12-23 21:56:28 +0000701 FrameIdx = 0;
Chris Lattner3c1c03d2002-12-28 20:32:28 +0000702 }
703}
704
Evan Chenga24dddd2007-04-26 01:09:28 +0000705/// emitSPUpdate - Emit a series of instructions to increment / decrement the
706/// stack pointer by a constant value.
707static
708void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
709 unsigned StackPtr, int64_t NumBytes, bool Is64Bit,
710 const TargetInstrInfo &TII) {
711 bool isSub = NumBytes < 0;
712 uint64_t Offset = isSub ? -NumBytes : NumBytes;
Dan Gohman7c2e0392010-05-19 00:53:19 +0000713 unsigned Opc = isSub ?
714 getSUBriOpcode(Is64Bit, Offset) :
715 getADDriOpcode(Is64Bit, Offset);
Evan Chenga24dddd2007-04-26 01:09:28 +0000716 uint64_t Chunk = (1LL << 31) - 1;
Dale Johannesen73e884b2010-01-20 21:36:02 +0000717 DebugLoc DL = MBB.findDebugLoc(MBBI);
Evan Chenga24dddd2007-04-26 01:09:28 +0000718
719 while (Offset) {
720 uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
Dan Gohmanbfd23c92008-12-18 22:03:42 +0000721 MachineInstr *MI =
Dale Johannesen8d13f8f2009-02-13 02:33:27 +0000722 BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr)
Bill Wendling3f5bb162009-08-15 21:27:32 +0000723 .addReg(StackPtr)
724 .addImm(ThisVal);
725 MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
Evan Chenga24dddd2007-04-26 01:09:28 +0000726 Offset -= ThisVal;
727 }
728}
729
Bill Wendling80c76432009-08-16 11:00:26 +0000730/// mergeSPUpdatesUp - Merge two stack-manipulating instructions upper iterator.
Anton Korobeynikov4f1c33f2007-10-06 16:17:49 +0000731static
732void mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
733 unsigned StackPtr, uint64_t *NumBytes = NULL) {
Chris Lattnereac93852007-10-07 21:53:12 +0000734 if (MBBI == MBB.begin()) return;
Evan Chengb63387a2010-05-06 06:36:08 +0000735
Chris Lattnereac93852007-10-07 21:53:12 +0000736 MachineBasicBlock::iterator PI = prior(MBBI);
737 unsigned Opc = PI->getOpcode();
738 if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
739 Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
740 PI->getOperand(0).getReg() == StackPtr) {
741 if (NumBytes)
742 *NumBytes += PI->getOperand(2).getImm();
743 MBB.erase(PI);
744 } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
745 Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
746 PI->getOperand(0).getReg() == StackPtr) {
747 if (NumBytes)
748 *NumBytes -= PI->getOperand(2).getImm();
749 MBB.erase(PI);
Anton Korobeynikov4f1c33f2007-10-06 16:17:49 +0000750 }
751}
752
Bill Wendling80c76432009-08-16 11:00:26 +0000753/// mergeSPUpdatesUp - Merge two stack-manipulating instructions lower iterator.
Anton Korobeynikov25083722007-10-06 16:39:43 +0000754static
Chris Lattnereac93852007-10-07 21:53:12 +0000755void mergeSPUpdatesDown(MachineBasicBlock &MBB,
756 MachineBasicBlock::iterator &MBBI,
Anton Korobeynikov25083722007-10-06 16:39:43 +0000757 unsigned StackPtr, uint64_t *NumBytes = NULL) {
Bill Wendling3f5bb162009-08-15 21:27:32 +0000758 // FIXME: THIS ISN'T RUN!!!
Chris Lattnerf443ba72007-10-07 22:00:31 +0000759 return;
Anton Korobeynikove2011902008-04-23 18:15:11 +0000760
Chris Lattnereac93852007-10-07 21:53:12 +0000761 if (MBBI == MBB.end()) return;
Anton Korobeynikove2011902008-04-23 18:15:11 +0000762
Chris Lattner7896c9f2009-12-03 00:50:42 +0000763 MachineBasicBlock::iterator NI = llvm::next(MBBI);
Chris Lattnereac93852007-10-07 21:53:12 +0000764 if (NI == MBB.end()) return;
Anton Korobeynikove2011902008-04-23 18:15:11 +0000765
Chris Lattnereac93852007-10-07 21:53:12 +0000766 unsigned Opc = NI->getOpcode();
767 if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
768 Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
769 NI->getOperand(0).getReg() == StackPtr) {
770 if (NumBytes)
771 *NumBytes -= NI->getOperand(2).getImm();
772 MBB.erase(NI);
773 MBBI = NI;
774 } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
775 Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
776 NI->getOperand(0).getReg() == StackPtr) {
777 if (NumBytes)
778 *NumBytes += NI->getOperand(2).getImm();
779 MBB.erase(NI);
780 MBBI = NI;
Anton Korobeynikov25083722007-10-06 16:39:43 +0000781 }
782}
783
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000784/// mergeSPUpdates - Checks the instruction before/after the passed
Bill Wendling80c76432009-08-16 11:00:26 +0000785/// instruction. If it is an ADD/SUB instruction it is deleted argument and the
786/// stack adjustment is returned as a positive value for ADD and a negative for
787/// SUB.
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000788static int mergeSPUpdates(MachineBasicBlock &MBB,
789 MachineBasicBlock::iterator &MBBI,
Anton Korobeynikove2011902008-04-23 18:15:11 +0000790 unsigned StackPtr,
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000791 bool doMergeWithPrevious) {
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000792 if ((doMergeWithPrevious && MBBI == MBB.begin()) ||
793 (!doMergeWithPrevious && MBBI == MBB.end()))
794 return 0;
795
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000796 MachineBasicBlock::iterator PI = doMergeWithPrevious ? prior(MBBI) : MBBI;
Chris Lattner7896c9f2009-12-03 00:50:42 +0000797 MachineBasicBlock::iterator NI = doMergeWithPrevious ? 0 : llvm::next(MBBI);
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000798 unsigned Opc = PI->getOpcode();
Bill Wendling80c76432009-08-16 11:00:26 +0000799 int Offset = 0;
800
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000801 if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
802 Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
803 PI->getOperand(0).getReg() == StackPtr){
804 Offset += PI->getOperand(2).getImm();
805 MBB.erase(PI);
806 if (!doMergeWithPrevious) MBBI = NI;
807 } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
808 Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
809 PI->getOperand(0).getReg() == StackPtr) {
810 Offset -= PI->getOperand(2).getImm();
811 MBB.erase(PI);
812 if (!doMergeWithPrevious) MBBI = NI;
Anton Korobeynikove2011902008-04-23 18:15:11 +0000813 }
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000814
815 return Offset;
816}
817
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000818void X86RegisterInfo::emitCalleeSavedFrameMoves(MachineFunction &MF,
Chris Lattner2e9919a2010-03-14 08:12:40 +0000819 MCSymbol *Label,
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000820 unsigned FramePtr) const {
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000821 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattnera267b002010-04-05 05:57:52 +0000822 MachineModuleInfo &MMI = MF.getMMI();
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000823
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000824 // Add callee saved registers to move list.
825 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
826 if (CSI.empty()) return;
827
Chris Lattnera267b002010-04-05 05:57:52 +0000828 std::vector<MachineMove> &Moves = MMI.getFrameMoves();
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000829 const TargetData *TD = MF.getTarget().getTargetData();
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000830 bool HasFP = hasFP(MF);
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000831
Bill Wendling80c76432009-08-16 11:00:26 +0000832 // Calculate amount of bytes used for return address storing.
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000833 int stackGrowth =
834 (MF.getTarget().getFrameInfo()->getStackGrowthDirection() ==
835 TargetFrameInfo::StackGrowsUp ?
836 TD->getPointerSize() : -TD->getPointerSize());
837
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000838 // FIXME: This is dirty hack. The code itself is pretty mess right now.
839 // It should be rewritten from scratch and generalized sometimes.
840
Bill Wendling80c76432009-08-16 11:00:26 +0000841 // Determine maximum offset (minumum due to stack growth).
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000842 int64_t MaxOffset = 0;
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000843 for (std::vector<CalleeSavedInfo>::const_iterator
844 I = CSI.begin(), E = CSI.end(); I != E; ++I)
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000845 MaxOffset = std::min(MaxOffset,
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000846 MFI->getObjectOffset(I->getFrameIdx()));
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000847
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000848 // Calculate offsets.
849 int64_t saveAreaOffset = (HasFP ? 3 : 2) * stackGrowth;
850 for (std::vector<CalleeSavedInfo>::const_iterator
851 I = CSI.begin(), E = CSI.end(); I != E; ++I) {
852 int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
853 unsigned Reg = I->getReg();
854 Offset = MaxOffset - Offset + saveAreaOffset;
855
Duncan Sandsdaf22122009-07-23 19:00:02 +0000856 // Don't output a new machine move if we're re-saving the frame
857 // pointer. This happens when the PrologEpilogInserter has inserted an extra
858 // "PUSH" of the frame pointer -- the "emitPrologue" method automatically
859 // generates one when frame pointers are used. If we generate a "machine
860 // move" for this extra "PUSH", the linker will lose track of the fact that
861 // the frame pointer should have the value of the first "PUSH" when it's
862 // trying to unwind.
863 //
864 // FIXME: This looks inelegant. It's possibly correct, but it's covering up
865 // another bug. I.e., one where we generate a prolog like this:
866 //
867 // pushl %ebp
868 // movl %esp, %ebp
869 // pushl %ebp
870 // pushl %esi
871 // ...
872 //
873 // The immediate re-push of EBP is unnecessary. At the least, it's an
874 // optimization bug. EBP can be used as a scratch register in certain
875 // cases, but probably not when we have a frame pointer.
876 if (HasFP && FramePtr == Reg)
877 continue;
878
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000879 MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
880 MachineLocation CSSrc(Reg);
Chris Lattner2e9919a2010-03-14 08:12:40 +0000881 Moves.push_back(MachineMove(Label, CSDst, CSSrc));
Bill Wendlingfe7f2942009-06-16 04:12:45 +0000882 }
Anton Korobeynikov9bbbea52008-04-23 18:15:48 +0000883}
884
Bill Wendling3f5bb162009-08-15 21:27:32 +0000885/// emitPrologue - Push callee-saved registers onto the stack, which
886/// automatically adjust the stack pointer. Adjust the stack pointer to allocate
887/// space for local variables. Also emit labels used by the exception handler to
888/// generate the exception handling frames.
Chris Lattnerbb07ef92004-02-14 19:49:54 +0000889void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
Bill Wendling3f5bb162009-08-15 21:27:32 +0000890 MachineBasicBlock &MBB = MF.front(); // Prologue goes in entry BB.
891 MachineBasicBlock::iterator MBBI = MBB.begin();
Chris Lattnereafa4232003-01-15 22:57:35 +0000892 MachineFrameInfo *MFI = MF.getFrameInfo();
Bill Wendling3f5bb162009-08-15 21:27:32 +0000893 const Function *Fn = MF.getFunction();
894 const X86Subtarget *Subtarget = &MF.getTarget().getSubtarget<X86Subtarget>();
Chris Lattnera267b002010-04-05 05:57:52 +0000895 MachineModuleInfo &MMI = MF.getMMI();
Evan Cheng89d16592007-07-17 07:59:08 +0000896 X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
Chris Lattnera267b002010-04-05 05:57:52 +0000897 bool needsFrameMoves = MMI.hasDebugInfo() ||
Bill Wendling3f5bb162009-08-15 21:27:32 +0000898 !Fn->doesNotThrow() || UnwindTablesMandatory;
899 uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment.
900 uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate.
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000901 bool HasFP = hasFP(MF);
Devang Patel369de262009-06-17 00:48:26 +0000902 DebugLoc DL;
Bill Wendling3d2445f2009-02-21 00:43:56 +0000903
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000904 // Add RETADDR move area to callee saved frame size.
905 int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
Anton Korobeynikove2011902008-04-23 18:15:11 +0000906 if (TailCallReturnAddrDelta < 0)
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000907 X86FI->setCalleeSavedFrameSize(
Bill Wendling3f5bb162009-08-15 21:27:32 +0000908 X86FI->getCalleeSavedFrameSize() - TailCallReturnAddrDelta);
Evan Chengd9245ca2006-04-14 07:26:43 +0000909
Dan Gohman336b6362009-01-27 00:40:06 +0000910 // If this is x86-64 and the Red Zone is not disabled, if we are a leaf
911 // function, and use up to 128 bytes of stack space, don't have a frame
912 // pointer, calls, or dynamic alloca then we do not need to adjust the
913 // stack pointer (we fit in the Red Zone).
Bill Wendling3f5bb162009-08-15 21:27:32 +0000914 if (Is64Bit && !Fn->hasFnAttr(Attribute::NoRedZone) &&
Dan Gohman336b6362009-01-27 00:40:06 +0000915 !needsStackRealignment(MF) &&
916 !MFI->hasVarSizedObjects() && // No dynamic alloca.
Bill Wendlingf84d60b2010-05-14 21:58:35 +0000917 !MFI->adjustsStack() && // No calls.
Eli Friedman9a417122009-06-04 02:02:01 +0000918 !Subtarget->isTargetWin64()) { // Win64 has no Red Zone
Dan Gohman336b6362009-01-27 00:40:06 +0000919 uint64_t MinSize = X86FI->getCalleeSavedFrameSize();
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000920 if (HasFP) MinSize += SlotSize;
Bill Wendling3f5bb162009-08-15 21:27:32 +0000921 StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0);
Dan Gohman336b6362009-01-27 00:40:06 +0000922 MFI->setStackSize(StackSize);
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000923 } else if (Subtarget->isTargetWin64()) {
924 // We need to always allocate 32 bytes as register spill area.
Bill Wendling3f5bb162009-08-15 21:27:32 +0000925 // FIXME: We might reuse these 32 bytes for leaf functions.
Anton Korobeynikovcf6b7392009-08-03 08:12:53 +0000926 StackSize += 32;
927 MFI->setStackSize(StackSize);
Dan Gohman336b6362009-01-27 00:40:06 +0000928 }
929
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000930 // Insert stack pointer adjustment for later moving of return addr. Only
931 // applies to tail call optimized functions where the callee argument stack
932 // size is bigger than the callers.
933 if (TailCallReturnAddrDelta < 0) {
Dan Gohmanbfd23c92008-12-18 22:03:42 +0000934 MachineInstr *MI =
Dan Gohman7c2e0392010-05-19 00:53:19 +0000935 BuildMI(MBB, MBBI, DL,
936 TII.get(getSUBriOpcode(Is64Bit, -TailCallReturnAddrDelta)),
Bill Wendling3f5bb162009-08-15 21:27:32 +0000937 StackPtr)
938 .addReg(StackPtr)
939 .addImm(-TailCallReturnAddrDelta);
940 MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +0000941 }
942
Bill Wendling3f5bb162009-08-15 21:27:32 +0000943 // Mapping for machine moves:
944 //
945 // DST: VirtualFP AND
946 // SRC: VirtualFP => DW_CFA_def_cfa_offset
947 // ELSE => DW_CFA_def_cfa
948 //
949 // SRC: VirtualFP AND
950 // DST: Register => DW_CFA_def_cfa_register
951 //
952 // ELSE
953 // OFFSET < 0 => DW_CFA_offset_extended_sf
954 // REG < 64 => DW_CFA_offset + Reg
955 // ELSE => DW_CFA_offset_extended
956
Chris Lattnera267b002010-04-05 05:57:52 +0000957 std::vector<MachineMove> &Moves = MMI.getFrameMoves();
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000958 const TargetData *TD = MF.getTarget().getTargetData();
Bill Wendling3f5bb162009-08-15 21:27:32 +0000959 uint64_t NumBytes = 0;
Chris Lattner464bee12010-03-13 08:04:35 +0000960 int stackGrowth = -TD->getPointerSize();
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000961
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000962 if (HasFP) {
Bill Wendling3f5bb162009-08-15 21:27:32 +0000963 // Calculate required stack adjustment.
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000964 uint64_t FrameSize = StackSize - SlotSize;
965 if (needsStackRealignment(MF))
Bill Wendling3f5bb162009-08-15 21:27:32 +0000966 FrameSize = (FrameSize + MaxAlign - 1) / MaxAlign * MaxAlign;
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000967
968 NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize();
969
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000970 // Get the offset of the stack slot for the EBP register, which is
Evan Cheng89d16592007-07-17 07:59:08 +0000971 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
972 // Update the frame offset adjustment.
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +0000973 MFI->setOffsetAdjustment(-NumBytes);
Evan Cheng89d16592007-07-17 07:59:08 +0000974
Bill Wendling3f5bb162009-08-15 21:27:32 +0000975 // Save EBP/RBP into the appropriate stack slot.
Dale Johannesen21b55412009-02-12 23:08:38 +0000976 BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
Bill Wendling587daed2009-05-13 21:33:08 +0000977 .addReg(FramePtr, RegState::Kill);
Evan Cheng89d16592007-07-17 07:59:08 +0000978
Bill Wendling92c1e122009-02-13 02:16:35 +0000979 if (needsFrameMoves) {
Bill Wendling3f5bb162009-08-15 21:27:32 +0000980 // Mark the place where EBP/RBP was saved.
Chris Lattnera267b002010-04-05 05:57:52 +0000981 MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
Chris Lattner2e9919a2010-03-14 08:12:40 +0000982 BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(FrameLabel);
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000983
984 // Define the current CFA rule to use the provided offset.
985 if (StackSize) {
986 MachineLocation SPDst(MachineLocation::VirtualFP);
Bill Wendling80c76432009-08-16 11:00:26 +0000987 MachineLocation SPSrc(MachineLocation::VirtualFP, 2 * stackGrowth);
Chris Lattner2e9919a2010-03-14 08:12:40 +0000988 Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000989 } else {
990 // FIXME: Verify & implement for FP
991 MachineLocation SPDst(StackPtr);
992 MachineLocation SPSrc(StackPtr, stackGrowth);
Chris Lattner2e9919a2010-03-14 08:12:40 +0000993 Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000994 }
995
996 // Change the rule for the FramePtr to be an "offset" rule.
Chris Lattner464bee12010-03-13 08:04:35 +0000997 MachineLocation FPDst(MachineLocation::VirtualFP, 2 * stackGrowth);
Bill Wendlingc3d505c2009-07-08 21:02:53 +0000998 MachineLocation FPSrc(FramePtr);
Chris Lattner2e9919a2010-03-14 08:12:40 +0000999 Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc));
Bill Wendling92c1e122009-02-13 02:16:35 +00001000 }
1001
Evan Cheng89d16592007-07-17 07:59:08 +00001002 // Update EBP with the new base value...
Dale Johannesen21b55412009-02-12 23:08:38 +00001003 BuildMI(MBB, MBBI, DL,
1004 TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr)
1005 .addReg(StackPtr);
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001006
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001007 if (needsFrameMoves) {
Bill Wendling3f5bb162009-08-15 21:27:32 +00001008 // Mark effective beginning of when frame pointer becomes valid.
Chris Lattnera267b002010-04-05 05:57:52 +00001009 MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
Chris Lattner2e9919a2010-03-14 08:12:40 +00001010 BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(FrameLabel);
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001011
1012 // Define the current CFA to use the EBP/RBP register.
1013 MachineLocation FPDst(FramePtr);
1014 MachineLocation FPSrc(MachineLocation::VirtualFP);
Chris Lattner2e9919a2010-03-14 08:12:40 +00001015 Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc));
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001016 }
1017
Dan Gohman34d6ad72008-12-18 22:01:52 +00001018 // Mark the FramePtr as live-in in every block except the entry.
Chris Lattner7896c9f2009-12-03 00:50:42 +00001019 for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
Dan Gohman34d6ad72008-12-18 22:01:52 +00001020 I != E; ++I)
1021 I->addLiveIn(FramePtr);
1022
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001023 // Realign stack
Dan Gohmanbfd23c92008-12-18 22:03:42 +00001024 if (needsStackRealignment(MF)) {
1025 MachineInstr *MI =
Dale Johannesen21b55412009-02-12 23:08:38 +00001026 BuildMI(MBB, MBBI, DL,
Dan Gohmanbfd23c92008-12-18 22:03:42 +00001027 TII.get(Is64Bit ? X86::AND64ri32 : X86::AND32ri),
1028 StackPtr).addReg(StackPtr).addImm(-MaxAlign);
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001029
Dan Gohmanbfd23c92008-12-18 22:03:42 +00001030 // The EFLAGS implicit def is dead.
1031 MI->getOperand(3).setIsDead();
1032 }
Bill Wendling3d2445f2009-02-21 00:43:56 +00001033 } else {
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001034 NumBytes = StackSize - X86FI->getCalleeSavedFrameSize();
Bill Wendling3d2445f2009-02-21 00:43:56 +00001035 }
Anton Korobeynikove2011902008-04-23 18:15:11 +00001036
Evan Cheng89d16592007-07-17 07:59:08 +00001037 // Skip the callee-saved push instructions.
Bill Wendling3f5bb162009-08-15 21:27:32 +00001038 bool PushedRegs = false;
1039 int StackOffset = 2 * stackGrowth;
1040
Evan Cheng89d16592007-07-17 07:59:08 +00001041 while (MBBI != MBB.end() &&
1042 (MBBI->getOpcode() == X86::PUSH32r ||
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001043 MBBI->getOpcode() == X86::PUSH64r)) {
Bill Wendling3f5bb162009-08-15 21:27:32 +00001044 PushedRegs = true;
Evan Cheng89d16592007-07-17 07:59:08 +00001045 ++MBBI;
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001046
Bill Wendling3f5bb162009-08-15 21:27:32 +00001047 if (!HasFP && needsFrameMoves) {
1048 // Mark callee-saved push instruction.
Chris Lattnera267b002010-04-05 05:57:52 +00001049 MCSymbol *Label = MMI.getContext().CreateTempSymbol();
Chris Lattner2e9919a2010-03-14 08:12:40 +00001050 BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(Label);
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001051
Bill Wendling3f5bb162009-08-15 21:27:32 +00001052 // Define the current CFA rule to use the provided offset.
1053 unsigned Ptr = StackSize ?
1054 MachineLocation::VirtualFP : StackPtr;
1055 MachineLocation SPDst(Ptr);
1056 MachineLocation SPSrc(Ptr, StackOffset);
Chris Lattner2e9919a2010-03-14 08:12:40 +00001057 Moves.push_back(MachineMove(Label, SPDst, SPSrc));
Bill Wendling3f5bb162009-08-15 21:27:32 +00001058 StackOffset += stackGrowth;
1059 }
Bill Wendlingc3d505c2009-07-08 21:02:53 +00001060 }
Evan Cheng89d16592007-07-17 07:59:08 +00001061
Dale Johannesen73e884b2010-01-20 21:36:02 +00001062 DL = MBB.findDebugLoc(MBBI);
Bill Wendling3d2445f2009-02-21 00:43:56 +00001063
Bill Wendling3ae67f52009-06-09 20:08:51 +00001064 // Adjust stack pointer: ESP -= numbytes.
1065 if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) {
1066 // Check, whether EAX is livein for this function.
1067 bool isEAXAlive = false;
1068 for (MachineRegisterInfo::livein_iterator
Chris Lattner84bc5422007-12-31 04:13:23 +00001069 II = MF.getRegInfo().livein_begin(),
1070 EE = MF.getRegInfo().livein_end(); (II != EE) && !isEAXAlive; ++II) {
Bill Wendling3ae67f52009-06-09 20:08:51 +00001071 unsigned Reg = II->first;
1072 isEAXAlive = (Reg == X86::EAX || Reg == X86::AX ||
1073 Reg == X86::AH || Reg == X86::AL);
Evan Cheng004fb922006-06-13 05:14:44 +00001074 }
Bill Wendling3ae67f52009-06-09 20:08:51 +00001075
1076 // Function prologue calls _alloca to probe the stack when allocating more
1077 // than 4k bytes in one go. Touching the stack at 4K increments is necessary
1078 // to ensure that the guard pages used by the OS virtual memory manager are
1079 // allocated in correct sequence.
1080 if (!isEAXAlive) {
1081 BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
1082 .addImm(NumBytes);
1083 BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
Anton Korobeynikov043f3c22010-03-06 19:32:29 +00001084 .addExternalSymbol("_alloca")
1085 .addReg(StackPtr, RegState::Define | RegState::Implicit);
Bill Wendling3ae67f52009-06-09 20:08:51 +00001086 } else {
1087 // Save EAX
1088 BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r))
1089 .addReg(X86::EAX, RegState::Kill);
1090
1091 // Allocate NumBytes-4 bytes on stack. We'll also use 4 already
1092 // allocated bytes for EAX.
1093 BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
1094 .addImm(NumBytes - 4);
1095 BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
Anton Korobeynikov043f3c22010-03-06 19:32:29 +00001096 .addExternalSymbol("_alloca")
1097 .addReg(StackPtr, RegState::Define | RegState::Implicit);
Bill Wendling3ae67f52009-06-09 20:08:51 +00001098
1099 // Restore EAX
1100 MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm),
1101 X86::EAX),
1102 StackPtr, false, NumBytes - 4);
1103 MBB.insert(MBBI, MI);
1104 }
1105 } else if (NumBytes) {
1106 // If there is an SUB32ri of ESP immediately before this instruction, merge
1107 // the two. This can be the case when tail call elimination is enabled and
1108 // the callee has more arguments then the caller.
1109 NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true);
1110
1111 // If there is an ADD32ri or SUB32ri of ESP immediately after this
1112 // instruction, merge the two instructions.
1113 mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes);
1114
1115 if (NumBytes)
1116 emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII);
Evan Chengd9245ca2006-04-14 07:26:43 +00001117 }
Bill Wendlingd15f45f2009-07-09 22:30:02 +00001118
Bill Wendlingeb3a7662009-09-03 22:19:22 +00001119 if ((NumBytes || PushedRegs) && needsFrameMoves) {
Bill Wendlingd15f45f2009-07-09 22:30:02 +00001120 // Mark end of stack pointer adjustment.
Chris Lattnera267b002010-04-05 05:57:52 +00001121 MCSymbol *Label = MMI.getContext().CreateTempSymbol();
Chris Lattner2e9919a2010-03-14 08:12:40 +00001122 BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(Label);
Bill Wendlingd15f45f2009-07-09 22:30:02 +00001123
Bill Wendlingeb3a7662009-09-03 22:19:22 +00001124 if (!HasFP && NumBytes) {
Bill Wendling3f5bb162009-08-15 21:27:32 +00001125 // Define the current CFA rule to use the provided offset.
1126 if (StackSize) {
1127 MachineLocation SPDst(MachineLocation::VirtualFP);
1128 MachineLocation SPSrc(MachineLocation::VirtualFP,
1129 -StackSize + stackGrowth);
Chris Lattner2e9919a2010-03-14 08:12:40 +00001130 Moves.push_back(MachineMove(Label, SPDst, SPSrc));
Bill Wendling3f5bb162009-08-15 21:27:32 +00001131 } else {
1132 // FIXME: Verify & implement for FP
1133 MachineLocation SPDst(StackPtr);
1134 MachineLocation SPSrc(StackPtr, stackGrowth);
Chris Lattner2e9919a2010-03-14 08:12:40 +00001135 Moves.push_back(MachineMove(Label, SPDst, SPSrc));
Bill Wendling3f5bb162009-08-15 21:27:32 +00001136 }
Bill Wendlingd15f45f2009-07-09 22:30:02 +00001137 }
Bill Wendling3f5bb162009-08-15 21:27:32 +00001138
1139 // Emit DWARF info specifying the offsets of the callee-saved registers.
1140 if (PushedRegs)
Chris Lattner2e9919a2010-03-14 08:12:40 +00001141 emitCalleeSavedFrameMoves(MF, Label, HasFP ? FramePtr : StackPtr);
Bill Wendlingd15f45f2009-07-09 22:30:02 +00001142 }
Misha Brukman2adb3952002-12-04 23:57:03 +00001143}
1144
Chris Lattnerbb07ef92004-02-14 19:49:54 +00001145void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
1146 MachineBasicBlock &MBB) const {
Chris Lattneraa09b752002-12-28 21:08:28 +00001147 const MachineFrameInfo *MFI = MF.getFrameInfo();
Evan Cheng89d16592007-07-17 07:59:08 +00001148 X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
Alkis Evlogimenosf81af212004-02-14 01:18:34 +00001149 MachineBasicBlock::iterator MBBI = prior(MBB.end());
Anton Korobeynikov2365f512007-07-14 14:06:15 +00001150 unsigned RetOpcode = MBBI->getOpcode();
Bill Wendling2625f9b2009-02-21 00:32:08 +00001151 DebugLoc DL = MBBI->getDebugLoc();
Chris Lattner2b3d56e2005-05-14 23:35:21 +00001152
Anton Korobeynikov2365f512007-07-14 14:06:15 +00001153 switch (RetOpcode) {
Bill Wendling80c76432009-08-16 11:00:26 +00001154 default:
1155 llvm_unreachable("Can only insert epilog into returning blocks");
Chris Lattner2b3d56e2005-05-14 23:35:21 +00001156 case X86::RET:
1157 case X86::RETI:
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001158 case X86::TCRETURNdi:
1159 case X86::TCRETURNri:
Evan Chengf48ef032010-03-14 03:48:46 +00001160 case X86::TCRETURNmi:
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001161 case X86::TCRETURNdi64:
Evan Chengf48ef032010-03-14 03:48:46 +00001162 case X86::TCRETURNri64:
1163 case X86::TCRETURNmi64:
Anton Korobeynikov2365f512007-07-14 14:06:15 +00001164 case X86::EH_RETURN:
Anton Korobeynikovb84c1672008-09-08 21:12:47 +00001165 case X86::EH_RETURN64:
Bill Wendling80c76432009-08-16 11:00:26 +00001166 break; // These are ok
Chris Lattner2b3d56e2005-05-14 23:35:21 +00001167 }
Misha Brukman2adb3952002-12-04 23:57:03 +00001168
Bill Wendling80c76432009-08-16 11:00:26 +00001169 // Get the number of bytes to allocate from the FrameInfo.
Evan Cheng89d16592007-07-17 07:59:08 +00001170 uint64_t StackSize = MFI->getStackSize();
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001171 uint64_t MaxAlign = MFI->getMaxAlignment();
Evan Cheng89d16592007-07-17 07:59:08 +00001172 unsigned CSSize = X86FI->getCalleeSavedFrameSize();
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001173 uint64_t NumBytes = 0;
Evan Cheng89d16592007-07-17 07:59:08 +00001174
Chris Lattner3c1c03d2002-12-28 20:32:28 +00001175 if (hasFP(MF)) {
Bill Wendling80c76432009-08-16 11:00:26 +00001176 // Calculate required stack adjustment.
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001177 uint64_t FrameSize = StackSize - SlotSize;
1178 if (needsStackRealignment(MF))
1179 FrameSize = (FrameSize + MaxAlign - 1)/MaxAlign*MaxAlign;
1180
1181 NumBytes = FrameSize - CSSize;
1182
Bill Wendling80c76432009-08-16 11:00:26 +00001183 // Pop EBP.
Bill Wendling3d2445f2009-02-21 00:43:56 +00001184 BuildMI(MBB, MBBI, DL,
Dale Johannesen21b55412009-02-12 23:08:38 +00001185 TII.get(Is64Bit ? X86::POP64r : X86::POP32r), FramePtr);
Bill Wendling2625f9b2009-02-21 00:32:08 +00001186 } else {
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001187 NumBytes = StackSize - CSSize;
Bill Wendling2625f9b2009-02-21 00:32:08 +00001188 }
Anton Korobeynikov2365f512007-07-14 14:06:15 +00001189
Evan Chengf27795d2007-07-17 18:03:34 +00001190 // Skip the callee-saved pop instructions.
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001191 MachineBasicBlock::iterator LastCSPop = MBBI;
Evan Chengf27795d2007-07-17 18:03:34 +00001192 while (MBBI != MBB.begin()) {
Evan Chengfcc87932007-07-26 17:45:41 +00001193 MachineBasicBlock::iterator PI = prior(MBBI);
1194 unsigned Opc = PI->getOpcode();
Bill Wendling80c76432009-08-16 11:00:26 +00001195
Bill Wendlingf7c09402008-10-31 18:30:19 +00001196 if (Opc != X86::POP32r && Opc != X86::POP64r &&
1197 !PI->getDesc().isTerminator())
Evan Chengf27795d2007-07-17 18:03:34 +00001198 break;
Bill Wendling80c76432009-08-16 11:00:26 +00001199
Evan Chengf27795d2007-07-17 18:03:34 +00001200 --MBBI;
1201 }
1202
Bill Wendling3d2445f2009-02-21 00:43:56 +00001203 DL = MBBI->getDebugLoc();
1204
Anton Korobeynikov4f1c33f2007-10-06 16:17:49 +00001205 // If there is an ADD32ri or SUB32ri of ESP immediately before this
1206 // instruction, merge the two instructions.
1207 if (NumBytes || MFI->hasVarSizedObjects())
1208 mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
Evan Cheng5b3332c2007-07-17 18:40:47 +00001209
Anton Korobeynikov4f1c33f2007-10-06 16:17:49 +00001210 // If dynamic alloca is used, then reset esp to point to the last callee-saved
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001211 // slot before popping them off! Same applies for the case, when stack was
Bill Wendling80c76432009-08-16 11:00:26 +00001212 // realigned.
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001213 if (needsStackRealignment(MF)) {
1214 // We cannot use LEA here, because stack pointer was realigned. We need to
Bill Wendling80c76432009-08-16 11:00:26 +00001215 // deallocate local frame back.
Evan Cheng3c46eef2007-07-18 21:26:06 +00001216 if (CSSize) {
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001217 emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII);
1218 MBBI = prior(LastCSPop);
1219 }
1220
Dale Johannesen21b55412009-02-12 23:08:38 +00001221 BuildMI(MBB, MBBI, DL,
Anton Korobeynikov2c430cb2008-04-23 18:21:27 +00001222 TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
1223 StackPtr).addReg(FramePtr);
1224 } else if (MFI->hasVarSizedObjects()) {
1225 if (CSSize) {
1226 unsigned Opc = Is64Bit ? X86::LEA64r : X86::LEA32r;
Bill Wendling80c76432009-08-16 11:00:26 +00001227 MachineInstr *MI =
1228 addLeaRegOffset(BuildMI(MF, DL, TII.get(Opc), StackPtr),
1229 FramePtr, false, -CSSize);
Evan Cheng3c46eef2007-07-18 21:26:06 +00001230 MBB.insert(MBBI, MI);
Bill Wendling80c76432009-08-16 11:00:26 +00001231 } else {
1232 BuildMI(MBB, MBBI, DL,
1233 TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), StackPtr)
1234 .addReg(FramePtr);
1235 }
1236 } else if (NumBytes) {
1237 // Adjust stack pointer back: ESP += numbytes.
1238 emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII);
Evan Cheng3c46eef2007-07-18 21:26:06 +00001239 }
1240
Evan Cheng5b3332c2007-07-17 18:40:47 +00001241 // We're returning from function via eh_return.
Anton Korobeynikovb84c1672008-09-08 21:12:47 +00001242 if (RetOpcode == X86::EH_RETURN || RetOpcode == X86::EH_RETURN64) {
Evan Cheng5b3332c2007-07-17 18:40:47 +00001243 MBBI = prior(MBB.end());
1244 MachineOperand &DestAddr = MBBI->getOperand(0);
Dan Gohmand735b802008-10-03 15:45:36 +00001245 assert(DestAddr.isReg() && "Offset should be in register!");
Dale Johannesen21b55412009-02-12 23:08:38 +00001246 BuildMI(MBB, MBBI, DL,
Anton Korobeynikovb84c1672008-09-08 21:12:47 +00001247 TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
1248 StackPtr).addReg(DestAddr.getReg());
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001249 } else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi ||
Evan Chengf48ef032010-03-14 03:48:46 +00001250 RetOpcode == X86::TCRETURNmi ||
1251 RetOpcode == X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64 ||
1252 RetOpcode == X86::TCRETURNmi64) {
1253 bool isMem = RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64;
Bill Wendling80c76432009-08-16 11:00:26 +00001254 // Tail call return: adjust the stack pointer and jump to callee.
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001255 MBBI = prior(MBB.end());
1256 MachineOperand &JumpTarget = MBBI->getOperand(0);
Evan Chengf48ef032010-03-14 03:48:46 +00001257 MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 5 : 1);
Dan Gohmand735b802008-10-03 15:45:36 +00001258 assert(StackAdjust.isImm() && "Expecting immediate value.");
Anton Korobeynikove2011902008-04-23 18:15:11 +00001259
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001260 // Adjust stack pointer.
1261 int StackAdj = StackAdjust.getImm();
1262 int MaxTCDelta = X86FI->getTCReturnAddrDelta();
1263 int Offset = 0;
1264 assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive");
Bill Wendling80c76432009-08-16 11:00:26 +00001265
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001266 // Incoporate the retaddr area.
1267 Offset = StackAdj-MaxTCDelta;
1268 assert(Offset >= 0 && "Offset should never be negative");
Bill Wendling3d2445f2009-02-21 00:43:56 +00001269
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001270 if (Offset) {
1271 // Check for possible merge with preceeding ADD instruction.
1272 Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true);
1273 emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII);
Anton Korobeynikove2011902008-04-23 18:15:11 +00001274 }
Bill Wendling3d2445f2009-02-21 00:43:56 +00001275
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001276 // Jump to label or value in register.
Evan Chengf48ef032010-03-14 03:48:46 +00001277 if (RetOpcode == X86::TCRETURNdi || RetOpcode == X86::TCRETURNdi64) {
1278 BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNdi)
1279 ? X86::TAILJMPd : X86::TAILJMPd64)).
Evan Cheng1d885c02010-01-30 01:16:15 +00001280 addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
1281 JumpTarget.getTargetFlags());
Evan Chengf48ef032010-03-14 03:48:46 +00001282 } else if (RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64) {
1283 MachineInstrBuilder MIB =
1284 BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNmi)
1285 ? X86::TAILJMPm : X86::TAILJMPm64));
1286 for (unsigned i = 0; i != 5; ++i)
1287 MIB.addOperand(MBBI->getOperand(i));
Evan Chengaa92bec2010-01-31 07:28:44 +00001288 } else if (RetOpcode == X86::TCRETURNri64) {
Dale Johannesen21b55412009-02-12 23:08:38 +00001289 BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr64), JumpTarget.getReg());
Evan Chengaa92bec2010-01-31 07:28:44 +00001290 } else {
Dan Gohman39a1fab2009-11-30 23:33:53 +00001291 BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr), JumpTarget.getReg());
Evan Chengaa92bec2010-01-31 07:28:44 +00001292 }
1293
1294 MachineInstr *NewMI = prior(MBBI);
1295 for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i)
1296 NewMI->addOperand(MBBI->getOperand(i));
Bill Wendling3d2445f2009-02-21 00:43:56 +00001297
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001298 // Delete the pseudo instruction TCRETURN.
1299 MBB.erase(MBBI);
Anton Korobeynikove2011902008-04-23 18:15:11 +00001300 } else if ((RetOpcode == X86::RET || RetOpcode == X86::RETI) &&
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001301 (X86FI->getTCReturnAddrDelta() < 0)) {
1302 // Add the return addr area delta back since we are not tail calling.
1303 int delta = -1*X86FI->getTCReturnAddrDelta();
1304 MBBI = prior(MBB.end());
Bill Wendling80c76432009-08-16 11:00:26 +00001305
Arnold Schwaighoferc85e1712007-10-11 19:40:01 +00001306 // Check for possible merge with preceeding ADD instruction.
1307 delta += mergeSPUpdates(MBB, MBBI, StackPtr, true);
1308 emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, TII);
Evan Cheng5b3332c2007-07-17 18:40:47 +00001309 }
Chris Lattner3c1c03d2002-12-28 20:32:28 +00001310}
1311
Jim Laskey41886992006-04-07 16:34:46 +00001312unsigned X86RegisterInfo::getRARegister() const {
Bill Wendling80c76432009-08-16 11:00:26 +00001313 return Is64Bit ? X86::RIP // Should have dwarf #16.
1314 : X86::EIP; // Should have dwarf #8.
Jim Laskey41886992006-04-07 16:34:46 +00001315}
1316
David Greene3f2bf852009-11-12 20:49:22 +00001317unsigned X86RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
Evan Cheng25ab6902006-09-08 06:48:29 +00001318 return hasFP(MF) ? FramePtr : StackPtr;
Jim Laskeyf1d78e82006-03-23 18:12:57 +00001319}
1320
Bill Wendling80c76432009-08-16 11:00:26 +00001321void
1322X86RegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves) const {
Anton Korobeynikov0ff3ca42007-05-12 22:36:25 +00001323 // Calculate amount of bytes used for return address storing
1324 int stackGrowth = (Is64Bit ? -8 : -4);
1325
Eric Christopherd2760d12010-05-04 22:13:03 +00001326 // Initial state of the frame pointer is esp+stackGrowth.
Jim Laskey0e410942007-01-24 19:15:24 +00001327 MachineLocation Dst(MachineLocation::VirtualFP);
Anton Korobeynikov0ff3ca42007-05-12 22:36:25 +00001328 MachineLocation Src(StackPtr, stackGrowth);
Jim Laskey0e410942007-01-24 19:15:24 +00001329 Moves.push_back(MachineMove(0, Dst, Src));
Anton Korobeynikov0ff3ca42007-05-12 22:36:25 +00001330
1331 // Add return address to move list
1332 MachineLocation CSDst(StackPtr, stackGrowth);
1333 MachineLocation CSSrc(getRARegister());
1334 Moves.push_back(MachineMove(0, CSDst, CSSrc));
Jim Laskey0e410942007-01-24 19:15:24 +00001335}
1336
Jim Laskey62819f32007-02-21 22:54:50 +00001337unsigned X86RegisterInfo::getEHExceptionRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +00001338 llvm_unreachable("What is the exception register");
Jim Laskey62819f32007-02-21 22:54:50 +00001339 return 0;
1340}
1341
1342unsigned X86RegisterInfo::getEHHandlerRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +00001343 llvm_unreachable("What is the exception handler register");
Jim Laskey62819f32007-02-21 22:54:50 +00001344 return 0;
1345}
1346
Evan Cheng8f7f7122006-05-05 05:40:20 +00001347namespace llvm {
Owen Andersone50ed302009-08-10 22:56:29 +00001348unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) {
Owen Anderson825b72b2009-08-11 20:47:22 +00001349 switch (VT.getSimpleVT().SimpleTy) {
Evan Cheng8f7f7122006-05-05 05:40:20 +00001350 default: return Reg;
Owen Anderson825b72b2009-08-11 20:47:22 +00001351 case MVT::i8:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001352 if (High) {
1353 switch (Reg) {
Evan Cheng25ab6902006-09-08 06:48:29 +00001354 default: return 0;
1355 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001356 return X86::AH;
Evan Cheng25ab6902006-09-08 06:48:29 +00001357 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001358 return X86::DH;
Evan Cheng25ab6902006-09-08 06:48:29 +00001359 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001360 return X86::CH;
Evan Cheng25ab6902006-09-08 06:48:29 +00001361 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001362 return X86::BH;
1363 }
1364 } else {
1365 switch (Reg) {
Evan Cheng25ab6902006-09-08 06:48:29 +00001366 default: return 0;
1367 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001368 return X86::AL;
Evan Cheng25ab6902006-09-08 06:48:29 +00001369 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001370 return X86::DL;
Evan Cheng25ab6902006-09-08 06:48:29 +00001371 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001372 return X86::CL;
Evan Cheng25ab6902006-09-08 06:48:29 +00001373 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001374 return X86::BL;
Evan Cheng25ab6902006-09-08 06:48:29 +00001375 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
1376 return X86::SIL;
1377 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
1378 return X86::DIL;
1379 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
1380 return X86::BPL;
1381 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
1382 return X86::SPL;
1383 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
1384 return X86::R8B;
1385 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
1386 return X86::R9B;
1387 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
1388 return X86::R10B;
1389 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
1390 return X86::R11B;
1391 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
1392 return X86::R12B;
1393 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
1394 return X86::R13B;
1395 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
1396 return X86::R14B;
1397 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
1398 return X86::R15B;
Evan Cheng8f7f7122006-05-05 05:40:20 +00001399 }
1400 }
Owen Anderson825b72b2009-08-11 20:47:22 +00001401 case MVT::i16:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001402 switch (Reg) {
1403 default: return Reg;
Evan Cheng25ab6902006-09-08 06:48:29 +00001404 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001405 return X86::AX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001406 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001407 return X86::DX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001408 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001409 return X86::CX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001410 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001411 return X86::BX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001412 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001413 return X86::SI;
Evan Cheng25ab6902006-09-08 06:48:29 +00001414 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001415 return X86::DI;
Evan Cheng25ab6902006-09-08 06:48:29 +00001416 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001417 return X86::BP;
Evan Cheng25ab6902006-09-08 06:48:29 +00001418 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001419 return X86::SP;
Evan Cheng25ab6902006-09-08 06:48:29 +00001420 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
1421 return X86::R8W;
1422 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
1423 return X86::R9W;
1424 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
1425 return X86::R10W;
1426 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
1427 return X86::R11W;
1428 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
1429 return X86::R12W;
1430 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
1431 return X86::R13W;
1432 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
1433 return X86::R14W;
1434 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
1435 return X86::R15W;
Evan Cheng8f7f7122006-05-05 05:40:20 +00001436 }
Owen Anderson825b72b2009-08-11 20:47:22 +00001437 case MVT::i32:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001438 switch (Reg) {
Evan Cheng25ab6902006-09-08 06:48:29 +00001439 default: return Reg;
1440 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001441 return X86::EAX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001442 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001443 return X86::EDX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001444 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001445 return X86::ECX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001446 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001447 return X86::EBX;
Evan Cheng25ab6902006-09-08 06:48:29 +00001448 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001449 return X86::ESI;
Evan Cheng25ab6902006-09-08 06:48:29 +00001450 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001451 return X86::EDI;
Evan Cheng25ab6902006-09-08 06:48:29 +00001452 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001453 return X86::EBP;
Evan Cheng25ab6902006-09-08 06:48:29 +00001454 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
Evan Cheng8f7f7122006-05-05 05:40:20 +00001455 return X86::ESP;
Evan Cheng25ab6902006-09-08 06:48:29 +00001456 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
1457 return X86::R8D;
1458 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
1459 return X86::R9D;
1460 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
1461 return X86::R10D;
1462 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
1463 return X86::R11D;
1464 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
1465 return X86::R12D;
1466 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
1467 return X86::R13D;
1468 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
1469 return X86::R14D;
1470 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
1471 return X86::R15D;
1472 }
Owen Anderson825b72b2009-08-11 20:47:22 +00001473 case MVT::i64:
Evan Cheng25ab6902006-09-08 06:48:29 +00001474 switch (Reg) {
1475 default: return Reg;
1476 case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
1477 return X86::RAX;
1478 case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
1479 return X86::RDX;
1480 case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
1481 return X86::RCX;
1482 case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
1483 return X86::RBX;
1484 case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
1485 return X86::RSI;
1486 case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
1487 return X86::RDI;
1488 case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
1489 return X86::RBP;
1490 case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
1491 return X86::RSP;
1492 case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
1493 return X86::R8;
1494 case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
1495 return X86::R9;
1496 case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
1497 return X86::R10;
1498 case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
1499 return X86::R11;
1500 case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
1501 return X86::R12;
1502 case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
1503 return X86::R13;
1504 case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
1505 return X86::R14;
1506 case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
1507 return X86::R15;
Evan Cheng8f7f7122006-05-05 05:40:20 +00001508 }
1509 }
1510
1511 return Reg;
1512}
1513}
1514
Chris Lattner7ad3e062003-08-03 15:48:14 +00001515#include "X86GenRegisterInfo.inc"
Jim Grosbachfa85eb62010-04-06 20:26:37 +00001516
1517namespace {
1518 struct MSAH : public MachineFunctionPass {
1519 static char ID;
1520 MSAH() : MachineFunctionPass(&ID) {}
1521
1522 virtual bool runOnMachineFunction(MachineFunction &MF) {
1523 const X86TargetMachine *TM =
1524 static_cast<const X86TargetMachine *>(&MF.getTarget());
1525 const X86RegisterInfo *X86RI = TM->getRegisterInfo();
1526 MachineRegisterInfo &RI = MF.getRegInfo();
1527 X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
1528 unsigned StackAlignment = X86RI->getStackAlignment();
1529
1530 // Be over-conservative: scan over all vreg defs and find whether vector
1531 // registers are used. If yes, there is a possibility that vector register
1532 // will be spilled and thus require dynamic stack realignment.
1533 for (unsigned RegNum = TargetRegisterInfo::FirstVirtualRegister;
1534 RegNum < RI.getLastVirtReg(); ++RegNum)
1535 if (RI.getRegClass(RegNum)->getAlignment() > StackAlignment) {
1536 FuncInfo->setReserveFP(true);
1537 return true;
1538 }
1539
1540 // Nothing to do
1541 return false;
1542 }
1543
1544 virtual const char *getPassName() const {
1545 return "X86 Maximal Stack Alignment Check";
1546 }
1547
1548 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1549 AU.setPreservesCFG();
1550 MachineFunctionPass::getAnalysisUsage(AU);
1551 }
1552 };
1553
1554 char MSAH::ID = 0;
1555}
1556
1557FunctionPass*
1558llvm::createX86MaxStackAlignmentHeuristicPass() { return new MSAH(); }