diff options
author | Brian Sullivan <briansul@microsoft.com> | 2016-03-21 16:11:43 -0700 |
---|---|---|
committer | Brian Sullivan <briansul@microsoft.com> | 2016-03-21 16:11:43 -0700 |
commit | f11845dae37f27023b23f0935129f5be6e76768e (patch) | |
tree | c6544bae8ff41a51098f5cfc6fb4604e848b18ba /src | |
parent | 0dbc5078010500386c1ddef0c0c452e9c94dc85a (diff) | |
parent | 7f2ec614cf710155850ddb0d37058de6b5b546a9 (diff) | |
download | coreclr-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.cpp | 32 |
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) |