[JAEGER] Fix ARM's load8 implementation and enable YARR for ARM. [Bug 564953] [r=me]
authorJacob Bramley <Jacob.Bramley@arm.com>
Mon, 16 Aug 2010 13:20:32 +0100
changeset 53431 73eb2d14f7ac542212fa83c1740b1f32f22b30e3
parent 53430 0bb64c9ca0b6e03a36da7ed535e8f69ab322a4c9
child 53432 fe75f7100230edabbb935b24010b228b4b1f16f4
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs564953
milestone2.0b4pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
[JAEGER] Fix ARM's load8 implementation and enable YARR for ARM. [Bug 564953] [r=me]
js/src/assembler/assembler/ARMAssembler.cpp
js/src/assembler/assembler/ARMAssembler.h
js/src/assembler/assembler/MacroAssemblerARM.h
js/src/assembler/wtf/Platform.h
--- a/js/src/assembler/assembler/ARMAssembler.cpp
+++ b/js/src/assembler/assembler/ARMAssembler.cpp
@@ -261,39 +261,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
@@ -649,16 +649,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)
@@ -1120,17 +1164,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.h
+++ b/js/src/assembler/assembler/MacroAssemblerARM.h
@@ -248,17 +248,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/wtf/Platform.h
+++ b/js/src/assembler/wtf/Platform.h
@@ -888,20 +888,21 @@ on MinGW. See https://bugs.webkit.org/sh
     #define WTF_USE_INTERPRETER 0
 #else
     #define WTF_USE_INTERPRETER 1
 #endif
 
 /* Yet Another Regex Runtime. */
 #if !defined(ENABLE_YARR_JIT)
 
-/* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */
+/* YARR supports ARM, 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_ARM_TRADITIONAL \
  || WTF_CPU_X86
 #define ENABLE_YARR_JIT 1
 #else
 #define ENABLE_YARR_JIT 0
 #endif
 
 #endif /* !defined(ENABLE_YARR_JIT) */