For arm, chooses hard vs. soft fp ABI based on compiler.

We have been hard-coding hardfp in the gyp file. This makes
using softfp hard. This change detects hardfp by looking at
a predefined gcc macro, and otherwise uses softfp. This
change also adds a flag to simarm so that we can test softfp.

R=regis@google.com

Review URL: https://codereview.chromium.org//298533002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@36337 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
zra@google.com 2014-05-19 23:13:25 +00:00
parent 2115a4ffa8
commit 0c562fdd16
5 changed files with 98 additions and 90 deletions

View file

@ -27,6 +27,7 @@ DEFINE_FLAG(bool, use_neon, true, "Use neon instructions if supported");
DEFINE_FLAG(bool, sim_use_armv7, true, "Use all ARMv7 instructions");
DEFINE_FLAG(bool, sim_use_armv5te, false, "Restrict to ARMv5TE instructions");
DEFINE_FLAG(bool, sim_use_armv6, false, "Restrict to ARMv6 instructions");
DEFINE_FLAG(bool, sim_use_hardfp, false, "Use the softfp ABI.");
#endif
void CPU::FlushICache(uword start, uword size) {
@ -66,6 +67,7 @@ const char* CPU::Id() {
bool HostCPUFeatures::integer_division_supported_ = false;
bool HostCPUFeatures::vfp_supported_ = false;
bool HostCPUFeatures::neon_supported_ = false;
bool HostCPUFeatures::hardfp_supported_ = false;
const char* HostCPUFeatures::hardware_ = NULL;
ARMVersion HostCPUFeatures::arm_version_ = ARMvUnknown;
#if defined(DEBUG)
@ -109,6 +111,15 @@ void HostCPUFeatures::InitOnce() {
}
neon_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "neon") &&
FLAG_use_vfp && FLAG_use_neon;
// Use the cross-compiler's predefined macros to determine whether we should
// use the hard or soft float ABI.
#if defined(__ARM_PCS_VFP)
hardfp_supported_ = true;
#else
hardfp_supported_ = false;
#endif
#if defined(DEBUG)
initialized_ = true;
#endif
@ -133,13 +144,16 @@ void HostCPUFeatures::InitOnce() {
hardware_ = CpuInfo::GetCpuModel();
vfp_supported_ = FLAG_use_vfp;
neon_supported_ = FLAG_use_vfp && FLAG_use_neon;
integer_division_supported_ = true;
hardfp_supported_ = FLAG_sim_use_hardfp;
if (FLAG_sim_use_armv5te) {
arm_version_ = ARMv5TE;
integer_division_supported_ = false;
} else if (FLAG_sim_use_armv6) {
arm_version_ = ARMv6;
integer_division_supported_ = true;
} else if (FLAG_sim_use_armv7) {
arm_version_ = ARMv7;
integer_division_supported_ = true;
}
#if defined(DEBUG)
initialized_ = true;

View file

@ -45,6 +45,10 @@ class HostCPUFeatures: public AllStatic {
DEBUG_ASSERT(initialized_);
return neon_supported_;
}
static bool hardfp_supported() {
DEBUG_ASSERT(initialized_);
return hardfp_supported_;
}
static ARMVersion arm_version() {
DEBUG_ASSERT(initialized_);
return arm_version_;
@ -74,6 +78,7 @@ class HostCPUFeatures: public AllStatic {
static bool integer_division_supported_;
static bool vfp_supported_;
static bool neon_supported_;
static bool hardfp_supported_;
static ARMVersion arm_version_;
#if defined(DEBUG)
static bool initialized_;
@ -100,6 +105,9 @@ class TargetCPUFeatures : public AllStatic {
static bool neon_supported() {
return HostCPUFeatures::neon_supported();
}
static bool hardfp_supported() {
return HostCPUFeatures::hardfp_supported();
}
static const char* hardware() {
return HostCPUFeatures::hardware();
}

View file

@ -4896,12 +4896,12 @@ LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const {
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
summary->set_in(0, Location::FpuRegisterLocation(Q0));
summary->set_out(0, Location::FpuRegisterLocation(Q0));
#if !defined(ARM_FLOAT_ABI_HARD)
summary->AddTemp(Location::RegisterLocation(R0));
summary->AddTemp(Location::RegisterLocation(R1));
summary->AddTemp(Location::RegisterLocation(R2));
summary->AddTemp(Location::RegisterLocation(R3));
#endif
if (!TargetCPUFeatures::hardfp_supported()) {
summary->AddTemp(Location::RegisterLocation(R0));
summary->AddTemp(Location::RegisterLocation(R1));
summary->AddTemp(Location::RegisterLocation(R2));
summary->AddTemp(Location::RegisterLocation(R3));
}
return summary;
}
ASSERT((kind() == MathUnaryInstr::kSqrt) ||
@ -4928,18 +4928,18 @@ void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
} else {
ASSERT((kind() == MathUnaryInstr::kSin) ||
(kind() == MathUnaryInstr::kCos));
#if defined(ARM_FLOAT_ABI_HARD)
__ CallRuntime(TargetFunction(), InputCount());
#else
// If we aren't doing "hardfp", then we have to move the double arguments
// to the integer registers, and take the results from the integer
// registers.
__ vmovrrd(R0, R1, D0);
__ vmovrrd(R2, R3, D1);
__ CallRuntime(TargetFunction(), InputCount());
__ vmovdrr(D0, R0, R1);
__ vmovdrr(D1, R2, R3);
#endif
if (TargetCPUFeatures::hardfp_supported()) {
__ CallRuntime(TargetFunction(), InputCount());
} else {
// If we aren't doing "hardfp", then we have to move the double arguments
// to the integer registers, and take the results from the integer
// registers.
__ vmovrrd(R0, R1, D0);
__ vmovrrd(R2, R3, D1);
__ CallRuntime(TargetFunction(), InputCount());
__ vmovdrr(D0, R0, R1);
__ vmovdrr(D1, R2, R3);
}
}
}
@ -5244,15 +5244,15 @@ LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
result->AddTemp(Location::RegisterLocation(R2));
}
#if !defined(ARM_FLOAT_ABI_HARD)
result->AddTemp(Location::RegisterLocation(R0));
result->AddTemp(Location::RegisterLocation(R1));
// Check if R2 is already added.
if (recognized_kind() != MethodRecognizer::kMathDoublePow) {
result->AddTemp(Location::RegisterLocation(R2));
if (!TargetCPUFeatures::hardfp_supported()) {
result->AddTemp(Location::RegisterLocation(R0));
result->AddTemp(Location::RegisterLocation(R1));
// Check if R2 is already added.
if (recognized_kind() != MethodRecognizer::kMathDoublePow) {
result->AddTemp(Location::RegisterLocation(R2));
}
result->AddTemp(Location::RegisterLocation(R3));
}
result->AddTemp(Location::RegisterLocation(R3));
#endif
result->set_out(0, Location::FpuRegisterLocation(Q0));
return result;
}
@ -5374,18 +5374,18 @@ static void InvokeDoublePow(FlowGraphCompiler* compiler,
// Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1.
__ vmovd(D1, D2);
#if defined(ARM_FLOAT_ABI_HARD)
__ CallRuntime(instr->TargetFunction(), kInputCount);
#else
// If the ABI is not "hardfp", then we have to move the double arguments
// to the integer registers, and take the results from the integer
// registers.
__ vmovrrd(R0, R1, D0);
__ vmovrrd(R2, R3, D1);
__ CallRuntime(instr->TargetFunction(), kInputCount);
__ vmovdrr(D0, R0, R1);
__ vmovdrr(D1, R2, R3);
#endif
if (TargetCPUFeatures::hardfp_supported()) {
__ CallRuntime(instr->TargetFunction(), kInputCount);
} else {
// If the ABI is not "hardfp", then we have to move the double arguments
// to the integer registers, and take the results from the integer
// registers.
__ vmovrrd(R0, R1, D0);
__ vmovrrd(R2, R3, D1);
__ CallRuntime(instr->TargetFunction(), kInputCount);
__ vmovdrr(D0, R0, R1);
__ vmovdrr(D1, R2, R3);
}
__ Bind(&skip_call);
}
@ -5400,18 +5400,18 @@ void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
// Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1.
__ vmovd(D1, D2);
}
#if defined(ARM_FLOAT_ABI_HARD)
__ CallRuntime(TargetFunction(), InputCount());
#else
// If the ABI is not "hardfp", then we have to move the double arguments
// to the integer registers, and take the results from the integer
// registers.
__ vmovrrd(R0, R1, D0);
__ vmovrrd(R2, R3, D1);
__ CallRuntime(TargetFunction(), InputCount());
__ vmovdrr(D0, R0, R1);
__ vmovdrr(D1, R2, R3);
#endif
if (TargetCPUFeatures::hardfp_supported()) {
__ CallRuntime(TargetFunction(), InputCount());
} else {
// If the ABI is not "hardfp", then we have to move the double arguments
// to the integer registers, and take the results from the integer
// registers.
__ vmovrrd(R0, R1, D0);
__ vmovrrd(R2, R3, D1);
__ CallRuntime(TargetFunction(), InputCount());
__ vmovdrr(D0, R0, R1);
__ vmovdrr(D1, R2, R3);
}
}

View file

@ -1458,31 +1458,31 @@ void Simulator::SupervisorCall(Instr* instr) {
(redirection->argument_count() <= 2));
SimulatorLeafFloatRuntimeCall target =
reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external);
#if defined(ARM_FLOAT_ABI_HARD)
// If we're doing "hardfp", the double arguments are already in the
// floating point registers.
double d0 = get_dregister(D0);
double d1 = get_dregister(D1);
d0 = target(d0, d1);
set_dregister(D0, d0);
#else
// If we're not doing "hardfp", we must be doing "soft" or "softfp",
// So take the double arguments from the integer registers.
uint32_t r0 = get_register(R0);
int32_t r1 = get_register(R1);
uint32_t r2 = get_register(R2);
int32_t r3 = get_register(R3);
int64_t a0 = Utils::LowHighTo64Bits(r0, r1);
int64_t a1 = Utils::LowHighTo64Bits(r2, r3);
double d0 = bit_cast<double, int64_t>(a0);
double d1 = bit_cast<double, int64_t>(a1);
d0 = target(d0, d1);
a0 = bit_cast<int64_t, double>(d0);
r0 = Utils::Low32Bits(a0);
r1 = Utils::High32Bits(a0);
set_register(R0, r0);
set_register(R1, r1);
#endif
if (TargetCPUFeatures::hardfp_supported()) {
// If we're doing "hardfp", the double arguments are already in the
// floating point registers.
double d0 = get_dregister(D0);
double d1 = get_dregister(D1);
d0 = target(d0, d1);
set_dregister(D0, d0);
} else {
// If we're not doing "hardfp", we must be doing "soft" or "softfp",
// So take the double arguments from the integer registers.
uint32_t r0 = get_register(R0);
int32_t r1 = get_register(R1);
uint32_t r2 = get_register(R2);
int32_t r3 = get_register(R3);
int64_t a0 = Utils::LowHighTo64Bits(r0, r1);
int64_t a1 = Utils::LowHighTo64Bits(r2, r3);
double d0 = bit_cast<double, int64_t>(a0);
double d1 = bit_cast<double, int64_t>(a1);
d0 = target(d0, d1);
a0 = bit_cast<int64_t, double>(d0);
r0 = Utils::Low32Bits(a0);
r1 = Utils::High32Bits(a0);
set_register(R0, r0);
set_register(R1, r1);
}
} else if (redirection->call_kind() == kBootstrapNativeCall) {
NativeArguments* arguments;
arguments = reinterpret_cast<NativeArguments*>(get_register(R0));

View file

@ -44,18 +44,12 @@
'abstract': 1,
'cflags': [ '-O3', '-m32', '-msse2' ],
'ldflags': [ '-m32', ],
'defines': [
'ARM_FLOAT_ABI_HARD',
],
},
'Dart_Linux_simarm64_Base': {
'abstract': 1,
'cflags': [ '-O3', '-m64', '-msse2' ],
'ldflags': [ '-m64', ],
'defines': [
'ARM64_FLOAT_ABI_HARD',
],
},
# ARM cross-build
@ -69,10 +63,6 @@
'-Wno-psabi', # suppresses va_list warning
'-fno-strict-overflow',
],
'defines': [
# In build.py, we specify the hf compiler.
'ARM_FLOAT_ABI_HARD',
],
}],
['_toolset=="host"', {
'cflags': ['-m32', '-msse2'],
@ -89,10 +79,6 @@
'-Wno-psabi', # suppresses va_list warning
'-fno-strict-overflow',
],
'defines': [
# In build.py, we specify the hf compiler.
'ARM_FLOAT_ABI_HARD',
],
},
'Dart_Linux_simmips_Base': {