diff options
author | Carol Eidt <carol.eidt@microsoft.com> | 2016-07-13 15:44:44 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-13 15:44:44 -0700 |
commit | 1a685cb47e0335ff3f7cd577cb8f0ba6ccbb8947 (patch) | |
tree | 25485d4ce0fd698794eb5b95c62f23d09399c80d /src | |
parent | d1770839b1ab1a2dc2922c9567559cae295e61b6 (diff) | |
parent | ba66eeab4b8306ac11feb19d09c19fd2d8e5aa95 (diff) | |
download | coreclr-1a685cb47e0335ff3f7cd577cb8f0ba6ccbb8947.tar.gz coreclr-1a685cb47e0335ff3f7cd577cb8f0ba6ccbb8947.tar.bz2 coreclr-1a685cb47e0335ff3f7cd577cb8f0ba6ccbb8947.zip |
Merge pull request #6182 from wateret/fix-6051
[ARM-softfp/Linux] Get precise type for struct
Diffstat (limited to 'src')
-rw-r--r-- | src/jit/compiler.cpp | 52 | ||||
-rw-r--r-- | src/jit/compiler.h | 4 | ||||
-rw-r--r-- | src/jit/morph.cpp | 4 |
3 files changed, 59 insertions, 1 deletions
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp index b7b332598f..04c90d78af 100644 --- a/src/jit/compiler.cpp +++ b/src/jit/compiler.cpp @@ -447,6 +447,49 @@ void Compiler::getStructGcPtrsFromOp(GenTreePtr op, BYTE *gcPtrsOut) } #endif // FEATURE_MULTIREG_ARGS +#ifdef ARM_SOFTFP +//--------------------------------------------------------------------------- +// IsSingleFloat32Struct: +// Check if the given struct type contains only one float32 value type +// +// Arguments: +// clsHnd - the handle for the struct type +// +// Return Value: +// true if the given struct type contains only one float32 value type, +// false otherwise. +// + +bool Compiler::isSingleFloat32Struct(CORINFO_CLASS_HANDLE clsHnd) +{ + for (;;) + { + // all of class chain must be of value type and must have only one field + if (!info.compCompHnd->isValueClass(clsHnd) && + info.compCompHnd->getClassNumInstanceFields(clsHnd) != 1) + { + return false; + } + + CORINFO_CLASS_HANDLE* pClsHnd = &clsHnd; + CORINFO_FIELD_HANDLE fldHnd = info.compCompHnd->getFieldInClass(clsHnd, 0); + CorInfoType fieldType = info.compCompHnd->getFieldType(fldHnd, pClsHnd); + + switch (fieldType) + { + case CORINFO_TYPE_VALUECLASS: + clsHnd = *pClsHnd; + break; + + case CORINFO_TYPE_FLOAT: + return true; + + default: + return false; + } + } +} +#endif // ARM_SOFTFP //----------------------------------------------------------------------------- // getPrimitiveTypeForStruct: @@ -521,8 +564,15 @@ var_types Compiler::getPrimitiveTypeForStruct( unsigned structSize, #endif // _TARGET_XARCH_ #endif // _TARGET_64BIT_ + case TARGET_POINTER_SIZE: +#ifdef ARM_SOFTFP + // For ARM_SOFTFP, HFA is unsupported so we need to check in another way + // This matters only for size-4 struct cause bigger structs would be processed with RetBuf + if (isSingleFloat32Struct(clsHnd)) +#else // !ARM_SOFTFP if (IsHfa(clsHnd)) +#endif // ARM_SOFTFP { #ifdef _TARGET_64BIT_ var_types hfaType = GetHfaType(clsHnd); @@ -547,7 +597,7 @@ var_types Compiler::getPrimitiveTypeForStruct( unsigned structSize, #else // a 32BIT target // A structSize of 4 with IsHfa, it must be an HFA of one float useType = TYP_FLOAT; -#endif +#endif // _TARGET_64BIT_ } else { diff --git a/src/jit/compiler.h b/src/jit/compiler.h index 26f028508d..c96defb9a7 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -1443,6 +1443,10 @@ public: GenTreePtr impAssignMultiRegTypeToVar(GenTreePtr op, CORINFO_CLASS_HANDLE hClass); #endif // FEATURE_MULTIREG_RET +#ifdef ARM_SOFTFP + bool isSingleFloat32Struct(CORINFO_CLASS_HANDLE hClass); +#endif // ARM_SOFTFP + //------------------------------------------------------------------------- // Functions to handle homogeneous floating-point aggregates (HFAs) in ARM. // HFAs are one to four element structs where each element is the same diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 12ee7791e3..c65b51b251 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -16010,7 +16010,11 @@ Compiler::fgWalkResult Compiler::fgMorphLocalField(GenTreePtr tree, fgWalkD tree->gtLclFld.SetLclNum(fieldLclIndex); // We need to keep the types 'compatible'. If we can switch back to a GT_LCL_VAR +#ifdef ARM_SOFTFP + assert(varTypeIsIntegralOrI(tree->TypeGet()) || varTypeIsFloating(tree->TypeGet())); +#else assert(varTypeIsIntegralOrI(tree->TypeGet())); +#endif if (varTypeCanReg(fldVarDsc->TypeGet())) { // If the type is integer-ish, then we can use it as-is |