From: sgjesse@chromium.org Date: Fri, 29 Apr 2011 08:50:38 +0000 (+0000) Subject: ARM: Support hardfloat in SCons build and make it a build time setting X-Git-Tag: upstream/4.7.83~19548 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=00bc2db28fa0c8c5ab5624af91227be8b08ee957;p=platform%2Fupstream%2Fv8.git 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 --- diff --git a/SConstruct b/SConstruct index 82b83ceaf..e7a16ad1a 100644 --- a/SConstruct +++ b/SConstruct @@ -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', diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index d523bc4bd..e65c883c9 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -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); diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index f65011d51..de0dac2b5 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -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 { diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h index 93d4f585c..9856716f0 100644 --- a/src/arm/macro-assembler-arm.h +++ b/src/arm/macro-assembler-arm.h @@ -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 diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index 801b63f44..39b88b5dd 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -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 diff --git a/src/arm/simulator-arm.h b/src/arm/simulator-arm.h index fa5466d35..40c9d6de2 100644 --- a/src/arm/simulator-arm.h +++ b/src/arm/simulator-arm.h @@ -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 diff --git a/src/flag-definitions.h b/src/flag-definitions.h index 5c165e220..3b5c087ed 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -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") diff --git a/src/platform-linux.cc b/src/platform-linux.cc index 1ecd8fc81..d857cd905 100644 --- a/src/platform-linux.cc +++ b/src/platform-linux.cc @@ -87,6 +87,25 @@ void OS::Setup() { uint64_t seed = static_cast(TimeCurrentMillis()); srandom(static_cast(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(FUNCTION_ADDR(ArmUsingHardFloatHelper)); + return f() == 1.0; +} #endif // def __arm__ diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc index aacad149d..295482d0c 100644 --- a/src/platform-nullos.cc +++ b/src/platform-nullos.cc @@ -186,6 +186,11 @@ bool OS::ArmCpuHasFeature(CpuFeature feature) { } +bool OS::ArmUsingHardFloat() { + UNIMPLEMENTED(); +} + + bool OS::IsOutsideAllocatedSpace(void* address) { UNIMPLEMENTED(); return false; diff --git a/src/platform.h b/src/platform.h index fc417ef38..725008a78 100644 --- a/src/platform.h +++ b/src/platform.h @@ -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); diff --git a/tools/test.py b/tools/test.py index fb0939170..c1840bb42 100755 --- a/tools/test.py +++ b/tools/test.py @@ -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