From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52681) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZQGSt-0007qS-17 for qemu-devel@nongnu.org; Fri, 14 Aug 2015 11:00:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZQGSs-0006eh-47 for qemu-devel@nongnu.org; Fri, 14 Aug 2015 11:00:14 -0400 Received: from mail-qg0-x22d.google.com ([2607:f8b0:400d:c04::22d]:36507) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZQGSr-0006eS-Vw for qemu-devel@nongnu.org; Fri, 14 Aug 2015 11:00:14 -0400 Received: by qgdd90 with SMTP id d90so53007988qgd.3 for ; Fri, 14 Aug 2015 08:00:13 -0700 (PDT) Sender: Richard Henderson From: Richard Henderson Date: Fri, 14 Aug 2015 07:59:24 -0700 Message-Id: <1439564366-11633-10-git-send-email-rth@twiddle.net> In-Reply-To: <1439564366-11633-1-git-send-email-rth@twiddle.net> References: <1439564366-11633-1-git-send-email-rth@twiddle.net> Subject: [Qemu-devel] [PATCH 09/11] target-m68k: Optimize gen_flush_flags List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, schwab@linux-m68k.org, laurent@vivier.eu, gerg@uclinux.org --- target-m68k/translate.c | 56 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 6f60c6f..19097c2 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -461,18 +461,66 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base) static void gen_flush_flags(DisasContext *s) { - TCGv tmp; + TCGv t0, t1; switch (s->cc_op) { case CC_OP_FLAGS: return; + + case CC_OP_ADD: + tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X); + tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + /* Compute signed overflow for addition. */ + t0 = tcg_temp_new(); + t1 = tcg_temp_new(); + tcg_gen_sub_i32(t0, QREG_CC_N, QREG_CC_V); + tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V); + tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0); + tcg_temp_free(t0); + tcg_gen_andc_i32(QREG_CC_V, t1, QREG_CC_V); + tcg_temp_free(t1); + break; + + case CC_OP_SUB: + tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X); + tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + /* Compute signed overflow for subtraction. */ + t0 = tcg_temp_new(); + t1 = tcg_temp_new(); + tcg_gen_add_i32(t0, QREG_CC_N, QREG_CC_V); + tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V); + tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0); + tcg_temp_free(t0); + tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t1); + tcg_temp_free(t1); + break; + + case CC_OP_CMP: + tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_C, QREG_CC_N, QREG_CC_V); + tcg_gen_sub_i32(QREG_CC_Z, QREG_CC_N, QREG_CC_V); + /* Compute signed overflow for subtraction. */ + t0 = tcg_temp_new(); + tcg_gen_xor_i32(t0, QREG_CC_Z, QREG_CC_N); + tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, QREG_CC_N); + tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, t0); + tcg_temp_free(t0); + tcg_gen_mov_i32(QREG_CC_N, QREG_CC_Z); + break; + + case CC_OP_LOGIC: + tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + tcg_gen_movi_i32(QREG_CC_C, 0); + tcg_gen_movi_i32(QREG_CC_V, 0); + break; + case CC_OP_DYNAMIC: gen_helper_flush_flags(cpu_env, QREG_CC_OP); break; + default: - tmp = tcg_const_i32(s->cc_op); - gen_helper_flush_flags(cpu_env, tmp); - tcg_temp_free(tmp); + t0 = tcg_const_i32(s->cc_op); + gen_helper_flush_flags(cpu_env, t0); + tcg_temp_free(t0); break; } -- 2.4.3