diff --git a/llvm/include/llvm/CodeGen/CallingConvLower.h b/llvm/include/llvm/CodeGen/CallingConvLower.h index 72845c43f443..715fa520defc 100644 --- a/llvm/include/llvm/CodeGen/CallingConvLower.h +++ b/llvm/include/llvm/CodeGen/CallingConvLower.h @@ -21,7 +21,9 @@ namespace llvm { class MRegisterInfo; class TargetMachine; - + class CCState; + class SDNode; + /// CCValAssign - Represent assignment of one arg/retval to a location. class CCValAssign { public: @@ -91,6 +93,12 @@ public: }; +/// CCAssignFn - This function assigns a location for Val, updating State to +/// reflect the change. +typedef bool CCAssignFn(unsigned ValNo, MVT::ValueType ValVT, + MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo, + unsigned ArgFlags, CCState &State); + /// CCState - This class holds information needed while lowering arguments and /// return values. It captures which registers are already assigned and which @@ -121,6 +129,15 @@ public: bool isAllocated(unsigned Reg) const { return UsedRegs[Reg/32] & (1 << (Reg&31)); } + + /// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info + /// about the passed values into this state. + void AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn); + + /// AnalyzeFormalArguments - Analyze an ISD::FORMAL_ARGUMENTS node, + /// incorporating info about the formals into this state. + void AnalyzeFormalArguments(SDNode *TheArgs, CCAssignFn Fn); + /// getFirstUnallocated - Return the first unallocated register in the set, or /// NumRegs if they are all allocated. @@ -168,6 +185,8 @@ private: void MarkAllocated(unsigned Reg); }; + + } // end namespace llvm #endif diff --git a/llvm/lib/CodeGen/SelectionDAG/CallingConvLower.cpp b/llvm/lib/CodeGen/SelectionDAG/CallingConvLower.cpp index b045fcb81847..3b3fa3ba276b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/CallingConvLower.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/CallingConvLower.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetMachine.h" using namespace llvm; @@ -35,3 +36,36 @@ void CCState::MarkAllocated(unsigned Reg) { for (; (Reg = *RegAliases); ++RegAliases) UsedRegs[Reg/32] |= 1 << (Reg&31); } + +/// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info +/// about the passed values into this state. +void CCState::AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn) { + unsigned NumOps = (TheCall->getNumOperands() - 5) / 2; + for (unsigned i = 0; i != NumOps; ++i) { + MVT::ValueType ArgVT = TheCall->getOperand(5+2*i).getValueType(); + SDOperand FlagOp = TheCall->getOperand(5+2*i+1); + unsigned ArgFlags =cast(FlagOp)->getValue(); + if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { + cerr << "Call operand #" << i << " has unhandled type " + << MVT::getValueTypeString(ArgVT) << "\n"; + abort(); + } + } +} + +/// AnalyzeFormalArguments - Analyze an ISD::FORMAL_ARGUMENTS node, +/// incorporating info about the formals into this state. +void CCState::AnalyzeFormalArguments(SDNode *TheArgs, CCAssignFn Fn) { + unsigned NumArgs = TheArgs->getNumValues()-1; + + for (unsigned i = 0; i != NumArgs; ++i) { + MVT::ValueType ArgVT = TheArgs->getValueType(i); + SDOperand FlagOp = TheArgs->getOperand(3+i); + unsigned ArgFlags = cast(FlagOp)->getValue(); + if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { + cerr << "Formal argument #" << i << " has unhandled type " + << MVT::getValueTypeString(ArgVT) << "\n"; + abort(); + } + } +}