[RyuJIT/ARM32] Implement storing multi-reg/HFA return value at caller (dotnet/coreclr...
authorHyung-Kyu Choi <hk0110.choi@samsung.com>
Tue, 20 Jun 2017 21:09:22 +0000 (06:09 +0900)
committerBruce Forstall <brucefo@microsoft.com>
Tue, 20 Jun 2017 21:09:22 +0000 (14:09 -0700)
* [RyuJIT/ARM32] Initial implementation of multi-reg return

Signed-off-by: Hyung-Kyu Choi <hk0110.choi@samsung.com>
* [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 <hk0110.choi@samsung.com>
* Update comments for GetABIReturnReg() and GetABIReturnRegs()

- Remove and update obsolete comment
- Fix format

Signed-off-by: Hyung-Kyu Choi <hk0110.choi@samsung.com>
Commit migrated from https://github.com/dotnet/coreclr/commit/cf63336cbc2597801d62e399be6bdba8938d1034

src/coreclr/src/jit/codegenarmarch.cpp
src/coreclr/src/jit/gentree.cpp

index 028dedd..d70fbb4 100644 (file)
@@ -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));
index 6a163f6..9e09ebc 100644 (file)
@@ -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()
 {