target-mips: implement movn/movz using movcond

Avoid the branches in movn/movz implementation and replace them with
movcond. Also update a wrong command.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Aurelien Jarno 2012-10-09 21:53:21 +02:00
parent 2d2826b99e
commit acf1246558
1 changed files with 12 additions and 15 deletions

View File

@ -2359,35 +2359,32 @@ static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
int rd, int rs, int rt) int rd, int rs, int rt)
{ {
const char *opn = "cond move"; const char *opn = "cond move";
int l1; TCGv t0, t1, t2;
if (rd == 0) { if (rd == 0) {
/* If no destination, treat it as a NOP. /* If no destination, treat it as a NOP. */
For add & sub, we must generate the overflow exception when needed. */
MIPS_DEBUG("NOP"); MIPS_DEBUG("NOP");
return; return;
} }
l1 = gen_new_label(); t0 = tcg_temp_new();
gen_load_gpr(t0, rt);
t1 = tcg_const_tl(0);
t2 = tcg_temp_new();
gen_load_gpr(t2, rs);
switch (opc) { switch (opc) {
case OPC_MOVN: case OPC_MOVN:
if (likely(rt != 0)) tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
else
tcg_gen_br(l1);
opn = "movn"; opn = "movn";
break; break;
case OPC_MOVZ: case OPC_MOVZ:
if (likely(rt != 0)) tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
opn = "movz"; opn = "movz";
break; break;
} }
if (rs != 0) tcg_temp_free(t2);
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); tcg_temp_free(t1);
else tcg_temp_free(t0);
tcg_gen_movi_tl(cpu_gpr[rd], 0);
gen_set_label(l1);
(void)opn; /* avoid a compiler warning */ (void)opn; /* avoid a compiler warning */
MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);