mirror of
https://git.proxmox.com/git/qemu
synced 2025-07-09 17:17:20 +00:00
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:
parent
a986fcc469
commit
9c29504eb7
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user