Bug 587597 - Fix ARM/Mobile bustage by building Yarr. Contains Jacob Bramley's load8 fix. r=sayrer a=blocking-fennec
authorMichael Wu <mwu@mozilla.com>
Mon, 16 Aug 2010 15:18:10 -0700
changeset 50693 dbc17795f035c0b767fcbaae16ca33e54795e926
parent 50692 be7c2f122492fea7270266dad29d006978b6c5bb
child 50695 5cce3845d654b1e25bb582700449e594d0457d68
push idunknown
push userunknown
push dateunknown
reviewerssayrer, blocking-fennec
bugs587597
milestone2.0b4pre
Bug 587597 - Fix ARM/Mobile bustage by building Yarr. Contains Jacob Bramley's load8 fix. r=sayrer a=blocking-fennec
js/src/Makefile.in
js/src/assembler/assembler/ARMAssembler.cpp
js/src/assembler/assembler/ARMAssembler.h
js/src/assembler/assembler/MacroAssemblerARM.cpp
js/src/assembler/assembler/MacroAssemblerARM.h
js/src/assembler/jit/ExecutableAllocator.h
js/src/assembler/wtf/Platform.h
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -829,21 +829,15 @@ endif
 
 ###############################################
 # BEGIN kludges for the Nitro assembler
 #
 
 # Needed to "configure" it correctly.  Unfortunately these
 # flags wind up being applied to all code in js/src, not just
 # the code in js/src/assembler.
-CXXFLAGS += -DUSE_SYSTEM_MALLOC=1
-
-ifeq (android,$(TARGET_VENDOR))
-CXXFLAGS += -DWTF_PLATFORM_ANDROID=1
-else
-CXXFLAGS += -DENABLE_ASSEMBLER=1 -DENABLE_JIT=1
-endif
+CXXFLAGS += -DUSE_SYSTEM_MALLOC=1 -DENABLE_ASSEMBLER=1 -DENABLE_JIT=1
 
 INCLUDES +=	-I$(srcdir)/assembler -I$(srcdir)/yarr
 
 #
 # END kludges for the Nitro assembler
 ###############################################
--- a/js/src/assembler/assembler/ARMAssembler.cpp
+++ b/js/src/assembler/assembler/ARMAssembler.cpp
@@ -257,39 +257,64 @@ ARMWord ARMAssembler::encodeComplexImm(A
 
     ldr_imm(dest, imm);
     return dest;
 #endif
 }
 
 // Memory load/store helpers
 
-void ARMAssembler::dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset, bool bytes)
+void ARMAssembler::dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset)
 {
-    ARMWord transferFlag = bytes ? DT_BYTE : 0;
     if (offset >= 0) {
         if (offset <= 0xfff)
-            dtr_u(isLoad, srcDst, base, offset | transferFlag);
+            dtr_u(isLoad, srcDst, base, offset);
         else if (offset <= 0xfffff) {
             add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
-            dtr_u(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff) | transferFlag);
+            dtr_u(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff));
         } else {
             ARMWord reg = getImm(offset, ARMRegisters::S0);
-            dtr_ur(isLoad, srcDst, base, reg | transferFlag);
+            dtr_ur(isLoad, srcDst, base, reg);
         }
     } else {
         offset = -offset;
         if (offset <= 0xfff)
-            dtr_d(isLoad, srcDst, base, offset | transferFlag);
+            dtr_d(isLoad, srcDst, base, offset);
         else if (offset <= 0xfffff) {
             sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
-            dtr_d(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff) | transferFlag);
+            dtr_d(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff));
         } else {
             ARMWord reg = getImm(offset, ARMRegisters::S0);
-            dtr_dr(isLoad, srcDst, base, reg | transferFlag);
+            dtr_dr(isLoad, srcDst, base, reg);
+        }
+    }
+}
+
+void ARMAssembler::dataTransfer8(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset)
+{
+    if (offset >= 0) {
+        if (offset <= 0xfff)
+            dtrb_u(isLoad, srcDst, base, offset);
+        else if (offset <= 0xfffff) {
+            add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
+            dtrb_u(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff));
+        } else {
+            ARMWord reg = getImm(offset, ARMRegisters::S0);
+            dtrb_ur(isLoad, srcDst, base, reg);
+        }
+    } else {
+        offset = -offset;
+        if (offset <= 0xfff)
+            dtrb_d(isLoad, srcDst, base, offset);
+        else if (offset <= 0xfffff) {
+            sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
+            dtrb_d(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff));
+        } else {
+            ARMWord reg = getImm(offset, ARMRegisters::S0);
+            dtrb_dr(isLoad, srcDst, base, reg);
         }
     }
 }
 
 void ARMAssembler::baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset)
 {
     ARMWord op2;
 
--- a/js/src/assembler/assembler/ARMAssembler.h
+++ b/js/src/assembler/assembler/ARMAssembler.h
@@ -638,16 +638,60 @@ namespace JSC {
         void dtr_dr(bool isLoad, int rd, int rb, int rm, Condition cc = AL)
         {
             char const * mnemonic = (isLoad) ? ("ldr") : ("str");
             js::JaegerSpew(js::JSpew_Insns,
                     IPFX   "%-15s %s, [%s, -%s]\n", MAYBE_PAD, mnemonic, nameGpReg(rd), nameGpReg(rb), nameGpReg(rm));
             emitInst(static_cast<ARMWord>(cc) | DTR | (isLoad ? DT_LOAD : 0) | OP2_OFSREG, rd, rb, rm);
         }
 
+        // Data transfers like this:
+        //  LDRB rd, [rb, +offset]
+        //  STRB rd, [rb, +offset]
+        void dtrb_u(bool isLoad, int rd, int rb, ARMWord offset, Condition cc = AL)
+        {
+            char const * mnemonic = (isLoad) ? ("ldrb") : ("strb");
+            js::JaegerSpew(js::JSpew_Insns,
+                    IPFX   "%-15s %s, [%s, #+%u]\n", MAYBE_PAD, mnemonic, nameGpReg(rd), nameGpReg(rb), offset);
+            emitInst(static_cast<ARMWord>(cc) | DTR | DT_BYTE | (isLoad ? DT_LOAD : 0) | DT_UP, rd, rb, offset);
+        }
+
+        // Data transfers like this:
+        //  LDRB rd, [rb, +rm]
+        //  STRB rd, [rb, +rm]
+        void dtrb_ur(bool isLoad, int rd, int rb, int rm, Condition cc = AL)
+        {
+            char const * mnemonic = (isLoad) ? ("ldrb") : ("strb");
+            js::JaegerSpew(js::JSpew_Insns,
+                    IPFX   "%-15s %s, [%s, +%s]\n", MAYBE_PAD, mnemonic, nameGpReg(rd), nameGpReg(rb), nameGpReg(rm));
+            emitInst(static_cast<ARMWord>(cc) | DTR | DT_BYTE | (isLoad ? DT_LOAD : 0) | DT_UP | OP2_OFSREG, rd, rb, rm);
+        }
+
+        // Data transfers like this:
+        //  LDRB rd, [rb, -offset]
+        //  STRB rd, [rb, -offset]
+        void dtrb_d(bool isLoad, int rd, int rb, ARMWord offset, Condition cc = AL)
+        {
+            char const * mnemonic = (isLoad) ? ("ldrb") : ("strb");
+            js::JaegerSpew(js::JSpew_Insns,
+                    IPFX   "%-15s %s, [%s, #-%u]\n", MAYBE_PAD, mnemonic, nameGpReg(rd), nameGpReg(rb), offset);
+            emitInst(static_cast<ARMWord>(cc) | DTR | DT_BYTE | (isLoad ? DT_LOAD : 0), rd, rb, offset);
+        }
+
+        // Data transfers like this:
+        //  LDRB rd, [rb, -rm]
+        //  STRB rd, [rb, -rm]
+        void dtrb_dr(bool isLoad, int rd, int rb, int rm, Condition cc = AL)
+        {
+            char const * mnemonic = (isLoad) ? ("ldrb") : ("strb");
+            js::JaegerSpew(js::JSpew_Insns,
+                    IPFX   "%-15s %s, [%s, -%s]\n", MAYBE_PAD, mnemonic, nameGpReg(rd), nameGpReg(rb), nameGpReg(rm));
+            emitInst(static_cast<ARMWord>(cc) | DTR | DT_BYTE | (isLoad ? DT_LOAD : 0) | OP2_OFSREG, rd, rb, rm);
+        }
+
         void ldrh_r(int rd, int rb, int rm, Condition cc = AL)
         {
             js::JaegerSpew(js::JSpew_Insns,
                     IPFX   "%-15s %s, [%s, +%s]\n", MAYBE_PAD, "ldrh", nameGpReg(rd), nameGpReg(rb), nameGpReg(rm));
             emitInst(static_cast<ARMWord>(cc) | LDRH | HDT_UH | DT_UP | DT_PRE, rd, rb, rm);
         }
 
         void ldrh_d(int rd, int rb, ARMWord offset, Condition cc = AL)
@@ -1100,17 +1144,18 @@ namespace JSC {
             if (imm <= 0xff)
                 return getOp2Byte(imm);
             // Otherwise, store the data in a temporary register
             return encodeComplexImm(imm, tmpReg);
         }
 
         // Memory load/store helpers
 
-        void dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset, bool bytes = false);
+        void dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset);
+        void dataTransfer8(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset);
         void baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset);
         void doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID base, int32_t offset);
 
         // Constant pool hnadlers
 
         static ARMWord placeConstantPoolBarrier(int offset)
         {
             offset = (offset - sizeof(ARMWord)) >> 2;
--- a/js/src/assembler/assembler/MacroAssemblerARM.cpp
+++ b/js/src/assembler/assembler/MacroAssemblerARM.cpp
@@ -25,17 +25,17 @@
  */
 
 #include "assembler/wtf/Platform.h"
 
 #if ENABLE_ASSEMBLER && WTF_CPU_ARM_TRADITIONAL
 
 #include "MacroAssemblerARM.h"
 
-#if WTF_PLATFORM_LINUX
+#if WTF_PLATFORM_LINUX || WTF_PLATFORM_ANDROID
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <elf.h>
 
 // lame check for kernel version
 // see bug 586550
--- a/js/src/assembler/assembler/MacroAssemblerARM.h
+++ b/js/src/assembler/assembler/MacroAssemblerARM.h
@@ -244,17 +244,17 @@ public:
     void xor32(Address src, RegisterID dest)
     {
         load32(src, ARMRegisters::S1);
         m_assembler.eors_r(dest, dest, ARMRegisters::S1);
     }
 
     void load8(ImplicitAddress address, RegisterID dest)
     {
-        m_assembler.dataTransfer32(true, dest, address.base, address.offset, true);
+        m_assembler.dataTransfer8(true, dest, address.base, address.offset);
     }
 
     void load32(ImplicitAddress address, RegisterID dest)
     {
         m_assembler.dataTransfer32(true, dest, address.base, address.offset);
     }
 
     void load32(BaseIndex address, RegisterID dest)
--- a/js/src/assembler/jit/ExecutableAllocator.h
+++ b/js/src/assembler/jit/ExecutableAllocator.h
@@ -281,17 +281,17 @@ public:
     }
 #elif WTF_PLATFORM_SYMBIAN
     static void cacheFlush(void* code, size_t size)
     {
         User::IMB_Range(code, static_cast<char*>(code) + size);
     }
 #elif WTF_CPU_ARM_TRADITIONAL && WTF_PLATFORM_LINUX && WTF_COMPILER_RVCT
     static __asm void cacheFlush(void* code, size_t size);
-#elif WTF_CPU_ARM_TRADITIONAL && WTF_PLATFORM_LINUX && WTF_COMPILER_GCC
+#elif WTF_CPU_ARM_TRADITIONAL && (WTF_PLATFORM_LINUX || WTF_PLATFORM_ANDROID) && WTF_COMPILER_GCC
     static void cacheFlush(void* code, size_t size)
     {
         asm volatile (
             "push    {r7}\n"
             "mov     r0, %0\n"
             "mov     r1, %1\n"
             "mov     r7, #0xf0000\n"
             "add     r7, r7, #0x2\n"
--- a/js/src/assembler/wtf/Platform.h
+++ b/js/src/assembler/wtf/Platform.h
@@ -269,18 +269,18 @@
 
 
 /* CPU(ARM_TRADITIONAL) - Thumb2 is not available, only traditional ARM (v4 or greater) */
 /* CPU(ARM_THUMB2) - Thumb2 instruction set is available */
 /* Only one of these will be defined. */
 #if !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2)
 #  if defined(thumb2) || defined(__thumb2__) \
   || ((defined(__thumb) || defined(__thumb__)) && WTF_THUMB_ARCH_VERSION == 4)
-#    define WTF_CPU_ARM_TRADITIONAL 0
-#    define WTF_CPU_ARM_THUMB2 1
+#    define WTF_CPU_ARM_TRADITIONAL 1
+#    define WTF_CPU_ARM_THUMB2 0
 #  elif WTF_ARM_ARCH_AT_LEAST(4)
 #    define WTF_CPU_ARM_TRADITIONAL 1
 #    define WTF_CPU_ARM_THUMB2 0
 #  else
 #    error "Not supported ARM architecture"
 #  endif
 #elif WTF_CPU_ARM_TRADITIONAL && WTF_CPU_ARM_THUMB2 /* Sanity Check */
 #  error "Cannot use both of WTF_CPU_ARM_TRADITIONAL and WTF_CPU_ARM_THUMB2 platforms"
@@ -872,25 +872,26 @@ on MinGW. See https://bugs.webkit.org/sh
 
 /* Yet Another Regex Runtime. */
 #if !defined(ENABLE_YARR_JIT)
 
 /* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */
 #if (WTF_CPU_X86 \
  || WTF_CPU_X86_64 \
  || WTF_CPU_ARM_THUMB2 \
- || WTF_CPU_X86) && !WTF_PLATFORM_ANDROID
+ || WTF_CPU_ARM_TRADITIONAL \
+ || WTF_CPU_X86)
 #define ENABLE_YARR_JIT 1
 #else
 #define ENABLE_YARR_JIT 0
 #endif
 
 #endif /* !defined(ENABLE_YARR_JIT) */
 
-#if (ENABLE_JIT || ENABLE_YARR_JIT) && !WTF_PLATFORM_ANDROID
+#if (ENABLE_JIT || ENABLE_YARR_JIT)
 #define ENABLE_ASSEMBLER 1
 #endif
 /* Setting this flag prevents the assembler from using RWX memory; this may improve
    security but currectly comes at a significant performance cost. */
 #if WTF_PLATFORM_IPHONE
 #define ENABLE_ASSEMBLER_WX_EXCLUSIVE 1
 #else
 #define ENABLE_ASSEMBLER_WX_EXCLUSIVE 0