mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
Implement @llvm.returnaddress. rdar://8015977.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104421 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5eb1951539
commit
2457f2c661
@ -125,6 +125,10 @@ class MachineFrameInfo {
|
|||||||
/// to builtin \@llvm.frameaddress.
|
/// to builtin \@llvm.frameaddress.
|
||||||
bool FrameAddressTaken;
|
bool FrameAddressTaken;
|
||||||
|
|
||||||
|
/// ReturnAddressTaken - This boolean keeps track of whether there is a call
|
||||||
|
/// to builtin \@llvm.returnaddress.
|
||||||
|
bool ReturnAddressTaken;
|
||||||
|
|
||||||
/// StackSize - The prolog/epilog code inserter calculates the final stack
|
/// StackSize - The prolog/epilog code inserter calculates the final stack
|
||||||
/// offsets for all of the fixed size objects, updating the Objects list
|
/// offsets for all of the fixed size objects, updating the Objects list
|
||||||
/// above. It then updates StackSize to contain the number of bytes that need
|
/// above. It then updates StackSize to contain the number of bytes that need
|
||||||
@ -193,6 +197,7 @@ public:
|
|||||||
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
|
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
|
||||||
HasVarSizedObjects = false;
|
HasVarSizedObjects = false;
|
||||||
FrameAddressTaken = false;
|
FrameAddressTaken = false;
|
||||||
|
ReturnAddressTaken = false;
|
||||||
AdjustsStack = false;
|
AdjustsStack = false;
|
||||||
HasCalls = false;
|
HasCalls = false;
|
||||||
StackProtectorIdx = -1;
|
StackProtectorIdx = -1;
|
||||||
@ -223,6 +228,12 @@ public:
|
|||||||
bool isFrameAddressTaken() const { return FrameAddressTaken; }
|
bool isFrameAddressTaken() const { return FrameAddressTaken; }
|
||||||
void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; }
|
void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; }
|
||||||
|
|
||||||
|
/// isReturnAddressTaken - This method may be called any time after instruction
|
||||||
|
/// selection is complete to determine if there is a call to
|
||||||
|
/// \@llvm.returnaddress in this function.
|
||||||
|
bool isReturnAddressTaken() const { return ReturnAddressTaken; }
|
||||||
|
void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
|
||||||
|
|
||||||
/// getObjectIndexBegin - Return the minimum frame object index.
|
/// getObjectIndexBegin - Return the minimum frame object index.
|
||||||
///
|
///
|
||||||
int getObjectIndexBegin() const { return -NumFixedObjects; }
|
int getObjectIndexBegin() const { return -NumFixedObjects; }
|
||||||
|
@ -352,7 +352,8 @@ public:
|
|||||||
/// storeRegToStackSlot(). Returns false otherwise.
|
/// storeRegToStackSlot(). Returns false otherwise.
|
||||||
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +363,8 @@ public:
|
|||||||
/// Returns false otherwise.
|
/// Returns false otherwise.
|
||||||
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ void PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) {
|
|||||||
if (! ShrinkWrapThisFunction) {
|
if (! ShrinkWrapThisFunction) {
|
||||||
// Spill using target interface.
|
// Spill using target interface.
|
||||||
I = EntryBlock->begin();
|
I = EntryBlock->begin();
|
||||||
if (!TII.spillCalleeSavedRegisters(*EntryBlock, I, CSI)) {
|
if (!TII.spillCalleeSavedRegisters(*EntryBlock, I, CSI, TRI)) {
|
||||||
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||||
// Add the callee-saved register as live-in.
|
// Add the callee-saved register as live-in.
|
||||||
// It's killed at the spill.
|
// It's killed at the spill.
|
||||||
@ -326,7 +326,7 @@ void PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) {
|
|||||||
|
|
||||||
// Restore all registers immediately before the return and any
|
// Restore all registers immediately before the return and any
|
||||||
// terminators that preceed it.
|
// terminators that preceed it.
|
||||||
if (!TII.restoreCalleeSavedRegisters(*MBB, I, CSI)) {
|
if (!TII.restoreCalleeSavedRegisters(*MBB, I, CSI, TRI)) {
|
||||||
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||||
TII.loadRegFromStackSlot(*MBB, I, CSI[i].getReg(),
|
TII.loadRegFromStackSlot(*MBB, I, CSI[i].getReg(),
|
||||||
CSI[i].getFrameIdx(),
|
CSI[i].getFrameIdx(),
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/CodeGen/MachineJumpTableInfo.h"
|
#include "llvm/CodeGen/MachineJumpTableInfo.h"
|
||||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||||
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
@ -196,6 +197,42 @@ ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
|||||||
return NewMIs[0];
|
return NewMIs[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ARMBaseInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
|
MachineBasicBlock::iterator MI,
|
||||||
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
|
if (CSI.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DebugLoc DL;
|
||||||
|
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
||||||
|
|
||||||
|
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||||
|
unsigned Reg = CSI[i].getReg();
|
||||||
|
bool isKill = true;
|
||||||
|
|
||||||
|
// Add the callee-saved register as live-in unless it's LR and
|
||||||
|
// @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
|
||||||
|
// then it's already added to the function and entry block live-in sets.
|
||||||
|
if (Reg == ARM::LR) {
|
||||||
|
MachineFunction &MF = *MBB.getParent();
|
||||||
|
if (MF.getFrameInfo()->isReturnAddressTaken() &&
|
||||||
|
MF.getRegInfo().isLiveIn(Reg))
|
||||||
|
isKill = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isKill)
|
||||||
|
MBB.addLiveIn(Reg);
|
||||||
|
|
||||||
|
// Insert the spill to the stack frame. The register is killed at the spill
|
||||||
|
//
|
||||||
|
storeRegToStackSlot(MBB, MI, Reg, isKill,
|
||||||
|
CSI[i].getFrameIdx(), CSI[i].getRegClass(), TRI);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Branch analysis.
|
// Branch analysis.
|
||||||
bool
|
bool
|
||||||
ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||||
|
@ -200,6 +200,11 @@ public:
|
|||||||
virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0;
|
virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0;
|
||||||
const ARMSubtarget &getSubtarget() const { return Subtarget; }
|
const ARMSubtarget &getSubtarget() const { return Subtarget; }
|
||||||
|
|
||||||
|
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
|
MachineBasicBlock::iterator MI,
|
||||||
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
|
|
||||||
// Branch analysis.
|
// Branch analysis.
|
||||||
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
|
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
|
||||||
MachineBasicBlock *&FBB,
|
MachineBasicBlock *&FBB,
|
||||||
|
@ -1701,7 +1701,7 @@ ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,
|
|||||||
RC = ARM::GPRRegisterClass;
|
RC = ARM::GPRRegisterClass;
|
||||||
|
|
||||||
// Transform the arguments stored in physical registers into virtual ones.
|
// Transform the arguments stored in physical registers into virtual ones.
|
||||||
unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC);
|
unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC);
|
||||||
SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
|
SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
|
||||||
|
|
||||||
SDValue ArgValue2;
|
SDValue ArgValue2;
|
||||||
@ -2141,9 +2141,34 @@ static SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) {
|
|||||||
return DAG.getNode(ARMISD::CNEG, dl, VT, AbsVal, AbsVal, ARMCC, CCR, Cmp);
|
return DAG.getNode(ARMISD::CNEG, dl, VT, AbsVal, AbsVal, ARMCC, CCR, Cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue ARMTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const{
|
||||||
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
|
MFI->setReturnAddressIsTaken(true);
|
||||||
|
|
||||||
|
EVT VT = Op.getValueType();
|
||||||
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
|
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
||||||
|
if (Depth) {
|
||||||
|
SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
|
||||||
|
SDValue Offset = DAG.getConstant(4, MVT::i32);
|
||||||
|
return DAG.getLoad(VT, dl, DAG.getEntryNode(),
|
||||||
|
DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
|
||||||
|
NULL, 0, false, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return LR, which contains the return address. Mark it an implicit live-in.
|
||||||
|
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||||
|
TargetRegisterClass *RC = AFI->isThumb1OnlyFunction()
|
||||||
|
? ARM::tGPRRegisterClass : ARM::GPRRegisterClass;
|
||||||
|
unsigned Reg = MF.addLiveIn(ARM::LR, RC);
|
||||||
|
return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
|
||||||
|
}
|
||||||
|
|
||||||
SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
|
SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
|
||||||
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
|
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
|
||||||
MFI->setFrameAddressIsTaken(true);
|
MFI->setFrameAddressIsTaken(true);
|
||||||
|
|
||||||
EVT VT = Op.getValueType();
|
EVT VT = Op.getValueType();
|
||||||
DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful
|
DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful
|
||||||
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
||||||
@ -3158,7 +3183,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
case ISD::FP_TO_SINT:
|
case ISD::FP_TO_SINT:
|
||||||
case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
|
case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
|
||||||
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
|
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
|
||||||
case ISD::RETURNADDR: break;
|
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
|
||||||
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
||||||
case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG);
|
case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG);
|
||||||
case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG);
|
case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG);
|
||||||
|
@ -302,6 +302,7 @@ namespace llvm {
|
|||||||
SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "ARMMachineFunctionInfo.h"
|
#include "ARMMachineFunctionInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
@ -150,7 +151,8 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|||||||
bool Thumb1InstrInfo::
|
bool Thumb1InstrInfo::
|
||||||
spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
if (CSI.empty())
|
if (CSI.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -161,9 +163,22 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|||||||
AddDefaultPred(MIB);
|
AddDefaultPred(MIB);
|
||||||
for (unsigned i = CSI.size(); i != 0; --i) {
|
for (unsigned i = CSI.size(); i != 0; --i) {
|
||||||
unsigned Reg = CSI[i-1].getReg();
|
unsigned Reg = CSI[i-1].getReg();
|
||||||
// Add the callee-saved register as live-in. It's killed at the spill.
|
bool isKill = true;
|
||||||
MBB.addLiveIn(Reg);
|
|
||||||
MIB.addReg(Reg, RegState::Kill);
|
// Add the callee-saved register as live-in unless it's LR and
|
||||||
|
// @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress
|
||||||
|
// then it's already added to the function and entry block live-in sets.
|
||||||
|
if (Reg == ARM::LR) {
|
||||||
|
MachineFunction &MF = *MBB.getParent();
|
||||||
|
if (MF.getFrameInfo()->isReturnAddressTaken() &&
|
||||||
|
MF.getRegInfo().isLiveIn(Reg))
|
||||||
|
isKill = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isKill) {
|
||||||
|
MBB.addLiveIn(Reg);
|
||||||
|
MIB.addReg(Reg, RegState::Kill);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -171,7 +186,8 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|||||||
bool Thumb1InstrInfo::
|
bool Thumb1InstrInfo::
|
||||||
restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
MachineFunction &MF = *MBB.getParent();
|
MachineFunction &MF = *MBB.getParent();
|
||||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||||
if (CSI.empty())
|
if (CSI.empty())
|
||||||
|
@ -39,10 +39,12 @@ public:
|
|||||||
|
|
||||||
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const;
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const;
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
|
|
||||||
bool copyRegToReg(MachineBasicBlock &MBB,
|
bool copyRegToReg(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator I,
|
MachineBasicBlock::iterator I,
|
||||||
|
@ -897,6 +897,9 @@ MSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
|
|||||||
|
|
||||||
SDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
|
SDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
|
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
|
||||||
|
MFI->setReturnAddressIsTaken(true);
|
||||||
|
|
||||||
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
||||||
DebugLoc dl = Op.getDebugLoc();
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
|
|
||||||
@ -920,6 +923,7 @@ SDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
|
|||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
|
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
|
||||||
MFI->setFrameAddressIsTaken(true);
|
MFI->setFrameAddressIsTaken(true);
|
||||||
|
|
||||||
EVT VT = Op.getValueType();
|
EVT VT = Op.getValueType();
|
||||||
DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful
|
DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful
|
||||||
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
||||||
|
@ -130,7 +130,8 @@ MSP430InstrInfo::isMoveInstr(const MachineInstr& MI,
|
|||||||
bool
|
bool
|
||||||
MSP430InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
MSP430InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
if (CSI.empty())
|
if (CSI.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -154,7 +155,8 @@ MSP430InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|||||||
bool
|
bool
|
||||||
MSP430InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
MSP430InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
if (CSI.empty())
|
if (CSI.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -73,10 +73,12 @@ public:
|
|||||||
|
|
||||||
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const;
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const;
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
|
|
||||||
unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
|
unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
|
||||||
|
|
||||||
|
@ -5496,12 +5496,15 @@ bool PPCTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
|
|||||||
|
|
||||||
SDValue PPCTargetLowering::LowerRETURNADDR(SDValue Op,
|
SDValue PPCTargetLowering::LowerRETURNADDR(SDValue Op,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
|
MFI->setReturnAddressIsTaken(true);
|
||||||
|
|
||||||
DebugLoc dl = Op.getDebugLoc();
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
||||||
|
|
||||||
// Make sure the function does not optimize away the store of the RA to
|
// Make sure the function does not optimize away the store of the RA to
|
||||||
// the stack.
|
// the stack.
|
||||||
MachineFunction &MF = DAG.getMachineFunction();
|
|
||||||
PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
|
PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
|
||||||
FuncInfo->setLRStoreRequired();
|
FuncInfo->setLRStoreRequired();
|
||||||
bool isPPC64 = PPCSubTarget.isPPC64();
|
bool isPPC64 = PPCSubTarget.isPPC64();
|
||||||
|
@ -270,7 +270,8 @@ unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
|
|||||||
bool
|
bool
|
||||||
SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
if (CSI.empty())
|
if (CSI.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -345,7 +346,8 @@ SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|||||||
bool
|
bool
|
||||||
SystemZInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
SystemZInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
if (CSI.empty())
|
if (CSI.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -86,10 +86,12 @@ public:
|
|||||||
|
|
||||||
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const;
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const;
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
|
|
||||||
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
|
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
|
||||||
virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
|
virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
|
||||||
|
@ -6981,6 +6981,9 @@ X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const
|
|||||||
|
|
||||||
SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op,
|
SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
|
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
|
||||||
|
MFI->setReturnAddressIsTaken(true);
|
||||||
|
|
||||||
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
||||||
DebugLoc dl = Op.getDebugLoc();
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
|
|
||||||
@ -7004,6 +7007,7 @@ SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op,
|
|||||||
SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
|
SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
|
||||||
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
|
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
|
||||||
MFI->setFrameAddressIsTaken(true);
|
MFI->setFrameAddressIsTaken(true);
|
||||||
|
|
||||||
EVT VT = Op.getValueType();
|
EVT VT = Op.getValueType();
|
||||||
DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful
|
DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful
|
||||||
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
||||||
|
@ -2258,7 +2258,8 @@ void X86InstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
|
|||||||
|
|
||||||
bool X86InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
bool X86InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
if (CSI.empty())
|
if (CSI.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -2297,7 +2298,8 @@ bool X86InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
bool X86InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
bool X86InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
if (CSI.empty())
|
if (CSI.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -620,11 +620,13 @@ public:
|
|||||||
|
|
||||||
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const;
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
|
|
||||||
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const;
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
|
|
||||||
virtual
|
virtual
|
||||||
MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
|
MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
|
||||||
|
@ -420,7 +420,8 @@ void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const {
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const {
|
||||||
if (CSI.empty()) {
|
if (CSI.empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -450,7 +451,8 @@ bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
bool XCoreInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
bool XCoreInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const
|
||||||
{
|
{
|
||||||
bool AtStart = MI == MBB.begin();
|
bool AtStart = MI == MBB.begin();
|
||||||
MachineBasicBlock::iterator BeforeI = MI;
|
MachineBasicBlock::iterator BeforeI = MI;
|
||||||
|
@ -84,11 +84,13 @@ public:
|
|||||||
|
|
||||||
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const;
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
|
|
||||||
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
const std::vector<CalleeSavedInfo> &CSI) const;
|
const std::vector<CalleeSavedInfo> &CSI,
|
||||||
|
const TargetRegisterInfo *TRI) const;
|
||||||
|
|
||||||
virtual bool ReverseBranchCondition(
|
virtual bool ReverseBranchCondition(
|
||||||
SmallVectorImpl<MachineOperand> &Cond) const;
|
SmallVectorImpl<MachineOperand> &Cond) const;
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
; RUN: llc < %s -mtriple=arm-apple-darwin | grep mov | grep r7
|
; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=DARWIN
|
||||||
; RUN: llc < %s -mtriple=arm-linux-gnueabi | grep mov | grep r11
|
; RUN: llc < %s -mtriple=arm-linux-gnueabi | FileCheck %s -check-prefix=LINUX
|
||||||
; PR4344
|
; PR4344
|
||||||
; PR4416
|
; PR4416
|
||||||
|
|
||||||
define arm_aapcscc i8* @t() nounwind {
|
define arm_aapcscc i8* @t() nounwind {
|
||||||
entry:
|
entry:
|
||||||
|
; DARWIN: t:
|
||||||
|
; DARWIN: mov r0, r7
|
||||||
|
|
||||||
|
; LINUX: t:
|
||||||
|
; LINUX: mov r0, r11
|
||||||
%0 = call i8* @llvm.frameaddress(i32 0)
|
%0 = call i8* @llvm.frameaddress(i32 0)
|
||||||
ret i8* %0
|
ret i8* %0
|
||||||
}
|
}
|
||||||
|
22
test/CodeGen/ARM/arm-returnaddr.ll
Normal file
22
test/CodeGen/ARM/arm-returnaddr.ll
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s
|
||||||
|
; rdar://8015977
|
||||||
|
|
||||||
|
define arm_apcscc i8* @rt0(i32 %x) nounwind readnone {
|
||||||
|
entry:
|
||||||
|
; CHECK: rt0:
|
||||||
|
; CHECK: mov r0, lr
|
||||||
|
%0 = tail call i8* @llvm.returnaddress(i32 0)
|
||||||
|
ret i8* %0
|
||||||
|
}
|
||||||
|
|
||||||
|
define arm_apcscc i8* @rt2() nounwind readnone {
|
||||||
|
entry:
|
||||||
|
; CHECK: rt2:
|
||||||
|
; CHECK: ldr r0, [r7]
|
||||||
|
; CHECK: ldr r0, [r0]
|
||||||
|
; CHECK: ldr r0, [r0, #4]
|
||||||
|
%0 = tail call i8* @llvm.returnaddress(i32 2)
|
||||||
|
ret i8* %0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i8* @llvm.returnaddress(i32) nounwind readnone
|
Loading…
Reference in New Issue
Block a user