aboutsummaryrefslogtreecommitdiff
path: root/target-sparc
diff options
context:
space:
mode:
Diffstat (limited to 'target-sparc')
-rw-r--r--target-sparc/op.c6
-rw-r--r--target-sparc/translate.c60
2 files changed, 42 insertions, 24 deletions
diff --git a/target-sparc/op.c b/target-sparc/op.c
index eadd1fd418..11a5519cb8 100644
--- a/target-sparc/op.c
+++ b/target-sparc/op.c
@@ -1589,12 +1589,6 @@ void OPPROTO op_fmovq_cc(void)
}
#endif
-void OPPROTO op_mov_cc(void)
-{
- if (T2)
- T0 = T1;
-}
-
void OPPROTO op_flushw(void)
{
if (env->cansave != NWINDOWS - 2) {
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index a366b1f1ac..58be1c78a0 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -577,6 +577,18 @@ static void gen_cond_reg(int cond)
break;
}
}
+
+// Inverted logic
+static const int gen_tcg_cond_reg[8] = {
+ -1,
+ TCG_COND_NE,
+ TCG_COND_GT,
+ TCG_COND_GE,
+ -1,
+ TCG_COND_EQ,
+ TCG_COND_LE,
+ TCG_COND_LT,
+};
#endif
/* XXX: potentially incorrect if dynamic npc */
@@ -2452,15 +2464,9 @@ static void disas_sparc_insn(DisasContext * dc)
{
int cc = GET_FIELD_SP(insn, 11, 12);
int cond = GET_FIELD_SP(insn, 14, 17);
- if (IS_IMM) { /* immediate */
- rs2 = GET_FIELD_SPs(insn, 0, 10);
- gen_movl_simm_T1(rs2);
- }
- else {
- rs2 = GET_FIELD_SP(insn, 0, 4);
- gen_movl_reg_T1(rs2);
- }
- gen_movl_reg_T0(rd);
+ TCGv r_zero;
+ int l1;
+
flush_T2(dc);
if (insn & (1 << 18)) {
if (cc == 0)
@@ -2472,8 +2478,21 @@ static void disas_sparc_insn(DisasContext * dc)
} else {
gen_fcond[cc][cond]();
}
- gen_op_mov_cc();
- gen_movl_T0_reg(rd);
+
+ l1 = gen_new_label();
+
+ r_zero = tcg_temp_new(TCG_TYPE_TL);
+ tcg_gen_movi_tl(r_zero, 0);
+ tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[2], r_zero, l1);
+ if (IS_IMM) { /* immediate */
+ rs2 = GET_FIELD_SPs(insn, 0, 10);
+ gen_movl_simm_T1(rs2);
+ } else {
+ rs2 = GET_FIELD_SP(insn, 0, 4);
+ gen_movl_reg_T1(rs2);
+ }
+ gen_movl_T1_reg(rd);
+ gen_set_label(l1);
break;
}
case 0x2d: /* V9 sdivx */
@@ -2498,21 +2517,26 @@ static void disas_sparc_insn(DisasContext * dc)
case 0x2f: /* V9 movr */
{
int cond = GET_FIELD_SP(insn, 10, 12);
+ TCGv r_zero;
+ int l1;
+
rs1 = GET_FIELD(insn, 13, 17);
- flush_T2(dc);
gen_movl_reg_T0(rs1);
- gen_cond_reg(cond);
+
+ l1 = gen_new_label();
+
+ r_zero = tcg_temp_new(TCG_TYPE_TL);
+ tcg_gen_movi_tl(r_zero, 0);
+ tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1);
if (IS_IMM) { /* immediate */
rs2 = GET_FIELD_SPs(insn, 0, 9);
gen_movl_simm_T1(rs2);
- }
- else {
+ } else {
rs2 = GET_FIELD_SP(insn, 0, 4);
gen_movl_reg_T1(rs2);
}
- gen_movl_reg_T0(rd);
- gen_op_mov_cc();
- gen_movl_T0_reg(rd);
+ gen_movl_T1_reg(rd);
+ gen_set_label(l1);
break;
}
#endif