Patchwork [21/57] target-i386: do not call helper to compute ZF/SF

login
register
mail settings
Submitter Richard Henderson
Date Feb. 19, 2013, 5:39 p.m.
Message ID <1361295631-21316-22-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/221927/
State New
Headers show

Comments

Richard Henderson - Feb. 19, 2013, 5:39 p.m.
ZF, SF and PF can always be computed from CC_DST except in the
CC_OP_EFLAGS case (and CC_OP_DYNAMIC, which just resolves to CC_OP_EFLAGS
in gen_compute_eflags).  Use setcond to compute ZF and SF.

We could also use a table lookup to compute PF.

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-i386/translate.c | 37 +++++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

Patch

diff --git a/target-i386/translate.c b/target-i386/translate.c
index a767b50..026fbd6 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -900,9 +900,22 @@  static void gen_compute_eflags_p(DisasContext *s, TCGv reg)
 /* compute eflags.S to reg */
 static void gen_compute_eflags_s(DisasContext *s, TCGv reg)
 {
-    gen_compute_eflags(s);
-    tcg_gen_shri_tl(reg, cpu_cc_src, 7);
-    tcg_gen_andi_tl(reg, reg, 1);
+    switch (s->cc_op) {
+    case CC_OP_DYNAMIC:
+        gen_compute_eflags(s);
+        /* FALLTHRU */
+    case CC_OP_EFLAGS:
+        tcg_gen_shri_tl(reg, cpu_cc_src, 7);
+        tcg_gen_andi_tl(reg, reg, 1);
+        break;
+    default:
+        {
+            int size = (s->cc_op - CC_OP_ADDB) & 3;
+            TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
+            tcg_gen_setcondi_tl(TCG_COND_LT, reg, t0, 0);
+        }
+        break;
+    }
 }
 
 /* compute eflags.O to reg */
@@ -916,9 +929,21 @@  static void gen_compute_eflags_o(DisasContext *s, TCGv reg)
 /* compute eflags.Z to reg */
 static void gen_compute_eflags_z(DisasContext *s, TCGv reg)
 {
-    gen_compute_eflags(s);
-    tcg_gen_shri_tl(reg, cpu_cc_src, 6);
-    tcg_gen_andi_tl(reg, reg, 1);
+    switch (s->cc_op) {
+    case CC_OP_DYNAMIC:
+        gen_compute_eflags(s);
+        /* FALLTHRU */
+    case CC_OP_EFLAGS:
+        tcg_gen_shri_tl(reg, cpu_cc_src, 6);
+        tcg_gen_andi_tl(reg, reg, 1);
+        break;
+    default:
+        {
+            int size = (s->cc_op - CC_OP_ADDB) & 3;
+            TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
+            tcg_gen_setcondi_tl(TCG_COND_EQ, reg, t0, 0);
+        }
+    }
 }
 
 static inline void gen_setcc_slow_T0(DisasContext *s, int jcc_op)