Commit 00bc2db2 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

ARM: Support hardfloat in SCons build and make it a build time setting

Add option armeabi to the SCons build for selecting the floating point variant to use. Also add externally defined CCFLAGS environment for all targets. Run test.py with option -S armeabi=hardfloat to test with hardfloat enabled.

Make selecting hardfloat EABI variant a build-time option instead of a runtime option.

Add a simple check of the EABI variant during V8 initialization to exit if the compilation was not configured correctly. The reason for this is that GCC does not provide a compile time symbol defining the EABI variant. This check is not fool-proof as it cannot check the compilation configuration used for the snapshot if any.

R=karlklose@chromium.org, erik.corry@gmail.com

BUG=none
TEST=none

Review URL: http://codereview.chromium.org//6905098

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7715 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 122133e8
......@@ -154,6 +154,18 @@ LIBRARY_FLAGS = {
},
'unalignedaccesses:off' : {
'CPPDEFINES' : ['CAN_USE_UNALIGNED_ACCESSES=0']
},
'armeabi:softfloat' : {
'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'],
'simulator:none': {
'CCFLAGS': ['-mfloat-abi=softfp'],
}
},
'armeabi:hardfloat' : {
'CPPDEFINES' : ['USE_EABI_HARDFLOAT=1', 'CAN_USE_VFP_INSTRUCTIONS'],
'simulator:none': {
'CCFLAGS': ['-mfloat-abi=hard'],
}
}
},
'simulator:arm': {
......@@ -286,6 +298,11 @@ V8_EXTRA_FLAGS = {
'os:macos': {
'WARNINGFLAGS': ['-pedantic']
},
'arch:arm': {
# This is to silence warnings about ABI changes that some versions of the
# CodeSourcery G++ tool chain produce for each occurrence of varargs.
'WARNINGFLAGS': ['-Wno-abi']
},
'disassembler:on': {
'CPPDEFINES': ['ENABLE_DISASSEMBLER']
}
......@@ -369,7 +386,10 @@ CCTEST_EXTRA_FLAGS = {
},
'gcc': {
'all': {
'LIBPATH': [abspath('.')]
'LIBPATH': [abspath('.')],
'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
'LINKFLAGS': ['$CCFLAGS'],
},
'os:linux': {
'LIBS': ['pthread'],
......@@ -419,8 +439,10 @@ SAMPLE_FLAGS = {
},
'gcc': {
'all': {
'LIBPATH': ['.'],
'CCFLAGS': ['-fno-rtti', '-fno-exceptions']
'LIBPATH': ['.'],
'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
'LINKFLAGS': ['$CCFLAGS'],
},
'os:linux': {
'LIBS': ['pthread'],
......@@ -445,7 +467,19 @@ SAMPLE_FLAGS = {
'LIBS': ['winmm', 'ws2_32']
},
'arch:arm': {
'LINKFLAGS': ARM_LINK_FLAGS
'LINKFLAGS': ARM_LINK_FLAGS,
'armeabi:softfloat' : {
'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'],
'simulator:none': {
'CCFLAGS': ['-mfloat-abi=softfp'],
}
},
'armeabi:hardfloat' : {
'CPPDEFINES' : ['USE_EABI_HARDFLOAT=1', 'CAN_USE_VFP_INSTRUCTIONS'],
'simulator:none': {
'CCFLAGS': ['-mfloat-abi=hard'],
}
}
},
'arch:ia32': {
'CCFLAGS': ['-m32'],
......@@ -547,14 +581,26 @@ PREPARSER_FLAGS = {
},
'gcc': {
'all': {
'LIBPATH': ['.'],
'CCFLAGS': ['-fno-rtti', '-fno-exceptions']
'LIBPATH': ['.'],
'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
'LINKFLAGS': ['$CCFLAGS'],
},
'os:win32': {
'LIBS': ['winmm', 'ws2_32']
},
'arch:arm': {
'LINKFLAGS': ARM_LINK_FLAGS
'LINKFLAGS': ARM_LINK_FLAGS,
'armeabi:softfloat' : {
'simulator:none': {
'CCFLAGS': ['-mfloat-abi=softfp'],
}
},
'armeabi:hardfloat' : {
'simulator:none': {
'CCFLAGS': ['-mfloat-abi=hard'],
}
}
},
'arch:ia32': {
'CCFLAGS': ['-m32'],
......@@ -674,6 +720,11 @@ PREPARSER_FLAGS = {
D8_FLAGS = {
'gcc': {
'all': {
'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'],
'LINKFLAGS': ['$CCFLAGS'],
},
'console:readline': {
'LIBS': ['readline']
},
......@@ -910,6 +961,11 @@ SIMPLE_OPTIONS = {
'default': 'off',
'help': 'select profile guided optimization variant',
},
'armeabi': {
'values': ['hardfloat', 'softfloat'],
'default': 'softfloat',
'help': 'generate calling conventiont according to selected ARM EABI variant'
},
'mipsabi': {
'values': ['hardfloat', 'softfloat', 'none'],
'default': 'hardfloat',
......
......@@ -839,8 +839,7 @@ void FloatingPointHelper::CallCCodeForDoubleOperation(
// through pop(pc) below.
__ push(lr);
__ PrepareCallCFunction(0, 2, scratch);
if (FLAG_hardfloat) {
ASSERT(CpuFeatures::IsSupported(VFP3));
if (masm->use_eabi_hardfloat()) {
CpuFeatures::Scope scope(VFP3);
__ vmov(d0, r0, r1);
__ vmov(d1, r2, r3);
......@@ -850,7 +849,7 @@ void FloatingPointHelper::CallCCodeForDoubleOperation(
0, 2);
// Store answer in the overwritable heap number. Double returned in
// registers r0 and r1 or in d0.
if (FLAG_hardfloat) {
if (masm->use_eabi_hardfloat()) {
CpuFeatures::Scope scope(VFP3);
__ vstr(d0,
FieldMemOperand(heap_number_result, HeapNumber::kValueOffset));
......@@ -1200,8 +1199,7 @@ static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm,
// Call C routine that may not cause GC or other trouble.
__ push(lr);
__ PrepareCallCFunction(0, 2, r5);
if (FLAG_hardfloat) {
ASSERT(CpuFeatures::IsSupported(VFP3));
if (masm->use_eabi_hardfloat()) {
CpuFeatures::Scope scope(VFP3);
__ vmov(d0, r0, r1);
__ vmov(d1, r2, r3);
......@@ -3158,7 +3156,7 @@ void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm,
__ push(lr);
__ PrepareCallCFunction(0, 1, scratch);
if (FLAG_hardfloat) {
if (masm->use_eabi_hardfloat()) {
__ vmov(d0, d2);
} else {
__ vmov(r0, r1, d2);
......
......@@ -872,7 +872,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
}
void MacroAssembler::GetCFunctionDoubleResult(const DoubleRegister dst) {
if (FLAG_hardfloat) {
if (use_eabi_hardfloat()) {
Move(dst, d0);
} else {
vmov(dst, r0, r1);
......@@ -2835,7 +2835,7 @@ static const int kRegisterPassedArguments = 4;
int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments,
int num_double_arguments) {
int stack_passed_words = 0;
if (FLAG_hardfloat) {
if (use_eabi_hardfloat()) {
// In the hard floating point calling convention, we can use
// all double registers to pass doubles.
if (num_double_arguments > DoubleRegister::kNumRegisters) {
......@@ -2882,7 +2882,7 @@ void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg) {
if (FLAG_hardfloat) {
if (use_eabi_hardfloat()) {
Move(d0, dreg);
} else {
vmov(r0, r1, dreg);
......@@ -2892,7 +2892,7 @@ void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg) {
void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg1,
DoubleRegister dreg2) {
if (FLAG_hardfloat) {
if (use_eabi_hardfloat()) {
if (dreg2.is(d0)) {
ASSERT(!dreg1.is(d1));
Move(d1, dreg2);
......@@ -2910,7 +2910,7 @@ void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg1,
void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg,
Register reg) {
if (FLAG_hardfloat) {
if (use_eabi_hardfloat()) {
Move(d0, dreg);
Move(r0, reg);
} else {
......
......@@ -855,6 +855,15 @@ class MacroAssembler: public Assembler {
void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
bool allow_stub_calls() { return allow_stub_calls_; }
// EABI variant for double arguments in use.
bool use_eabi_hardfloat() {
#if USE_EABI_HARDFLOAT
return true;
#else
return false;
#endif
}
// ---------------------------------------------------------------------------
// Number utilities
......
......@@ -1012,7 +1012,7 @@ double Simulator::get_double_from_d_register(int dreg) {
// For use in calls that take two double values, constructed either
// from r0-r3 or d0 and d1.
void Simulator::GetFpArgs(double* x, double* y) {
if (FLAG_hardfloat) {
if (use_eabi_hardfloat()) {
*x = vfp_register[0];
*y = vfp_register[1];
} else {
......@@ -1031,7 +1031,7 @@ void Simulator::GetFpArgs(double* x, double* y) {
// For use in calls that take one double value, constructed either
// from r0 and r1 or d0.
void Simulator::GetFpArgs(double* x) {
if (FLAG_hardfloat) {
if (use_eabi_hardfloat()) {
*x = vfp_register[0];
} else {
// We use a char buffer to get around the strict-aliasing rules which
......@@ -1047,7 +1047,7 @@ void Simulator::GetFpArgs(double* x) {
// For use in calls that take two double values, constructed either
// from r0-r3 or d0 and d1.
void Simulator::GetFpArgs(double* x, int32_t* y) {
if (FLAG_hardfloat) {
if (use_eabi_hardfloat()) {
*x = vfp_register[0];
*y = registers_[1];
} else {
......@@ -1066,7 +1066,7 @@ void Simulator::GetFpArgs(double* x, int32_t* y) {
// The return value is either in r0/r1 or d0.
void Simulator::SetFpResult(const double& result) {
if (FLAG_hardfloat) {
if (use_eabi_hardfloat()) {
char buffer[2 * sizeof(vfp_register[0])];
memcpy(buffer, &result, sizeof(buffer));
// Copy result to d0.
......@@ -1738,7 +1738,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
(redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
(redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
(redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
if (FLAG_hardfloat) {
if (use_eabi_hardfloat()) {
// With the hard floating point calling convention, double
// arguments are passed in VFP registers. Fetch the arguments
// from there and call the builtin using soft floating point
......
......@@ -200,6 +200,15 @@ class Simulator {
// below (bad_lr, end_sim_pc).
bool has_bad_pc() const;
// EABI variant for double arguments in use.
bool use_eabi_hardfloat() {
#if USE_EABI_HARDFLOAT
return true;
#else
return false;
#endif
}
private:
enum special_values {
// Known bad pc value to ensure that the simulator does not execute
......
......@@ -144,8 +144,6 @@ DEFINE_int(stress_runs, 0, "number of stress runs")
DEFINE_bool(optimize_closures, true, "optimize closures")
// assembler-ia32.cc / assembler-arm.cc / assembler-x64.cc
DEFINE_bool(hardfloat, false,
"use hardware floating point ABI")
DEFINE_bool(debug_code, false,
"generate extra code (assertions) for debugging")
DEFINE_bool(code_comments, false, "emit comments in code disassembly")
......
......@@ -87,6 +87,25 @@ void OS::Setup() {
uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
srandom(static_cast<unsigned int>(seed));
limit_mutex = CreateMutex();
#ifdef __arm__
// When running on ARM hardware check that the EABI used by V8 and
// by the C code is the same.
bool hard_float = OS::ArmUsingHardFloat();
if (hard_float) {
#if !USE_EABI_HARDFLOAT
PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without "
"-DUSE_EABI_HARDFLOAT\n");
exit(1);
#endif
} else {
#if USE_EABI_HARDFLOAT
PrintF("ERROR: Binary not compiled with -mfloat-abi=hard but with "
"-DUSE_EABI_HARDFLOAT\n");
exit(1);
#endif
}
#endif
}
......@@ -142,6 +161,7 @@ static bool CPUInfoContainsString(const char * search_string) {
return false;
}
bool OS::ArmCpuHasFeature(CpuFeature feature) {
const char* search_string = NULL;
// Simple detection of VFP at runtime for Linux.
......@@ -177,6 +197,28 @@ bool OS::ArmCpuHasFeature(CpuFeature feature) {
return false;
}
// Simple helper function to detect whether the C code is compiled with
// option -mfloat-abi=hard. The register d0 is loaded with 1.0 and the register
// pair r0, r1 is loaded with 0.0. If -mfloat-abi=hard is pased to GCC then
// calling this will return 1.0 and otherwise 0.0.
static void ArmUsingHardFloatHelper() {
asm("mov r0, #0");
asm("mov r1, #0");
asm("movt r1, #16368");
asm("vmov d0, r0, r1");
asm("mov r0, #0");
asm("mov r1, #0");
}
bool OS::ArmUsingHardFloat() {
// Cast helper function from returning void to returning double.
typedef double (*F)();
F f = FUNCTION_CAST<F>(FUNCTION_ADDR(ArmUsingHardFloatHelper));
return f() == 1.0;
}
#endif // def __arm__
......
......@@ -186,6 +186,11 @@ bool OS::ArmCpuHasFeature(CpuFeature feature) {
}
bool OS::ArmUsingHardFloat() {
UNIMPLEMENTED();
}
bool OS::IsOutsideAllocatedSpace(void* address) {
UNIMPLEMENTED();
return false;
......
......@@ -294,6 +294,10 @@ class OS {
// Support runtime detection of VFP3 on ARM CPUs.
static bool ArmCpuHasFeature(CpuFeature feature);
// Support runtime detection of whether the hard float option of the
// EABI is used.
static bool ArmUsingHardFloat();
// Support runtime detection of FPU on MIPS CPUs.
static bool MipsCpuHasFeature(CpuFeature feature);
......
......@@ -1229,8 +1229,6 @@ def BuildOptions():
default=1, type="int")
result.add_option("--noprof", help="Disable profiling support",
default=False)
result.add_option("--hardfloat", help="use hardware floating point ABI",
default=False, action="store_true")
return result
......@@ -1273,11 +1271,6 @@ def ProcessOptions(options):
if options.noprof:
options.scons_flags.append("prof=off")
options.scons_flags.append("profilingsupport=off")
if options.hardfloat:
if options.special_command:
options.special_command += " --hardfloat"
else:
options.special_command = "@--hardfloat"
return True
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment