ARM: Support hardfloat in SCons build and make it a build time setting
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 29 Apr 2011 08:50:38 +0000 (08:50 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 29 Apr 2011 08:50:38 +0000 (08:50 +0000)
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

SConstruct
src/arm/code-stubs-arm.cc
src/arm/macro-assembler-arm.cc
src/arm/macro-assembler-arm.h
src/arm/simulator-arm.cc
src/arm/simulator-arm.h
src/flag-definitions.h
src/platform-linux.cc
src/platform-nullos.cc
src/platform.h
tools/test.py

index 82b83ceafa0c0dfd87dff352b5cda7ea63151dbc..e7a16ad1a6950d7eec6ad07646702f3175e956c1 100644 (file)
@@ -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',
index d523bc4bd72c5b8fb4b2e8329c4e7b6de0a18d83..e65c883c905749e4e087f900105edf3b015dca9a 100644 (file)
@@ -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);
index f65011d51d4b434c1b7a309916f2b062db420b5b..de0dac2b549b8cfd3817544431d5f3389cb22c3a 100644 (file)
@@ -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 {
index 93d4f585cf0c3e3710b51e48910fb058be0c8342..9856716f06f1292def92813beadacd0f5922a188 100644 (file)
@@ -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
 
index 801b63f44e7608b9f092bd14d4acc715a215deda..39b88b5dded959b8847481ed2282c0f01bc488de 100644 (file)
@@ -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
index fa5466d35238222490eac731e8a790561515af2f..40c9d6de20c20d52d7ceab9c4d3d93237957b778 100644 (file)
@@ -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
index 5c165e220a99c71bb37e20e2a4b463936b9f6291..3b5c087ed8ce9e75066cb030660be29516a7f441 100644 (file)
@@ -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")
index 1ecd8fc81b08b05a7dad8f2495255ec37db95091..d857cd90590dd74db84a6df1bebc2bffad42f930 100644 (file)
@@ -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__
 
 
index aacad149d68c23b3cec8f683fcf88c0c0a038558..295482d0c5f555a6a1f7c5f296ec0c0ca2c6aea1 100644 (file)
@@ -186,6 +186,11 @@ bool OS::ArmCpuHasFeature(CpuFeature feature) {
 }
 
 
+bool OS::ArmUsingHardFloat() {
+  UNIMPLEMENTED();
+}
+
+
 bool OS::IsOutsideAllocatedSpace(void* address) {
   UNIMPLEMENTED();
   return false;
index fc417ef3823c979463467228fa8d70ef0ac0a7ef..725008a784c531c139117e5c86a35372c5fcc4fa 100644 (file)
@@ -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);
 
index fb0939170605edbacdfba8735239bf1e2a8282c2..c1840bb428803f36ee3727da4b325d0bb487c5bc 100755 (executable)
@@ -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