diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h index da111e6ce63..3e38ccc6c79 100644 --- a/include/llvm/Target/MRegisterInfo.h +++ b/include/llvm/Target/MRegisterInfo.h @@ -469,7 +469,15 @@ public: /// getRARegister - This method should return the register where the return /// address can be found. virtual unsigned getRARegister() const = 0; - + + /// getEHExceptionRegister - This method should return the register containing + /// the address of the exception info on entry to a landing pad. + virtual unsigned getEHExceptionRegister() const = 0; + + /// getEHHandlerRegister - This method should return the register containing + /// the switch table selection on entry to an landing pad. + virtual unsigned getEHHandlerRegister() const = 0; + /// getLocation - This method should return the actual location of a frame /// variable given the frame index. The location is returned in ML. /// Subclasses should override this method for special handling of frame diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 90d02b82cf6..37b1febd1f7 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1190,6 +1190,9 @@ SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::RETURNADDR: break; case ISD::FRAMEADDR: break; + // Exception address and exception selector. Currently unimplemented. + case ISD::EXCEPTIONADDR: break; + case ISD::EHSELECTION: break; } return SDOperand(); } diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp index 41f5e461047..9805892db80 100644 --- a/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/lib/Target/ARM/ARMRegisterInfo.cpp @@ -1287,5 +1287,15 @@ unsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const { return STI.useThumbBacktraces() ? ARM::R7 : ARM::R11; } +unsigned ARMRegisterInfo::getEHExceptionRegister() const { + assert(0 && "What is the exception register"); + return 0; +} + +unsigned ARMRegisterInfo::getEHHandlerRegister() const { + assert(0 && "What is the exception handler register"); + return 0; +} + #include "ARMGenRegisterInfo.inc" diff --git a/lib/Target/ARM/ARMRegisterInfo.h b/lib/Target/ARM/ARMRegisterInfo.h index d5c8021e7aa..35674ef40c2 100644 --- a/lib/Target/ARM/ARMRegisterInfo.h +++ b/lib/Target/ARM/ARMRegisterInfo.h @@ -85,6 +85,10 @@ public: // Debug information queries. unsigned getRARegister() const; unsigned getFrameRegister(MachineFunction &MF) const; + + // Exception handling queries. + unsigned getEHExceptionRegister() const; + unsigned getEHHandlerRegister() const; }; } // end namespace llvm diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index 1674d444350..12b299aeda6 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -548,8 +548,11 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(AlphaISD::GlobalRetAddr, MVT::i64); //FIXME: implement case ISD::FRAMEADDR: break; + // Exception address and exception selector. Currently unimplemented. + case ISD::EXCEPTIONADDR: break; + case ISD::EHSELECTION: break; } - + return SDOperand(); } diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp index f08195e8beb..d6260e815a7 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.cpp +++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp @@ -399,6 +399,16 @@ unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const { return hasFP(MF) ? Alpha::R15 : Alpha::R30; } +unsigned AlphaRegisterInfo::getEHExceptionRegister() const { + assert(0 && "What is the exception register"); + return 0; +} + +unsigned AlphaRegisterInfo::getEHHandlerRegister() const { + assert(0 && "What is the exception handler register"); + return 0; +} + #include "AlphaGenRegisterInfo.inc" std::string AlphaRegisterInfo::getPrettyName(unsigned reg) diff --git a/lib/Target/Alpha/AlphaRegisterInfo.h b/lib/Target/Alpha/AlphaRegisterInfo.h index 4629aaa9aec..b1642f41c5b 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.h +++ b/lib/Target/Alpha/AlphaRegisterInfo.h @@ -68,6 +68,10 @@ struct AlphaRegisterInfo : public AlphaGenRegisterInfo { unsigned getRARegister() const; unsigned getFrameRegister(MachineFunction &MF) const; + // Exception handling queries. + unsigned getEHExceptionRegister() const; + unsigned getEHHandlerRegister() const; + static std::string getPrettyName(unsigned reg); }; diff --git a/lib/Target/IA64/IA64ISelLowering.cpp b/lib/Target/IA64/IA64ISelLowering.cpp index 1c7c51db0d1..9a1c57bace3 100644 --- a/lib/Target/IA64/IA64ISelLowering.cpp +++ b/lib/Target/IA64/IA64ISelLowering.cpp @@ -590,6 +590,9 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) { // Frame & Return address. Currently unimplemented case ISD::RETURNADDR: break; case ISD::FRAMEADDR: break; + // Exception address and exception selector. Currently unimplemented. + case ISD::EXCEPTIONADDR: break; + case ISD::EHSELECTION: break; } return SDOperand(); } diff --git a/lib/Target/IA64/IA64RegisterInfo.cpp b/lib/Target/IA64/IA64RegisterInfo.cpp index f5f82266863..1e451c41e43 100644 --- a/lib/Target/IA64/IA64RegisterInfo.cpp +++ b/lib/Target/IA64/IA64RegisterInfo.cpp @@ -360,5 +360,15 @@ unsigned IA64RegisterInfo::getFrameRegister(MachineFunction &MF) const { return hasFP(MF) ? IA64::r5 : IA64::r12; } +unsigned IA64RegisterInfo::getEHExceptionRegister() const { + assert(0 && "What is the exception register"); + return 0; +} + +unsigned IA64RegisterInfo::getEHHandlerRegister() const { + assert(0 && "What is the exception handler register"); + return 0; +} + #include "IA64GenRegisterInfo.inc" diff --git a/lib/Target/IA64/IA64RegisterInfo.h b/lib/Target/IA64/IA64RegisterInfo.h index 9a977122304..17df2e92904 100644 --- a/lib/Target/IA64/IA64RegisterInfo.h +++ b/lib/Target/IA64/IA64RegisterInfo.h @@ -64,6 +64,10 @@ struct IA64RegisterInfo : public IA64GenRegisterInfo { // Debug information queries. unsigned getRARegister() const; unsigned getFrameRegister(MachineFunction &MF) const; + + // Exception handling queries. + unsigned getEHExceptionRegister() const; + unsigned getEHHandlerRegister() const; }; } // End llvm namespace diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index f8c970e88da..9c2867e87ad 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2610,6 +2610,30 @@ static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG) { } } +/// LowerEXCEPTIONADDR - Replace EXCEPTIONADDR with a copy from the exception +/// register. The register was made live in the ISel. +static SDOperand LowerEXCEPTIONADDR(SDOperand Op, SelectionDAG &DAG) { + const MRegisterInfo *MRI = DAG.getTargetLoweringInfo(). + getTargetMachine(). + getRegisterInfo(); + MVT::ValueType VT = Op.Val->getValueType(0); + unsigned Reg = MRI->getEHExceptionRegister(); + SDOperand Result = DAG.getCopyFromReg(Op.getOperand(0), Reg, VT); + return Result.getValue(Op.ResNo); +} + +/// LowerEXCEPTIONADDR - Replace EHSELECTION with a copy from the exception +/// selection register. The register was made live in the ISel. +static SDOperand LowerEHSELECTION(SDOperand Op, SelectionDAG &DAG) { + const MRegisterInfo *MRI = DAG.getTargetLoweringInfo(). + getTargetMachine(). + getRegisterInfo(); + MVT::ValueType VT = Op.Val->getValueType(0); + unsigned Reg = MRI->getEHHandlerRegister(); + SDOperand Result = DAG.getCopyFromReg(Op.getOperand(1), Reg, VT); + return Result.getValue(Op.ResNo); +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -2647,6 +2671,10 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { // Frame & Return address. Currently unimplemented case ISD::RETURNADDR: break; case ISD::FRAMEADDR: break; + + // Exception address and exception selector. + case ISD::EXCEPTIONADDR: return LowerEXCEPTIONADDR(Op, DAG); + case ISD::EHSELECTION: return LowerEHSELECTION(Op, DAG); } return SDOperand(); } diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 7553634066e..38e57da1dd8 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -1022,7 +1022,6 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF, unsigned PPCRegisterInfo::getRARegister() const { return !Subtarget.isPPC64() ? PPC::LR : PPC::LR8; - } unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const { @@ -1040,5 +1039,13 @@ void PPCRegisterInfo::getInitialFrameState(std::vector &Moves) Moves.push_back(MachineMove(0, Dst, Src)); } +unsigned PPCRegisterInfo::getEHExceptionRegister() const { + return !Subtarget.isPPC64() ? PPC::R3 : PPC::X3; +} + +unsigned PPCRegisterInfo::getEHHandlerRegister() const { + return !Subtarget.isPPC64() ? PPC::R4 : PPC::X4; +} + #include "PPCGenRegisterInfo.inc" diff --git a/lib/Target/PowerPC/PPCRegisterInfo.h b/lib/Target/PowerPC/PPCRegisterInfo.h index 6c30f6b2a5d..eedb62770e8 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/lib/Target/PowerPC/PPCRegisterInfo.h @@ -89,6 +89,10 @@ public: unsigned getRARegister() const; unsigned getFrameRegister(MachineFunction &MF) const; void getInitialFrameState(std::vector &Moves) const; + + // Exception handling queries. + unsigned getEHExceptionRegister() const; + unsigned getEHHandlerRegister() const; }; } // end namespace llvm diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 647007e86bf..59c7901ab4b 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -871,6 +871,9 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) { // Frame & Return address. Currently unimplemented case ISD::RETURNADDR: break; case ISD::FRAMEADDR: break; + // Exception address and exception selector. Currently unimplemented. + case ISD::EXCEPTIONADDR: break; + case ISD::EHSELECTION: break; } return SDOperand(); } diff --git a/lib/Target/Sparc/SparcRegisterInfo.cpp b/lib/Target/Sparc/SparcRegisterInfo.cpp index dab0b1037d1..4ea31e2e8e1 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.cpp +++ b/lib/Target/Sparc/SparcRegisterInfo.cpp @@ -250,5 +250,15 @@ unsigned SparcRegisterInfo::getFrameRegister(MachineFunction &MF) const { return SP::G1; } +unsigned SparcRegisterInfo::getEHExceptionRegister() const { + assert(0 && "What is the exception register"); + return 0; +} + +unsigned SparcRegisterInfo::getEHHandlerRegister() const { + assert(0 && "What is the exception handler register"); + return 0; +} + #include "SparcGenRegisterInfo.inc" diff --git a/lib/Target/Sparc/SparcRegisterInfo.h b/lib/Target/Sparc/SparcRegisterInfo.h index 763156a70c0..426cc664a4a 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.h +++ b/lib/Target/Sparc/SparcRegisterInfo.h @@ -70,6 +70,10 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo { // Debug information queries. unsigned getRARegister() const; unsigned getFrameRegister(MachineFunction &MF) const; + + // Exception handling queries. + unsigned getEHExceptionRegister() const; + unsigned getEHHandlerRegister() const; }; } // end namespace llvm diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 839eb8a8ab2..801c22d62b5 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -4675,7 +4675,11 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); + // Exception address and exception selector. Currently unimplemented. + case ISD::EXCEPTIONADDR: break; + case ISD::EHSELECTION: break; } + return SDOperand(); } const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 65e847e0dbb..75a2c7579d2 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -1193,6 +1193,16 @@ void X86RegisterInfo::getInitialFrameState(std::vector &Moves) Moves.push_back(MachineMove(0, Dst, Src)); } +unsigned X86RegisterInfo::getEHExceptionRegister() const { + assert(0 && "What is the exception register"); + return 0; +} + +unsigned X86RegisterInfo::getEHHandlerRegister() const { + assert(0 && "What is the exception handler register"); + return 0; +} + namespace llvm { unsigned getX86SubSuperRegister(unsigned Reg, MVT::ValueType VT, bool High) { switch (VT) { diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h index d504675b058..551661607db 100644 --- a/lib/Target/X86/X86RegisterInfo.h +++ b/lib/Target/X86/X86RegisterInfo.h @@ -101,6 +101,10 @@ public: unsigned getRARegister() const; unsigned getFrameRegister(MachineFunction &MF) const; void getInitialFrameState(std::vector &Moves) const; + + // Exception handling queries. + unsigned getEHExceptionRegister() const; + unsigned getEHHandlerRegister() const; }; // getX86SubSuperRegister - X86 utility function. It returns the sub or super