Add X32 port into V8
authorhaitao.feng@intel.com <haitao.feng@intel.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 24 Jun 2014 05:27:44 +0000 (05:27 +0000)
committerhaitao.feng@intel.com <haitao.feng@intel.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 24 Jun 2014 05:27:44 +0000 (05:27 +0000)
R=verwaest@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21955 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

12 files changed:
Makefile
build/toolchain.gypi
src/base/build_config.h
src/execution.h
src/gdb-jit.cc
src/globals.h
src/log.cc
src/runtime.cc
src/utils.h
test/cctest/test-lockers.cc
tools/gyp/v8.gyp
tools/run-tests.py

index 9c170f6..8ba931e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -220,7 +220,7 @@ endif
 
 # Architectures and modes to be compiled. Consider these to be internal
 # variables, don't override them (use the targets instead).
-ARCHES = ia32 x64 arm arm64 mips mipsel x87
+ARCHES = ia32 x64 x32 arm arm64 mips mipsel x87
 DEFAULT_ARCHES = ia32 x64 arm
 MODES = release debug optdebug
 DEFAULT_MODES = release debug
index 4e6869b..0852eac 100644 (file)
         },
         'msvs_configuration_platform': 'x64',
       }],  # v8_target_arch=="x64"
+      ['v8_target_arch=="x32"', {
+        'defines': [
+          # x32 port shares the source code with x64 port.
+          'V8_TARGET_ARCH_X64',
+          'V8_TARGET_ARCH_32_BIT',
+        ],
+        'cflags': [
+          '-mx32',
+          # Inhibit warning if long long type is used.
+          '-Wno-long-long',
+        ],
+        'ldflags': [
+          '-mx32',
+        ],
+      }],  # v8_target_arch=="x32"
       ['OS=="win"', {
         'defines': [
           'WIN32',
index e412b92..bdee4b4 100644 (file)
 #define V8_HOST_CAN_READ_UNALIGNED 1
 #else
 #define V8_HOST_ARCH_X64 1
+#if defined(__x86_64__) && !defined(__LP64__)
+#define V8_HOST_ARCH_32_BIT 1
+#else
 #define V8_HOST_ARCH_64_BIT 1
+#endif
 #define V8_HOST_CAN_READ_UNALIGNED 1
 #endif  // __native_client__
 #elif defined(_M_IX86) || defined(__i386__)
 #endif
 #endif
 
+// Determine architecture pointer size.
+#if V8_TARGET_ARCH_IA32
+#define V8_TARGET_ARCH_32_BIT 1
+#elif V8_TARGET_ARCH_X64
+#if !V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_64_BIT
+#if defined(__x86_64__) && !defined(__LP64__)
+#define V8_TARGET_ARCH_32_BIT 1
+#else
+#define V8_TARGET_ARCH_64_BIT 1
+#endif
+#endif
+#elif V8_TARGET_ARCH_ARM
+#define V8_TARGET_ARCH_32_BIT 1
+#elif V8_TARGET_ARCH_ARM64
+#define V8_TARGET_ARCH_64_BIT 1
+#elif V8_TARGET_ARCH_MIPS
+#define V8_TARGET_ARCH_32_BIT 1
+#elif V8_TARGET_ARCH_X87
+#define V8_TARGET_ARCH_32_BIT 1
+#else
+#error Unknown target architecture pointer size
+#endif
+
 // Check for supported combinations of host and target architectures.
 #if V8_TARGET_ARCH_IA32 && !V8_HOST_ARCH_IA32
 #error Target architecture ia32 is only supported on ia32 host
 #endif
-#if V8_TARGET_ARCH_X64 && !V8_HOST_ARCH_X64
+#if (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT && \
+     !(V8_HOST_ARCH_X64 && V8_HOST_ARCH_64_BIT))
 #error Target architecture x64 is only supported on x64 host
 #endif
+#if (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT && \
+     !(V8_HOST_ARCH_X64 && V8_HOST_ARCH_32_BIT))
+#error Target architecture x32 is only supported on x64 host with x32 support
+#endif
 #if (V8_TARGET_ARCH_ARM && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_ARM))
 #error Target architecture arm is only supported on arm and ia32 host
 #endif
index 74d0feb..81fbbb8 100644 (file)
@@ -227,7 +227,7 @@ enum InterruptFlag {
   void EnableInterrupts();
   void DisableInterrupts();
 
-#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
+#if V8_TARGET_ARCH_64_BIT
   static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe);
   static const uintptr_t kIllegalLimit = V8_UINT64_C(0xfffffffffffffff8);
 #else
index 20e3f2a..09da388 100644 (file)
@@ -649,10 +649,11 @@ class ELF BASE_EMBEDDED {
   void WriteHeader(Writer* w) {
     ASSERT(w->position() == 0);
     Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>();
-#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X87
+#if (V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X87 || \
+     (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT))
     const uint8_t ident[16] =
         { 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-#elif V8_TARGET_ARCH_X64
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT
     const uint8_t ident[16] =
         { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 #else
@@ -762,7 +763,8 @@ class ELFSymbol BASE_EMBEDDED {
   Binding binding() const {
     return static_cast<Binding>(info >> 4);
   }
-#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X87
+#if (V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X87 || \
+     (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT))
   struct SerializedLayout {
     SerializedLayout(uint32_t name,
                      uintptr_t value,
@@ -785,7 +787,7 @@ class ELFSymbol BASE_EMBEDDED {
     uint8_t other;
     uint16_t section;
   };
-#elif V8_TARGET_ARCH_X64
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT
   struct SerializedLayout {
     SerializedLayout(uint32_t name,
                      uintptr_t value,
index 595ecc3..742daef 100644 (file)
@@ -138,7 +138,11 @@ const int kInt64Size     = sizeof(int64_t);   // NOLINT
 const int kDoubleSize    = sizeof(double);    // NOLINT
 const int kIntptrSize    = sizeof(intptr_t);  // NOLINT
 const int kPointerSize   = sizeof(void*);     // NOLINT
+#if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
+const int kRegisterSize  = kPointerSize + kPointerSize;
+#else
 const int kRegisterSize  = kPointerSize;
+#endif
 const int kPCOnStackSize = kRegisterSize;
 const int kFPOnStackSize = kRegisterSize;
 
@@ -154,9 +158,15 @@ const size_t kMaximalCodeRangeSize = 512 * MB;
 const int kPointerSizeLog2 = 2;
 const intptr_t kIntptrSignBit = 0x80000000;
 const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu;
+#if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
+// x32 port also requires code range.
+const bool kRequiresCodeRange = true;
+const size_t kMaximalCodeRangeSize = 256 * MB;
+#else
 const bool kRequiresCodeRange = false;
 const size_t kMaximalCodeRangeSize = 0 * MB;
 #endif
+#endif
 
 const int kBitsPerByte = 8;
 const int kBitsPerByteLog2 = 3;
index e8af5d0..01afa85 100644 (file)
@@ -554,8 +554,10 @@ LowLevelLogger::~LowLevelLogger() {
 void LowLevelLogger::LogCodeInfo() {
 #if V8_TARGET_ARCH_IA32
   const char arch[] = "ia32";
-#elif V8_TARGET_ARCH_X64
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT
   const char arch[] = "x64";
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
+  const char arch[] = "x32";
 #elif V8_TARGET_ARCH_ARM
   const char arch[] = "arm";
 #elif V8_TARGET_ARCH_MIPS
index 3cb6fe2..ca533df 100644 (file)
@@ -9138,6 +9138,23 @@ static inline ObjectPair MakePair(Object* x, Object* y) {
   // In Win64 they are assigned to a hidden first argument.
   return result;
 }
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
+// For x32 a 128-bit struct return is done as rax and rdx from the ObjectPair
+// are used in the full codegen and Crankshaft compiler. An alternative is
+// using uint64_t and modifying full codegen and Crankshaft compiler.
+struct ObjectPair {
+  Object* x;
+  uint32_t x_upper;
+  Object* y;
+  uint32_t y_upper;
+};
+
+
+static inline ObjectPair MakePair(Object* x, Object* y) {
+  ObjectPair result = {x, 0, y, 0};
+  // Pointers x and y returned in rax and rdx, in x32-abi.
+  return result;
+}
 #else
 typedef uint64_t ObjectPair;
 static inline ObjectPair MakePair(Object* x, Object* y) {
index 5422985..86420b4 100644 (file)
@@ -1318,8 +1318,12 @@ inline void MemsetPointer(T** dest, U* value, int counter) {
 #if V8_HOST_ARCH_IA32
 #define STOS "stosl"
 #elif V8_HOST_ARCH_X64
+#if V8_HOST_ARCH_32_BIT
+#define STOS "addr32 stosl"
+#else
 #define STOS "stosq"
 #endif
+#endif
 #if defined(__native_client__)
   // This STOS sequence does not validate for x86_64 Native Client.
   // Here we #undef STOS to force use of the slower C version.
index f92a81e..0e6f14a 100644 (file)
@@ -247,6 +247,8 @@ class IsolateNonlockingThread : public JoinableThread {
 TEST(MultithreadedParallelIsolates) {
 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
   const int kNThreads = 10;
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
+  const int kNThreads = 4;
 #else
   const int kNThreads = 50;
 #endif
@@ -713,6 +715,8 @@ class IsolateGenesisThread : public JoinableThread {
 TEST(ExtensionsRegistration) {
 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
   const int kNThreads = 10;
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
+  const int kNThreads = 4;
 #else
   const int kNThreads = 40;
 #endif
index c6dcf69..babbedc 100644 (file)
             '../../src/mips/stub-cache-mips.cc',
           ],
         }],
-        ['v8_target_arch=="x64"', {
+        ['v8_target_arch=="x64" or v8_target_arch=="x32"', {
           'sources': [  ### gcmole(arch:x64) ###
             '../../src/x64/assembler-x64-inl.h',
             '../../src/x64/assembler-x64.cc',
index 794c864..fbbe416 100755 (executable)
@@ -86,6 +86,7 @@ SUPPORTED_ARCHS = ["android_arm",
                    "nacl_ia32",
                    "nacl_x64",
                    "x64",
+                   "x32",
                    "arm64"]
 # Double the timeout for these:
 SLOW_ARCHS = ["android_arm",