diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 73e6f196cae11..b0f6aab8e30e3 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -12641,7 +12641,23 @@ void CodeGen::genCodeForBitCast(GenTreeOp* treeNode) } else { - genBitCast(targetType, targetReg, op1->TypeGet(), op1->GetRegNum()); +#ifdef TARGET_ARM + if (compiler->opts.compUseSoftFP && (targetType == TYP_LONG)) + { + // This is a special arm-softFP case when a TYP_LONG node was introduced during lowering + // for a call argument, so it was not handled by decomposelongs phase as all other TYP_LONG nodes. + // Example foo(double LclVar V01), LclVar V01 has to be passed in general registers r0, r1, + // so lowering will add `BITCAST long(LclVar double V01)` and codegen has to support it here. + const regNumber srcReg = op1->GetRegNum(); + const regNumber otherReg = treeNode->AsMultiRegOp()->gtOtherReg; + assert(otherReg != REG_NA); + inst_RV_RV_RV(INS_vmov_d2i, targetReg, otherReg, srcReg, EA_8BYTE); + } + else +#endif // TARGET_ARM + { + genBitCast(targetType, targetReg, op1->TypeGet(), op1->GetRegNum()); + } } genProduceReg(treeNode); } diff --git a/src/coreclr/jit/instr.cpp b/src/coreclr/jit/instr.cpp index 752626f20184d..ac37c4c86b103 100644 --- a/src/coreclr/jit/instr.cpp +++ b/src/coreclr/jit/instr.cpp @@ -1911,15 +1911,19 @@ instruction CodeGen::ins_Copy(regNumber srcReg, var_types dstType) return INS_mov; } #elif defined(TARGET_ARM) - // No SIMD support yet + // No SIMD support yet. assert(!varTypeIsSIMD(dstType)); if (dstIsFloatReg) { - return (dstType == TYP_DOUBLE) ? INS_vmov_i2d : INS_vmov_i2f; + // Can't have LONG in a register. + assert(dstType == TYP_FLOAT); + return INS_vmov_i2f; } else { - return (dstType == TYP_LONG) ? INS_vmov_d2i : INS_vmov_f2i; + // Can't have LONG in a register. + assert(dstType == TYP_INT); + return INS_vmov_f2i; } #else // TARGET* #error "Unknown TARGET" diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index c5b6a75ef2f17..a328206151a00 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -1507,6 +1507,11 @@ GenTree* Lowering::LowerFloatArgReg(GenTree* arg, regNumber regNum) #ifdef TARGET_ARM if (floatType == TYP_DOUBLE) { + // A special case when we introduce TYP_LONG + // during lowering for arm32 softFP to pass double + // in int registers. + assert(comp->opts.compUseSoftFP); + regNumber nextReg = REG_NEXT(regNum); intArg->AsMultiRegOp()->gtOtherReg = nextReg; }