diff options
author | zherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2015-04-23 13:51:51 +0000 |
---|---|---|
committer | zherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2015-04-23 13:51:51 +0000 |
commit | 4ef0a06d7be50e00918c63c90ad934ba29970c42 (patch) | |
tree | e5c9b2e6beeb7c3997be8565269dc5a71b8fa0d9 /sljit | |
parent | 6e0ad9548f065a2f24f5a3e9aa018d10819cfa22 (diff) | |
download | pcre-4ef0a06d7be50e00918c63c90ad934ba29970c42.tar.gz |
Fix ARM64 SP alignment issue in JIT.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1551 2f5784b3-3f2a-0410-8824-cb99058d5e15
Diffstat (limited to 'sljit')
-rw-r--r-- | sljit/sljitNativeARM_64.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/sljit/sljitNativeARM_64.c b/sljit/sljitNativeARM_64.c index c5251be..b66455f 100644 --- a/sljit/sljitNativeARM_64.c +++ b/sljit/sljitNativeARM_64.c @@ -1081,12 +1081,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil 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 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil } 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 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi 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 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi 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 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi 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; |