From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48352) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YQNOw-00051L-KN for qemu-devel@nongnu.org; Tue, 24 Feb 2015 16:52:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YQNOs-0006sQ-IF for qemu-devel@nongnu.org; Tue, 24 Feb 2015 16:52:22 -0500 Received: from e9.ny.us.ibm.com ([32.97.182.139]:60286) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YQNOs-0006sG-7n for qemu-devel@nongnu.org; Tue, 24 Feb 2015 16:52:18 -0500 Received: from /spool/local by e9.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 24 Feb 2015 16:52:17 -0500 From: Michael Roth Date: Tue, 24 Feb 2015 15:47:55 -0600 Message-Id: <1424814498-6993-21-git-send-email-mdroth@linux.vnet.ibm.com> In-Reply-To: <1424814498-6993-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1424814498-6993-1-git-send-email-mdroth@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 20/43] target-xtensa: fix translation for opcodes crossing page boundary List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Max Filippov , qemu-stable@nongnu.org From: Max Filippov If TB ends with an opcode that crosses page boundary and the following page is not executable then EPC1 for the code fetch exception wrongly points at the beginning of the TB. Always treat instruction that crosses page boundary as a separate TB. Cc: qemu-stable@nongnu.org Signed-off-by: Max Filippov (cherry picked from commit 01673a3401614b4199c9946ad47b97bedfc7a7c2) Signed-off-by: Michael Roth --- target-xtensa/translate.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index badca19..a81573d 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -887,6 +887,11 @@ static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned) return m; } +static inline unsigned xtensa_op0_insn_len(unsigned op0) +{ + return op0 >= 8 ? 2 : 3; +} + static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) { #define HAS_OPTION_BITS(opt) do { \ @@ -989,6 +994,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) uint8_t b0 = cpu_ldub_code(env, dc->pc); uint8_t b1 = cpu_ldub_code(env, dc->pc + 1); uint8_t b2 = 0; + unsigned len = xtensa_op0_insn_len(OP0); static const uint32_t B4CONST[] = { 0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256 @@ -998,13 +1004,19 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) 32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256 }; - if (OP0 >= 8) { - dc->next_pc = dc->pc + 2; + switch (len) { + case 2: HAS_OPTION(XTENSA_OPTION_CODE_DENSITY); - } else { - dc->next_pc = dc->pc + 3; + break; + + case 3: b2 = cpu_ldub_code(env, dc->pc + 2); + break; + + default: + RESERVED(); } + dc->next_pc = dc->pc + len; switch (OP0) { case 0: /*QRST*/ @@ -2949,6 +2961,12 @@ invalid_opcode: #undef HAS_OPTION } +static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc) +{ + uint8_t b0 = cpu_ldub_code(env, dc->pc); + return xtensa_op0_insn_len(OP0); +} + static void check_breakpoint(CPUXtensaState *env, DisasContext *dc) { CPUState *cs = CPU(xtensa_env_get_cpu(env)); @@ -3081,6 +3099,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu, } while (dc.is_jmp == DISAS_NEXT && insn_count < max_insns && dc.pc < next_page_start && + dc.pc + xtensa_insn_len(env, &dc) <= next_page_start && tcg_ctx.gen_opc_ptr < gen_opc_end); reset_litbase(&dc); -- 1.9.1