mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 20:41:24 +00:00
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:
parent
2115a4ffa8
commit
0c562fdd16
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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': {
|
||||
|
|
Loading…
Reference in a new issue