target-arm: use native tcg-ops for ror/bic/vorn
Acked-by: Laurent Desnogues <laurent.desnogues@gmail.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
50f67e95e2
commit
f669df275c
|
@ -151,7 +151,6 @@ DEF_HELPER_2(sbc_cc, i32, i32, i32)
|
||||||
DEF_HELPER_2(shl, i32, i32, i32)
|
DEF_HELPER_2(shl, i32, i32, i32)
|
||||||
DEF_HELPER_2(shr, i32, i32, i32)
|
DEF_HELPER_2(shr, i32, i32, i32)
|
||||||
DEF_HELPER_2(sar, i32, i32, i32)
|
DEF_HELPER_2(sar, i32, i32, i32)
|
||||||
DEF_HELPER_2(ror, i32, i32, i32)
|
|
||||||
DEF_HELPER_2(shl_cc, i32, i32, i32)
|
DEF_HELPER_2(shl_cc, i32, i32, i32)
|
||||||
DEF_HELPER_2(shr_cc, i32, i32, i32)
|
DEF_HELPER_2(shr_cc, i32, i32, i32)
|
||||||
DEF_HELPER_2(sar_cc, i32, i32, i32)
|
DEF_HELPER_2(sar_cc, i32, i32, i32)
|
||||||
|
|
|
@ -379,14 +379,6 @@ uint32_t HELPER(sar)(uint32_t x, uint32_t i)
|
||||||
return (int32_t)x >> shift;
|
return (int32_t)x >> shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t HELPER(ror)(uint32_t x, uint32_t i)
|
|
||||||
{
|
|
||||||
int shift = i & 0xff;
|
|
||||||
if (shift == 0)
|
|
||||||
return x;
|
|
||||||
return (x >> shift) | (x << (32 - shift));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
|
uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
|
||||||
{
|
{
|
||||||
int shift = i & 0xff;
|
int shift = i & 0xff;
|
||||||
|
|
|
@ -405,34 +405,9 @@ static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
|
||||||
dead_tmp(tmp);
|
dead_tmp(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* T0 &= ~T1. Clobbers T1. */
|
|
||||||
/* FIXME: Implement bic natively. */
|
|
||||||
static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
|
|
||||||
{
|
|
||||||
TCGv tmp = new_tmp();
|
|
||||||
tcg_gen_not_i32(tmp, t1);
|
|
||||||
tcg_gen_and_i32(dest, t0, tmp);
|
|
||||||
dead_tmp(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Implement this natively. */
|
/* FIXME: Implement this natively. */
|
||||||
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
|
#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
|
||||||
|
|
||||||
/* FIXME: Implement this natively. */
|
|
||||||
static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
|
|
||||||
{
|
|
||||||
TCGv tmp;
|
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
tmp = new_tmp();
|
|
||||||
tcg_gen_shri_i32(tmp, t1, i);
|
|
||||||
tcg_gen_shli_i32(t1, t1, 32 - i);
|
|
||||||
tcg_gen_or_i32(t0, t1, tmp);
|
|
||||||
dead_tmp(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void shifter_out_im(TCGv var, int shift)
|
static void shifter_out_im(TCGv var, int shift)
|
||||||
{
|
{
|
||||||
TCGv tmp = new_tmp();
|
TCGv tmp = new_tmp();
|
||||||
|
@ -484,7 +459,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
|
||||||
if (shift != 0) {
|
if (shift != 0) {
|
||||||
if (flags)
|
if (flags)
|
||||||
shifter_out_im(var, shift - 1);
|
shifter_out_im(var, shift - 1);
|
||||||
tcg_gen_rori_i32(var, var, shift); break;
|
tcg_gen_rotri_i32(var, var, shift); break;
|
||||||
} else {
|
} else {
|
||||||
TCGv tmp = load_cpu_field(CF);
|
TCGv tmp = load_cpu_field(CF);
|
||||||
if (flags)
|
if (flags)
|
||||||
|
@ -512,7 +487,8 @@ static inline void gen_arm_shift_reg(TCGv var, int shiftop,
|
||||||
case 0: gen_helper_shl(var, var, shift); break;
|
case 0: gen_helper_shl(var, var, shift); break;
|
||||||
case 1: gen_helper_shr(var, var, shift); break;
|
case 1: gen_helper_shr(var, var, shift); break;
|
||||||
case 2: gen_helper_sar(var, var, shift); break;
|
case 2: gen_helper_sar(var, var, shift); break;
|
||||||
case 3: gen_helper_ror(var, var, shift); break;
|
case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
|
||||||
|
tcg_gen_rotr_i32(var, var, shift); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dead_tmp(shift);
|
dead_tmp(shift);
|
||||||
|
@ -1453,7 +1429,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
|
||||||
case ARM_IWMMXT_wCSSF:
|
case ARM_IWMMXT_wCSSF:
|
||||||
tmp = iwmmxt_load_creg(wrd);
|
tmp = iwmmxt_load_creg(wrd);
|
||||||
tmp2 = load_reg(s, rd);
|
tmp2 = load_reg(s, rd);
|
||||||
tcg_gen_bic_i32(tmp, tmp, tmp2);
|
tcg_gen_andc_i32(tmp, tmp, tmp2);
|
||||||
dead_tmp(tmp2);
|
dead_tmp(tmp2);
|
||||||
iwmmxt_store_creg(wrd, tmp);
|
iwmmxt_store_creg(wrd, tmp);
|
||||||
break;
|
break;
|
||||||
|
@ -3931,7 +3907,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
|
static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
|
||||||
{
|
{
|
||||||
tcg_gen_and_i32(t, t, c);
|
tcg_gen_and_i32(t, t, c);
|
||||||
tcg_gen_bic_i32(f, f, c);
|
tcg_gen_andc_i32(f, f, c);
|
||||||
tcg_gen_or_i32(dest, t, f);
|
tcg_gen_or_i32(dest, t, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4244,14 +4220,13 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
tcg_gen_and_i32(tmp, tmp, tmp2);
|
tcg_gen_and_i32(tmp, tmp, tmp2);
|
||||||
break;
|
break;
|
||||||
case 1: /* BIC */
|
case 1: /* BIC */
|
||||||
tcg_gen_bic_i32(tmp, tmp, tmp2);
|
tcg_gen_andc_i32(tmp, tmp, tmp2);
|
||||||
break;
|
break;
|
||||||
case 2: /* VORR */
|
case 2: /* VORR */
|
||||||
tcg_gen_or_i32(tmp, tmp, tmp2);
|
tcg_gen_or_i32(tmp, tmp, tmp2);
|
||||||
break;
|
break;
|
||||||
case 3: /* VORN */
|
case 3: /* VORN */
|
||||||
tcg_gen_not_i32(tmp2, tmp2);
|
tcg_gen_orc_i32(tmp, tmp, tmp2);
|
||||||
tcg_gen_or_i32(tmp, tmp, tmp2);
|
|
||||||
break;
|
break;
|
||||||
case 4: /* VEOR */
|
case 4: /* VEOR */
|
||||||
tcg_gen_xor_i32(tmp, tmp, tmp2);
|
tcg_gen_xor_i32(tmp, tmp, tmp2);
|
||||||
|
@ -6304,7 +6279,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0e:
|
case 0x0e:
|
||||||
tcg_gen_bic_i32(tmp, tmp, tmp2);
|
tcg_gen_andc_i32(tmp, tmp, tmp2);
|
||||||
if (logic_cc) {
|
if (logic_cc) {
|
||||||
gen_logic_CC(tmp);
|
gen_logic_CC(tmp);
|
||||||
}
|
}
|
||||||
|
@ -6635,7 +6610,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
|
||||||
/* ??? In many cases it's not neccessary to do a
|
/* ??? In many cases it's not neccessary to do a
|
||||||
rotate, a shift is sufficient. */
|
rotate, a shift is sufficient. */
|
||||||
if (shift != 0)
|
if (shift != 0)
|
||||||
tcg_gen_rori_i32(tmp, tmp, shift * 8);
|
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
|
||||||
op1 = (insn >> 20) & 7;
|
op1 = (insn >> 20) & 7;
|
||||||
switch (op1) {
|
switch (op1) {
|
||||||
case 0: gen_sxtb16(tmp); break;
|
case 0: gen_sxtb16(tmp); break;
|
||||||
|
@ -7023,7 +6998,7 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCG
|
||||||
logic_cc = conds;
|
logic_cc = conds;
|
||||||
break;
|
break;
|
||||||
case 1: /* bic */
|
case 1: /* bic */
|
||||||
tcg_gen_bic_i32(t0, t0, t1);
|
tcg_gen_andc_i32(t0, t0, t1);
|
||||||
logic_cc = conds;
|
logic_cc = conds;
|
||||||
break;
|
break;
|
||||||
case 2: /* orr */
|
case 2: /* orr */
|
||||||
|
@ -7449,7 +7424,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
|
||||||
/* ??? In many cases it's not neccessary to do a
|
/* ??? In many cases it's not neccessary to do a
|
||||||
rotate, a shift is sufficient. */
|
rotate, a shift is sufficient. */
|
||||||
if (shift != 0)
|
if (shift != 0)
|
||||||
tcg_gen_rori_i32(tmp, tmp, shift * 8);
|
tcg_gen_rotri_i32(tmp, tmp, shift * 8);
|
||||||
op = (insn >> 20) & 7;
|
op = (insn >> 20) & 7;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case 0: gen_sxth(tmp); break;
|
case 0: gen_sxth(tmp); break;
|
||||||
|
@ -8346,7 +8321,8 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
|
||||||
break;
|
break;
|
||||||
case 0x7: /* ror */
|
case 0x7: /* ror */
|
||||||
if (s->condexec_mask) {
|
if (s->condexec_mask) {
|
||||||
gen_helper_ror(tmp2, tmp2, tmp);
|
tcg_gen_andi_i32(tmp, tmp, 0x1f);
|
||||||
|
tcg_gen_rotr_i32(tmp2, tmp2, tmp);
|
||||||
} else {
|
} else {
|
||||||
gen_helper_ror_cc(tmp2, tmp2, tmp);
|
gen_helper_ror_cc(tmp2, tmp2, tmp);
|
||||||
gen_logic_CC(tmp2);
|
gen_logic_CC(tmp2);
|
||||||
|
@ -8382,7 +8358,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
|
||||||
gen_logic_CC(tmp);
|
gen_logic_CC(tmp);
|
||||||
break;
|
break;
|
||||||
case 0xe: /* bic */
|
case 0xe: /* bic */
|
||||||
tcg_gen_bic_i32(tmp, tmp, tmp2);
|
tcg_gen_andc_i32(tmp, tmp, tmp2);
|
||||||
if (!s->condexec_mask)
|
if (!s->condexec_mask)
|
||||||
gen_logic_CC(tmp);
|
gen_logic_CC(tmp);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue