summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian Sullivan <briansul@microsoft.com>2016-03-21 16:11:43 -0700
committerBrian Sullivan <briansul@microsoft.com>2016-03-21 16:11:43 -0700
commitf11845dae37f27023b23f0935129f5be6e76768e (patch)
treec6544bae8ff41a51098f5cfc6fb4604e848b18ba /src
parent0dbc5078010500386c1ddef0c0c452e9c94dc85a (diff)
parent7f2ec614cf710155850ddb0d37058de6b5b546a9 (diff)
downloadcoreclr-f11845dae37f27023b23f0935129f5be6e76768e.tar.gz
coreclr-f11845dae37f27023b23f0935129f5be6e76768e.tar.bz2
coreclr-f11845dae37f27023b23f0935129f5be6e76768e.zip
Merge pull request #3815 from briansull/struct16-fp-args
Fixes issue 3750 - passing fp arguments
Diffstat (limited to 'src')
-rw-r--r--src/jit/morph.cpp32
1 files changed, 21 insertions, 11 deletions
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp
index 23ee8f3ffc..fb9585a38c 100644
--- a/src/jit/morph.cpp
+++ b/src/jit/morph.cpp
@@ -2587,13 +2587,11 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
regMaskTP fltArgSkippedRegMask = RBM_NONE;
#endif
-#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
- // On x64, every argument takes up exactly 1 slot, regardless of type.
- // Only the first 4 slots are enregistered.
- const unsigned maxRegArgs = MAX_REG_ARG;
-#elif defined(_TARGET_X86_)
- unsigned maxRegArgs = MAX_REG_ARG;
-#endif
+#if defined(_TARGET_X86_)
+ unsigned maxRegArgs = MAX_REG_ARG; // X86: non-const, must be calculated
+#else
+ const unsigned maxRegArgs = MAX_REG_ARG; // other arch: fixed constant number
+#endif
unsigned argSlots = 0;
unsigned nonRegPassedStructSlots = 0;
@@ -3124,12 +3122,12 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
{
size = 1; // Large structs are passed by reference (to a copy)
}
- // TODO-ARM64-NYI: There are some additional rules for size=2 structs,
+ // Note that there are some additional rules for size=2 structs,
// (i.e they cannot be split betwen registers and the stack)
}
else
{
- size = 1; // On ARM64, all primitives fit in a single (64-bit) 'slot'
+ size = 1; // On ARM64, all primitive types fit in a single (64-bit) 'slot'
}
#elif defined(_TARGET_ARM_)
if (isStructArg)
@@ -3415,7 +3413,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
}
}
- // This size has now been computed
+ // The 'size' value has now must have been set. (the original value of zero is an invalid value)
assert(size != 0);
//
@@ -3468,7 +3466,19 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
{
isRegArg = intArgRegNum < MAX_REG_ARG;
}
-#else // _TARGET_ARM_
+#elif _TARGET_ARM64_
+ if (passUsingFloatRegs)
+ {
+ // Check if the last register needed is still in the fp argument register range.
+ isRegArg = (nextFltArgRegNum + (size - 1)) < MAX_FLOAT_REG_ARG;
+ }
+ else
+ {
+ // Check if the last register needed is still in the int argument register range.
+ isRegArg = (intArgRegNum + (size - 1)) < maxRegArgs;
+ }
+#else // not _TARGET_ARM_ or _TARGET_ARM64_
+
#if defined(UNIX_AMD64_ABI)
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)