diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-10-05 18:02:41 +0200 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-02-18 15:03:55 -0800 |
commit | d824df34e8cdd2fbe55258f26731d7ef3ac7ced2 (patch) | |
tree | b2bcb41f78f7bc060cdbd38eb8a2c55ca4f22ac7 /target-i386/translate.c | |
parent | 93ab25d7d129fbe47a99fd8c91292ea99bff747e (diff) |
target-i386: introduce gen_ext_tl
Introduce a function that abstracts extracting an 8, 16, 32 or 64-bit value
with or without sign, generalizing gen_extu and gen_exts.
Reviewed-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-i386/translate.c')
-rw-r--r-- | target-i386/translate.c | 146 |
1 files changed, 37 insertions, 109 deletions
diff --git a/target-i386/translate.c b/target-i386/translate.c index 94e14342d3..ccb06e27f5 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -659,38 +659,45 @@ static inline void gen_op_movl_T0_Dshift(int ot) tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot); }; -static void gen_extu(int ot, TCGv reg) +static TCGv gen_ext_tl(TCGv dst, TCGv src, int size, bool sign) { - switch(ot) { + switch (size) { case OT_BYTE: - tcg_gen_ext8u_tl(reg, reg); - break; + if (sign) { + tcg_gen_ext8s_tl(dst, src); + } else { + tcg_gen_ext8u_tl(dst, src); + } + return dst; case OT_WORD: - tcg_gen_ext16u_tl(reg, reg); - break; + if (sign) { + tcg_gen_ext16s_tl(dst, src); + } else { + tcg_gen_ext16u_tl(dst, src); + } + return dst; +#ifdef TARGET_X86_64 case OT_LONG: - tcg_gen_ext32u_tl(reg, reg); - break; + if (sign) { + tcg_gen_ext32s_tl(dst, src); + } else { + tcg_gen_ext32u_tl(dst, src); + } + return dst; +#endif default: - break; + return src; } } +static void gen_extu(int ot, TCGv reg) +{ + gen_ext_tl(reg, reg, ot, false); +} + static void gen_exts(int ot, TCGv reg) { - switch(ot) { - case OT_BYTE: - tcg_gen_ext8s_tl(reg, reg); - break; - case OT_WORD: - tcg_gen_ext16s_tl(reg, reg); - break; - case OT_LONG: - tcg_gen_ext32s_tl(reg, reg); - break; - default: - break; - } + gen_ext_tl(reg, reg, ot, true); } static inline void gen_op_jnz_ecx(int size, int label1) @@ -966,54 +973,15 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1) switch(jcc_op) { case JCC_Z: fast_jcc_z: - switch(size) { - case 0: - tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xff); - t0 = cpu_tmp0; - break; - case 1: - tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffff); - t0 = cpu_tmp0; - break; -#ifdef TARGET_X86_64 - case 2: - tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffffffff); - t0 = cpu_tmp0; - break; -#endif - default: - t0 = cpu_cc_dst; - break; - } + t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, false); tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1); break; case JCC_S: fast_jcc_s: - switch(size) { - case 0: - tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80); - tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, - 0, l1); - break; - case 1: - tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x8000); - tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, - 0, l1); - break; -#ifdef TARGET_X86_64 - case 2: - tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80000000); - tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, - 0, l1); - break; -#endif - default: - tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, cpu_cc_dst, - 0, l1); - break; - } + t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, true); + tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, t0, 0, l1); break; - + case JCC_B: cond = inv ? TCG_COND_GEU : TCG_COND_LTU; goto fast_jcc_b; @@ -1021,28 +989,8 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1) cond = inv ? TCG_COND_GTU : TCG_COND_LEU; fast_jcc_b: tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src); - switch(size) { - case 0: - t0 = cpu_tmp0; - tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xff); - tcg_gen_andi_tl(t0, cpu_cc_src, 0xff); - break; - case 1: - t0 = cpu_tmp0; - tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffff); - tcg_gen_andi_tl(t0, cpu_cc_src, 0xffff); - break; -#ifdef TARGET_X86_64 - case 2: - t0 = cpu_tmp0; - tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffffffff); - tcg_gen_andi_tl(t0, cpu_cc_src, 0xffffffff); - break; -#endif - default: - t0 = cpu_cc_src; - break; - } + gen_extu(size, cpu_tmp4); + t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false); tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1); break; @@ -1053,28 +1001,8 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1) cond = inv ? TCG_COND_GT : TCG_COND_LE; fast_jcc_l: tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src); - switch(size) { - case 0: - t0 = cpu_tmp0; - tcg_gen_ext8s_tl(cpu_tmp4, cpu_tmp4); - tcg_gen_ext8s_tl(t0, cpu_cc_src); - break; - case 1: - t0 = cpu_tmp0; - tcg_gen_ext16s_tl(cpu_tmp4, cpu_tmp4); - tcg_gen_ext16s_tl(t0, cpu_cc_src); - break; -#ifdef TARGET_X86_64 - case 2: - t0 = cpu_tmp0; - tcg_gen_ext32s_tl(cpu_tmp4, cpu_tmp4); - tcg_gen_ext32s_tl(t0, cpu_cc_src); - break; -#endif - default: - t0 = cpu_cc_src; - break; - } + gen_exts(size, cpu_tmp4); + t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true); tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1); break; |