summaryrefslogtreecommitdiff
path: root/src/jit/regalloc.cpp
diff options
context:
space:
mode:
authorBrian Sullivan <briansul@microsoft.com>2016-05-24 14:03:49 -0700
committerBrian Sullivan <briansul@microsoft.com>2016-05-25 21:00:21 -0700
commitb2efe59bec6e0b70b2ede2dc0301a790d465e6a4 (patch)
tree278183de495c72a4e1adf2e1661c978909ab56af /src/jit/regalloc.cpp
parent049961ad651dda73a2578f37df5b1d5e88345d0a (diff)
downloadcoreclr-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.cpp33
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;
}