alpha: convert cmov and bcond to TCG

Patch mostly by Tristan Gingold

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5245 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aurel32 2008-09-17 22:04:44 +00:00
parent a986fcc469
commit 9c29504eb7
3 changed files with 69 additions and 115 deletions

View File

@ -434,72 +434,6 @@ void OPPROTO op_cmpbge (void)
RETURN(); RETURN();
} }
void OPPROTO op_cmpeqz (void)
{
if (T0 == 0)
T0 = 1;
else
T0 = 0;
RETURN();
}
void OPPROTO op_cmpnez (void)
{
if (T0 != 0)
T0 = 1;
else
T0 = 0;
RETURN();
}
void OPPROTO op_cmpltz (void)
{
if ((int64_t)T0 < 0)
T0 = 1;
else
T0 = 0;
RETURN();
}
void OPPROTO op_cmplez (void)
{
if ((int64_t)T0 <= 0)
T0 = 1;
else
T0 = 0;
RETURN();
}
void OPPROTO op_cmpgtz (void)
{
if ((int64_t)T0 > 0)
T0 = 1;
else
T0 = 0;
RETURN();
}
void OPPROTO op_cmpgez (void)
{
if ((int64_t)T0 >= 0)
T0 = 1;
else
T0 = 0;
RETURN();
}
void OPPROTO op_cmplbs (void)
{
T0 &= 1;
RETURN();
}
void OPPROTO op_cmplbc (void)
{
T0 = (~T0) & 1;
RETURN();
}
#if 0 // Qemu does not know how to do this... #if 0 // Qemu does not know how to do this...
void OPPROTO op_bcond (void) void OPPROTO op_bcond (void)
{ {

View File

@ -37,15 +37,7 @@ void OPPROTO glue(op_reset_FT, REG) (void)
#endif /* REG < 3 */ #endif /* REG < 3 */
/* Fixed-point register moves */
#if REG < 31 #if REG < 31
void OPPROTO glue(op_cmov_ir, REG) (void)
{
if (T0)
env->ir[REG] = T1;
RETURN();
}
/* floating point registers moves */ /* floating point registers moves */
void OPPROTO glue(op_load_FT0_fir, REG) (void) void OPPROTO glue(op_load_FT0_fir, REG) (void)
{ {

View File

@ -124,11 +124,6 @@ static always_inline void func (int n) \
NAME ## _table[n](); \ NAME ## _table[n](); \
} }
/* IR moves */
/* Special hacks for ir31 */
#define gen_op_cmov_ir31 gen_op_nop
GEN32(gen_op_cmov_ir, gen_op_cmov_ir);
/* FIR moves */ /* FIR moves */
/* Special hacks for fir31 */ /* Special hacks for fir31 */
#define gen_op_load_FT0_fir31 gen_op_reset_FT0 #define gen_op_load_FT0_fir31 gen_op_reset_FT0
@ -328,16 +323,32 @@ static always_inline void gen_store_fmem (DisasContext *ctx,
} }
static always_inline void gen_bcond (DisasContext *ctx, static always_inline void gen_bcond (DisasContext *ctx,
void (*gen_test_op)(void), TCGCond cond,
int ra, int32_t disp16) int ra, int32_t disp16, int mask)
{ {
tcg_gen_movi_i64(cpu_T[1], ctx->pc + (int64_t)(disp16 << 2)); int l1, l2;
if (ra != 31)
tcg_gen_mov_i64(cpu_T[0], cpu_ir[ra]); l1 = gen_new_label();
else l2 = gen_new_label();
tcg_gen_movi_i64(cpu_T[0], 0); if (likely(ra != 31)) {
(*gen_test_op)(); if (mask) {
_gen_op_bcond(ctx); TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
tcg_gen_brcondi_i64(cond, tmp, 0, l1);
tcg_temp_free(tmp);
} else
tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, l1);
} else {
/* Very uncommon case - Do not bother to optimize. */
TCGv tmp = tcg_const_i64(0);
tcg_gen_brcondi_i64(cond, tmp, 0, l1);
tcg_temp_free(tmp);
}
tcg_gen_movi_i64(cpu_pc, ctx->pc);
tcg_gen_br(l2);
gen_set_label(l1);
tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2));
gen_set_label(l2);
} }
static always_inline void gen_fbcond (DisasContext *ctx, static always_inline void gen_fbcond (DisasContext *ctx,
@ -371,22 +382,39 @@ static always_inline void gen_arith3 (DisasContext *ctx,
} }
static always_inline void gen_cmov (DisasContext *ctx, static always_inline void gen_cmov (DisasContext *ctx,
void (*gen_test_op)(void), TCGCond inv_cond,
int ra, int rb, int rc, int ra, int rb, int rc,
int islit, uint8_t lit) int islit, int8_t lit, int mask)
{ {
if (ra != 31) int l1;
tcg_gen_mov_i64(cpu_T[0], cpu_ir[ra]);
else if (unlikely(rc == 31))
tcg_gen_movi_i64(cpu_T[0], 0); return;
l1 = gen_new_label();
if (ra != 31) {
if (mask) {
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
tcg_temp_free(tmp);
} else
tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
} else {
/* Very uncommon case - Do not bother to optimize. */
TCGv tmp = tcg_const_i64(0);
tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
tcg_temp_free(tmp);
}
if (islit) if (islit)
tcg_gen_movi_i64(cpu_T[1], lit); tcg_gen_movi_i64(cpu_ir[rc], lit);
else if (rb != 31) else if (rb != 31)
tcg_gen_mov_i64(cpu_T[1], cpu_ir[rb]); tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
else else
tcg_gen_movi_i64(cpu_T[1], 0); tcg_gen_movi_i64(cpu_ir[rc], 0);
(*gen_test_op)(); gen_set_label(l1);
gen_op_cmov_ir(rc);
} }
static always_inline void gen_farith2 (DisasContext *ctx, static always_inline void gen_farith2 (DisasContext *ctx,
@ -933,11 +961,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
break; break;
case 0x14: case 0x14:
/* CMOVLBS */ /* CMOVLBS */
gen_cmov(ctx, &gen_op_cmplbs, ra, rb, rc, islit, lit); gen_cmov(ctx, TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
break; break;
case 0x16: case 0x16:
/* CMOVLBC */ /* CMOVLBC */
gen_cmov(ctx, &gen_op_cmplbc, ra, rb, rc, islit, lit); gen_cmov(ctx, TCG_COND_NE, ra, rb, rc, islit, lit, 1);
break; break;
case 0x20: case 0x20:
/* BIS */ /* BIS */
@ -961,11 +989,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
break; break;
case 0x24: case 0x24:
/* CMOVEQ */ /* CMOVEQ */
gen_cmov(ctx, &gen_op_cmpeqz, ra, rb, rc, islit, lit); gen_cmov(ctx, TCG_COND_NE, ra, rb, rc, islit, lit, 0);
break; break;
case 0x26: case 0x26:
/* CMOVNE */ /* CMOVNE */
gen_cmov(ctx, &gen_op_cmpnez, ra, rb, rc, islit, lit); gen_cmov(ctx, TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
break; break;
case 0x28: case 0x28:
/* ORNOT */ /* ORNOT */
@ -1011,11 +1039,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
break; break;
case 0x44: case 0x44:
/* CMOVLT */ /* CMOVLT */
gen_cmov(ctx, &gen_op_cmpltz, ra, rb, rc, islit, lit); gen_cmov(ctx, TCG_COND_GE, ra, rb, rc, islit, lit, 0);
break; break;
case 0x46: case 0x46:
/* CMOVGE */ /* CMOVGE */
gen_cmov(ctx, &gen_op_cmpgez, ra, rb, rc, islit, lit); gen_cmov(ctx, TCG_COND_LT, ra, rb, rc, islit, lit, 0);
break; break;
case 0x48: case 0x48:
/* EQV */ /* EQV */
@ -1053,11 +1081,11 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
break; break;
case 0x64: case 0x64:
/* CMOVLE */ /* CMOVLE */
gen_cmov(ctx, &gen_op_cmplez, ra, rb, rc, islit, lit); gen_cmov(ctx, TCG_COND_GT, ra, rb, rc, islit, lit, 0);
break; break;
case 0x66: case 0x66:
/* CMOVGT */ /* CMOVGT */
gen_cmov(ctx, &gen_op_cmpgtz, ra, rb, rc, islit, lit); gen_cmov(ctx, TCG_COND_LE, ra, rb, rc, islit, lit, 0);
break; break;
case 0x6C: case 0x6C:
/* IMPLVER */ /* IMPLVER */
@ -2173,42 +2201,42 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
break; break;
case 0x38: case 0x38:
/* BLBC */ /* BLBC */
gen_bcond(ctx, &gen_op_cmplbc, ra, disp16); gen_bcond(ctx, TCG_COND_EQ, ra, disp16, 1);
ret = 1; ret = 1;
break; break;
case 0x39: case 0x39:
/* BEQ */ /* BEQ */
gen_bcond(ctx, &gen_op_cmpeqz, ra, disp16); gen_bcond(ctx, TCG_COND_EQ, ra, disp16, 0);
ret = 1; ret = 1;
break; break;
case 0x3A: case 0x3A:
/* BLT */ /* BLT */
gen_bcond(ctx, &gen_op_cmpltz, ra, disp16); gen_bcond(ctx, TCG_COND_LT, ra, disp16, 0);
ret = 1; ret = 1;
break; break;
case 0x3B: case 0x3B:
/* BLE */ /* BLE */
gen_bcond(ctx, &gen_op_cmplez, ra, disp16); gen_bcond(ctx, TCG_COND_LE, ra, disp16, 0);
ret = 1; ret = 1;
break; break;
case 0x3C: case 0x3C:
/* BLBS */ /* BLBS */
gen_bcond(ctx, &gen_op_cmplbs, ra, disp16); gen_bcond(ctx, TCG_COND_NE, ra, disp16, 1);
ret = 1; ret = 1;
break; break;
case 0x3D: case 0x3D:
/* BNE */ /* BNE */
gen_bcond(ctx, &gen_op_cmpnez, ra, disp16); gen_bcond(ctx, TCG_COND_NE, ra, disp16, 0);
ret = 1; ret = 1;
break; break;
case 0x3E: case 0x3E:
/* BGE */ /* BGE */
gen_bcond(ctx, &gen_op_cmpgez, ra, disp16); gen_bcond(ctx, TCG_COND_GE, ra, disp16, 0);
ret = 1; ret = 1;
break; break;
case 0x3F: case 0x3F:
/* BGT */ /* BGT */
gen_bcond(ctx, &gen_op_cmpgtz, ra, disp16); gen_bcond(ctx, TCG_COND_GT, ra, disp16, 0);
ret = 1; ret = 1;
break; break;
invalid_opc: invalid_opc: