From patchwork Sun Jul 24 17:11:03 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 106537 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 7EC54B6F84 for ; Mon, 25 Jul 2011 03:14:34 +1000 (EST) Received: from localhost ([::1]:54830 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ql2G7-0007u2-21 for incoming@patchwork.ozlabs.org; Sun, 24 Jul 2011 13:14:31 -0400 Received: from eggs.gnu.org ([140.186.70.92]:57674) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ql2Fm-00078l-L9 for qemu-devel@nongnu.org; Sun, 24 Jul 2011 13:14:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ql2Fc-0005O0-5c for qemu-devel@nongnu.org; Sun, 24 Jul 2011 13:14:10 -0400 Received: from mail-fx0-f47.google.com ([209.85.161.47]:58230) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ql2Fb-0005Lw-TY for qemu-devel@nongnu.org; Sun, 24 Jul 2011 13:14:00 -0400 Received: by mail-fx0-f47.google.com with SMTP id 11so8355253fxg.34 for ; Sun, 24 Jul 2011 10:13:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=9vQBbNwa6KdLWrspQ8s0s8H02FKiIysyTj1LBxFx5fk=; b=b4hs4BPGrdUSeuQLINSHg1Us9CiHZ6kZ17KqkF3uqJHG0YvQU4bxoXBqlJaWG4qVat zzR8JkPprf6xZcRk5Z9aDkYMWQRdujwlwO377igLOsDbDWh9FcA0wiPl6F5RPA4iBDKx IGIVjfXR0tcBeBf6HThdOpIyTyFkv+gmcsHug= Received: by 10.204.103.2 with SMTP id i2mr1011048bko.7.1311527629437; Sun, 24 Jul 2011 10:13:49 -0700 (PDT) Received: from octofox.metropolis ([188.134.19.124]) by mx.google.com with ESMTPS id a22sm1071065bke.53.2011.07.24.10.13.46 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 24 Jul 2011 10:13:48 -0700 (PDT) Received: by octofox.metropolis (sSMTP sendmail emulation); Sun, 24 Jul 2011 21:13:39 +0400 From: Max Filippov To: qemu-devel@nongnu.org Date: Sun, 24 Jul 2011 21:11:03 +0400 Message-Id: <1311527469-12963-26-git-send-email-jcmvbkbc@gmail.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1311527469-12963-1-git-send-email-jcmvbkbc@gmail.com> References: <1311527469-12963-1-git-send-email-jcmvbkbc@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.161.47 Cc: jcmvbkbc@gmail.com Subject: [Qemu-devel] [PATCH v2 25/31] target-xtensa: implement accurate window check X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org See ISA, 4.7.1.3 for details. Window check is inserted before commands that push "used register watermark" beyond its current level. Used register watermark is reset on instructions that change WINDOW_BASE/WINDOW_START SRs. Signed-off-by: Max Filippov --- v1 -> v2 changes: - dc->used_window is updated as necessary in the gen_window_check1; --- target-xtensa/translate.c | 110 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 110 insertions(+), 0 deletions(-) diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index e947766..6d6ad1b 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -60,6 +60,7 @@ typedef struct DisasContext { TCGv_i32 sar_m32; uint32_t ccount_delta; + unsigned used_window; } DisasContext; static TCGv_ptr cpu_env; @@ -225,6 +226,11 @@ static void gen_advance_ccount(DisasContext *dc) } } +static void reset_used_window(DisasContext *dc) +{ + dc->used_window = 0; +} + static void gen_exception(DisasContext *dc, int excp) { TCGv_i32 tmp = tcg_const_i32(excp); @@ -418,6 +424,13 @@ static void gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s) static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v) { gen_helper_wsr_windowbase(v); + reset_used_window(dc); +} + +static void gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v) +{ + tcg_gen_mov_i32(cpu_SR[sr], v); + reset_used_window(dc); } static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v) @@ -429,6 +442,7 @@ static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v) mask |= PS_RING; } tcg_gen_andi_i32(cpu_SR[sr], v, mask); + reset_used_window(dc); /* This can change mmu index and tb->flags, so exit tb */ gen_jumpi_check_loop_end(dc, -1); } @@ -453,6 +467,7 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) [SAR] = gen_wsr_sar, [LITBASE] = gen_wsr_litbase, [WINDOW_BASE] = gen_wsr_windowbase, + [WINDOW_START] = gen_wsr_windowstart, [PS] = gen_wsr_ps, [CCOMPARE] = gen_wsr_ccompare, [CCOMPARE + 1] = gen_wsr_ccompare, @@ -497,6 +512,36 @@ static void gen_waiti(DisasContext *dc, uint32_t imm4) tcg_temp_free(intlevel); } +static void gen_window_check1(DisasContext *dc, unsigned r1) +{ + if (dc->tb->flags & XTENSA_TBFLAG_EXCM) { + return; + } + if (option_enabled(dc, XTENSA_OPTION_WINDOWED_REGISTER) && + r1 / 4 > dc->used_window) { + TCGv_i32 pc = tcg_const_i32(dc->pc); + TCGv_i32 w = tcg_const_i32(r1 / 4); + + dc->used_window = r1 / 4; + gen_advance_ccount(dc); + gen_helper_window_check(pc, w); + + tcg_temp_free(w); + tcg_temp_free(pc); + } +} + +static void gen_window_check2(DisasContext *dc, unsigned r1, unsigned r2) +{ + gen_window_check1(dc, r1 > r2 ? r1 : r2); +} + +static void gen_window_check3(DisasContext *dc, unsigned r1, unsigned r2, + unsigned r3) +{ + gen_window_check2(dc, r1, r2 > r3 ? r2 : r3); +} + static void disas_xtensa_insn(DisasContext *dc) { #define HAS_OPTION(opt) do { \ @@ -626,6 +671,7 @@ static void disas_xtensa_insn(DisasContext *dc) switch (CALLX_N) { case 0: /*RET*/ case 2: /*JX*/ + gen_window_check1(dc, CALLX_S); gen_jump(dc, cpu_R[CALLX_S]); break; @@ -647,6 +693,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 3: /*CALLX*/ + gen_window_check2(dc, CALLX_S, CALLX_N << 2); switch (CALLX_N) { case 0: /*CALLX0*/ { @@ -677,6 +724,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 1: /*MOVSPw*/ HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); + gen_window_check2(dc, RRR_T, RRR_S); { TCGv_i32 pc = tcg_const_i32(dc->pc); gen_advance_ccount(dc); @@ -821,6 +869,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 6: /*RSILx*/ HAS_OPTION(XTENSA_OPTION_INTERRUPT); gen_check_privilege(dc); + gen_window_check1(dc, RRR_T); tcg_gen_mov_i32(cpu_R[RRR_T], cpu_SR[PS]); tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL); tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], RRR_S); @@ -860,28 +909,34 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 1: /*AND*/ + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); break; case 2: /*OR*/ + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); break; case 3: /*XOR*/ + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); break; case 4: /*ST1*/ switch (RRR_R) { case 0: /*SSR*/ + gen_window_check1(dc, RRR_S); gen_right_shift_sar(dc, cpu_R[RRR_S]); break; case 1: /*SSL*/ + gen_window_check1(dc, RRR_S); gen_left_shift_sar(dc, cpu_R[RRR_S]); break; case 2: /*SSA8L*/ + gen_window_check1(dc, RRR_S); { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3); @@ -891,6 +946,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 3: /*SSA8B*/ + gen_window_check1(dc, RRR_S); { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3); @@ -924,16 +980,19 @@ static void disas_xtensa_insn(DisasContext *dc) RRR_T | ((RRR_T & 8) ? 0xfffffff0 : 0)); gen_helper_rotw(tmp); tcg_temp_free(tmp); + reset_used_window(dc); } break; case 14: /*NSAu*/ HAS_OPTION(XTENSA_OPTION_MISC_OP); + gen_window_check2(dc, RRR_S, RRR_T); gen_helper_nsa(cpu_R[RRR_T], cpu_R[RRR_S]); break; case 15: /*NSAUu*/ HAS_OPTION(XTENSA_OPTION_MISC_OP); + gen_window_check2(dc, RRR_S, RRR_T); gen_helper_nsau(cpu_R[RRR_T], cpu_R[RRR_S]); break; @@ -948,6 +1007,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 6: /*RT0*/ + gen_window_check2(dc, RRR_R, RRR_T); switch (RRR_S) { case 0: /*NEG*/ tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]); @@ -975,12 +1035,14 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 8: /*ADD*/ + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); break; case 9: /*ADD**/ case 10: case 11: + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_shli_i32(tmp, cpu_R[RRR_S], _OP2 - 8); @@ -990,12 +1052,14 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 12: /*SUB*/ + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]); break; case 13: /*SUB**/ case 14: case 15: + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_shli_i32(tmp, cpu_R[RRR_S], _OP2 - 12); @@ -1010,17 +1074,20 @@ static void disas_xtensa_insn(DisasContext *dc) switch (_OP2) { case 0: /*SLLI*/ case 1: + gen_window_check2(dc, RRR_R, RRR_S); tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S], 32 - (RRR_T | ((_OP2 & 1) << 4))); break; case 2: /*SRAI*/ case 3: + gen_window_check2(dc, RRR_R, RRR_T); tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S | ((_OP2 & 1) << 4)); break; case 4: /*SRLI*/ + gen_window_check2(dc, RRR_R, RRR_T); tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S); break; @@ -1030,6 +1097,7 @@ static void disas_xtensa_insn(DisasContext *dc) if (RSR_SR >= 64) { gen_check_privilege(dc); } + gen_window_check1(dc, RRR_T); tcg_gen_mov_i32(tmp, cpu_R[RRR_T]); gen_rsr(dc, cpu_R[RRR_T], RSR_SR); gen_wsr(dc, RSR_SR, tmp); @@ -1056,6 +1124,7 @@ static void disas_xtensa_insn(DisasContext *dc) #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR]) case 8: /*SRC*/ + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); { TCGv_i64 v = tcg_temp_new_i64(); tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]); @@ -1064,6 +1133,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 9: /*SRL*/ + gen_window_check2(dc, RRR_R, RRR_T); if (dc->sar_5bit) { tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]); } else { @@ -1074,6 +1144,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 10: /*SLL*/ + gen_window_check2(dc, RRR_R, RRR_S); if (dc->sar_m32_5bit) { tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32); } else { @@ -1088,6 +1159,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 11: /*SRA*/ + gen_window_check2(dc, RRR_R, RRR_T); if (dc->sar_5bit) { tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]); } else { @@ -1101,6 +1173,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 12: /*MUL16U*/ HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL); + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); { TCGv_i32 v1 = tcg_temp_new_i32(); TCGv_i32 v2 = tcg_temp_new_i32(); @@ -1114,6 +1187,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 13: /*MUL16S*/ HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL); + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); { TCGv_i32 v1 = tcg_temp_new_i32(); TCGv_i32 v2 = tcg_temp_new_i32(); @@ -1132,6 +1206,8 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 2: /*RST2*/ + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); + if (_OP2 >= 12) { HAS_OPTION(XTENSA_OPTION_32_BIT_IDIV); int label = gen_new_label(); @@ -1199,6 +1275,7 @@ static void disas_xtensa_insn(DisasContext *dc) if (RSR_SR >= 64) { gen_check_privilege(dc); } + gen_window_check1(dc, RRR_T); gen_rsr(dc, cpu_R[RRR_T], RSR_SR); if (!sregnames[RSR_SR]) { TBD(); @@ -1209,6 +1286,7 @@ static void disas_xtensa_insn(DisasContext *dc) if (RSR_SR >= 64) { gen_check_privilege(dc); } + gen_window_check1(dc, RRR_T); gen_wsr(dc, RSR_SR, cpu_R[RRR_T]); if (!sregnames[RSR_SR]) { TBD(); @@ -1217,6 +1295,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 2: /*SEXTu*/ HAS_OPTION(XTENSA_OPTION_MISC_OP); + gen_window_check2(dc, RRR_R, RRR_S); { int shift = 24 - RRR_T; @@ -1235,6 +1314,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 3: /*CLAMPSu*/ HAS_OPTION(XTENSA_OPTION_MISC_OP); + gen_window_check2(dc, RRR_R, RRR_S); { TCGv_i32 tmp1 = tcg_temp_new_i32(); TCGv_i32 tmp2 = tcg_temp_new_i32(); @@ -1262,6 +1342,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 6: /*MINUu*/ case 7: /*MAXUu*/ HAS_OPTION(XTENSA_OPTION_MISC_OP); + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); { static const TCGCond cond[] = { TCG_COND_LE, @@ -1289,6 +1370,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 9: /*MOVNEZ*/ case 10: /*MOVLTZ*/ case 11: /*MOVGEZ*/ + gen_window_check3(dc, RRR_R, RRR_S, RRR_T); { static const TCGCond cond[] = { TCG_COND_NE, @@ -1314,6 +1396,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 14: /*RUR*/ + gen_window_check1(dc, RRR_R); { int st = (RRR_S << 4) + RRR_T; if (uregnames[st]) { @@ -1326,6 +1409,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 15: /*WUR*/ + gen_window_check1(dc, RRR_T); { if (uregnames[RSR_SR]) { tcg_gen_mov_i32(cpu_UR[RSR_SR], cpu_R[RRR_T]); @@ -1341,6 +1425,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 4: /*EXTUI*/ case 5: + gen_window_check2(dc, RRR_R, RRR_T); { int shiftimm = RRR_S | (_OP1 << 4); int maskimm = (1 << (_OP2 + 1)) - 1; @@ -1366,6 +1451,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 9: /*LSC4*/ + gen_window_check2(dc, RRR_S, RRR_T); switch (_OP2) { case 0: /*L32E*/ HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); @@ -1414,6 +1500,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 1: /*L32R*/ + gen_window_check1(dc, RRR_T); { TCGv_i32 tmp = tcg_const_i32( ((dc->tb->flags & XTENSA_TBFLAG_LITBASE) ? @@ -1431,6 +1518,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 2: /*LSAI*/ #define gen_load_store(type, shift) do { \ TCGv_i32 addr = tcg_temp_new_i32(); \ + gen_window_check2(dc, RRI8_S, RRI8_T); \ tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \ if (shift) { \ gen_load_store_alignment(dc, shift, addr, false); \ @@ -1567,6 +1655,7 @@ static void disas_xtensa_insn(DisasContext *dc) #undef gen_load_store case 10: /*MOVI*/ + gen_window_check1(dc, RRI8_T); tcg_gen_movi_i32(cpu_R[RRI8_T], RRI8_IMM8 | (RRI8_S << 8) | ((RRI8_S & 0x8) ? 0xfffff000 : 0)); @@ -1574,6 +1663,7 @@ static void disas_xtensa_insn(DisasContext *dc) #define gen_load_store_no_hw_align(type) do { \ TCGv_i32 addr = tcg_temp_local_new_i32(); \ + gen_window_check2(dc, RRI8_S, RRI8_T); \ tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); \ gen_load_store_alignment(dc, 2, addr, true); \ tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \ @@ -1586,15 +1676,18 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 12: /*ADDI*/ + gen_window_check2(dc, RRI8_S, RRI8_T); tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE); break; case 13: /*ADDMI*/ + gen_window_check2(dc, RRI8_S, RRI8_T); tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE << 8); break; case 14: /*S32C1Iy*/ HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO); + gen_window_check2(dc, RRI8_S, RRI8_T); { int label = gen_new_label(); TCGv_i32 tmp = tcg_temp_local_new_i32(); @@ -1648,6 +1741,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 2: /*CALL8w*/ case 3: /*CALL12w*/ HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER); + gen_window_check1(dc, CALL_N << 2); gen_callwi(dc, CALL_N, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0); break; @@ -1661,6 +1755,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 1: /*BZ*/ + gen_window_check1(dc, BRI12_S); { static const TCGCond cond[] = { TCG_COND_EQ, /*BEQZ*/ @@ -1675,6 +1770,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 2: /*BI0*/ + gen_window_check1(dc, BRI8_S); { static const TCGCond cond[] = { TCG_COND_EQ, /*BEQI*/ @@ -1701,6 +1797,7 @@ static void disas_xtensa_insn(DisasContext *dc) tcg_temp_free(imm); tcg_temp_free(s); tcg_temp_free(pc); + reset_used_window(dc); } break; @@ -1720,6 +1817,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 9: /*LOOPNEZ*/ case 10: /*LOOPGTZ*/ HAS_OPTION(XTENSA_OPTION_LOOP); + gen_window_check1(dc, RRI8_S); { uint32_t lend = dc->pc + RRI8_IMM8 + 4; TCGv_i32 tmp = tcg_const_i32(lend); @@ -1751,6 +1849,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 2: /*BLTUI*/ case 3: /*BGEUI*/ + gen_window_check1(dc, BRI8_S); gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU, cpu_R[BRI8_S], B4CONSTU[BRI8_R], 4 + BRI8_IMM8_SE); break; @@ -1766,6 +1865,7 @@ static void disas_xtensa_insn(DisasContext *dc) switch (RRI8_R & 7) { case 0: /*BNONE*/ /*BANY*/ + gen_window_check2(dc, RRI8_S, RRI8_T); { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]); @@ -1777,6 +1877,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 1: /*BEQ*/ /*BNE*/ case 2: /*BLT*/ /*BGE*/ case 3: /*BLTU*/ /*BGEU*/ + gen_window_check2(dc, RRI8_S, RRI8_T); { static const TCGCond cond[] = { [1] = TCG_COND_EQ, @@ -1792,6 +1893,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 4: /*BALL*/ /*BNALL*/ + gen_window_check2(dc, RRI8_S, RRI8_T); { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]); @@ -1802,6 +1904,7 @@ static void disas_xtensa_insn(DisasContext *dc) break; case 5: /*BBC*/ /*BBS*/ + gen_window_check2(dc, RRI8_S, RRI8_T); { TCGv_i32 bit = tcg_const_i32(1); TCGv_i32 tmp = tcg_temp_new_i32(); @@ -1816,6 +1919,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 6: /*BBCI*/ /*BBSI*/ case 7: + gen_window_check1(dc, RRI8_S); { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_andi_i32(tmp, cpu_R[RRI8_S], @@ -1831,6 +1935,7 @@ static void disas_xtensa_insn(DisasContext *dc) #define gen_narrow_load_store(type) do { \ TCGv_i32 addr = tcg_temp_new_i32(); \ + gen_window_check2(dc, RRRN_S, RRRN_T); \ tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \ gen_load_store_alignment(dc, 2, addr, false); \ tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \ @@ -1847,14 +1952,17 @@ static void disas_xtensa_insn(DisasContext *dc) #undef gen_narrow_load_store case 10: /*ADD.Nn*/ + gen_window_check3(dc, RRRN_R, RRRN_S, RRRN_T); tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]); break; case 11: /*ADDI.Nn*/ + gen_window_check2(dc, RRRN_R, RRRN_S); tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], RRRN_T ? RRRN_T : -1); break; case 12: /*ST2n*/ + gen_window_check1(dc, RRRN_S); if (RRRN_T < 8) { /*MOVI.Nn*/ tcg_gen_movi_i32(cpu_R[RRRN_S], RRRN_R | (RRRN_T << 4) | @@ -1870,6 +1978,7 @@ static void disas_xtensa_insn(DisasContext *dc) case 13: /*ST3n*/ switch (RRRN_R) { case 0: /*MOV.Nn*/ + gen_window_check2(dc, RRRN_S, RRRN_T); tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]); break; @@ -1973,6 +2082,7 @@ static void gen_intermediate_code_internal( init_litbase(&dc); init_sar_tracker(&dc); + reset_used_window(&dc); gen_icount_start();