[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 25/31] target-xtensa: implement accurate window c
From: |
Max Filippov |
Subject: |
[Qemu-devel] [PATCH v2 25/31] target-xtensa: implement accurate window check |
Date: |
Sun, 24 Jul 2011 21:11:03 +0400 |
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 <address@hidden>
---
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();
--
1.7.3.4
- [Qemu-devel] [PATCH v2 10/31] target-xtensa: implement RST3 group, (continued)
- [Qemu-devel] [PATCH v2 10/31] target-xtensa: implement RST3 group, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 13/31] target-xtensa: mark reserved and TBD opcodes, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 15/31] target-xtensa: implement CACHE group, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 17/31] target-xtensa: implement exceptions, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 16/31] target-xtensa: add PS register and access control, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 18/31] target-xtensa: implement RST2 group (32 bit mul/div/rem), Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 20/31] target-xtensa: implement loop option, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 21/31] target-xtensa: implement extended L32R, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 23/31] target-xtensa: implement SIMCALL, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 22/31] target-xtensa: implement unaligned exception option, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 25/31] target-xtensa: implement accurate window check,
Max Filippov <=
- [Qemu-devel] [PATCH v2 26/31] target-xtensa: implement CPENABLE and PRID SRs, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 24/31] target-xtensa: implement interrupt option, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 28/31] target-xtensa: add gdb support, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 30/31] target-xtensa: add dc232b core and board, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 27/31] target-xtensa: implement relocatable vectors, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 31/31] MAINTAINERS: add xtensa maintainer, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 29/31] target-xtensa: implement memory protection options, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 11/31] target-xtensa: implement shifts (ST1 and RST1 groups), Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 14/31] target-xtensa: implement SYNC group, Max Filippov, 2011/07/24
- [Qemu-devel] [PATCH v2 12/31] target-xtensa: implement LSAI group, Max Filippov, 2011/07/24