summaryrefslogtreecommitdiff
path: root/src/vm/callingconvention.h
diff options
context:
space:
mode:
authorjashook <jashoo@microsoft.com>2017-04-19 10:03:13 -0700
committerjashook <jashoo@microsoft.com>2017-04-19 10:03:13 -0700
commitaa0eee4ae0ea70620783e215c68a7cdeb9439cf4 (patch)
treebcdbdac1cc0fa60f8424a167eebeaf33eb794ee0 /src/vm/callingconvention.h
parent6252b1628317776e36b674841aaed8bffb3f88f8 (diff)
downloadcoreclr-aa0eee4ae0ea70620783e215c68a7cdeb9439cf4.tar.gz
coreclr-aa0eee4ae0ea70620783e215c68a7cdeb9439cf4.tar.bz2
coreclr-aa0eee4ae0ea70620783e215c68a7cdeb9439cf4.zip
For Reflection invoke, use ArgLocDesc
For arm64 if the struct needs to be passed in registers, then pass that information along when we do the reflection invoke. Note this adds more test cases for passing different struct types via reflection. I am guessing similar work would need to be done for Arm32.
Diffstat (limited to 'src/vm/callingconvention.h')
-rw-r--r--src/vm/callingconvention.h43
1 files changed, 33 insertions, 10 deletions
diff --git a/src/vm/callingconvention.h b/src/vm/callingconvention.h
index cde2ba465a..b707b4bc8c 100644
--- a/src/vm/callingconvention.h
+++ b/src/vm/callingconvention.h
@@ -34,21 +34,26 @@ BOOL IsRetBuffPassedAsFirstArg();
// and possibly on to the stack as well.
struct ArgLocDesc
{
- int m_idxFloatReg; // First floating point register used (or -1)
- int m_cFloatReg; // Count of floating point registers used (or 0)
+ int m_idxFloatReg; // First floating point register used (or -1)
+ int m_cFloatReg; // Count of floating point registers used (or 0)
- int m_idxGenReg; // First general register used (or -1)
- int m_cGenReg; // Count of general registers used (or 0)
+ int m_idxGenReg; // First general register used (or -1)
+ int m_cGenReg; // Count of general registers used (or 0)
- int m_idxStack; // First stack slot used (or -1)
- int m_cStack; // Count of stack slots used (or 0)
+ int m_idxStack; // First stack slot used (or -1)
+ int m_cStack; // Count of stack slots used (or 0)
#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
- EEClass* m_eeClass; // For structs passed in register, it points to the EEClass of the struct
+ EEClass* m_eeClass; // For structs passed in register, it points to the EEClass of the struct
#endif // UNIX_AMD64_ABI && FEATURE_UNIX_AMD64_STRUCT_PASSING
+#if defined(_TARGET_ARM64_)
+ bool m_isSinglePrecision; // For determining if HFA is single or double
+ // precision
+#endif // defined(_TARGET_ARM64_)
+
#if defined(_TARGET_ARM_)
BOOL m_fRequires64BitAlignment; // True if the argument should always be aligned (in registers or on the stack
#endif
@@ -70,6 +75,9 @@ struct ArgLocDesc
#if defined(_TARGET_ARM_)
m_fRequires64BitAlignment = FALSE;
#endif
+#if defined(_TARGET_ARM64_)
+ m_isSinglePrecision = FALSE;
+#endif // defined(_TARGET_ARM64_)
#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
m_eeClass = NULL;
#endif
@@ -490,7 +498,7 @@ public:
ArgLocDesc* GetArgLocDescForStructInRegs()
{
-#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#if (defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)) || defined (_TARGET_ARM64_)
return m_hasArgLocDescForStructInRegs ? &m_argLocDescForStructInRegs : NULL;
#else
return NULL;
@@ -556,7 +564,10 @@ public:
if (!m_argTypeHandle.IsNull() && m_argTypeHandle.IsHFA())
{
CorElementType type = m_argTypeHandle.GetHFAType();
- pLoc->m_cFloatReg = (type == ELEMENT_TYPE_R4)? GetArgSize()/sizeof(float): GetArgSize()/sizeof(double);
+ bool isFloatType = (type == ELEMENT_TYPE_R4);
+
+ pLoc->m_cFloatReg = isFloatType ? GetArgSize()/sizeof(float): GetArgSize()/sizeof(double);
+ pLoc->m_isSinglePrecision = isFloatType;
}
else
{
@@ -639,7 +650,7 @@ protected:
CorElementType m_argType;
int m_argSize;
TypeHandle m_argTypeHandle;
-#if defined(_TARGET_AMD64_) && defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#if (defined(_TARGET_AMD64_) && defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)) || defined(_TARGET_ARM64_)
ArgLocDesc m_argLocDescForStructInRegs;
bool m_hasArgLocDescForStructInRegs;
#endif // _TARGET_AMD64_ && UNIX_AMD64_ABI && FEATURE_UNIX_AMD64_STRUCT_PASSING
@@ -1103,7 +1114,9 @@ int ArgIteratorTemplate<ARGITERATOR_BASE>::GetNextOffset()
// Handle HFAs: packed structures of 1-4 floats or doubles that are passed in FP argument
// registers if possible.
if (thValueType.IsHFA())
+ {
fFloatingPoint = true;
+ }
#endif
break;
@@ -1255,7 +1268,17 @@ int ArgIteratorTemplate<ARGITERATOR_BASE>::GetNextOffset()
if (thValueType.IsHFA())
{
CorElementType type = thValueType.GetHFAType();
+ bool isFloatType = (type == ELEMENT_TYPE_R4);
+
cFPRegs = (type == ELEMENT_TYPE_R4)? (argSize/sizeof(float)): (argSize/sizeof(double));
+
+ m_argLocDescForStructInRegs.Init();
+ m_argLocDescForStructInRegs.m_cFloatReg = cFPRegs;
+ m_argLocDescForStructInRegs.m_idxFloatReg = m_idxFPReg;
+
+ m_argLocDescForStructInRegs.m_isSinglePrecision = isFloatType;
+
+ m_hasArgLocDescForStructInRegs = true;
}
else
{