[RyuJIT/armel] Support putting floating-point args
authorHanjoung Lee <hanjoung.lee@samsung.com>
Wed, 7 Jun 2017 10:12:19 +0000 (19:12 +0900)
committerHanjoung Lee <hanjoung.lee@samsung.com>
Thu, 8 Jun 2017 03:04:03 +0000 (12:04 +0900)
- Make Lowering and LSRA be aware of armel argument push convention.
- Implement codegen for GT_COPY that was newly created from `LowerArg()`.
- Only `float` type is supported. (`double` is not supported yet.)

Fix dotnet/coreclr#11928

Commit migrated from https://github.com/dotnet/coreclr/commit/2b3d55acdd920e9bb221830f2c16bff9f14f3ce2

src/coreclr/src/jit/codegenarmarch.cpp
src/coreclr/src/jit/lower.cpp
src/coreclr/src/jit/lsra.cpp
src/coreclr/src/jit/lsraarm.cpp

index dc0503a..4f4bdc5 100644 (file)
@@ -1501,10 +1501,31 @@ void CodeGen::genRegCopy(GenTree* treeNode)
 
     if (varTypeIsFloating(treeNode) != varTypeIsFloating(op1))
     {
-        NYI_ARM("genRegCopy floating point");
 #ifdef _TARGET_ARM64_
         inst_RV_RV(INS_fmov, targetReg, genConsumeReg(op1), targetType);
-#endif // _TARGET_ARM64_
+#else  // !_TARGET_ARM64_
+        if (varTypeIsFloating(treeNode))
+        {
+            NYI_ARM("genRegCopy from 'int' to 'float'");
+        }
+        else
+        {
+            assert(varTypeIsFloating(op1));
+
+            if (op1->TypeGet() == TYP_FLOAT)
+            {
+                inst_RV_RV(INS_vmov_f2i, targetReg, genConsumeReg(op1), targetType);
+            }
+            else
+            {
+                // TODO-Arm-Bug: We cannot assume the second destination be the next of targetReg
+                // since LSRA doesn't know that register is used. So we cannot write code like:
+                //
+                // inst_RV_RV_RV(INS_vmov_d2i, targetReg, REG_NEXT(targetReg), genConsumeReg(op1), EA_8BYTE);
+                NYI_ARM("genRegCopy from 'double' to 'int'+'int'");
+            }
+        }
+#endif // !_TARGET_ARM64_
     }
     else
     {
index 5c46d3d..3ba892c 100644 (file)
@@ -1187,10 +1187,10 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg)
 #endif // !defined(_TARGET_64BIT_)
     {
 
-#ifdef _TARGET_ARM64_
+#ifdef _TARGET_ARMARCH_
         // For vararg call, reg args should be all integer.
         // Insert a copy to move float value to integer register.
-        if (call->IsVarargs() && varTypeIsFloating(type))
+        if ((call->IsVarargs() || comp->opts.compUseSoftFP) && varTypeIsFloating(type))
         {
             var_types  intType = (type == TYP_DOUBLE) ? TYP_LONG : TYP_INT;
             GenTreePtr intArg  = comp->gtNewOperNode(GT_COPY, intType, arg);
index cd21bca..7cbfa51 100644 (file)
@@ -2205,6 +2205,12 @@ void LinearScan::identifyCandidates()
                 {
                     varDsc->lvLRACandidate = 0;
                 }
+#ifdef ARM_SOFTFP
+                if (varDsc->lvIsParam && varDsc->lvIsRegArg)
+                {
+                    type = (type == TYP_DOUBLE) ? TYP_LONG : TYP_INT;
+                }
+#endif // ARM_SOFTFP
                 break;
 #endif // CPU_HAS_FP_SUPPORT
 
@@ -4377,7 +4383,7 @@ void LinearScan::updateRegStateForArg(LclVarDsc* argDsc)
 #ifndef _TARGET_AMD64_
                         && !compiler->info.compIsVarArgs
 #endif
-                        );
+                        && !compiler->opts.compUseSoftFP);
 
         if (argDsc->lvIsHfaRegArg())
         {
@@ -10327,7 +10333,16 @@ void TreeNodeInfo::Initialize(LinearScan* lsra, GenTree* node, LsraLocation loca
     // TODO-Cleanup: get rid of those NOPs.
     if (node->gtRegNum == REG_NA || node->gtOper == GT_NOP)
     {
-        dstCandidates = lsra->allRegs(node->TypeGet());
+#ifdef ARM_SOFTFP
+        if (node->OperGet() == GT_PUTARG_REG)
+        {
+            dstCandidates = lsra->allRegs(TYP_INT);
+        }
+        else
+#endif
+        {
+            dstCandidates = lsra->allRegs(node->TypeGet());
+        }
     }
     else
     {
index e480aa6..275ad1f 100644 (file)
@@ -750,6 +750,7 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
         case GT_SETCC:
         case GT_MEMORYBARRIER:
         case GT_OBJ:
+        case GT_COPY:
             info->dstCount = tree->IsValue() ? 1 : 0;
             if (kind & (GTK_CONST | GTK_LEAF))
             {