@@ -1632,6 +1632,14 @@ static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
}
+static void gen_load_fpr32_tl(DisasContext *ctx, TCGv t, int reg)
+{
+ if (ctx->hflags & MIPS_HFLAG_FRE) {
+ generate_exception(ctx, EXCP_RI);
+ }
+ tcg_gen_trunc_i64_tl(t, fpu_f64[reg]);
+}
+
static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
{
TCGv_i64 t64;
@@ -1644,6 +1652,17 @@ static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
tcg_temp_free_i64(t64);
}
+static void gen_store_fpr32_tl(DisasContext *ctx, TCGv t, int reg)
+{
+ TCGv_i64 t64 = tcg_temp_new_i64();
+ if (ctx->hflags & MIPS_HFLAG_FRE) {
+ generate_exception(ctx, EXCP_RI);
+ }
+ tcg_gen_extu_tl_i64(t64, t);
+ tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
+ tcg_temp_free_i64(t64);
+}
+
static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
{
if (ctx->hflags & MIPS_HFLAG_F64) {
@@ -8821,102 +8840,126 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
tcg_temp_free(t0);
}
-static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
+static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
{
- TCGLabel *l1;
TCGCond cond;
- TCGv_i32 t0;
+ TCGv t0, ts, zero;
if (rd == 0) {
/* Treat as NOP. */
return;
}
- if (tf)
+ if (tf) {
cond = TCG_COND_EQ;
- else
- cond = TCG_COND_NE;
-
- l1 = gen_new_label();
- t0 = tcg_temp_new_i32();
- tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
- tcg_gen_brcondi_i32(cond, t0, 0, l1);
- tcg_temp_free_i32(t0);
- if (rs == 0) {
- tcg_gen_movi_tl(cpu_gpr[rd], 0);
} else {
- tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
+ cond = TCG_COND_NE;
}
- gen_set_label(l1);
+
+ t0 = tcg_temp_new();
+ tcg_gen_extu_i32_tl(t0, fpu_fcr31);
+ tcg_gen_andi_tl(t0, t0, 1 << get_fp_bit(cc));
+
+ zero = tcg_const_tl(0);
+ ts = rs ? cpu_gpr[rs] : zero;
+ tcg_gen_movcond_tl(cond, cpu_gpr[rd], t0, zero, ts, cpu_gpr[rd]);
+ tcg_temp_free(zero);
+ tcg_temp_free(t0);
}
-static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
- int tf)
+static void gen_mov_s_cond(DisasContext *ctx, int fs, int fd,
+ TCGv cc, TCGCond cond)
{
- int cond;
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGLabel *l1 = gen_new_label();
+ TCGv td = tcg_temp_new();
+ TCGv ts = tcg_temp_new();
+ TCGv zero = tcg_const_tl(0);
+
+ gen_load_fpr32_tl(ctx, ts, fs);
+ gen_load_fpr32_tl(ctx, td, fd);
+ tcg_gen_movcond_tl(cond, td, cc, zero, ts, td);
+ gen_store_fpr32_tl(ctx, td, fd);
+
+ tcg_temp_free(ts);
+ tcg_temp_free(td);
+ tcg_temp_free(zero);
+}
- if (tf)
- cond = TCG_COND_EQ;
- else
- cond = TCG_COND_NE;
+static void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, int tf)
+{
+ TCGCond cond = tf ? TCG_COND_EQ : TCG_COND_NE;
+ TCGv_i32 tc = tcg_temp_new_i32();
+ TCGv_i32 td = tcg_temp_new_i32();
+ TCGv_i32 ts = tcg_temp_new_i32();
+ TCGv_i32 zero = tcg_const_i32(0);
+
+ tcg_gen_andi_i32(tc, fpu_fcr31, 1 << get_fp_bit(cc));
+ gen_load_fpr32(ctx, ts, fs);
+ gen_load_fpr32(ctx, td, fd);
+ tcg_gen_movcond_i32(cond, td, tc, zero, ts, td);
+ gen_store_fpr32(ctx, td, fd);
+
+ tcg_temp_free_i32(tc);
+ tcg_temp_free_i32(ts);
+ tcg_temp_free_i32(td);
+ tcg_temp_free_i32(zero);
+}
- tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
- tcg_gen_brcondi_i32(cond, t0, 0, l1);
- gen_load_fpr32(ctx, t0, fs);
- gen_store_fpr32(ctx, t0, fd);
- gen_set_label(l1);
- tcg_temp_free_i32(t0);
+static void gen_mov_d_cond(DisasContext *ctx, int fs, int fd,
+ TCGv cc, TCGCond cond)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 td = tcg_temp_new_i64();
+ TCGv_i64 ts = tcg_temp_new_i64();
+ TCGv_i64 zero = tcg_const_i64(0);
+
+ tcg_gen_extu_tl_i64(t0, cc);
+ gen_load_fpr64(ctx, ts, fs);
+ gen_load_fpr64(ctx, td, fs);
+ tcg_gen_movcond_i64(cond, td, t0, zero, ts, td);
+ gen_store_fpr64(ctx, td, fd);
+
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(ts);
+ tcg_temp_free_i64(td);
+ tcg_temp_free_i64(zero);
}
-static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
+static void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, int tf)
{
- int cond;
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i64 fp0;
- TCGLabel *l1 = gen_new_label();
+ TCGCond cond = tf ? TCG_COND_EQ : TCG_COND_NE;
+ TCGv t0 = tcg_temp_new();
- if (tf)
- cond = TCG_COND_EQ;
- else
- cond = TCG_COND_NE;
+ tcg_gen_extu_i32_tl(t0, fpu_fcr31);
+ tcg_gen_andi_tl(t0, t0, 1 << get_fp_bit(cc));
+ gen_mov_d_cond(ctx, fs, fd, t0, cond);
- tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
- tcg_gen_brcondi_i32(cond, t0, 0, l1);
- tcg_temp_free_i32(t0);
- fp0 = tcg_temp_new_i64();
- gen_load_fpr64(ctx, fp0, fs);
- gen_store_fpr64(ctx, fp0, fd);
- tcg_temp_free_i64(fp0);
- gen_set_label(l1);
+ tcg_temp_free(t0);
}
-static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
- int cc, int tf)
+static void gen_movcf_ps(DisasContext *ctx, int fs, int fd, int cc, int tf)
{
- int cond;
+ TCGCond cond = tf ? TCG_COND_EQ : TCG_COND_NE;
TCGv_i32 t0 = tcg_temp_new_i32();
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
-
- if (tf)
- cond = TCG_COND_EQ;
- else
- cond = TCG_COND_NE;
+ TCGv_i32 ts = tcg_temp_new_i32();
+ TCGv_i32 td = tcg_temp_new_i32();
+ TCGv_i32 zero = tcg_const_i32(0);
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
- tcg_gen_brcondi_i32(cond, t0, 0, l1);
- gen_load_fpr32(ctx, t0, fs);
- gen_store_fpr32(ctx, t0, fd);
- gen_set_label(l1);
+ gen_load_fpr32(ctx, ts, fs);
+ gen_load_fpr32(ctx, td, fd);
+ tcg_gen_movcond_i32(cond, td, t0, zero, ts, td);
+ gen_store_fpr32(ctx, td, fd);
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
- tcg_gen_brcondi_i32(cond, t0, 0, l2);
- gen_load_fpr32h(ctx, t0, fs);
- gen_store_fpr32h(ctx, t0, fd);
+ gen_load_fpr32h(ctx, ts, fs);
+ gen_load_fpr32h(ctx, td, fs);
+ tcg_gen_movcond_i32(cond, td, t0, zero, ts, td);
+ gen_store_fpr32h(ctx, td, fd);
+
tcg_temp_free_i32(t0);
- gen_set_label(l2);
+ tcg_temp_free_i32(ts);
+ tcg_temp_free_i32(td);
+ tcg_temp_free_i32(zero);
}
static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
@@ -9261,35 +9304,20 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
break;
case OPC_MOVZ_S:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
- {
- TCGLabel *l1 = gen_new_label();
- TCGv_i32 fp0;
-
- if (ft != 0) {
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
- }
- fp0 = tcg_temp_new_i32();
+ if (ft != 0) {
+ gen_mov_s_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_EQ);
+ } else {
+ TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(ctx, fp0, fs);
gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0);
- gen_set_label(l1);
}
opn = "movz.s";
break;
case OPC_MOVN_S:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
- {
- TCGLabel *l1 = gen_new_label();
- TCGv_i32 fp0;
-
- if (ft != 0) {
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
- fp0 = tcg_temp_new_i32();
- gen_load_fpr32(ctx, fp0, fs);
- gen_store_fpr32(ctx, fp0, fd);
- tcg_temp_free_i32(fp0);
- gen_set_label(l1);
- }
+ if (ft != 0) {
+ gen_mov_s_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_NE);
}
opn = "movn.s";
break;
@@ -9806,35 +9834,20 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
break;
case OPC_MOVZ_D:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
- {
- TCGLabel *l1 = gen_new_label();
- TCGv_i64 fp0;
-
- if (ft != 0) {
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
- }
- fp0 = tcg_temp_new_i64();
+ if (ft != 0) {
+ gen_mov_d_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_EQ);
+ } else {
+ TCGv_i64 fp0 = tcg_temp_new_i64();
gen_load_fpr64(ctx, fp0, fs);
gen_store_fpr64(ctx, fp0, fd);
tcg_temp_free_i64(fp0);
- gen_set_label(l1);
}
opn = "movz.d";
break;
case OPC_MOVN_D:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
- {
- TCGLabel *l1 = gen_new_label();
- TCGv_i64 fp0;
-
- if (ft != 0) {
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
- fp0 = tcg_temp_new_i64();
- gen_load_fpr64(ctx, fp0, fs);
- gen_store_fpr64(ctx, fp0, fd);
- tcg_temp_free_i64(fp0);
- gen_set_label(l1);
- }
+ if (ft != 0) {
+ gen_mov_d_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_NE);
}
opn = "movn.d";
break;
@@ -10244,34 +10257,20 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
break;
case OPC_MOVZ_PS:
check_ps(ctx);
- {
- TCGLabel *l1 = gen_new_label();
- TCGv_i64 fp0;
-
- if (ft != 0)
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
- fp0 = tcg_temp_new_i64();
+ if (ft != 0) {
+ gen_mov_d_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_EQ);
+ } else {
+ TCGv_i64 fp0 = tcg_temp_new_i64();
gen_load_fpr64(ctx, fp0, fs);
gen_store_fpr64(ctx, fp0, fd);
tcg_temp_free_i64(fp0);
- gen_set_label(l1);
}
opn = "movz.ps";
break;
case OPC_MOVN_PS:
check_ps(ctx);
- {
- TCGLabel *l1 = gen_new_label();
- TCGv_i64 fp0;
-
- if (ft != 0) {
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
- fp0 = tcg_temp_new_i64();
- gen_load_fpr64(ctx, fp0, fs);
- gen_store_fpr64(ctx, fp0, fd);
- tcg_temp_free_i64(fp0);
- gen_set_label(l1);
- }
+ if (ft != 0) {
+ gen_mov_d_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_NE);
}
opn = "movn.ps";
break;
Signed-off-by: Richard Henderson <rth@twiddle.net> --- target-mips/translate.c | 255 ++++++++++++++++++++++++------------------------ 1 file changed, 127 insertions(+), 128 deletions(-)