summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2016-04-06 13:38:05 -0700
committerBruce Forstall <brucefo@microsoft.com>2016-04-06 13:38:05 -0700
commit0a88545e68de8177efa1ae911d4a6948defd68c6 (patch)
treefc56311c5fa47844ddc72287281c44b5cc49c177 /src/jit
parentae674a6e0550fee3884e536d8aeeaa83b8155d63 (diff)
parent40fc77eb6e799ecb7afdaa912900f3463650781e (diff)
downloadcoreclr-0a88545e68de8177efa1ae911d4a6948defd68c6.tar.gz
coreclr-0a88545e68de8177efa1ae911d4a6948defd68c6.tar.bz2
coreclr-0a88545e68de8177efa1ae911d4a6948defd68c6.zip
Merge pull request #3929 from papaslavik/arm_softfp
Arm softfp For Issue #3785
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/CMakeLists.txt4
-rw-r--r--src/jit/codegencommon.cpp4
-rw-r--r--src/jit/codegenlegacy.cpp2
-rw-r--r--src/jit/compiler.h6
-rw-r--r--src/jit/compiler.hpp2
-rw-r--r--src/jit/lclvars.cpp10
-rw-r--r--src/jit/morph.cpp6
-rw-r--r--src/jit/regalloc.cpp4
-rw-r--r--src/jit/registerfp.cpp2
9 files changed, 25 insertions, 15 deletions
diff --git a/src/jit/CMakeLists.txt b/src/jit/CMakeLists.txt
index 8990afca47..79351e0861 100644
--- a/src/jit/CMakeLists.txt
+++ b/src/jit/CMakeLists.txt
@@ -11,6 +11,10 @@ if (CLR_CMAKE_PLATFORM_ARCH_AMD64)
add_definitions(-DFEATURE_AVX_SUPPORT)
endif (CLR_CMAKE_PLATFORM_ARCH_AMD64)
+if (ARM_SOFTFP)
+ add_definitions(-DARM_SOFTFP)
+endif (ARM_SOFTFP)
+
set( JIT_SOURCES
alloc.cpp
assertionprop.cpp
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index f07bf46aa4..b96f5c0956 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -4150,7 +4150,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg,
(varDsc->lvType == TYP_STRUCT) ||
(varDsc->lvAddrExposed && compiler->info.compIsVarArgs));
#else // LEGACY_BACKEND
- noway_assert(varDsc->lvType == TYP_STRUCT || (varDsc->lvAddrExposed && compiler->info.compIsVarArgs));
+ noway_assert(varDsc->lvType == TYP_STRUCT || (varDsc->lvAddrExposed && (compiler->info.compIsVarArgs || compiler->opts.compUseSoftFP)));
#endif // LEGACY_BACKEND
#endif // !_TARGET_X86_
}
@@ -7449,7 +7449,7 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORIN
emitAttr attr = EA_UNKNOWN;
if (compiler->info.compRetType == TYP_VOID ||
- (!compiler->info.compIsVarArgs && (varTypeIsFloating(compiler->info.compRetType) || compiler->IsHfa(compiler->info.compMethodInfo->args.retTypeClass))))
+ (!compiler->opts.compUseSoftFP && !compiler->info.compIsVarArgs && (varTypeIsFloating(compiler->info.compRetType) || compiler->IsHfa(compiler->info.compMethodInfo->args.retTypeClass))))
{
r0Trashed = false;
}
diff --git a/src/jit/codegenlegacy.cpp b/src/jit/codegenlegacy.cpp
index 8b9f95937d..b5cacc3d91 100644
--- a/src/jit/codegenlegacy.cpp
+++ b/src/jit/codegenlegacy.cpp
@@ -20431,7 +20431,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call,
if (call->gtType == TYP_FLOAT || call->gtType == TYP_DOUBLE)
{
#ifdef _TARGET_ARM_
- if (call->gtCall.IsVarargs())
+ if (call->gtCall.IsVarargs() || compiler->opts.compUseSoftFP)
{
// Result return for vararg methods is in r0, r1, but our callers would
// expect the return in s0, s1 because of floating type. Do the move now.
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 0c18dba75f..b8ad1f540b 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -7583,6 +7583,12 @@ public :
bool compTailCallLoopOpt;
#endif
+#ifdef ARM_SOFTFP
+ static const bool compUseSoftFP = true;
+#else // !ARM_SOFTFP
+ static const bool compUseSoftFP = false;
+#endif
+
GCPollType compGCPollType;
}
opts;
diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp
index cabd6ba8cd..198c8cfa5e 100644
--- a/src/jit/compiler.hpp
+++ b/src/jit/compiler.hpp
@@ -2574,7 +2574,7 @@ inline
var_types Compiler::mangleVarArgsType(var_types type)
{
#ifdef _TARGET_ARMARCH_
- if (info.compIsVarArgs)
+ if (info.compIsVarArgs || opts.compUseSoftFP)
{
switch (type) {
case TYP_FLOAT:
diff --git a/src/jit/lclvars.cpp b/src/jit/lclvars.cpp
index e6956cf3cf..3953d04b96 100644
--- a/src/jit/lclvars.cpp
+++ b/src/jit/lclvars.cpp
@@ -136,7 +136,7 @@ void Compiler::lvaInitTypeRef()
{
#ifdef _TARGET_ARM_
// TODO-ARM64-NYI: HFA
- if (!info.compIsVarArgs && IsHfa(info.compMethodInfo->args.retTypeClass))
+ if (!info.compIsVarArgs && !opts.compUseSoftFP && IsHfa(info.compMethodInfo->args.retTypeClass))
{
info.compRetNativeType = TYP_STRUCT;
}
@@ -570,13 +570,13 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo * varDscInfo)
#ifdef _TARGET_ARM_
var_types hfaType = (varTypeIsStruct(argType)) ? GetHfaType(typeHnd) : TYP_UNDEF;
- bool isHfaArg = !info.compIsVarArgs && varTypeIsFloating(hfaType);
+ bool isHfaArg = !info.compIsVarArgs && !opts.compUseSoftFP && varTypeIsFloating(hfaType);
// On ARM we pass the first 4 words of integer arguments and non-HFA structs in registers.
// But we pre-spill user arguments in varargs methods and structs.
//
unsigned cAlign;
- bool preSpill = info.compIsVarArgs;
+ bool preSpill = info.compIsVarArgs || opts.compUseSoftFP;
switch (argType)
{
@@ -912,7 +912,7 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo * varDscInfo)
#else // !FEATURE_UNIX_AMD64_STRUCT_PASSING
compArgSize += argSize;
#endif // !FEATURE_UNIX_AMD64_STRUCT_PASSING
- if (info.compIsVarArgs)
+ if (info.compIsVarArgs || opts.compUseSoftFP)
{
#if defined(_TARGET_X86_)
varDsc->lvStkOffs = compArgSize;
@@ -4606,7 +4606,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, unsigned argSize
if (!compIsProfilerHookNeeded())
#endif
{
- bool cond = (info.compIsVarArgs &&
+ bool cond = ((info.compIsVarArgs || opts.compUseSoftFP) &&
// Does cur stk arg require double alignment?
((varDsc->lvType == TYP_STRUCT && varDsc->lvStructDoubleAlign) ||
(varDsc->lvType == TYP_DOUBLE) ||
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp
index cc642ec433..444be6b018 100644
--- a/src/jit/morph.cpp
+++ b/src/jit/morph.cpp
@@ -2799,8 +2799,9 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
// this can't be a struct.
assert(argx->gtType != TYP_STRUCT);
+ // FIXME: Issue #4025 Why do we need floating type for 'this' argument
/* Increment the argument register count and argument index */
- if (!varTypeIsFloating(argx->gtType))
+ if (!varTypeIsFloating(argx->gtType) || opts.compUseSoftFP)
{
intArgRegNum++;
#if defined(_TARGET_AMD64_) && !defined(UNIX_AMD64_ABI)
@@ -2950,7 +2951,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
#ifdef _TARGET_ARM_
bool passUsingIntRegs;
-
if (lateArgsComputed)
{
passUsingFloatRegs = isValidFloatArgReg(argEntry->regNum);
@@ -2958,7 +2958,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
}
else
{
- passUsingFloatRegs = !callIsVararg && (isHfaArg || varTypeIsFloating(argx));
+ passUsingFloatRegs = !callIsVararg && (isHfaArg || varTypeIsFloating(argx)) && !opts.compUseSoftFP;
passUsingIntRegs = passUsingFloatRegs ? false : (intArgRegNum < MAX_REG_ARG);
}
diff --git a/src/jit/regalloc.cpp b/src/jit/regalloc.cpp
index 1675f2c018..89f2955724 100644
--- a/src/jit/regalloc.cpp
+++ b/src/jit/regalloc.cpp
@@ -595,7 +595,7 @@ void Compiler::raSetupArgMasks(RegState *regState)
continue;
// only process args that apply to the current register file
- if ((argDsc->IsFloatRegType() && !info.compIsVarArgs) != regState->rsIsFloat)
+ if ((argDsc->IsFloatRegType() && !info.compIsVarArgs && !opts.compUseSoftFP) != regState->rsIsFloat)
{
continue;
}
@@ -691,7 +691,7 @@ regNumber Compiler::raUpdateRegStateForArg(RegState *regState, LclVarDsc *ar
#ifdef _TARGET_ARM_
if (argDsc->lvType == TYP_DOUBLE)
{
- if (info.compIsVarArgs)
+ if (info.compIsVarArgs || opts.compUseSoftFP)
{
assert((inArgReg == REG_R0) || (inArgReg == REG_R2));
assert(!regState->rsIsFloat);
diff --git a/src/jit/registerfp.cpp b/src/jit/registerfp.cpp
index 7779cfe8c2..9b7f651d41 100644
--- a/src/jit/registerfp.cpp
+++ b/src/jit/registerfp.cpp
@@ -229,7 +229,7 @@ void CodeGen::genFloatSimple(GenTree *tree, RegSet::RegisterPreference *pref)
genCodeForTreeFloat(op1, pref);
inst_RV_TT(ins_FloatConv(tree->TypeGet(), op1->TypeGet()), REG_FLOATRET, op1);
- if (compiler->info.compIsVarArgs)
+ if (compiler->info.compIsVarArgs || compiler->opts.compUseSoftFP)
{
if (tree->TypeGet() == TYP_FLOAT)
{