2002-11-22 22:43:47 +00:00
|
|
|
//===- X86RegisterInfo.cpp - X86 Register Information -----------*- C++ -*-===//
|
2004-03-14 07:19:51 +00:00
|
|
|
//
|
2003-10-20 19:43:21 +00:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 20:36:04 +00:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2004-03-14 07:19:51 +00:00
|
|
|
//
|
2003-10-20 19:43:21 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2002-10-25 22:55:53 +00:00
|
|
|
//
|
2008-02-10 18:45:23 +00:00
|
|
|
// This file contains the X86 implementation of the TargetRegisterInfo class.
|
|
|
|
// This file is responsible for the frame pointer elimination optimization
|
|
|
|
// on X86.
|
2002-10-25 22:55:53 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2002-11-20 18:59:43 +00:00
|
|
|
#include "X86.h"
|
2002-10-25 22:55:53 +00:00
|
|
|
#include "X86RegisterInfo.h"
|
2002-11-22 22:43:47 +00:00
|
|
|
#include "X86InstrBuilder.h"
|
2006-06-06 23:30:24 +00:00
|
|
|
#include "X86MachineFunctionInfo.h"
|
2006-09-08 06:48:29 +00:00
|
|
|
#include "X86Subtarget.h"
|
2006-06-06 23:30:24 +00:00
|
|
|
#include "X86TargetMachine.h"
|
2002-11-20 18:59:43 +00:00
|
|
|
#include "llvm/Constants.h"
|
2006-06-02 22:38:37 +00:00
|
|
|
#include "llvm/Function.h"
|
2006-09-08 06:48:29 +00:00
|
|
|
#include "llvm/Type.h"
|
2003-07-29 05:14:16 +00:00
|
|
|
#include "llvm/CodeGen/ValueTypes.h"
|
2002-11-20 18:59:43 +00:00
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
2002-12-15 20:06:35 +00:00
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
2008-07-01 18:15:35 +00:00
|
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
2002-12-28 21:08:28 +00:00
|
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
2006-03-23 18:12:57 +00:00
|
|
|
#include "llvm/CodeGen/MachineLocation.h"
|
2007-12-31 04:13:23 +00:00
|
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
2009-08-22 20:48:53 +00:00
|
|
|
#include "llvm/MC/MCAsmInfo.h"
|
2003-01-16 02:20:12 +00:00
|
|
|
#include "llvm/Target/TargetFrameInfo.h"
|
2006-12-07 01:21:59 +00:00
|
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
2004-06-21 21:10:24 +00:00
|
|
|
#include "llvm/Target/TargetMachine.h"
|
2004-07-11 04:17:10 +00:00
|
|
|
#include "llvm/Target/TargetOptions.h"
|
2007-02-19 21:49:54 +00:00
|
|
|
#include "llvm/ADT/BitVector.h"
|
2004-09-01 22:55:40 +00:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2009-07-30 01:56:29 +00:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2009-07-11 20:10:48 +00:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2004-02-14 06:00:36 +00:00
|
|
|
using namespace llvm;
|
2003-11-11 22:41:34 +00:00
|
|
|
|
2006-09-08 06:48:29 +00:00
|
|
|
X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm,
|
|
|
|
const TargetInstrInfo &tii)
|
2008-10-01 18:28:06 +00:00
|
|
|
: X86GenRegisterInfo(tm.getSubtarget<X86Subtarget>().is64Bit() ?
|
|
|
|
X86::ADJCALLSTACKDOWN64 :
|
|
|
|
X86::ADJCALLSTACKDOWN32,
|
|
|
|
tm.getSubtarget<X86Subtarget>().is64Bit() ?
|
|
|
|
X86::ADJCALLSTACKUP64 :
|
|
|
|
X86::ADJCALLSTACKUP32),
|
2006-09-08 06:48:29 +00:00
|
|
|
TM(tm), TII(tii) {
|
|
|
|
// Cache some information.
|
|
|
|
const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
|
|
|
|
Is64Bit = Subtarget->is64Bit();
|
2008-03-22 21:04:01 +00:00
|
|
|
IsWin64 = Subtarget->isTargetWin64();
|
2007-11-05 07:30:01 +00:00
|
|
|
StackAlign = TM.getFrameInfo()->getStackAlignment();
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2006-09-08 06:48:29 +00:00
|
|
|
if (Is64Bit) {
|
|
|
|
SlotSize = 8;
|
|
|
|
StackPtr = X86::RSP;
|
|
|
|
FramePtr = X86::RBP;
|
|
|
|
} else {
|
|
|
|
SlotSize = 4;
|
|
|
|
StackPtr = X86::ESP;
|
|
|
|
FramePtr = X86::EBP;
|
|
|
|
}
|
|
|
|
}
|
2003-08-03 15:48:14 +00:00
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
/// getDwarfRegNum - This function maps LLVM register identifiers to the DWARF
|
|
|
|
/// specific numbering, used in debug info and exception tables.
|
2007-11-13 19:13:01 +00:00
|
|
|
int X86RegisterInfo::getDwarfRegNum(unsigned RegNo, bool isEH) const {
|
2007-11-09 18:07:11 +00:00
|
|
|
const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
|
2007-11-11 19:50:10 +00:00
|
|
|
unsigned Flavour = DWARFFlavour::X86_64;
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2007-11-09 18:07:11 +00:00
|
|
|
if (!Subtarget->is64Bit()) {
|
2007-11-11 19:50:10 +00:00
|
|
|
if (Subtarget->isTargetDarwin()) {
|
2008-01-25 00:34:13 +00:00
|
|
|
if (isEH)
|
|
|
|
Flavour = DWARFFlavour::X86_32_DarwinEH;
|
|
|
|
else
|
|
|
|
Flavour = DWARFFlavour::X86_32_Generic;
|
2007-11-11 19:50:10 +00:00
|
|
|
} else if (Subtarget->isTargetCygMing()) {
|
|
|
|
// Unsupported by now, just quick fallback
|
2008-01-25 00:34:13 +00:00
|
|
|
Flavour = DWARFFlavour::X86_32_Generic;
|
2007-11-11 19:50:10 +00:00
|
|
|
} else {
|
2008-01-25 00:34:13 +00:00
|
|
|
Flavour = DWARFFlavour::X86_32_Generic;
|
2007-11-09 18:07:11 +00:00
|
|
|
}
|
2007-11-07 00:25:05 +00:00
|
|
|
}
|
2007-11-11 19:50:10 +00:00
|
|
|
|
|
|
|
return X86GenRegisterInfo::getDwarfRegNumFull(RegNo, Flavour);
|
2007-11-07 00:25:05 +00:00
|
|
|
}
|
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
/// getX86RegNum - This function maps LLVM register identifiers to their X86
|
|
|
|
/// specific numbering, which is used in various places encoding instructions.
|
2008-04-16 20:10:13 +00:00
|
|
|
unsigned X86RegisterInfo::getX86RegNum(unsigned RegNo) {
|
2007-08-29 19:01:20 +00:00
|
|
|
switch(RegNo) {
|
|
|
|
case X86::RAX: case X86::EAX: case X86::AX: case X86::AL: return N86::EAX;
|
|
|
|
case X86::RCX: case X86::ECX: case X86::CX: case X86::CL: return N86::ECX;
|
|
|
|
case X86::RDX: case X86::EDX: case X86::DX: case X86::DL: return N86::EDX;
|
|
|
|
case X86::RBX: case X86::EBX: case X86::BX: case X86::BL: return N86::EBX;
|
|
|
|
case X86::RSP: case X86::ESP: case X86::SP: case X86::SPL: case X86::AH:
|
|
|
|
return N86::ESP;
|
|
|
|
case X86::RBP: case X86::EBP: case X86::BP: case X86::BPL: case X86::CH:
|
|
|
|
return N86::EBP;
|
|
|
|
case X86::RSI: case X86::ESI: case X86::SI: case X86::SIL: case X86::DH:
|
|
|
|
return N86::ESI;
|
|
|
|
case X86::RDI: case X86::EDI: case X86::DI: case X86::DIL: case X86::BH:
|
|
|
|
return N86::EDI;
|
|
|
|
|
|
|
|
case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
|
|
|
|
return N86::EAX;
|
|
|
|
case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
|
|
|
|
return N86::ECX;
|
|
|
|
case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
|
|
|
|
return N86::EDX;
|
|
|
|
case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
|
|
|
|
return N86::EBX;
|
|
|
|
case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
|
|
|
|
return N86::ESP;
|
|
|
|
case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
|
|
|
|
return N86::EBP;
|
|
|
|
case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
|
|
|
|
return N86::ESI;
|
|
|
|
case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
|
|
|
|
return N86::EDI;
|
|
|
|
|
|
|
|
case X86::ST0: case X86::ST1: case X86::ST2: case X86::ST3:
|
|
|
|
case X86::ST4: case X86::ST5: case X86::ST6: case X86::ST7:
|
|
|
|
return RegNo-X86::ST0;
|
|
|
|
|
2007-12-11 18:06:14 +00:00
|
|
|
case X86::XMM0: case X86::XMM8: case X86::MM0:
|
2007-11-13 17:54:34 +00:00
|
|
|
return 0;
|
2007-12-11 18:06:14 +00:00
|
|
|
case X86::XMM1: case X86::XMM9: case X86::MM1:
|
2007-11-13 17:54:34 +00:00
|
|
|
return 1;
|
2007-12-11 18:06:14 +00:00
|
|
|
case X86::XMM2: case X86::XMM10: case X86::MM2:
|
2007-11-13 17:54:34 +00:00
|
|
|
return 2;
|
2007-12-11 18:06:14 +00:00
|
|
|
case X86::XMM3: case X86::XMM11: case X86::MM3:
|
2007-11-13 17:54:34 +00:00
|
|
|
return 3;
|
2007-12-11 18:06:14 +00:00
|
|
|
case X86::XMM4: case X86::XMM12: case X86::MM4:
|
2007-11-13 17:54:34 +00:00
|
|
|
return 4;
|
2007-12-11 18:06:14 +00:00
|
|
|
case X86::XMM5: case X86::XMM13: case X86::MM5:
|
2007-11-13 17:54:34 +00:00
|
|
|
return 5;
|
2007-12-11 18:06:14 +00:00
|
|
|
case X86::XMM6: case X86::XMM14: case X86::MM6:
|
2007-11-13 17:54:34 +00:00
|
|
|
return 6;
|
2007-12-11 18:06:14 +00:00
|
|
|
case X86::XMM7: case X86::XMM15: case X86::MM7:
|
2007-11-13 17:54:34 +00:00
|
|
|
return 7;
|
2007-08-29 19:01:20 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
assert(isVirtualRegister(RegNo) && "Unknown physical register!");
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable("Register allocator hasn't allocated reg correctly yet!");
|
2007-08-29 19:01:20 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-18 02:10:10 +00:00
|
|
|
const TargetRegisterClass *
|
|
|
|
X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
|
|
|
|
const TargetRegisterClass *B,
|
|
|
|
unsigned SubIdx) const {
|
|
|
|
switch (SubIdx) {
|
|
|
|
default: return 0;
|
|
|
|
case 1:
|
|
|
|
// 8-bit
|
|
|
|
if (B == &X86::GR8RegClass) {
|
2009-07-20 19:47:55 +00:00
|
|
|
if (A->getSize() == 2 || A->getSize() == 4 || A->getSize() == 8)
|
|
|
|
return A;
|
2009-07-18 02:10:10 +00:00
|
|
|
} else if (B == &X86::GR8_ABCD_LRegClass || B == &X86::GR8_ABCD_HRegClass) {
|
2009-07-20 19:47:55 +00:00
|
|
|
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
|
2009-07-30 01:56:29 +00:00
|
|
|
A == &X86::GR64_NOREXRegClass ||
|
|
|
|
A == &X86::GR64_NOSPRegClass ||
|
|
|
|
A == &X86::GR64_NOREX_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR64_ABCDRegClass;
|
2009-07-20 19:47:55 +00:00
|
|
|
else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
|
2009-07-30 01:56:29 +00:00
|
|
|
A == &X86::GR32_NOREXRegClass ||
|
|
|
|
A == &X86::GR32_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR32_ABCDRegClass;
|
2009-07-20 19:47:55 +00:00
|
|
|
else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
|
|
|
|
A == &X86::GR16_NOREXRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR16_ABCDRegClass;
|
|
|
|
} else if (B == &X86::GR8_NOREXRegClass) {
|
2009-07-30 01:56:29 +00:00
|
|
|
if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
|
|
|
|
A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR64_NOREXRegClass;
|
2009-07-20 19:47:55 +00:00
|
|
|
else if (A == &X86::GR64_ABCDRegClass)
|
|
|
|
return &X86::GR64_ABCDRegClass;
|
2009-07-30 01:56:29 +00:00
|
|
|
else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass ||
|
|
|
|
A == &X86::GR32_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR32_NOREXRegClass;
|
2009-07-20 19:47:55 +00:00
|
|
|
else if (A == &X86::GR32_ABCDRegClass)
|
|
|
|
return &X86::GR32_ABCDRegClass;
|
2009-07-18 02:10:10 +00:00
|
|
|
else if (A == &X86::GR16RegClass || A == &X86::GR16_NOREXRegClass)
|
|
|
|
return &X86::GR16_NOREXRegClass;
|
2009-07-20 19:47:55 +00:00
|
|
|
else if (A == &X86::GR16_ABCDRegClass)
|
|
|
|
return &X86::GR16_ABCDRegClass;
|
2010-02-28 00:17:42 +00:00
|
|
|
} else if (B == &X86::FR32RegClass) {
|
|
|
|
return A;
|
2009-07-18 02:10:10 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
// 8-bit hi
|
|
|
|
if (B == &X86::GR8_ABCD_HRegClass) {
|
2009-07-20 19:47:55 +00:00
|
|
|
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
|
2009-07-30 01:56:29 +00:00
|
|
|
A == &X86::GR64_NOREXRegClass ||
|
|
|
|
A == &X86::GR64_NOSPRegClass ||
|
|
|
|
A == &X86::GR64_NOREX_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR64_ABCDRegClass;
|
2009-07-20 19:47:55 +00:00
|
|
|
else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
|
2009-07-30 01:56:29 +00:00
|
|
|
A == &X86::GR32_NOREXRegClass || A == &X86::GR32_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR32_ABCDRegClass;
|
2009-07-20 19:47:55 +00:00
|
|
|
else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass ||
|
|
|
|
A == &X86::GR16_NOREXRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR16_ABCDRegClass;
|
2010-02-28 00:17:42 +00:00
|
|
|
} else if (B == &X86::FR64RegClass) {
|
|
|
|
return A;
|
2009-07-18 02:10:10 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
// 16-bit
|
|
|
|
if (B == &X86::GR16RegClass) {
|
2009-07-20 19:47:55 +00:00
|
|
|
if (A->getSize() == 4 || A->getSize() == 8)
|
|
|
|
return A;
|
2009-07-18 02:10:10 +00:00
|
|
|
} else if (B == &X86::GR16_ABCDRegClass) {
|
2009-07-20 19:47:55 +00:00
|
|
|
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
|
2009-07-30 01:56:29 +00:00
|
|
|
A == &X86::GR64_NOREXRegClass ||
|
|
|
|
A == &X86::GR64_NOSPRegClass ||
|
|
|
|
A == &X86::GR64_NOREX_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR64_ABCDRegClass;
|
2009-07-20 19:47:55 +00:00
|
|
|
else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass ||
|
2009-07-30 01:56:29 +00:00
|
|
|
A == &X86::GR32_NOREXRegClass || A == &X86::GR32_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR32_ABCDRegClass;
|
|
|
|
} else if (B == &X86::GR16_NOREXRegClass) {
|
2009-07-30 01:56:29 +00:00
|
|
|
if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
|
|
|
|
A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR64_NOREXRegClass;
|
2009-07-20 19:47:55 +00:00
|
|
|
else if (A == &X86::GR64_ABCDRegClass)
|
|
|
|
return &X86::GR64_ABCDRegClass;
|
2009-07-30 01:56:29 +00:00
|
|
|
else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass ||
|
|
|
|
A == &X86::GR32_NOSPRegClass)
|
2009-07-20 19:47:55 +00:00
|
|
|
return &X86::GR32_NOREXRegClass;
|
|
|
|
else if (A == &X86::GR32_ABCDRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR64_ABCDRegClass;
|
2010-02-28 00:17:42 +00:00
|
|
|
} else if (B == &X86::VR128RegClass) {
|
|
|
|
return A;
|
2009-07-18 02:10:10 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
// 32-bit
|
2009-07-30 01:56:29 +00:00
|
|
|
if (B == &X86::GR32RegClass || B == &X86::GR32_NOSPRegClass) {
|
2009-07-20 19:47:55 +00:00
|
|
|
if (A->getSize() == 8)
|
|
|
|
return A;
|
2009-07-18 02:10:10 +00:00
|
|
|
} else if (B == &X86::GR32_ABCDRegClass) {
|
2009-07-20 19:47:55 +00:00
|
|
|
if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass ||
|
2009-07-30 01:56:29 +00:00
|
|
|
A == &X86::GR64_NOREXRegClass ||
|
|
|
|
A == &X86::GR64_NOSPRegClass ||
|
|
|
|
A == &X86::GR64_NOREX_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR64_ABCDRegClass;
|
|
|
|
} else if (B == &X86::GR32_NOREXRegClass) {
|
2009-07-30 01:56:29 +00:00
|
|
|
if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass ||
|
|
|
|
A == &X86::GR64_NOSPRegClass || A == &X86::GR64_NOREX_NOSPRegClass)
|
2009-07-18 02:10:10 +00:00
|
|
|
return &X86::GR64_NOREXRegClass;
|
2009-07-20 19:47:55 +00:00
|
|
|
else if (A == &X86::GR64_ABCDRegClass)
|
|
|
|
return &X86::GR64_ABCDRegClass;
|
2009-07-18 02:10:10 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
const TargetRegisterClass *
|
|
|
|
X86RegisterInfo::getPointerRegClass(unsigned Kind) const {
|
2009-07-30 01:56:29 +00:00
|
|
|
switch (Kind) {
|
|
|
|
default: llvm_unreachable("Unexpected Kind in getPointerRegClass!");
|
|
|
|
case 0: // Normal GPRs.
|
|
|
|
if (TM.getSubtarget<X86Subtarget>().is64Bit())
|
|
|
|
return &X86::GR64RegClass;
|
|
|
|
return &X86::GR32RegClass;
|
|
|
|
case 1: // Normal GRPs except the stack pointer (for encoding reasons).
|
2009-08-05 17:40:24 +00:00
|
|
|
if (TM.getSubtarget<X86Subtarget>().is64Bit())
|
|
|
|
return &X86::GR64_NOSPRegClass;
|
|
|
|
return &X86::GR32_NOSPRegClass;
|
2009-07-30 01:56:29 +00:00
|
|
|
}
|
2009-02-06 17:43:24 +00:00
|
|
|
}
|
|
|
|
|
2007-09-26 21:31:07 +00:00
|
|
|
const TargetRegisterClass *
|
|
|
|
X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
|
2008-02-20 12:07:57 +00:00
|
|
|
if (RC == &X86::CCRRegClass) {
|
2007-09-27 21:50:05 +00:00
|
|
|
if (Is64Bit)
|
|
|
|
return &X86::GR64RegClass;
|
|
|
|
else
|
|
|
|
return &X86::GR32RegClass;
|
2008-02-20 12:07:57 +00:00
|
|
|
}
|
2007-09-26 21:31:07 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2007-03-20 08:09:38 +00:00
|
|
|
|
Change instruction description to split OperandList into OutOperandList and
InOperandList. This gives one piece of important information: # of results
produced by an instruction.
An example of the change:
def ADD32rr : I<0x01, MRMDestReg, (ops GR32:$dst, GR32:$src1, GR32:$src2),
"add{l} {$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>;
=>
def ADD32rr : I<0x01, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
"add{l} {$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>;
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40033 91177308-0d34-0410-b5e6-96231b3b80d8
2007-07-19 01:14:50 +00:00
|
|
|
const unsigned *
|
|
|
|
X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
2008-09-08 21:12:47 +00:00
|
|
|
bool callsEHReturn = false;
|
2010-03-11 00:22:57 +00:00
|
|
|
bool ghcCall = false;
|
2008-09-08 21:12:47 +00:00
|
|
|
|
|
|
|
if (MF) {
|
2010-04-05 05:57:52 +00:00
|
|
|
callsEHReturn = MF->getMMI().callsEHReturn();
|
2010-03-11 00:22:57 +00:00
|
|
|
const Function *F = MF->getFunction();
|
|
|
|
ghcCall = (F ? F->getCallingConv() == CallingConv::GHC : false);
|
2008-09-08 21:12:47 +00:00
|
|
|
}
|
|
|
|
|
2010-03-11 00:22:57 +00:00
|
|
|
static const unsigned GhcCalleeSavedRegs[] = {
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
2007-01-02 21:33:40 +00:00
|
|
|
static const unsigned CalleeSavedRegs32Bit[] = {
|
2006-05-18 00:12:58 +00:00
|
|
|
X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0
|
|
|
|
};
|
2007-07-14 14:06:15 +00:00
|
|
|
|
|
|
|
static const unsigned CalleeSavedRegs32EHRet[] = {
|
|
|
|
X86::EAX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0
|
|
|
|
};
|
|
|
|
|
2007-01-02 21:33:40 +00:00
|
|
|
static const unsigned CalleeSavedRegs64Bit[] = {
|
2006-09-08 06:48:29 +00:00
|
|
|
X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
|
|
|
|
};
|
|
|
|
|
2008-09-08 21:12:47 +00:00
|
|
|
static const unsigned CalleeSavedRegs64EHRet[] = {
|
|
|
|
X86::RAX, X86::RDX, X86::RBX, X86::R12,
|
|
|
|
X86::R13, X86::R14, X86::R15, X86::RBP, 0
|
|
|
|
};
|
|
|
|
|
2008-03-22 21:04:01 +00:00
|
|
|
static const unsigned CalleeSavedRegsWin64[] = {
|
2008-09-24 22:03:04 +00:00
|
|
|
X86::RBX, X86::RBP, X86::RDI, X86::RSI,
|
|
|
|
X86::R12, X86::R13, X86::R14, X86::R15,
|
|
|
|
X86::XMM6, X86::XMM7, X86::XMM8, X86::XMM9,
|
|
|
|
X86::XMM10, X86::XMM11, X86::XMM12, X86::XMM13,
|
|
|
|
X86::XMM14, X86::XMM15, 0
|
2008-03-22 21:04:01 +00:00
|
|
|
};
|
|
|
|
|
2010-03-11 00:22:57 +00:00
|
|
|
if (ghcCall) {
|
|
|
|
return GhcCalleeSavedRegs;
|
|
|
|
} else if (Is64Bit) {
|
2008-03-22 21:04:01 +00:00
|
|
|
if (IsWin64)
|
|
|
|
return CalleeSavedRegsWin64;
|
|
|
|
else
|
2008-09-08 21:12:47 +00:00
|
|
|
return (callsEHReturn ? CalleeSavedRegs64EHRet : CalleeSavedRegs64Bit);
|
2008-03-22 21:04:01 +00:00
|
|
|
} else {
|
2008-09-08 21:12:47 +00:00
|
|
|
return (callsEHReturn ? CalleeSavedRegs32EHRet : CalleeSavedRegs32Bit);
|
2007-07-14 14:06:15 +00:00
|
|
|
}
|
2006-05-18 00:12:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const TargetRegisterClass* const*
|
2007-07-14 14:06:15 +00:00
|
|
|
X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
|
2008-09-08 21:12:47 +00:00
|
|
|
bool callsEHReturn = false;
|
2010-04-05 05:57:52 +00:00
|
|
|
if (MF)
|
|
|
|
callsEHReturn = MF->getMMI().callsEHReturn();
|
2008-09-08 21:12:47 +00:00
|
|
|
|
2007-01-02 21:33:40 +00:00
|
|
|
static const TargetRegisterClass * const CalleeSavedRegClasses32Bit[] = {
|
2006-05-18 00:12:58 +00:00
|
|
|
&X86::GR32RegClass, &X86::GR32RegClass,
|
|
|
|
&X86::GR32RegClass, &X86::GR32RegClass, 0
|
|
|
|
};
|
2007-07-14 14:06:15 +00:00
|
|
|
static const TargetRegisterClass * const CalleeSavedRegClasses32EHRet[] = {
|
|
|
|
&X86::GR32RegClass, &X86::GR32RegClass,
|
|
|
|
&X86::GR32RegClass, &X86::GR32RegClass,
|
|
|
|
&X86::GR32RegClass, &X86::GR32RegClass, 0
|
|
|
|
};
|
2007-01-02 21:33:40 +00:00
|
|
|
static const TargetRegisterClass * const CalleeSavedRegClasses64Bit[] = {
|
2006-09-08 06:48:29 +00:00
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass,
|
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass,
|
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass, 0
|
|
|
|
};
|
2008-09-08 21:12:47 +00:00
|
|
|
static const TargetRegisterClass * const CalleeSavedRegClasses64EHRet[] = {
|
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass,
|
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass,
|
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass,
|
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass, 0
|
|
|
|
};
|
2008-03-22 21:04:01 +00:00
|
|
|
static const TargetRegisterClass * const CalleeSavedRegClassesWin64[] = {
|
2008-09-24 22:03:04 +00:00
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass,
|
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass,
|
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass,
|
|
|
|
&X86::GR64RegClass, &X86::GR64RegClass,
|
|
|
|
&X86::VR128RegClass, &X86::VR128RegClass,
|
|
|
|
&X86::VR128RegClass, &X86::VR128RegClass,
|
|
|
|
&X86::VR128RegClass, &X86::VR128RegClass,
|
|
|
|
&X86::VR128RegClass, &X86::VR128RegClass,
|
|
|
|
&X86::VR128RegClass, &X86::VR128RegClass, 0
|
2008-03-22 21:04:01 +00:00
|
|
|
};
|
2006-09-08 06:48:29 +00:00
|
|
|
|
2008-03-22 21:04:01 +00:00
|
|
|
if (Is64Bit) {
|
|
|
|
if (IsWin64)
|
|
|
|
return CalleeSavedRegClassesWin64;
|
|
|
|
else
|
2008-09-08 21:12:47 +00:00
|
|
|
return (callsEHReturn ?
|
|
|
|
CalleeSavedRegClasses64EHRet : CalleeSavedRegClasses64Bit);
|
2008-03-22 21:04:01 +00:00
|
|
|
} else {
|
2008-09-08 21:12:47 +00:00
|
|
|
return (callsEHReturn ?
|
|
|
|
CalleeSavedRegClasses32EHRet : CalleeSavedRegClasses32Bit);
|
2007-07-14 14:06:15 +00:00
|
|
|
}
|
2006-05-18 00:12:58 +00:00
|
|
|
}
|
|
|
|
|
2007-02-19 21:49:54 +00:00
|
|
|
BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
|
|
|
BitVector Reserved(getNumRegs());
|
2008-12-18 01:05:09 +00:00
|
|
|
// Set the stack-pointer register and its aliases as reserved.
|
2007-02-19 21:49:54 +00:00
|
|
|
Reserved.set(X86::RSP);
|
|
|
|
Reserved.set(X86::ESP);
|
|
|
|
Reserved.set(X86::SP);
|
|
|
|
Reserved.set(X86::SPL);
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2009-11-13 21:56:01 +00:00
|
|
|
// Set the instruction pointer register and its aliases as reserved.
|
|
|
|
Reserved.set(X86::RIP);
|
|
|
|
Reserved.set(X86::EIP);
|
|
|
|
Reserved.set(X86::IP);
|
|
|
|
|
2008-12-18 01:05:09 +00:00
|
|
|
// Set the frame-pointer register and its aliases as reserved if needed.
|
2007-02-19 21:49:54 +00:00
|
|
|
if (hasFP(MF)) {
|
|
|
|
Reserved.set(X86::RBP);
|
|
|
|
Reserved.set(X86::EBP);
|
|
|
|
Reserved.set(X86::BP);
|
|
|
|
Reserved.set(X86::BPL);
|
|
|
|
}
|
2009-08-16 11:00:26 +00:00
|
|
|
|
|
|
|
// Mark the x87 stack registers as reserved, since they don't behave normally
|
|
|
|
// with respect to liveness. We don't fully model the effects of x87 stack
|
|
|
|
// pushes and pops after stackification.
|
2008-12-18 01:05:09 +00:00
|
|
|
Reserved.set(X86::ST0);
|
|
|
|
Reserved.set(X86::ST1);
|
|
|
|
Reserved.set(X86::ST2);
|
|
|
|
Reserved.set(X86::ST3);
|
|
|
|
Reserved.set(X86::ST4);
|
|
|
|
Reserved.set(X86::ST5);
|
|
|
|
Reserved.set(X86::ST6);
|
|
|
|
Reserved.set(X86::ST7);
|
2007-02-19 21:49:54 +00:00
|
|
|
return Reserved;
|
|
|
|
}
|
|
|
|
|
2002-12-28 20:32:28 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Stack Frame Processing methods
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
/// hasFP - Return true if the specified function should have a dedicated frame
|
|
|
|
/// pointer register. This is true if the function has variable sized allocas
|
|
|
|
/// or if frame pointer elimination is disabled.
|
2007-01-23 00:57:47 +00:00
|
|
|
bool X86RegisterInfo::hasFP(const MachineFunction &MF) const {
|
2008-07-07 23:14:23 +00:00
|
|
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
2010-04-05 05:57:52 +00:00
|
|
|
const MachineModuleInfo &MMI = MF.getMMI();
|
2007-07-14 14:06:15 +00:00
|
|
|
|
2008-04-23 18:15:11 +00:00
|
|
|
return (NoFramePointerElim ||
|
2008-04-23 18:15:48 +00:00
|
|
|
needsStackRealignment(MF) ||
|
2007-07-19 00:42:05 +00:00
|
|
|
MFI->hasVarSizedObjects() ||
|
2008-09-27 01:56:22 +00:00
|
|
|
MFI->isFrameAddressTaken() ||
|
2007-07-14 14:06:15 +00:00
|
|
|
MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() ||
|
2010-04-05 05:57:52 +00:00
|
|
|
MMI.callsUnwindInit());
|
2002-11-22 22:43:47 +00:00
|
|
|
}
|
|
|
|
|
2010-01-19 18:31:11 +00:00
|
|
|
bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
|
|
|
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
|
|
|
return (RealignStack &&
|
|
|
|
!MFI->hasVarSizedObjects());
|
|
|
|
}
|
|
|
|
|
2008-04-23 18:15:48 +00:00
|
|
|
bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
|
2009-03-19 05:51:39 +00:00
|
|
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
2010-02-19 18:17:13 +00:00
|
|
|
const Function *F = MF.getFunction();
|
2009-11-08 12:58:40 +00:00
|
|
|
bool requiresRealignment =
|
2010-02-19 18:17:13 +00:00
|
|
|
RealignStack && ((MFI->getMaxAlignment() > StackAlign) ||
|
|
|
|
F->hasFnAttr(Attribute::StackAlignment));
|
2008-04-23 18:15:48 +00:00
|
|
|
|
2008-04-23 18:16:43 +00:00
|
|
|
// FIXME: Currently we don't support stack realignment for functions with
|
2009-11-14 18:01:41 +00:00
|
|
|
// variable-sized allocas.
|
|
|
|
// FIXME: Temporary disable the error - it seems to be too conservative.
|
|
|
|
if (0 && requiresRealignment && MFI->hasVarSizedObjects())
|
2009-11-08 12:58:40 +00:00
|
|
|
llvm_report_error(
|
|
|
|
"Stack realignment in presense of dynamic allocas is not supported");
|
|
|
|
|
2009-11-14 18:01:41 +00:00
|
|
|
return (requiresRealignment && !MFI->hasVarSizedObjects());
|
2008-04-23 18:15:48 +00:00
|
|
|
}
|
|
|
|
|
2007-07-19 00:42:05 +00:00
|
|
|
bool X86RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
|
|
|
|
return !MF.getFrameInfo()->hasVarSizedObjects();
|
|
|
|
}
|
|
|
|
|
2009-07-09 06:53:48 +00:00
|
|
|
bool X86RegisterInfo::hasReservedSpillSlot(MachineFunction &MF, unsigned Reg,
|
|
|
|
int &FrameIdx) const {
|
|
|
|
if (Reg == FramePtr && hasFP(MF)) {
|
|
|
|
FrameIdx = MF.getFrameInfo()->getObjectIndexBegin();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-04-23 18:18:36 +00:00
|
|
|
int
|
2010-01-26 23:15:09 +00:00
|
|
|
X86RegisterInfo::getFrameIndexOffset(const MachineFunction &MF, int FI) const {
|
2009-08-03 08:12:53 +00:00
|
|
|
const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
|
2010-01-26 23:15:09 +00:00
|
|
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
2009-08-03 08:12:53 +00:00
|
|
|
int Offset = MFI->getObjectOffset(FI) - TFI.getOffsetOfLocalArea();
|
|
|
|
uint64_t StackSize = MFI->getStackSize();
|
2008-04-23 18:18:36 +00:00
|
|
|
|
2008-04-23 18:21:02 +00:00
|
|
|
if (needsStackRealignment(MF)) {
|
2009-08-16 11:00:26 +00:00
|
|
|
if (FI < 0) {
|
|
|
|
// Skip the saved EBP.
|
2008-04-23 18:21:02 +00:00
|
|
|
Offset += SlotSize;
|
2009-08-16 11:00:26 +00:00
|
|
|
} else {
|
2009-08-03 08:12:53 +00:00
|
|
|
unsigned Align = MFI->getObjectAlignment(FI);
|
2010-02-13 01:56:41 +00:00
|
|
|
assert((-(Offset + StackSize)) % Align == 0);
|
2008-12-23 21:56:28 +00:00
|
|
|
Align = 0;
|
2008-06-26 01:51:13 +00:00
|
|
|
return Offset + StackSize;
|
2008-04-23 18:21:27 +00:00
|
|
|
}
|
2008-04-23 18:21:02 +00:00
|
|
|
// FIXME: Support tail calls
|
|
|
|
} else {
|
|
|
|
if (!hasFP(MF))
|
2008-04-23 18:21:27 +00:00
|
|
|
return Offset + StackSize;
|
2008-04-23 18:21:02 +00:00
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
// Skip the saved EBP.
|
2008-04-23 18:21:02 +00:00
|
|
|
Offset += SlotSize;
|
|
|
|
|
|
|
|
// Skip the RETADDR move area
|
2010-01-26 23:15:09 +00:00
|
|
|
const X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
|
2008-04-23 18:21:02 +00:00
|
|
|
int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
|
2009-08-16 11:00:26 +00:00
|
|
|
if (TailCallReturnAddrDelta < 0)
|
|
|
|
Offset -= TailCallReturnAddrDelta;
|
2008-04-23 18:21:02 +00:00
|
|
|
}
|
2008-04-23 18:19:23 +00:00
|
|
|
|
2008-04-23 18:18:36 +00:00
|
|
|
return Offset;
|
|
|
|
}
|
|
|
|
|
2004-02-14 19:49:54 +00:00
|
|
|
void X86RegisterInfo::
|
|
|
|
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
|
|
|
MachineBasicBlock::iterator I) const {
|
2007-07-19 00:42:05 +00:00
|
|
|
if (!hasReservedCallFrame(MF)) {
|
|
|
|
// If the stack pointer can be changed after prologue, turn the
|
|
|
|
// adjcallstackup instruction into a 'sub ESP, <amt>' and the
|
|
|
|
// adjcallstackdown instruction into 'add ESP, <amt>'
|
|
|
|
// TODO: consider using push / pop instead of sub + store / add
|
2004-02-14 19:49:54 +00:00
|
|
|
MachineInstr *Old = I;
|
2007-04-25 04:25:10 +00:00
|
|
|
uint64_t Amount = Old->getOperand(0).getImm();
|
2002-12-28 20:32:28 +00:00
|
|
|
if (Amount != 0) {
|
2003-01-16 02:20:12 +00:00
|
|
|
// We need to keep the stack aligned properly. To do this, we round the
|
|
|
|
// amount of space needed for the outgoing arguments up to the next
|
|
|
|
// alignment boundary.
|
2009-08-16 11:00:26 +00:00
|
|
|
Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign;
|
2003-01-16 02:20:12 +00:00
|
|
|
|
2005-05-13 21:44:04 +00:00
|
|
|
MachineInstr *New = 0;
|
2008-10-01 18:28:06 +00:00
|
|
|
if (Old->getOpcode() == getCallFrameSetupOpcode()) {
|
2009-02-12 23:08:38 +00:00
|
|
|
New = BuildMI(MF, Old->getDebugLoc(),
|
|
|
|
TII.get(Is64Bit ? X86::SUB64ri32 : X86::SUB32ri),
|
2009-08-16 11:00:26 +00:00
|
|
|
StackPtr)
|
|
|
|
.addReg(StackPtr)
|
|
|
|
.addImm(Amount);
|
2002-12-28 20:32:28 +00:00
|
|
|
} else {
|
2008-10-01 18:28:06 +00:00
|
|
|
assert(Old->getOpcode() == getCallFrameDestroyOpcode());
|
2009-08-16 11:00:26 +00:00
|
|
|
|
|
|
|
// Factor out the amount the callee already popped.
|
2007-04-25 04:25:10 +00:00
|
|
|
uint64_t CalleeAmt = Old->getOperand(1).getImm();
|
2005-05-13 21:44:04 +00:00
|
|
|
Amount -= CalleeAmt;
|
2009-08-16 11:00:26 +00:00
|
|
|
|
|
|
|
if (Amount) {
|
2006-09-08 06:48:29 +00:00
|
|
|
unsigned Opc = (Amount < 128) ?
|
|
|
|
(Is64Bit ? X86::ADD64ri8 : X86::ADD32ri8) :
|
|
|
|
(Is64Bit ? X86::ADD64ri32 : X86::ADD32ri);
|
2009-02-12 23:08:38 +00:00
|
|
|
New = BuildMI(MF, Old->getDebugLoc(), TII.get(Opc), StackPtr)
|
2009-08-16 11:00:26 +00:00
|
|
|
.addReg(StackPtr)
|
|
|
|
.addImm(Amount);
|
2006-02-03 18:20:04 +00:00
|
|
|
}
|
2002-12-28 20:32:28 +00:00
|
|
|
}
|
2004-02-14 19:49:54 +00:00
|
|
|
|
2009-02-11 19:50:24 +00:00
|
|
|
if (New) {
|
|
|
|
// The EFLAGS implicit def is dead.
|
|
|
|
New->getOperand(3).setIsDead();
|
2008-12-18 22:03:42 +00:00
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
// Replace the pseudo instruction with a new instruction.
|
2009-02-11 19:50:24 +00:00
|
|
|
MBB.insert(I, New);
|
|
|
|
}
|
2005-05-13 21:44:04 +00:00
|
|
|
}
|
2008-10-01 18:28:06 +00:00
|
|
|
} else if (I->getOpcode() == getCallFrameDestroyOpcode()) {
|
2005-05-13 21:44:04 +00:00
|
|
|
// If we are performing frame pointer elimination and if the callee pops
|
|
|
|
// something off the stack pointer, add it back. We do this until we have
|
|
|
|
// more advanced stack pointer tracking ability.
|
2007-04-25 04:25:10 +00:00
|
|
|
if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
|
2006-09-08 06:48:29 +00:00
|
|
|
unsigned Opc = (CalleeAmt < 128) ?
|
|
|
|
(Is64Bit ? X86::SUB64ri8 : X86::SUB32ri8) :
|
|
|
|
(Is64Bit ? X86::SUB64ri32 : X86::SUB32ri);
|
2009-02-12 23:08:38 +00:00
|
|
|
MachineInstr *Old = I;
|
2005-07-27 06:12:32 +00:00
|
|
|
MachineInstr *New =
|
2009-02-12 23:08:38 +00:00
|
|
|
BuildMI(MF, Old->getDebugLoc(), TII.get(Opc),
|
2009-08-16 11:00:26 +00:00
|
|
|
StackPtr)
|
|
|
|
.addReg(StackPtr)
|
|
|
|
.addImm(CalleeAmt);
|
|
|
|
|
2008-12-18 22:03:42 +00:00
|
|
|
// The EFLAGS implicit def is dead.
|
|
|
|
New->getOperand(3).setIsDead();
|
2004-02-14 19:49:54 +00:00
|
|
|
MBB.insert(I, New);
|
2002-12-28 20:32:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-02-14 19:49:54 +00:00
|
|
|
MBB.erase(I);
|
2002-12-03 23:11:21 +00:00
|
|
|
}
|
|
|
|
|
2009-10-07 17:12:56 +00:00
|
|
|
unsigned
|
|
|
|
X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
2010-03-09 21:45:49 +00:00
|
|
|
int SPAdj, FrameIndexValue *Value,
|
2009-10-07 17:12:56 +00:00
|
|
|
RegScavenger *RS) const{
|
2007-05-01 09:13:03 +00:00
|
|
|
assert(SPAdj == 0 && "Unexpected");
|
|
|
|
|
2003-01-13 00:50:33 +00:00
|
|
|
unsigned i = 0;
|
2004-02-12 02:27:10 +00:00
|
|
|
MachineInstr &MI = *II;
|
2004-08-14 22:05:10 +00:00
|
|
|
MachineFunction &MF = *MI.getParent()->getParent();
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2008-10-03 15:45:36 +00:00
|
|
|
while (!MI.getOperand(i).isFI()) {
|
2002-12-28 20:32:28 +00:00
|
|
|
++i;
|
|
|
|
assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
|
|
|
|
}
|
|
|
|
|
2007-12-30 23:10:15 +00:00
|
|
|
int FrameIndex = MI.getOperand(i).getIndex();
|
2008-04-23 18:21:02 +00:00
|
|
|
unsigned BasePtr;
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2008-04-23 18:21:02 +00:00
|
|
|
if (needsStackRealignment(MF))
|
|
|
|
BasePtr = (FrameIndex < 0 ? FramePtr : StackPtr);
|
|
|
|
else
|
|
|
|
BasePtr = (hasFP(MF) ? FramePtr : StackPtr);
|
|
|
|
|
2002-12-28 20:32:28 +00:00
|
|
|
// This must be part of a four operand memory reference. Replace the
|
2006-09-08 06:48:29 +00:00
|
|
|
// FrameIndex with base register with EBP. Add an offset to the offset.
|
2008-04-23 18:21:02 +00:00
|
|
|
MI.getOperand(i).ChangeToRegister(BasePtr, false);
|
2002-12-03 23:11:21 +00:00
|
|
|
|
2008-12-24 00:27:51 +00:00
|
|
|
// Now add the frame object offset to the offset from EBP.
|
|
|
|
if (MI.getOperand(i+3).isImm()) {
|
|
|
|
// Offset is a 32-bit integer.
|
|
|
|
int Offset = getFrameIndexOffset(MF, FrameIndex) +
|
2009-08-16 11:00:26 +00:00
|
|
|
(int)(MI.getOperand(i + 3).getImm());
|
2009-11-12 20:49:22 +00:00
|
|
|
|
|
|
|
MI.getOperand(i + 3).ChangeToImmediate(Offset);
|
2008-12-24 00:27:51 +00:00
|
|
|
} else {
|
|
|
|
// Offset is symbolic. This is extremely rare.
|
|
|
|
uint64_t Offset = getFrameIndexOffset(MF, FrameIndex) +
|
|
|
|
(uint64_t)MI.getOperand(i+3).getOffset();
|
|
|
|
MI.getOperand(i+3).setOffset(Offset);
|
|
|
|
}
|
2009-10-07 17:12:56 +00:00
|
|
|
return 0;
|
2002-12-03 23:11:21 +00:00
|
|
|
}
|
2002-12-04 23:57:03 +00:00
|
|
|
|
2008-04-23 18:20:17 +00:00
|
|
|
void
|
|
|
|
X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|
|
|
RegScavenger *RS) const {
|
2009-08-03 08:12:53 +00:00
|
|
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
2008-04-23 18:20:17 +00:00
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
|
|
|
|
int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
if (TailCallReturnAddrDelta < 0) {
|
|
|
|
// create RETURNADDR area
|
|
|
|
// arg
|
|
|
|
// arg
|
|
|
|
// RETADDR
|
|
|
|
// { ...
|
|
|
|
// RETADDR area
|
|
|
|
// ...
|
|
|
|
// }
|
|
|
|
// [EBP]
|
2009-08-03 08:12:53 +00:00
|
|
|
MFI->CreateFixedObject(-TailCallReturnAddrDelta,
|
2009-11-12 20:49:22 +00:00
|
|
|
(-1U*SlotSize)+TailCallReturnAddrDelta,
|
|
|
|
true, false);
|
2007-10-11 19:40:01 +00:00
|
|
|
}
|
2009-08-03 08:12:53 +00:00
|
|
|
|
2002-12-28 20:32:28 +00:00
|
|
|
if (hasFP(MF)) {
|
2007-10-11 19:40:01 +00:00
|
|
|
assert((TailCallReturnAddrDelta <= 0) &&
|
|
|
|
"The Delta should always be zero or negative");
|
2009-08-03 08:14:30 +00:00
|
|
|
const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2002-12-28 20:32:28 +00:00
|
|
|
// Create a frame entry for the EBP register that must be saved.
|
2009-08-03 08:12:53 +00:00
|
|
|
int FrameIdx = MFI->CreateFixedObject(SlotSize,
|
2009-08-03 08:14:30 +00:00
|
|
|
-(int)SlotSize +
|
|
|
|
TFI.getOffsetOfLocalArea() +
|
2009-11-12 20:49:22 +00:00
|
|
|
TailCallReturnAddrDelta,
|
|
|
|
true, false);
|
2009-08-03 08:12:53 +00:00
|
|
|
assert(FrameIdx == MFI->getObjectIndexBegin() &&
|
2004-02-15 00:15:37 +00:00
|
|
|
"Slot for EBP register must be last in order to be found!");
|
2008-12-23 21:56:28 +00:00
|
|
|
FrameIdx = 0;
|
2002-12-28 20:32:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-04-26 01:09:28 +00:00
|
|
|
/// emitSPUpdate - Emit a series of instructions to increment / decrement the
|
|
|
|
/// stack pointer by a constant value.
|
|
|
|
static
|
|
|
|
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
|
|
|
|
unsigned StackPtr, int64_t NumBytes, bool Is64Bit,
|
|
|
|
const TargetInstrInfo &TII) {
|
|
|
|
bool isSub = NumBytes < 0;
|
|
|
|
uint64_t Offset = isSub ? -NumBytes : NumBytes;
|
|
|
|
unsigned Opc = isSub
|
|
|
|
? ((Offset < 128) ?
|
|
|
|
(Is64Bit ? X86::SUB64ri8 : X86::SUB32ri8) :
|
|
|
|
(Is64Bit ? X86::SUB64ri32 : X86::SUB32ri))
|
|
|
|
: ((Offset < 128) ?
|
|
|
|
(Is64Bit ? X86::ADD64ri8 : X86::ADD32ri8) :
|
|
|
|
(Is64Bit ? X86::ADD64ri32 : X86::ADD32ri));
|
|
|
|
uint64_t Chunk = (1LL << 31) - 1;
|
2010-01-20 21:36:02 +00:00
|
|
|
DebugLoc DL = MBB.findDebugLoc(MBBI);
|
2007-04-26 01:09:28 +00:00
|
|
|
|
|
|
|
while (Offset) {
|
|
|
|
uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
|
2008-12-18 22:03:42 +00:00
|
|
|
MachineInstr *MI =
|
2009-02-13 02:33:27 +00:00
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr)
|
2009-08-15 21:27:32 +00:00
|
|
|
.addReg(StackPtr)
|
|
|
|
.addImm(ThisVal);
|
|
|
|
MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
|
2007-04-26 01:09:28 +00:00
|
|
|
Offset -= ThisVal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
/// mergeSPUpdatesUp - Merge two stack-manipulating instructions upper iterator.
|
2007-10-06 16:17:49 +00:00
|
|
|
static
|
|
|
|
void mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
|
|
|
|
unsigned StackPtr, uint64_t *NumBytes = NULL) {
|
2007-10-07 21:53:12 +00:00
|
|
|
if (MBBI == MBB.begin()) return;
|
2008-04-23 18:15:11 +00:00
|
|
|
|
2007-10-07 21:53:12 +00:00
|
|
|
MachineBasicBlock::iterator PI = prior(MBBI);
|
|
|
|
unsigned Opc = PI->getOpcode();
|
|
|
|
if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
|
|
|
|
Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
|
|
|
|
PI->getOperand(0).getReg() == StackPtr) {
|
|
|
|
if (NumBytes)
|
|
|
|
*NumBytes += PI->getOperand(2).getImm();
|
|
|
|
MBB.erase(PI);
|
|
|
|
} else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
|
|
|
|
Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
|
|
|
|
PI->getOperand(0).getReg() == StackPtr) {
|
|
|
|
if (NumBytes)
|
|
|
|
*NumBytes -= PI->getOperand(2).getImm();
|
|
|
|
MBB.erase(PI);
|
2007-10-06 16:17:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
/// mergeSPUpdatesUp - Merge two stack-manipulating instructions lower iterator.
|
2007-10-06 16:39:43 +00:00
|
|
|
static
|
2007-10-07 21:53:12 +00:00
|
|
|
void mergeSPUpdatesDown(MachineBasicBlock &MBB,
|
|
|
|
MachineBasicBlock::iterator &MBBI,
|
2007-10-06 16:39:43 +00:00
|
|
|
unsigned StackPtr, uint64_t *NumBytes = NULL) {
|
2009-08-15 21:27:32 +00:00
|
|
|
// FIXME: THIS ISN'T RUN!!!
|
2007-10-07 22:00:31 +00:00
|
|
|
return;
|
2008-04-23 18:15:11 +00:00
|
|
|
|
2007-10-07 21:53:12 +00:00
|
|
|
if (MBBI == MBB.end()) return;
|
2008-04-23 18:15:11 +00:00
|
|
|
|
2009-12-03 00:50:42 +00:00
|
|
|
MachineBasicBlock::iterator NI = llvm::next(MBBI);
|
2007-10-07 21:53:12 +00:00
|
|
|
if (NI == MBB.end()) return;
|
2008-04-23 18:15:11 +00:00
|
|
|
|
2007-10-07 21:53:12 +00:00
|
|
|
unsigned Opc = NI->getOpcode();
|
|
|
|
if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
|
|
|
|
Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
|
|
|
|
NI->getOperand(0).getReg() == StackPtr) {
|
|
|
|
if (NumBytes)
|
|
|
|
*NumBytes -= NI->getOperand(2).getImm();
|
|
|
|
MBB.erase(NI);
|
|
|
|
MBBI = NI;
|
|
|
|
} else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
|
|
|
|
Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
|
|
|
|
NI->getOperand(0).getReg() == StackPtr) {
|
|
|
|
if (NumBytes)
|
|
|
|
*NumBytes += NI->getOperand(2).getImm();
|
|
|
|
MBB.erase(NI);
|
|
|
|
MBBI = NI;
|
2007-10-06 16:39:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
/// mergeSPUpdates - Checks the instruction before/after the passed
|
2009-08-16 11:00:26 +00:00
|
|
|
/// instruction. If it is an ADD/SUB instruction it is deleted argument and the
|
|
|
|
/// stack adjustment is returned as a positive value for ADD and a negative for
|
|
|
|
/// SUB.
|
2007-10-11 19:40:01 +00:00
|
|
|
static int mergeSPUpdates(MachineBasicBlock &MBB,
|
|
|
|
MachineBasicBlock::iterator &MBBI,
|
2008-04-23 18:15:11 +00:00
|
|
|
unsigned StackPtr,
|
2007-10-11 19:40:01 +00:00
|
|
|
bool doMergeWithPrevious) {
|
|
|
|
if ((doMergeWithPrevious && MBBI == MBB.begin()) ||
|
|
|
|
(!doMergeWithPrevious && MBBI == MBB.end()))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
MachineBasicBlock::iterator PI = doMergeWithPrevious ? prior(MBBI) : MBBI;
|
2009-12-03 00:50:42 +00:00
|
|
|
MachineBasicBlock::iterator NI = doMergeWithPrevious ? 0 : llvm::next(MBBI);
|
2007-10-11 19:40:01 +00:00
|
|
|
unsigned Opc = PI->getOpcode();
|
2009-08-16 11:00:26 +00:00
|
|
|
int Offset = 0;
|
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
|
|
|
|
Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
|
|
|
|
PI->getOperand(0).getReg() == StackPtr){
|
|
|
|
Offset += PI->getOperand(2).getImm();
|
|
|
|
MBB.erase(PI);
|
|
|
|
if (!doMergeWithPrevious) MBBI = NI;
|
|
|
|
} else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
|
|
|
|
Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
|
|
|
|
PI->getOperand(0).getReg() == StackPtr) {
|
|
|
|
Offset -= PI->getOperand(2).getImm();
|
|
|
|
MBB.erase(PI);
|
|
|
|
if (!doMergeWithPrevious) MBBI = NI;
|
2008-04-23 18:15:11 +00:00
|
|
|
}
|
2007-10-11 19:40:01 +00:00
|
|
|
|
|
|
|
return Offset;
|
|
|
|
}
|
|
|
|
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
void X86RegisterInfo::emitCalleeSavedFrameMoves(MachineFunction &MF,
|
2010-03-14 08:12:40 +00:00
|
|
|
MCSymbol *Label,
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
unsigned FramePtr) const {
|
2008-04-23 18:15:48 +00:00
|
|
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
2010-04-05 05:57:52 +00:00
|
|
|
MachineModuleInfo &MMI = MF.getMMI();
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
|
|
|
|
// Add callee saved registers to move list.
|
|
|
|
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
|
|
|
|
if (CSI.empty()) return;
|
2008-04-23 18:15:48 +00:00
|
|
|
|
2010-04-05 05:57:52 +00:00
|
|
|
std::vector<MachineMove> &Moves = MMI.getFrameMoves();
|
2008-04-23 18:15:48 +00:00
|
|
|
const TargetData *TD = MF.getTarget().getTargetData();
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
bool HasFP = hasFP(MF);
|
2008-04-23 18:15:48 +00:00
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
// Calculate amount of bytes used for return address storing.
|
2008-04-23 18:15:48 +00:00
|
|
|
int stackGrowth =
|
|
|
|
(MF.getTarget().getFrameInfo()->getStackGrowthDirection() ==
|
|
|
|
TargetFrameInfo::StackGrowsUp ?
|
|
|
|
TD->getPointerSize() : -TD->getPointerSize());
|
|
|
|
|
|
|
|
// FIXME: This is dirty hack. The code itself is pretty mess right now.
|
|
|
|
// It should be rewritten from scratch and generalized sometimes.
|
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
// Determine maximum offset (minumum due to stack growth).
|
2008-04-23 18:15:48 +00:00
|
|
|
int64_t MaxOffset = 0;
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
for (std::vector<CalleeSavedInfo>::const_iterator
|
|
|
|
I = CSI.begin(), E = CSI.end(); I != E; ++I)
|
2008-04-23 18:15:48 +00:00
|
|
|
MaxOffset = std::min(MaxOffset,
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
MFI->getObjectOffset(I->getFrameIdx()));
|
|
|
|
|
|
|
|
// Calculate offsets.
|
|
|
|
int64_t saveAreaOffset = (HasFP ? 3 : 2) * stackGrowth;
|
|
|
|
for (std::vector<CalleeSavedInfo>::const_iterator
|
|
|
|
I = CSI.begin(), E = CSI.end(); I != E; ++I) {
|
|
|
|
int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
|
|
|
|
unsigned Reg = I->getReg();
|
|
|
|
Offset = MaxOffset - Offset + saveAreaOffset;
|
|
|
|
|
2009-07-23 19:00:02 +00:00
|
|
|
// Don't output a new machine move if we're re-saving the frame
|
|
|
|
// pointer. This happens when the PrologEpilogInserter has inserted an extra
|
|
|
|
// "PUSH" of the frame pointer -- the "emitPrologue" method automatically
|
|
|
|
// generates one when frame pointers are used. If we generate a "machine
|
|
|
|
// move" for this extra "PUSH", the linker will lose track of the fact that
|
|
|
|
// the frame pointer should have the value of the first "PUSH" when it's
|
|
|
|
// trying to unwind.
|
|
|
|
//
|
|
|
|
// FIXME: This looks inelegant. It's possibly correct, but it's covering up
|
|
|
|
// another bug. I.e., one where we generate a prolog like this:
|
|
|
|
//
|
|
|
|
// pushl %ebp
|
|
|
|
// movl %esp, %ebp
|
|
|
|
// pushl %ebp
|
|
|
|
// pushl %esi
|
|
|
|
// ...
|
|
|
|
//
|
|
|
|
// The immediate re-push of EBP is unnecessary. At the least, it's an
|
|
|
|
// optimization bug. EBP can be used as a scratch register in certain
|
|
|
|
// cases, but probably not when we have a frame pointer.
|
|
|
|
if (HasFP && FramePtr == Reg)
|
|
|
|
continue;
|
|
|
|
|
2008-04-23 18:15:48 +00:00
|
|
|
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
|
|
|
|
MachineLocation CSSrc(Reg);
|
2010-03-14 08:12:40 +00:00
|
|
|
Moves.push_back(MachineMove(Label, CSDst, CSSrc));
|
2009-06-16 04:12:45 +00:00
|
|
|
}
|
2008-04-23 18:15:48 +00:00
|
|
|
}
|
|
|
|
|
2009-08-15 21:27:32 +00:00
|
|
|
/// emitPrologue - Push callee-saved registers onto the stack, which
|
|
|
|
/// automatically adjust the stack pointer. Adjust the stack pointer to allocate
|
|
|
|
/// space for local variables. Also emit labels used by the exception handler to
|
|
|
|
/// generate the exception handling frames.
|
2004-02-14 19:49:54 +00:00
|
|
|
void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
2009-08-15 21:27:32 +00:00
|
|
|
MachineBasicBlock &MBB = MF.front(); // Prologue goes in entry BB.
|
|
|
|
MachineBasicBlock::iterator MBBI = MBB.begin();
|
2003-01-15 22:57:35 +00:00
|
|
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
2009-08-15 21:27:32 +00:00
|
|
|
const Function *Fn = MF.getFunction();
|
|
|
|
const X86Subtarget *Subtarget = &MF.getTarget().getSubtarget<X86Subtarget>();
|
2010-04-05 05:57:52 +00:00
|
|
|
MachineModuleInfo &MMI = MF.getMMI();
|
2007-07-17 07:59:08 +00:00
|
|
|
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
|
2010-04-05 05:57:52 +00:00
|
|
|
bool needsFrameMoves = MMI.hasDebugInfo() ||
|
2009-08-15 21:27:32 +00:00
|
|
|
!Fn->doesNotThrow() || UnwindTablesMandatory;
|
|
|
|
uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment.
|
|
|
|
uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate.
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
bool HasFP = hasFP(MF);
|
2009-06-17 00:48:26 +00:00
|
|
|
DebugLoc DL;
|
2009-02-21 00:43:56 +00:00
|
|
|
|
2009-01-27 00:40:06 +00:00
|
|
|
// Add RETADDR move area to callee saved frame size.
|
|
|
|
int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
|
|
|
|
if (TailCallReturnAddrDelta < 0)
|
|
|
|
X86FI->setCalleeSavedFrameSize(
|
2009-08-15 21:27:32 +00:00
|
|
|
X86FI->getCalleeSavedFrameSize() - TailCallReturnAddrDelta);
|
2009-01-27 00:40:06 +00:00
|
|
|
|
2009-01-26 22:22:31 +00:00
|
|
|
// If this is x86-64 and the Red Zone is not disabled, if we are a leaf
|
|
|
|
// function, and use up to 128 bytes of stack space, don't have a frame
|
|
|
|
// pointer, calls, or dynamic alloca then we do not need to adjust the
|
|
|
|
// stack pointer (we fit in the Red Zone).
|
2009-08-15 21:27:32 +00:00
|
|
|
if (Is64Bit && !Fn->hasFnAttr(Attribute::NoRedZone) &&
|
2009-01-27 00:40:06 +00:00
|
|
|
!needsStackRealignment(MF) &&
|
2009-01-26 22:22:31 +00:00
|
|
|
!MFI->hasVarSizedObjects() && // No dynamic alloca.
|
2009-06-04 02:02:01 +00:00
|
|
|
!MFI->hasCalls() && // No calls.
|
|
|
|
!Subtarget->isTargetWin64()) { // Win64 has no Red Zone
|
2009-01-27 00:40:06 +00:00
|
|
|
uint64_t MinSize = X86FI->getCalleeSavedFrameSize();
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
if (HasFP) MinSize += SlotSize;
|
2009-08-15 21:27:32 +00:00
|
|
|
StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0);
|
2009-01-26 22:22:31 +00:00
|
|
|
MFI->setStackSize(StackSize);
|
2009-08-03 08:12:53 +00:00
|
|
|
} else if (Subtarget->isTargetWin64()) {
|
|
|
|
// We need to always allocate 32 bytes as register spill area.
|
2009-08-15 21:27:32 +00:00
|
|
|
// FIXME: We might reuse these 32 bytes for leaf functions.
|
2009-08-03 08:12:53 +00:00
|
|
|
StackSize += 32;
|
|
|
|
MFI->setStackSize(StackSize);
|
2009-01-26 22:22:31 +00:00
|
|
|
}
|
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
// Insert stack pointer adjustment for later moving of return addr. Only
|
|
|
|
// applies to tail call optimized functions where the callee argument stack
|
|
|
|
// size is bigger than the callers.
|
|
|
|
if (TailCallReturnAddrDelta < 0) {
|
2008-12-18 22:03:42 +00:00
|
|
|
MachineInstr *MI =
|
2009-02-12 23:08:38 +00:00
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit? X86::SUB64ri32 : X86::SUB32ri),
|
2009-08-15 21:27:32 +00:00
|
|
|
StackPtr)
|
|
|
|
.addReg(StackPtr)
|
|
|
|
.addImm(-TailCallReturnAddrDelta);
|
|
|
|
MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
|
2007-10-11 19:40:01 +00:00
|
|
|
}
|
|
|
|
|
2009-08-15 21:27:32 +00:00
|
|
|
// Mapping for machine moves:
|
|
|
|
//
|
|
|
|
// DST: VirtualFP AND
|
|
|
|
// SRC: VirtualFP => DW_CFA_def_cfa_offset
|
|
|
|
// ELSE => DW_CFA_def_cfa
|
|
|
|
//
|
|
|
|
// SRC: VirtualFP AND
|
|
|
|
// DST: Register => DW_CFA_def_cfa_register
|
|
|
|
//
|
|
|
|
// ELSE
|
|
|
|
// OFFSET < 0 => DW_CFA_offset_extended_sf
|
|
|
|
// REG < 64 => DW_CFA_offset + Reg
|
|
|
|
// ELSE => DW_CFA_offset_extended
|
|
|
|
|
2010-04-05 05:57:52 +00:00
|
|
|
std::vector<MachineMove> &Moves = MMI.getFrameMoves();
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
const TargetData *TD = MF.getTarget().getTargetData();
|
2009-08-15 21:27:32 +00:00
|
|
|
uint64_t NumBytes = 0;
|
2010-03-13 08:04:35 +00:00
|
|
|
int stackGrowth = -TD->getPointerSize();
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
|
|
|
|
if (HasFP) {
|
2009-08-15 21:27:32 +00:00
|
|
|
// Calculate required stack adjustment.
|
2008-04-23 18:21:27 +00:00
|
|
|
uint64_t FrameSize = StackSize - SlotSize;
|
|
|
|
if (needsStackRealignment(MF))
|
2009-08-15 21:27:32 +00:00
|
|
|
FrameSize = (FrameSize + MaxAlign - 1) / MaxAlign * MaxAlign;
|
2008-04-23 18:21:27 +00:00
|
|
|
|
|
|
|
NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize();
|
|
|
|
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
// Get the offset of the stack slot for the EBP register, which is
|
2007-07-17 07:59:08 +00:00
|
|
|
// guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
|
|
|
|
// Update the frame offset adjustment.
|
2008-04-23 18:21:27 +00:00
|
|
|
MFI->setOffsetAdjustment(-NumBytes);
|
2007-07-17 07:59:08 +00:00
|
|
|
|
2009-08-15 21:27:32 +00:00
|
|
|
// Save EBP/RBP into the appropriate stack slot.
|
2009-02-12 23:08:38 +00:00
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
|
2009-05-13 21:33:08 +00:00
|
|
|
.addReg(FramePtr, RegState::Kill);
|
2007-07-17 07:59:08 +00:00
|
|
|
|
2009-02-13 02:16:35 +00:00
|
|
|
if (needsFrameMoves) {
|
2009-08-15 21:27:32 +00:00
|
|
|
// Mark the place where EBP/RBP was saved.
|
2010-04-05 05:57:52 +00:00
|
|
|
MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
|
2010-03-14 08:12:40 +00:00
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(FrameLabel);
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
|
|
|
|
// Define the current CFA rule to use the provided offset.
|
|
|
|
if (StackSize) {
|
|
|
|
MachineLocation SPDst(MachineLocation::VirtualFP);
|
2009-08-16 11:00:26 +00:00
|
|
|
MachineLocation SPSrc(MachineLocation::VirtualFP, 2 * stackGrowth);
|
2010-03-14 08:12:40 +00:00
|
|
|
Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
} else {
|
|
|
|
// FIXME: Verify & implement for FP
|
|
|
|
MachineLocation SPDst(StackPtr);
|
|
|
|
MachineLocation SPSrc(StackPtr, stackGrowth);
|
2010-03-14 08:12:40 +00:00
|
|
|
Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Change the rule for the FramePtr to be an "offset" rule.
|
2010-03-13 08:04:35 +00:00
|
|
|
MachineLocation FPDst(MachineLocation::VirtualFP, 2 * stackGrowth);
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
MachineLocation FPSrc(FramePtr);
|
2010-03-14 08:12:40 +00:00
|
|
|
Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc));
|
2009-02-13 02:16:35 +00:00
|
|
|
}
|
|
|
|
|
2007-07-17 07:59:08 +00:00
|
|
|
// Update EBP with the new base value...
|
2009-02-12 23:08:38 +00:00
|
|
|
BuildMI(MBB, MBBI, DL,
|
|
|
|
TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr)
|
|
|
|
.addReg(StackPtr);
|
2008-04-23 18:21:27 +00:00
|
|
|
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
if (needsFrameMoves) {
|
2009-08-15 21:27:32 +00:00
|
|
|
// Mark effective beginning of when frame pointer becomes valid.
|
2010-04-05 05:57:52 +00:00
|
|
|
MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
|
2010-03-14 08:12:40 +00:00
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(FrameLabel);
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
|
|
|
|
// Define the current CFA to use the EBP/RBP register.
|
|
|
|
MachineLocation FPDst(FramePtr);
|
|
|
|
MachineLocation FPSrc(MachineLocation::VirtualFP);
|
2010-03-14 08:12:40 +00:00
|
|
|
Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc));
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
}
|
|
|
|
|
2008-12-18 22:01:52 +00:00
|
|
|
// Mark the FramePtr as live-in in every block except the entry.
|
2009-12-03 00:50:42 +00:00
|
|
|
for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
|
2008-12-18 22:01:52 +00:00
|
|
|
I != E; ++I)
|
|
|
|
I->addLiveIn(FramePtr);
|
|
|
|
|
2008-04-23 18:21:27 +00:00
|
|
|
// Realign stack
|
2008-12-18 22:03:42 +00:00
|
|
|
if (needsStackRealignment(MF)) {
|
|
|
|
MachineInstr *MI =
|
2009-02-12 23:08:38 +00:00
|
|
|
BuildMI(MBB, MBBI, DL,
|
2008-12-18 22:03:42 +00:00
|
|
|
TII.get(Is64Bit ? X86::AND64ri32 : X86::AND32ri),
|
|
|
|
StackPtr).addReg(StackPtr).addImm(-MaxAlign);
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
|
2008-12-18 22:03:42 +00:00
|
|
|
// The EFLAGS implicit def is dead.
|
|
|
|
MI->getOperand(3).setIsDead();
|
|
|
|
}
|
2009-02-21 00:43:56 +00:00
|
|
|
} else {
|
2008-04-23 18:21:27 +00:00
|
|
|
NumBytes = StackSize - X86FI->getCalleeSavedFrameSize();
|
2009-02-21 00:43:56 +00:00
|
|
|
}
|
2008-04-23 18:15:11 +00:00
|
|
|
|
2007-07-17 07:59:08 +00:00
|
|
|
// Skip the callee-saved push instructions.
|
2009-08-15 21:27:32 +00:00
|
|
|
bool PushedRegs = false;
|
|
|
|
int StackOffset = 2 * stackGrowth;
|
|
|
|
|
2007-07-17 07:59:08 +00:00
|
|
|
while (MBBI != MBB.end() &&
|
|
|
|
(MBBI->getOpcode() == X86::PUSH32r ||
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
MBBI->getOpcode() == X86::PUSH64r)) {
|
2009-08-15 21:27:32 +00:00
|
|
|
PushedRegs = true;
|
2007-07-17 07:59:08 +00:00
|
|
|
++MBBI;
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
|
2009-08-15 21:27:32 +00:00
|
|
|
if (!HasFP && needsFrameMoves) {
|
|
|
|
// Mark callee-saved push instruction.
|
2010-04-05 05:57:52 +00:00
|
|
|
MCSymbol *Label = MMI.getContext().CreateTempSymbol();
|
2010-03-14 08:12:40 +00:00
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(Label);
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
|
2009-08-15 21:27:32 +00:00
|
|
|
// Define the current CFA rule to use the provided offset.
|
|
|
|
unsigned Ptr = StackSize ?
|
|
|
|
MachineLocation::VirtualFP : StackPtr;
|
|
|
|
MachineLocation SPDst(Ptr);
|
|
|
|
MachineLocation SPSrc(Ptr, StackOffset);
|
2010-03-14 08:12:40 +00:00
|
|
|
Moves.push_back(MachineMove(Label, SPDst, SPSrc));
|
2009-08-15 21:27:32 +00:00
|
|
|
StackOffset += stackGrowth;
|
|
|
|
}
|
Recommit r74952 with a bug fix:
DWARF requires frame moves be specified at specific times. If you have a
prologue like this:
__Z3fooi:
Leh_func_begin1:
LBB1_0: ## entry
pushl %ebp
Llabel1:
movl %esp, %ebp
Llabel2:
pushl %esi
Llabel3:
subl $20, %esp
call "L1$pb"
"L1$pb":
popl %esi
The "pushl %ebp" needs a table entry specifying the offset. The "movl %esp,
%ebp" makes %ebp the new stack frame register, so that needs to be specified in
DWARF. And "pushl %esi" saves the callee-saved %esi register, which also needs
to be specified in DWARF.
Before, all of this logic was in one method. This didn't work too well, because
as you can see there are multiple FDE line entries that need to be created.
This fix creates the "MachineMove" objects directly when they're needed; instead
of waiting until the end, and losing information.
There is some ugliness where we generate code like this:
LBB22_0: ## entry
pushl %ebp
Llabel280:
movl %esp, %ebp
Llabel281:
Llabel284:
pushl %ebp <----------
pushl %ebx
pushl %edi
pushl %esi
Llabel282:
subl $328, %esp
Notice the extra "pushl %ebp". If we generate a "machine move" instruction in
the FDE for that pushl, the linker may get very confused about what value %ebp
should have when exitting the function. I.e., it'll give it the value %esp
instead of the %ebp value from the first "pushl". Not to mention that, in this
case, %ebp isn't modified in the function (that's a separate bug). I put a small
hack in to get it to work. It might be the only solution, but should be
revisited once the above case is fixed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75047 91177308-0d34-0410-b5e6-96231b3b80d8
2009-07-08 21:02:53 +00:00
|
|
|
}
|
2007-07-17 07:59:08 +00:00
|
|
|
|
2010-01-20 21:36:02 +00:00
|
|
|
DL = MBB.findDebugLoc(MBBI);
|
2009-02-21 00:43:56 +00:00
|
|
|
|
2009-06-09 20:08:51 +00:00
|
|
|
// Adjust stack pointer: ESP -= numbytes.
|
|
|
|
if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) {
|
|
|
|
// Check, whether EAX is livein for this function.
|
|
|
|
bool isEAXAlive = false;
|
|
|
|
for (MachineRegisterInfo::livein_iterator
|
2007-12-31 04:13:23 +00:00
|
|
|
II = MF.getRegInfo().livein_begin(),
|
|
|
|
EE = MF.getRegInfo().livein_end(); (II != EE) && !isEAXAlive; ++II) {
|
2009-06-09 20:08:51 +00:00
|
|
|
unsigned Reg = II->first;
|
|
|
|
isEAXAlive = (Reg == X86::EAX || Reg == X86::AX ||
|
|
|
|
Reg == X86::AH || Reg == X86::AL);
|
|
|
|
}
|
2007-04-17 09:20:00 +00:00
|
|
|
|
2009-06-09 20:08:51 +00:00
|
|
|
// Function prologue calls _alloca to probe the stack when allocating more
|
|
|
|
// than 4k bytes in one go. Touching the stack at 4K increments is necessary
|
|
|
|
// to ensure that the guard pages used by the OS virtual memory manager are
|
|
|
|
// allocated in correct sequence.
|
|
|
|
if (!isEAXAlive) {
|
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
|
|
|
|
.addImm(NumBytes);
|
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
2010-03-06 19:32:29 +00:00
|
|
|
.addExternalSymbol("_alloca")
|
|
|
|
.addReg(StackPtr, RegState::Define | RegState::Implicit);
|
2006-06-13 05:14:44 +00:00
|
|
|
} else {
|
2009-06-09 20:08:51 +00:00
|
|
|
// Save EAX
|
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r))
|
|
|
|
.addReg(X86::EAX, RegState::Kill);
|
|
|
|
|
|
|
|
// Allocate NumBytes-4 bytes on stack. We'll also use 4 already
|
|
|
|
// allocated bytes for EAX.
|
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
|
|
|
|
.addImm(NumBytes - 4);
|
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
2010-03-06 19:32:29 +00:00
|
|
|
.addExternalSymbol("_alloca")
|
|
|
|
.addReg(StackPtr, RegState::Define | RegState::Implicit);
|
2009-06-09 20:08:51 +00:00
|
|
|
|
|
|
|
// Restore EAX
|
|
|
|
MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm),
|
|
|
|
X86::EAX),
|
|
|
|
StackPtr, false, NumBytes - 4);
|
|
|
|
MBB.insert(MBBI, MI);
|
2006-06-13 05:14:44 +00:00
|
|
|
}
|
2009-06-09 20:08:51 +00:00
|
|
|
} else if (NumBytes) {
|
|
|
|
// If there is an SUB32ri of ESP immediately before this instruction, merge
|
|
|
|
// the two. This can be the case when tail call elimination is enabled and
|
|
|
|
// the callee has more arguments then the caller.
|
|
|
|
NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true);
|
|
|
|
|
|
|
|
// If there is an ADD32ri or SUB32ri of ESP immediately after this
|
|
|
|
// instruction, merge the two instructions.
|
|
|
|
mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes);
|
|
|
|
|
|
|
|
if (NumBytes)
|
|
|
|
emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII);
|
2006-04-14 07:26:43 +00:00
|
|
|
}
|
2009-07-09 22:30:02 +00:00
|
|
|
|
2009-09-03 22:19:22 +00:00
|
|
|
if ((NumBytes || PushedRegs) && needsFrameMoves) {
|
2009-07-09 22:30:02 +00:00
|
|
|
// Mark end of stack pointer adjustment.
|
2010-04-05 05:57:52 +00:00
|
|
|
MCSymbol *Label = MMI.getContext().CreateTempSymbol();
|
2010-03-14 08:12:40 +00:00
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(Label);
|
2009-07-09 22:30:02 +00:00
|
|
|
|
2009-09-03 22:19:22 +00:00
|
|
|
if (!HasFP && NumBytes) {
|
2009-08-15 21:27:32 +00:00
|
|
|
// Define the current CFA rule to use the provided offset.
|
|
|
|
if (StackSize) {
|
|
|
|
MachineLocation SPDst(MachineLocation::VirtualFP);
|
|
|
|
MachineLocation SPSrc(MachineLocation::VirtualFP,
|
|
|
|
-StackSize + stackGrowth);
|
2010-03-14 08:12:40 +00:00
|
|
|
Moves.push_back(MachineMove(Label, SPDst, SPSrc));
|
2009-08-15 21:27:32 +00:00
|
|
|
} else {
|
|
|
|
// FIXME: Verify & implement for FP
|
|
|
|
MachineLocation SPDst(StackPtr);
|
|
|
|
MachineLocation SPSrc(StackPtr, stackGrowth);
|
2010-03-14 08:12:40 +00:00
|
|
|
Moves.push_back(MachineMove(Label, SPDst, SPSrc));
|
2009-08-15 21:27:32 +00:00
|
|
|
}
|
2009-07-09 22:30:02 +00:00
|
|
|
}
|
2009-08-15 21:27:32 +00:00
|
|
|
|
|
|
|
// Emit DWARF info specifying the offsets of the callee-saved registers.
|
|
|
|
if (PushedRegs)
|
2010-03-14 08:12:40 +00:00
|
|
|
emitCalleeSavedFrameMoves(MF, Label, HasFP ? FramePtr : StackPtr);
|
2009-07-09 22:30:02 +00:00
|
|
|
}
|
2002-12-04 23:57:03 +00:00
|
|
|
}
|
|
|
|
|
2004-02-14 19:49:54 +00:00
|
|
|
void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|
|
|
MachineBasicBlock &MBB) const {
|
2002-12-28 21:08:28 +00:00
|
|
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
2007-07-17 07:59:08 +00:00
|
|
|
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
|
2004-02-14 01:18:34 +00:00
|
|
|
MachineBasicBlock::iterator MBBI = prior(MBB.end());
|
2007-07-14 14:06:15 +00:00
|
|
|
unsigned RetOpcode = MBBI->getOpcode();
|
2009-02-21 00:32:08 +00:00
|
|
|
DebugLoc DL = MBBI->getDebugLoc();
|
2005-05-14 23:35:21 +00:00
|
|
|
|
2007-07-14 14:06:15 +00:00
|
|
|
switch (RetOpcode) {
|
2009-08-16 11:00:26 +00:00
|
|
|
default:
|
|
|
|
llvm_unreachable("Can only insert epilog into returning blocks");
|
2005-05-14 23:35:21 +00:00
|
|
|
case X86::RET:
|
|
|
|
case X86::RETI:
|
2007-10-11 19:40:01 +00:00
|
|
|
case X86::TCRETURNdi:
|
|
|
|
case X86::TCRETURNri:
|
2010-03-14 03:48:46 +00:00
|
|
|
case X86::TCRETURNmi:
|
2007-10-11 19:40:01 +00:00
|
|
|
case X86::TCRETURNdi64:
|
2010-03-14 03:48:46 +00:00
|
|
|
case X86::TCRETURNri64:
|
|
|
|
case X86::TCRETURNmi64:
|
2007-07-14 14:06:15 +00:00
|
|
|
case X86::EH_RETURN:
|
2008-09-08 21:12:47 +00:00
|
|
|
case X86::EH_RETURN64:
|
2009-08-16 11:00:26 +00:00
|
|
|
break; // These are ok
|
2005-05-14 23:35:21 +00:00
|
|
|
}
|
2002-12-04 23:57:03 +00:00
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
// Get the number of bytes to allocate from the FrameInfo.
|
2007-07-17 07:59:08 +00:00
|
|
|
uint64_t StackSize = MFI->getStackSize();
|
2008-04-23 18:21:27 +00:00
|
|
|
uint64_t MaxAlign = MFI->getMaxAlignment();
|
2007-07-17 07:59:08 +00:00
|
|
|
unsigned CSSize = X86FI->getCalleeSavedFrameSize();
|
2008-04-23 18:21:27 +00:00
|
|
|
uint64_t NumBytes = 0;
|
2002-12-28 20:32:28 +00:00
|
|
|
|
2007-07-17 07:59:08 +00:00
|
|
|
if (hasFP(MF)) {
|
2009-08-16 11:00:26 +00:00
|
|
|
// Calculate required stack adjustment.
|
2008-04-23 18:21:27 +00:00
|
|
|
uint64_t FrameSize = StackSize - SlotSize;
|
|
|
|
if (needsStackRealignment(MF))
|
|
|
|
FrameSize = (FrameSize + MaxAlign - 1)/MaxAlign*MaxAlign;
|
|
|
|
|
|
|
|
NumBytes = FrameSize - CSSize;
|
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
// Pop EBP.
|
2009-02-21 00:43:56 +00:00
|
|
|
BuildMI(MBB, MBBI, DL,
|
2009-02-12 23:08:38 +00:00
|
|
|
TII.get(Is64Bit ? X86::POP64r : X86::POP32r), FramePtr);
|
2009-02-21 00:32:08 +00:00
|
|
|
} else {
|
2008-04-23 18:21:27 +00:00
|
|
|
NumBytes = StackSize - CSSize;
|
2009-02-21 00:32:08 +00:00
|
|
|
}
|
2007-07-14 14:06:15 +00:00
|
|
|
|
2007-07-17 18:03:34 +00:00
|
|
|
// Skip the callee-saved pop instructions.
|
2008-04-23 18:21:27 +00:00
|
|
|
MachineBasicBlock::iterator LastCSPop = MBBI;
|
2007-07-17 18:03:34 +00:00
|
|
|
while (MBBI != MBB.begin()) {
|
2007-07-26 17:45:41 +00:00
|
|
|
MachineBasicBlock::iterator PI = prior(MBBI);
|
|
|
|
unsigned Opc = PI->getOpcode();
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2008-10-31 18:30:19 +00:00
|
|
|
if (Opc != X86::POP32r && Opc != X86::POP64r &&
|
|
|
|
!PI->getDesc().isTerminator())
|
2007-07-17 18:03:34 +00:00
|
|
|
break;
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2007-07-17 18:03:34 +00:00
|
|
|
--MBBI;
|
|
|
|
}
|
2007-07-17 07:59:08 +00:00
|
|
|
|
2009-02-21 00:43:56 +00:00
|
|
|
DL = MBBI->getDebugLoc();
|
|
|
|
|
2007-10-06 16:17:49 +00:00
|
|
|
// If there is an ADD32ri or SUB32ri of ESP immediately before this
|
|
|
|
// instruction, merge the two instructions.
|
|
|
|
if (NumBytes || MFI->hasVarSizedObjects())
|
|
|
|
mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
|
2007-07-17 07:59:08 +00:00
|
|
|
|
2007-10-06 16:17:49 +00:00
|
|
|
// If dynamic alloca is used, then reset esp to point to the last callee-saved
|
2008-04-23 18:21:27 +00:00
|
|
|
// slot before popping them off! Same applies for the case, when stack was
|
2009-08-16 11:00:26 +00:00
|
|
|
// realigned.
|
2008-04-23 18:21:27 +00:00
|
|
|
if (needsStackRealignment(MF)) {
|
|
|
|
// We cannot use LEA here, because stack pointer was realigned. We need to
|
2009-08-16 11:00:26 +00:00
|
|
|
// deallocate local frame back.
|
2008-04-23 18:21:27 +00:00
|
|
|
if (CSSize) {
|
|
|
|
emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII);
|
|
|
|
MBBI = prior(LastCSPop);
|
|
|
|
}
|
|
|
|
|
2009-02-12 23:08:38 +00:00
|
|
|
BuildMI(MBB, MBBI, DL,
|
2008-04-23 18:21:27 +00:00
|
|
|
TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
|
|
|
|
StackPtr).addReg(FramePtr);
|
|
|
|
} else if (MFI->hasVarSizedObjects()) {
|
2007-07-18 21:26:06 +00:00
|
|
|
if (CSSize) {
|
2008-04-23 18:21:27 +00:00
|
|
|
unsigned Opc = Is64Bit ? X86::LEA64r : X86::LEA32r;
|
2009-08-16 11:00:26 +00:00
|
|
|
MachineInstr *MI =
|
|
|
|
addLeaRegOffset(BuildMI(MF, DL, TII.get(Opc), StackPtr),
|
|
|
|
FramePtr, false, -CSSize);
|
2007-07-18 21:26:06 +00:00
|
|
|
MBB.insert(MBBI, MI);
|
2009-08-16 11:00:26 +00:00
|
|
|
} else {
|
|
|
|
BuildMI(MBB, MBBI, DL,
|
|
|
|
TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), StackPtr)
|
|
|
|
.addReg(FramePtr);
|
|
|
|
}
|
|
|
|
} else if (NumBytes) {
|
|
|
|
// Adjust stack pointer back: ESP += numbytes.
|
|
|
|
emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII);
|
2007-07-17 07:59:08 +00:00
|
|
|
}
|
2007-07-17 18:40:47 +00:00
|
|
|
|
|
|
|
// We're returning from function via eh_return.
|
2008-09-08 21:12:47 +00:00
|
|
|
if (RetOpcode == X86::EH_RETURN || RetOpcode == X86::EH_RETURN64) {
|
2007-07-17 18:40:47 +00:00
|
|
|
MBBI = prior(MBB.end());
|
|
|
|
MachineOperand &DestAddr = MBBI->getOperand(0);
|
2008-10-03 15:45:36 +00:00
|
|
|
assert(DestAddr.isReg() && "Offset should be in register!");
|
2009-02-12 23:08:38 +00:00
|
|
|
BuildMI(MBB, MBBI, DL,
|
2008-09-08 21:12:47 +00:00
|
|
|
TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
|
|
|
|
StackPtr).addReg(DestAddr.getReg());
|
2007-10-11 19:40:01 +00:00
|
|
|
} else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi ||
|
2010-03-14 03:48:46 +00:00
|
|
|
RetOpcode == X86::TCRETURNmi ||
|
|
|
|
RetOpcode == X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64 ||
|
|
|
|
RetOpcode == X86::TCRETURNmi64) {
|
|
|
|
bool isMem = RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64;
|
2009-08-16 11:00:26 +00:00
|
|
|
// Tail call return: adjust the stack pointer and jump to callee.
|
2007-10-11 19:40:01 +00:00
|
|
|
MBBI = prior(MBB.end());
|
|
|
|
MachineOperand &JumpTarget = MBBI->getOperand(0);
|
2010-03-14 03:48:46 +00:00
|
|
|
MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 5 : 1);
|
2008-10-03 15:45:36 +00:00
|
|
|
assert(StackAdjust.isImm() && "Expecting immediate value.");
|
2008-04-23 18:15:11 +00:00
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
// Adjust stack pointer.
|
|
|
|
int StackAdj = StackAdjust.getImm();
|
|
|
|
int MaxTCDelta = X86FI->getTCReturnAddrDelta();
|
|
|
|
int Offset = 0;
|
|
|
|
assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive");
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
// Incoporate the retaddr area.
|
|
|
|
Offset = StackAdj-MaxTCDelta;
|
|
|
|
assert(Offset >= 0 && "Offset should never be negative");
|
2009-02-21 00:43:56 +00:00
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
if (Offset) {
|
|
|
|
// Check for possible merge with preceeding ADD instruction.
|
|
|
|
Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true);
|
|
|
|
emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII);
|
2008-04-23 18:15:11 +00:00
|
|
|
}
|
2009-02-21 00:43:56 +00:00
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
// Jump to label or value in register.
|
2010-03-14 03:48:46 +00:00
|
|
|
if (RetOpcode == X86::TCRETURNdi || RetOpcode == X86::TCRETURNdi64) {
|
|
|
|
BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNdi)
|
|
|
|
? X86::TAILJMPd : X86::TAILJMPd64)).
|
2010-01-30 01:16:15 +00:00
|
|
|
addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
|
|
|
|
JumpTarget.getTargetFlags());
|
2010-03-14 03:48:46 +00:00
|
|
|
} else if (RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64) {
|
|
|
|
MachineInstrBuilder MIB =
|
|
|
|
BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNmi)
|
|
|
|
? X86::TAILJMPm : X86::TAILJMPm64));
|
|
|
|
for (unsigned i = 0; i != 5; ++i)
|
|
|
|
MIB.addOperand(MBBI->getOperand(i));
|
2010-01-31 07:28:44 +00:00
|
|
|
} else if (RetOpcode == X86::TCRETURNri64) {
|
2009-02-12 23:08:38 +00:00
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr64), JumpTarget.getReg());
|
2010-01-31 07:28:44 +00:00
|
|
|
} else {
|
2009-11-30 23:33:53 +00:00
|
|
|
BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr), JumpTarget.getReg());
|
2010-01-31 07:28:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MachineInstr *NewMI = prior(MBBI);
|
|
|
|
for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i)
|
|
|
|
NewMI->addOperand(MBBI->getOperand(i));
|
2009-02-21 00:43:56 +00:00
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
// Delete the pseudo instruction TCRETURN.
|
|
|
|
MBB.erase(MBBI);
|
2008-04-23 18:15:11 +00:00
|
|
|
} else if ((RetOpcode == X86::RET || RetOpcode == X86::RETI) &&
|
2007-10-11 19:40:01 +00:00
|
|
|
(X86FI->getTCReturnAddrDelta() < 0)) {
|
|
|
|
// Add the return addr area delta back since we are not tail calling.
|
|
|
|
int delta = -1*X86FI->getTCReturnAddrDelta();
|
|
|
|
MBBI = prior(MBB.end());
|
2009-08-16 11:00:26 +00:00
|
|
|
|
2007-10-11 19:40:01 +00:00
|
|
|
// Check for possible merge with preceeding ADD instruction.
|
|
|
|
delta += mergeSPUpdates(MBB, MBBI, StackPtr, true);
|
|
|
|
emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, TII);
|
2007-07-17 18:40:47 +00:00
|
|
|
}
|
2002-12-28 20:32:28 +00:00
|
|
|
}
|
|
|
|
|
2006-04-07 16:34:46 +00:00
|
|
|
unsigned X86RegisterInfo::getRARegister() const {
|
2009-08-16 11:00:26 +00:00
|
|
|
return Is64Bit ? X86::RIP // Should have dwarf #16.
|
|
|
|
: X86::EIP; // Should have dwarf #8.
|
2006-04-07 16:34:46 +00:00
|
|
|
}
|
|
|
|
|
2009-11-12 20:49:22 +00:00
|
|
|
unsigned X86RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
2006-09-08 06:48:29 +00:00
|
|
|
return hasFP(MF) ? FramePtr : StackPtr;
|
2006-03-23 18:12:57 +00:00
|
|
|
}
|
|
|
|
|
2009-08-16 11:00:26 +00:00
|
|
|
void
|
|
|
|
X86RegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves) const {
|
2007-05-12 22:36:25 +00:00
|
|
|
// Calculate amount of bytes used for return address storing
|
|
|
|
int stackGrowth = (Is64Bit ? -8 : -4);
|
|
|
|
|
|
|
|
// Initial state of the frame pointer is esp+4.
|
2007-01-24 19:15:24 +00:00
|
|
|
MachineLocation Dst(MachineLocation::VirtualFP);
|
2007-05-12 22:36:25 +00:00
|
|
|
MachineLocation Src(StackPtr, stackGrowth);
|
2007-01-24 19:15:24 +00:00
|
|
|
Moves.push_back(MachineMove(0, Dst, Src));
|
2007-05-12 22:36:25 +00:00
|
|
|
|
|
|
|
// Add return address to move list
|
|
|
|
MachineLocation CSDst(StackPtr, stackGrowth);
|
|
|
|
MachineLocation CSSrc(getRARegister());
|
|
|
|
Moves.push_back(MachineMove(0, CSDst, CSSrc));
|
2007-01-24 19:15:24 +00:00
|
|
|
}
|
|
|
|
|
2007-02-21 22:54:50 +00:00
|
|
|
unsigned X86RegisterInfo::getEHExceptionRegister() const {
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable("What is the exception register");
|
2007-02-21 22:54:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned X86RegisterInfo::getEHHandlerRegister() const {
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable("What is the exception handler register");
|
2007-02-21 22:54:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-05-05 05:40:20 +00:00
|
|
|
namespace llvm {
|
2009-08-10 22:56:29 +00:00
|
|
|
unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) {
|
2009-08-11 20:47:22 +00:00
|
|
|
switch (VT.getSimpleVT().SimpleTy) {
|
2006-05-05 05:40:20 +00:00
|
|
|
default: return Reg;
|
2009-08-11 20:47:22 +00:00
|
|
|
case MVT::i8:
|
2006-05-05 05:40:20 +00:00
|
|
|
if (High) {
|
|
|
|
switch (Reg) {
|
2006-09-08 06:48:29 +00:00
|
|
|
default: return 0;
|
|
|
|
case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::AH;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::DH;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::CH;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::BH;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (Reg) {
|
2006-09-08 06:48:29 +00:00
|
|
|
default: return 0;
|
|
|
|
case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::AL;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::DL;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::CL;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::BL;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
|
|
|
|
return X86::SIL;
|
|
|
|
case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
|
|
|
|
return X86::DIL;
|
|
|
|
case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
|
|
|
|
return X86::BPL;
|
|
|
|
case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
|
|
|
|
return X86::SPL;
|
|
|
|
case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
|
|
|
|
return X86::R8B;
|
|
|
|
case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
|
|
|
|
return X86::R9B;
|
|
|
|
case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
|
|
|
|
return X86::R10B;
|
|
|
|
case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
|
|
|
|
return X86::R11B;
|
|
|
|
case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
|
|
|
|
return X86::R12B;
|
|
|
|
case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
|
|
|
|
return X86::R13B;
|
|
|
|
case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
|
|
|
|
return X86::R14B;
|
|
|
|
case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
|
|
|
|
return X86::R15B;
|
2006-05-05 05:40:20 +00:00
|
|
|
}
|
|
|
|
}
|
2009-08-11 20:47:22 +00:00
|
|
|
case MVT::i16:
|
2006-05-05 05:40:20 +00:00
|
|
|
switch (Reg) {
|
|
|
|
default: return Reg;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::AX;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::DX;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::CX;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::BX;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::SI;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::DI;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::BP;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::SP;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
|
|
|
|
return X86::R8W;
|
|
|
|
case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
|
|
|
|
return X86::R9W;
|
|
|
|
case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
|
|
|
|
return X86::R10W;
|
|
|
|
case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
|
|
|
|
return X86::R11W;
|
|
|
|
case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
|
|
|
|
return X86::R12W;
|
|
|
|
case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
|
|
|
|
return X86::R13W;
|
|
|
|
case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
|
|
|
|
return X86::R14W;
|
|
|
|
case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
|
|
|
|
return X86::R15W;
|
2006-05-05 05:40:20 +00:00
|
|
|
}
|
2009-08-11 20:47:22 +00:00
|
|
|
case MVT::i32:
|
2006-05-05 05:40:20 +00:00
|
|
|
switch (Reg) {
|
2006-09-08 06:48:29 +00:00
|
|
|
default: return Reg;
|
|
|
|
case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::EAX;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::EDX;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::ECX;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::EBX;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::ESI;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::EDI;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::EBP;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
|
2006-05-05 05:40:20 +00:00
|
|
|
return X86::ESP;
|
2006-09-08 06:48:29 +00:00
|
|
|
case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
|
|
|
|
return X86::R8D;
|
|
|
|
case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
|
|
|
|
return X86::R9D;
|
|
|
|
case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
|
|
|
|
return X86::R10D;
|
|
|
|
case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
|
|
|
|
return X86::R11D;
|
|
|
|
case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
|
|
|
|
return X86::R12D;
|
|
|
|
case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
|
|
|
|
return X86::R13D;
|
|
|
|
case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
|
|
|
|
return X86::R14D;
|
|
|
|
case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
|
|
|
|
return X86::R15D;
|
|
|
|
}
|
2009-08-11 20:47:22 +00:00
|
|
|
case MVT::i64:
|
2006-09-08 06:48:29 +00:00
|
|
|
switch (Reg) {
|
|
|
|
default: return Reg;
|
|
|
|
case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
|
|
|
|
return X86::RAX;
|
|
|
|
case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
|
|
|
|
return X86::RDX;
|
|
|
|
case X86::CH: case X86::CL: case X86::CX: case X86::ECX: case X86::RCX:
|
|
|
|
return X86::RCX;
|
|
|
|
case X86::BH: case X86::BL: case X86::BX: case X86::EBX: case X86::RBX:
|
|
|
|
return X86::RBX;
|
|
|
|
case X86::SIL: case X86::SI: case X86::ESI: case X86::RSI:
|
|
|
|
return X86::RSI;
|
|
|
|
case X86::DIL: case X86::DI: case X86::EDI: case X86::RDI:
|
|
|
|
return X86::RDI;
|
|
|
|
case X86::BPL: case X86::BP: case X86::EBP: case X86::RBP:
|
|
|
|
return X86::RBP;
|
|
|
|
case X86::SPL: case X86::SP: case X86::ESP: case X86::RSP:
|
|
|
|
return X86::RSP;
|
|
|
|
case X86::R8B: case X86::R8W: case X86::R8D: case X86::R8:
|
|
|
|
return X86::R8;
|
|
|
|
case X86::R9B: case X86::R9W: case X86::R9D: case X86::R9:
|
|
|
|
return X86::R9;
|
|
|
|
case X86::R10B: case X86::R10W: case X86::R10D: case X86::R10:
|
|
|
|
return X86::R10;
|
|
|
|
case X86::R11B: case X86::R11W: case X86::R11D: case X86::R11:
|
|
|
|
return X86::R11;
|
|
|
|
case X86::R12B: case X86::R12W: case X86::R12D: case X86::R12:
|
|
|
|
return X86::R12;
|
|
|
|
case X86::R13B: case X86::R13W: case X86::R13D: case X86::R13:
|
|
|
|
return X86::R13;
|
|
|
|
case X86::R14B: case X86::R14W: case X86::R14D: case X86::R14:
|
|
|
|
return X86::R14;
|
|
|
|
case X86::R15B: case X86::R15W: case X86::R15D: case X86::R15:
|
|
|
|
return X86::R15;
|
2006-05-05 05:40:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Reg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-08-03 15:48:14 +00:00
|
|
|
#include "X86GenRegisterInfo.inc"
|
2010-04-06 20:26:37 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
struct MSAH : public MachineFunctionPass {
|
|
|
|
static char ID;
|
|
|
|
MSAH() : MachineFunctionPass(&ID) {}
|
|
|
|
|
|
|
|
virtual bool runOnMachineFunction(MachineFunction &MF) {
|
|
|
|
const X86TargetMachine *TM =
|
|
|
|
static_cast<const X86TargetMachine *>(&MF.getTarget());
|
|
|
|
const X86RegisterInfo *X86RI = TM->getRegisterInfo();
|
|
|
|
MachineRegisterInfo &RI = MF.getRegInfo();
|
|
|
|
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
|
|
|
|
unsigned StackAlignment = X86RI->getStackAlignment();
|
|
|
|
|
|
|
|
// Be over-conservative: scan over all vreg defs and find whether vector
|
|
|
|
// registers are used. If yes, there is a possibility that vector register
|
|
|
|
// will be spilled and thus require dynamic stack realignment.
|
|
|
|
for (unsigned RegNum = TargetRegisterInfo::FirstVirtualRegister;
|
|
|
|
RegNum < RI.getLastVirtReg(); ++RegNum)
|
|
|
|
if (RI.getRegClass(RegNum)->getAlignment() > StackAlignment) {
|
|
|
|
FuncInfo->setReserveFP(true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Nothing to do
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const char *getPassName() const {
|
|
|
|
return "X86 Maximal Stack Alignment Check";
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
|
|
|
AU.setPreservesCFG();
|
|
|
|
MachineFunctionPass::getAnalysisUsage(AU);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
char MSAH::ID = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
FunctionPass*
|
|
|
|
llvm::createX86MaxStackAlignmentHeuristicPass() { return new MSAH(); }
|