mirror of
https://git.proxmox.com/git/qemu
synced 2025-07-03 22:22:31 +00:00
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>
This commit is contained in:
parent
93ab25d7d1
commit
d824df34e8
@ -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);
|
tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static TCGv gen_ext_tl(TCGv dst, TCGv src, int size, bool sign)
|
||||||
|
{
|
||||||
|
switch (size) {
|
||||||
|
case OT_BYTE:
|
||||||
|
if (sign) {
|
||||||
|
tcg_gen_ext8s_tl(dst, src);
|
||||||
|
} else {
|
||||||
|
tcg_gen_ext8u_tl(dst, src);
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
case OT_WORD:
|
||||||
|
if (sign) {
|
||||||
|
tcg_gen_ext16s_tl(dst, src);
|
||||||
|
} else {
|
||||||
|
tcg_gen_ext16u_tl(dst, src);
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
#ifdef TARGET_X86_64
|
||||||
|
case OT_LONG:
|
||||||
|
if (sign) {
|
||||||
|
tcg_gen_ext32s_tl(dst, src);
|
||||||
|
} else {
|
||||||
|
tcg_gen_ext32u_tl(dst, src);
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void gen_extu(int ot, TCGv reg)
|
static void gen_extu(int ot, TCGv reg)
|
||||||
{
|
{
|
||||||
switch(ot) {
|
gen_ext_tl(reg, reg, ot, false);
|
||||||
case OT_BYTE:
|
|
||||||
tcg_gen_ext8u_tl(reg, reg);
|
|
||||||
break;
|
|
||||||
case OT_WORD:
|
|
||||||
tcg_gen_ext16u_tl(reg, reg);
|
|
||||||
break;
|
|
||||||
case OT_LONG:
|
|
||||||
tcg_gen_ext32u_tl(reg, reg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_exts(int ot, TCGv reg)
|
static void gen_exts(int ot, TCGv reg)
|
||||||
{
|
{
|
||||||
switch(ot) {
|
gen_ext_tl(reg, reg, ot, true);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_op_jnz_ecx(int size, int label1)
|
static inline void gen_op_jnz_ecx(int size, int label1)
|
||||||
@ -966,52 +973,13 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
|
|||||||
switch(jcc_op) {
|
switch(jcc_op) {
|
||||||
case JCC_Z:
|
case JCC_Z:
|
||||||
fast_jcc_z:
|
fast_jcc_z:
|
||||||
switch(size) {
|
t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, false);
|
||||||
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;
|
|
||||||
}
|
|
||||||
tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1);
|
tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1);
|
||||||
break;
|
break;
|
||||||
case JCC_S:
|
case JCC_S:
|
||||||
fast_jcc_s:
|
fast_jcc_s:
|
||||||
switch(size) {
|
t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, true);
|
||||||
case 0:
|
tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, t0, 0, l1);
|
||||||
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;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JCC_B:
|
case 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;
|
cond = inv ? TCG_COND_GTU : TCG_COND_LEU;
|
||||||
fast_jcc_b:
|
fast_jcc_b:
|
||||||
tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
|
tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
|
||||||
switch(size) {
|
gen_extu(size, cpu_tmp4);
|
||||||
case 0:
|
t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
|
||||||
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;
|
|
||||||
}
|
|
||||||
tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
|
tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
|
||||||
break;
|
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;
|
cond = inv ? TCG_COND_GT : TCG_COND_LE;
|
||||||
fast_jcc_l:
|
fast_jcc_l:
|
||||||
tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
|
tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
|
||||||
switch(size) {
|
gen_exts(size, cpu_tmp4);
|
||||||
case 0:
|
t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
|
||||||
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;
|
|
||||||
}
|
|
||||||
tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
|
tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user