summaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2007-05-02 19:53:33 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2007-05-02 19:53:33 +0000
commitce3b46552a03f502e56fb3c4db82f3f92c09eff9 (patch)
tree6241e4df88b94c9e7cc5671f29ac0abcfc34b7c4 /lib/Target
parent038082d96652601c70a98d4edffc834c835fc0bf (diff)
downloadllvm-ce3b46552a03f502e56fb3c4db82f3f92c09eff9.tar.gz
llvm-ce3b46552a03f502e56fb3c4db82f3f92c09eff9.tar.bz2
llvm-ce3b46552a03f502e56fb3c4db82f3f92c09eff9.tar.xz
Emit correct register move information in eh frames for X86. This allows Shootout-C++/except to pass on x86/linux
with non-llvm-compiled (e.g. "native") unwind runtime. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36647 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp13
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp51
2 files changed, 56 insertions, 8 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 996ffe94ec..9366f9a6e3 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -226,6 +226,19 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
!Subtarget->isTargetCygMing())
setOperationAction(ISD::LABEL, MVT::Other, Expand);
+ setOperationAction(ISD::EXCEPTIONADDR, MVT::i64, Expand);
+ setOperationAction(ISD::EHSELECTION, MVT::i64, Expand);
+ setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand);
+ setOperationAction(ISD::EHSELECTION, MVT::i32, Expand);
+ if (Subtarget->is64Bit()) {
+ // FIXME: Verify
+ setExceptionPointerRegister(X86::RAX);
+ setExceptionSelectorRegister(X86::RDX);
+ } else {
+ setExceptionPointerRegister(X86::EAX);
+ setExceptionSelectorRegister(X86::EDX);
+ }
+
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
setOperationAction(ISD::VASTART , MVT::Other, Custom);
setOperationAction(ISD::VAARG , MVT::Other, Expand);
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 4795319a28..06d12b0a42 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -26,6 +26,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
@@ -1060,11 +1061,17 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
// Prepare for frame info.
- unsigned FrameLabelId = 0;
+ unsigned FrameLabelId = 0, StartLabelId = 0;
// Get the number of bytes to allocate from the FrameInfo
uint64_t NumBytes = MFI->getStackSize();
+ if (MMI && MMI->needsFrameInfo()) {
+ // Mark function start
+ StartLabelId = MMI->NextLabelID();
+ BuildMI(MBB, MBBI, TII.get(X86::LABEL)).addImm(StartLabelId);
+ }
+
if (NumBytes) { // adjust stack pointer: ESP -= numbytes
if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) {
// Check, whether EAX is livein for this function
@@ -1138,17 +1145,38 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
if (MMI && MMI->needsFrameInfo()) {
std::vector<MachineMove> &Moves = MMI->getFrameMoves();
-
+ const TargetAsmInfo *TAI = MF.getTarget().getTargetAsmInfo();
+
+ // Calculate amount of bytes used for return address storing
+ int stackGrowth =
+ (MF.getTarget().getFrameInfo()->getStackGrowthDirection() ==
+ TargetFrameInfo::StackGrowsUp ?
+ TAI->getAddressSize() : -TAI->getAddressSize());
+
+ // Add return address to move list
+ MachineLocation CSDst(StackPtr, stackGrowth);
+ MachineLocation CSSrc(getRARegister());
+ Moves.push_back(MachineMove(StartLabelId, CSDst, CSSrc));
+
if (NumBytes) {
// Show update of SP.
- MachineLocation SPDst(MachineLocation::VirtualFP);
- MachineLocation SPSrc(MachineLocation::VirtualFP, -NumBytes);
- Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
+ if (hasFP(MF)) {
+ // Adjust SP
+ MachineLocation SPDst(MachineLocation::VirtualFP);
+ MachineLocation SPSrc(MachineLocation::VirtualFP, 2*stackGrowth);
+ Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
+ } else {
+ MachineLocation SPDst(MachineLocation::VirtualFP);
+ MachineLocation SPSrc(MachineLocation::VirtualFP, -NumBytes+stackGrowth);
+ Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
+ }
} else {
- MachineLocation SP(StackPtr);
- Moves.push_back(MachineMove(FrameLabelId, SP, SP));
+ //FIXME: Verify & implement for FP
+ MachineLocation SPDst(StackPtr);
+ MachineLocation SPSrc(StackPtr, stackGrowth);
+ Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
}
-
+
// Add callee saved registers to move list.
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
@@ -1162,6 +1190,13 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
// Mark effective beginning of when frame pointer is ready.
unsigned ReadyLabelId = MMI->NextLabelID();
BuildMI(MBB, MBBI, TII.get(X86::LABEL)).addImm(ReadyLabelId);
+
+ if (hasFP(MF)) {
+ // Save FP
+ MachineLocation FPDst(MachineLocation::VirtualFP, 2*stackGrowth);
+ MachineLocation FPSrc(FramePtr);
+ Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc));
+ }
MachineLocation FPDst(hasFP(MF) ? FramePtr : StackPtr);
MachineLocation FPSrc(MachineLocation::VirtualFP);