target/rx: Swap stack pointers on clrpsw/setpsw instruction
authorRichard Henderson <richard.henderson@linaro.org>
Sun, 17 Apr 2022 16:51:30 +0000 (09:51 -0700)
committerRichard Henderson <richard.henderson@linaro.org>
Thu, 21 Apr 2022 17:04:34 +0000 (10:04 -0700)
We properly perform this swap in helper_set_psw for MVTC,
but we missed doing so for the CLRPSW/SETPSW of the U bit.

Reported-by: Tomoaki Kawada <i@yvt.jp>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Message-Id: <20220417165130.695085-5-richard.henderson@linaro.org>

target/rx/translate.c

index bd4d110e8b541dce4d702a1880cf5cc4eaf43087..63c062993e61b1f1c695a82a64d9b47ec6707dab 100644 (file)
@@ -2165,7 +2165,12 @@ static inline void clrsetpsw(DisasContext *ctx, int cb, int val)
             ctx->base.is_jmp = DISAS_UPDATE;
             break;
         case PSW_U:
-            tcg_gen_movi_i32(cpu_psw_u, val);
+            if (FIELD_EX32(ctx->tb_flags, PSW, U) != val) {
+                ctx->tb_flags = FIELD_DP32(ctx->tb_flags, PSW, U, val);
+                tcg_gen_movi_i32(cpu_psw_u, val);
+                tcg_gen_mov_i32(val ? cpu_isp : cpu_usp, cpu_sp);
+                tcg_gen_mov_i32(cpu_sp, val ? cpu_usp : cpu_isp);
+            }
             break;
         default:
             qemu_log_mask(LOG_GUEST_ERROR, "Invalid distination %d", cb);