[Pcre-svn] [1551] code/trunk/sljit/sljitNativeARM_64.c: Fix …

Inizio della pagina
Delete this message
Autore: Subversion repository
Data:  
To: pcre-svn
Oggetto: [Pcre-svn] [1551] code/trunk/sljit/sljitNativeARM_64.c: Fix ARM64 SP alignment issue in JIT.
Revision: 1551
          http://vcs.pcre.org/viewvc?view=rev&revision=1551
Author:   zherczeg
Date:     2015-04-23 14:51:51 +0100 (Thu, 23 Apr 2015)


Log Message:
-----------
Fix ARM64 SP alignment issue in JIT.

Modified Paths:
--------------
    code/trunk/sljit/sljitNativeARM_64.c


Modified: code/trunk/sljit/sljitNativeARM_64.c
===================================================================
--- code/trunk/sljit/sljitNativeARM_64.c    2015-04-22 15:43:50 UTC (rev 1550)
+++ code/trunk/sljit/sljitNativeARM_64.c    2015-04-23 13:51:51 UTC (rev 1551)
@@ -1081,12 +1081,13 @@
         FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
         offs = (local_size - saved_regs_size) << (15 - 3);
     } else {
-        compiler->local_size += 2 * sizeof(sljit_sw);
-        local_size -= saved_regs_size;
-        saved_regs_size += 2 * sizeof(sljit_sw);
-        FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR)
-            | RN(TMP_SP) | ((-(saved_regs_size >> 3) & 0x7f) << 15)));
-        offs = 2 << 15;
+        offs = 0 << 15;
+        if (saved_regs_size & 0x8) {
+            offs = 1 << 15;
+            saved_regs_size += sizeof(sljit_sw);
+        }
+        local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
+        FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
     }


     tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
@@ -1122,6 +1123,8 @@
         }
         if (local_size)
             FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10)));
+        FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR)
+            | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15)));
         FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10)));
     }


@@ -1145,8 +1148,6 @@

     local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET;
     local_size = (local_size + 15) & ~0xf;
-    if (local_size > (63 * sizeof(sljit_sw)))
-        local_size += 2 * sizeof(sljit_sw);
     compiler->local_size = local_size;
     return SLJIT_SUCCESS;
 }
@@ -1167,16 +1168,20 @@
     if (local_size <= (63 * sizeof(sljit_sw)))
         offs = (local_size - saved_regs_size) << (15 - 3);
     else {
-        saved_regs_size += 2 * sizeof(sljit_sw);
-        local_size -= saved_regs_size;
+        FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
+            | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15)));
+        offs = 0 << 15;
+        if (saved_regs_size & 0x8) {
+            offs = 1 << 15;
+            saved_regs_size += sizeof(sljit_sw);
+        }
+        local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
         if (local_size > 0xfff) {
             FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22)));
             local_size &= 0xfff;
         }
         if (local_size)
             FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10)));
-        local_size = saved_regs_size;
-        offs = 2 << 15;
     }


     tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
@@ -1204,8 +1209,12 @@
     if (prev != -1)
         FAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(TMP_SP) | (offs >> 5)));


-    FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
-        | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15)));
+    if (compiler->local_size <= (63 * sizeof(sljit_sw))) {
+        FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
+            | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15)));
+    } else {
+        FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
+    }


     FAIL_IF(push_inst(compiler, RET | RN(TMP_LR)));
     return SLJIT_SUCCESS;