diff options
author | Brian Sullivan <briansul@microsoft.com> | 2016-05-24 14:03:49 -0700 |
---|---|---|
committer | Brian Sullivan <briansul@microsoft.com> | 2016-05-25 21:00:21 -0700 |
commit | b2efe59bec6e0b70b2ede2dc0301a790d465e6a4 (patch) | |
tree | 278183de495c72a4e1adf2e1661c978909ab56af /src/jit/regalloc.cpp | |
parent | 049961ad651dda73a2578f37df5b1d5e88345d0a (diff) | |
download | coreclr-b2efe59bec6e0b70b2ede2dc0301a790d465e6a4.tar.gz coreclr-b2efe59bec6e0b70b2ede2dc0301a790d465e6a4.tar.bz2 coreclr-b2efe59bec6e0b70b2ede2dc0301a790d465e6a4.zip |
Enable HFA support for passing arguments on ARM64
Fixes #4946 ARM64: ABI - Passing HFA struct arguments in floating point registers
We are now passing 24 additional HFA tests and have one test regression
Previously HFA support was enabled on ARM32 using #ifdef _TARGET_ARM_
Now HFA support is enabled for both platform using #ifdef FEATURE_HFA
Note that FEATURE_HFA is a VM defined and enable only for platforms that have HFA support
The VM is responsible for determining if a stuct is a HFA or not
The JIT Calls this method CorInfoType CEEInfo::getHFAType(CORINFO_CLASS_HANDLE hClass) to identify HFA types
Note that when using an AltJit targeting Arm32 or Arm64 we will never see an HFA type
In CodegenArm64.cpp
Method genPutArgStk
Implement passing of HFA structs on the stack
Refactored to handle both 16-byte structs and HFA struct
Track GC types for the 16-byte structs or he floating point types for HFA's
Use ldp when we have a 16-byte struct with no GC pointers
Added asserts to check that we never write past the end of the outgoing arg area
In CodegenCommon.cpp
Method genFnPrologCalleRegArgs
Implement the homing of incoming HDF variables
These are currently homed into a stack based struct as we did for ARM32
Use floating point types and registers when handling HFAs
Added asserts to check that we never write past the end of the stack based struct
Added Dump method for fgArgTabEntry to display how arguments will be passed
Added GetNextSlotNum for fgArgInfo which returns what stack offset we would use for the next stack base argument
Fixed tree dump so that it can print multireg struct arguments
In Morph.cpp
Method ArgsComplete
We currently chose to spill odd sized structs (11,13,14,15 bytes in size) into a GT_LCL_VAR temp so that we don't
need to use more than two instructions to pass a GT_OBJ struct. (Since we cannot read beyond the end of a GT_OBJ struct)
Method fgMorpgArgs
Handle HFAs for multireg and stack arguments
In this method 'size' is the number of registers used when passing an argument in registers
or the number of TARGET_POINTER_SIZE stack slots when passing them on the stack
For HFA this means that 'size' can change if we can't pass them using registers.
Use new Dump method to print out how each argument is passed (what register or what stack slot)
Method fgMorphMultiregStuctArg
Implement the expansion of multireg HFA arguments into GT_LISTs
Refactored to handle both 16-byte structs and HFA struct
Track GC types for the 16-byte structs or he floating point types for HFA's
Changes from code review feedback
Diffstat (limited to 'src/jit/regalloc.cpp')
-rw-r--r-- | src/jit/regalloc.cpp | 33 |
1 files changed, 9 insertions, 24 deletions
diff --git a/src/jit/regalloc.cpp b/src/jit/regalloc.cpp index 4d10ea0274..26f1ac9675 100644 --- a/src/jit/regalloc.cpp +++ b/src/jit/regalloc.cpp @@ -293,13 +293,11 @@ regMaskTP Compiler::genReturnRegForTree(GenTreePtr tree) { var_types type = tree->TypeGet(); -#ifdef _TARGET_ARM_ if (type == TYP_STRUCT && IsHfa(tree)) { - int retSlots = GetHfaSlots(tree); + int retSlots = GetHfaCount(tree); return ((1 << retSlots) - 1) << REG_FLOATRET; } -#endif const static regMaskTP returnMap[TYP_COUNT] = @@ -672,22 +670,6 @@ regNumber Compiler::raUpdateRegStateForArg(RegState *regState, LclVarDsc *ar regState->rsCalleeRegArgMaskLiveIn |= genRegMask(inArgReg); -#if FEATURE_MULTIREG_ARGS -#ifdef _TARGET_ARM64_ - if ((argDsc->lvOtherArgReg != REG_STK) && (argDsc->lvOtherArgReg != REG_NA)) - { - assert(argDsc->lvIsMultiregStruct()); - - regNumber secondArgReg = argDsc->lvOtherArgReg; - - noway_assert(regState->rsIsFloat == false); - noway_assert(genRegMask(secondArgReg) & RBM_ARG_REGS); - - regState->rsCalleeRegArgMaskLiveIn |= genRegMask(secondArgReg); - } -#endif // TARGET_ARM64_ -#endif // FEATURE_MULTIREG_ARGS - #ifdef _TARGET_ARM_ if (argDsc->lvType == TYP_DOUBLE) { @@ -710,12 +692,15 @@ regNumber Compiler::raUpdateRegStateForArg(RegState *regState, LclVarDsc *ar regState->rsCalleeRegArgMaskLiveIn |= genRegMask((regNumber)(inArgReg+1)); } - else if (argDsc->lvType == TYP_STRUCT) +#endif // _TARGET_ARM_ + +#if FEATURE_MULTIREG_ARGS + if (argDsc->lvType == TYP_STRUCT) { - if (argDsc->lvIsHfaRegArg) + if (argDsc->lvIsHfaRegArg()) { assert(regState->rsIsFloat); - unsigned cSlots = GetHfaSlots(argDsc->lvVerTypeInfo.GetClassHandleForValueClass()); + unsigned cSlots = GetHfaCount(argDsc->lvVerTypeInfo.GetClassHandleForValueClass()); for (unsigned i = 1; i < cSlots; i++) { assert(inArgReg + i <= LAST_FP_ARGREG); @@ -732,12 +717,12 @@ regNumber Compiler::raUpdateRegStateForArg(RegState *regState, LclVarDsc *ar { break; } - assert(!regState->rsIsFloat); + assert(regState->rsIsFloat == false); regState->rsCalleeRegArgMaskLiveIn |= genRegMask(nextArgReg); } } } -#endif // _TARGET_ARM_ +#endif // FEATURE_MULTIREG_ARGS return inArgReg; } |