From c86376dfac8780a07bd9a836d528e9db5db36453 Mon Sep 17 00:00:00 2001 From: Hyung-Kyu Choi Date: Wed, 21 Jun 2017 06:09:22 +0900 Subject: [PATCH] [RyuJIT/ARM32] Implement storing multi-reg/HFA return value at caller (dotnet/coreclr#12294) * [RyuJIT/ARM32] Initial implementation of multi-reg return Signed-off-by: Hyung-Kyu Choi * [RyuJIT/ARM32] Update multi-reg return for ARM32 - Update comment - Remove wrong implementation - Handle HFA struct correctly by consitering type Signed-off-by: Hyung-Kyu Choi * Update comments for GetABIReturnReg() and GetABIReturnRegs() - Remove and update obsolete comment - Fix format Signed-off-by: Hyung-Kyu Choi Commit migrated from https://github.com/dotnet/coreclr/commit/cf63336cbc2597801d62e399be6bdba8938d1034 --- src/coreclr/src/jit/codegenarmarch.cpp | 3 ++- src/coreclr/src/jit/gentree.cpp | 48 +++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index 028dedd..d70fbb4 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -904,7 +904,8 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTreePtr treeNode) #if defined(_TARGET_ARM_) // Longs are returned in two return registers on Arm32. - assert(varTypeIsLong(treeNode)); + // Structs are returned in four registers on ARM32 and HFAs. + assert(varTypeIsLong(treeNode) || varTypeIsStruct(treeNode)); #elif defined(_TARGET_ARM64_) // Structs of size >=9 and <=16 are returned in two return registers on ARM64 and HFAs. assert(varTypeIsStruct(treeNode)); diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 6a163f6..9e09ebc 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -16928,12 +16928,9 @@ void ReturnTypeDesc::InitializeLongReturnType(Compiler* comp) // Returns ith return register as per target ABI. // // Notes: -// Right now this is implemented only for x64 Unix -// and yet to be implemented for other multi-reg return -// targets (Arm64/Arm32/x86). +// x86 and ARM return long in multiple registers. +// ARM and ARM64 return HFA struct in multiple registers. // -// TODO-ARM: Implement this routine to support HFA returns. -// TODO-X86: Implement this routine to support long returns. regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx) { unsigned count = GetReturnRegCount(); @@ -16986,7 +16983,7 @@ regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx) } } -#elif defined(_TARGET_X86_) || defined(_TARGET_ARM_) +#elif defined(_TARGET_X86_) if (idx == 0) { @@ -16997,6 +16994,38 @@ regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx) resultReg = REG_LNGRET_HI; } +#elif defined(_TARGET_ARM_) + + var_types regType = GetReturnRegType(idx); + if (varTypeIsIntegralOrI(regType)) + { + // Ints are returned in one return register. + // Longs are returned in two return registers. + if (idx == 0) + { + resultReg = REG_LNGRET_LO; + } + else if (idx == 1) + { + resultReg = REG_LNGRET_HI; + } + } + else + { + // Floats are returned in one return register (f0). + // Doubles are returned in one return register (d0). + // Structs are returned in four registers with HFAs. + assert(idx < MAX_RET_REG_COUNT); // Up to 4 return registers for HFA's + if (regType == TYP_DOUBLE) + { + resultReg = (regNumber)((unsigned)(REG_FLOATRET) + idx * 2); // d0, d1, d2 or d3 + } + else + { + resultReg = (regNumber)((unsigned)(REG_FLOATRET) + idx); // f0, f1, f2 or f3 + } + } + #elif defined(_TARGET_ARM64_) var_types regType = GetReturnRegType(idx); @@ -17027,16 +17056,9 @@ regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx) // reg mask of return registers in which the return type is returned. // // Note: -// For now this is implemented only for x64 Unix and yet to be implemented -// for other multi-reg return targets (Arm64/Arm32x86). -// // This routine can be used when the caller is not particular about the order // of return registers and wants to know the set of return registers. // -// TODO-ARM: Implement this routine to support HFA returns. -// TODO-ARM64: Implement this routine to support HFA returns. -// TODO-X86: Implement this routine to support long returns. -// // static regMaskTP ReturnTypeDesc::GetABIReturnRegs() { -- 2.7.4