diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2013-07-21 07:54:37 +0400 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2013-07-29 18:35:45 +0400 |
commit | 0857a06ef784783887e756d4b7b5f874512c506c (patch) | |
tree | 8bdbac6dbc0b077ca60a2414bd9fda423b9e9590 | |
parent | aaa2ebc567619474d219017785b46ddc9295fffa (diff) |
target-xtensa: don't generate dead code to access invalid SRs
This fixes the following test failure caused by access to undefined SR:
qemu-system-xtensa -M sim -cpu dc232b -nographic -semihosting -kernel ./test_sr.tst
QEMU 1.4.50 monitor - type 'help' for more information
(qemu) QEMU 1.4.50 monitor - type 'help' for more information
(qemu) qemu-system-xtensa: tcg/tcg.c:1673: temp_save: Assertion `s->temps[temp].val_type == 2 || s->temps[temp].fixed_reg' failed.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
-rw-r--r-- | target-xtensa/translate.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index 7ea5e2ae16..15fab1ba30 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -491,7 +491,7 @@ static void gen_brcondi(DisasContext *dc, TCGCond cond, tcg_temp_free(tmp); } -static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access) +static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access) { if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) { if (sregnames[sr].name) { @@ -500,6 +500,7 @@ static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access) qemu_log("SR %d is not implemented\n", sr); } gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); + return false; } else if (!(sregnames[sr].access & access)) { static const char * const access_text[] = { [SR_R] = "rsr", @@ -510,7 +511,9 @@ static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access) qemu_log("SR %s is not available for %s\n", sregnames[sr].name, access_text[access]); gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); + return false; } + return true; } static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr) @@ -1482,9 +1485,9 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) break; case 6: /*XSR*/ - { + if (gen_check_sr(dc, RSR_SR, SR_X)) { TCGv_i32 tmp = tcg_temp_new_i32(); - gen_check_sr(dc, RSR_SR, SR_X); + if (RSR_SR >= 64) { gen_check_privilege(dc); } @@ -1707,21 +1710,23 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) case 3: /*RST3*/ switch (OP2) { case 0: /*RSR*/ - gen_check_sr(dc, RSR_SR, SR_R); - if (RSR_SR >= 64) { - gen_check_privilege(dc); + if (gen_check_sr(dc, RSR_SR, SR_R)) { + if (RSR_SR >= 64) { + gen_check_privilege(dc); + } + gen_window_check1(dc, RRR_T); + gen_rsr(dc, cpu_R[RRR_T], RSR_SR); } - gen_window_check1(dc, RRR_T); - gen_rsr(dc, cpu_R[RRR_T], RSR_SR); break; case 1: /*WSR*/ - gen_check_sr(dc, RSR_SR, SR_W); - if (RSR_SR >= 64) { - gen_check_privilege(dc); + if (gen_check_sr(dc, RSR_SR, SR_W)) { + if (RSR_SR >= 64) { + gen_check_privilege(dc); + } + gen_window_check1(dc, RRR_T); + gen_wsr(dc, RSR_SR, cpu_R[RRR_T]); } - gen_window_check1(dc, RRR_T); - gen_wsr(dc, RSR_SR, cpu_R[RRR_T]); break; case 2: /*SEXTu*/ |