target-alpha: convert some arith3 instructions to TCG
Replace gen_arith3 generic macro and dyngen ops by instruction specific optimized TCG code. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5236 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
ae8ecd4231
commit
30c7183b67
@ -198,72 +198,36 @@ void OPPROTO op_clear_irf (void)
|
||||
}
|
||||
|
||||
/* Arithmetic */
|
||||
void OPPROTO op_addq (void)
|
||||
{
|
||||
T0 += T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_addqv (void)
|
||||
{
|
||||
helper_addqv();
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_addl (void)
|
||||
{
|
||||
T0 = (int64_t)((int32_t)(T0 + T1));
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_addlv (void)
|
||||
{
|
||||
helper_addlv();
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_subq (void)
|
||||
{
|
||||
T0 -= T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_subqv (void)
|
||||
{
|
||||
helper_subqv();
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_subl (void)
|
||||
{
|
||||
T0 = (int64_t)((int32_t)(T0 - T1));
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_sublv (void)
|
||||
{
|
||||
helper_sublv();
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_mull (void)
|
||||
{
|
||||
T0 = (int64_t)((int32_t)T0 * (int32_t)T1);
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_mullv (void)
|
||||
{
|
||||
helper_mullv();
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_mulq (void)
|
||||
{
|
||||
T0 = (int64_t)T0 * (int64_t)T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_mulqv (void)
|
||||
{
|
||||
helper_mulqv();
|
||||
@ -280,60 +244,6 @@ void OPPROTO op_umulh (void)
|
||||
}
|
||||
|
||||
/* Logical */
|
||||
void OPPROTO op_and (void)
|
||||
{
|
||||
T0 &= T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_bic (void)
|
||||
{
|
||||
T0 &= ~T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_bis (void)
|
||||
{
|
||||
T0 |= T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_eqv (void)
|
||||
{
|
||||
T0 ^= ~T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_ornot (void)
|
||||
{
|
||||
T0 |= ~T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_xor (void)
|
||||
{
|
||||
T0 ^= T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_sll (void)
|
||||
{
|
||||
T0 <<= T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_srl (void)
|
||||
{
|
||||
T0 >>= T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_sra (void)
|
||||
{
|
||||
T0 = (int64_t)T0 >> T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO op_mskbl (void)
|
||||
{
|
||||
helper_mskbl();
|
||||
|
@ -440,54 +440,6 @@ static always_inline void gen_itf (DisasContext *ctx,
|
||||
gen_store_fir(ctx, rc, 0);
|
||||
}
|
||||
|
||||
static always_inline void gen_s4addl (void)
|
||||
{
|
||||
tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
|
||||
gen_op_addl();
|
||||
}
|
||||
|
||||
static always_inline void gen_s4subl (void)
|
||||
{
|
||||
tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
|
||||
gen_op_subl();
|
||||
}
|
||||
|
||||
static always_inline void gen_s8addl (void)
|
||||
{
|
||||
tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
|
||||
gen_op_addl();
|
||||
}
|
||||
|
||||
static always_inline void gen_s8subl (void)
|
||||
{
|
||||
tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
|
||||
gen_op_subl();
|
||||
}
|
||||
|
||||
static always_inline void gen_s4addq (void)
|
||||
{
|
||||
tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
|
||||
tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
|
||||
}
|
||||
|
||||
static always_inline void gen_s4subq (void)
|
||||
{
|
||||
tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
|
||||
tcg_gen_sub_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
|
||||
}
|
||||
|
||||
static always_inline void gen_s8addq (void)
|
||||
{
|
||||
tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
|
||||
tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
|
||||
}
|
||||
|
||||
static always_inline void gen_s8subq (void)
|
||||
{
|
||||
tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
|
||||
tcg_gen_sub_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
|
||||
}
|
||||
|
||||
static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
{
|
||||
uint32_t palcode;
|
||||
@ -616,19 +568,103 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
switch (fn7) {
|
||||
case 0x00:
|
||||
/* ADDL */
|
||||
gen_arith3(ctx, &gen_op_addl, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit) {
|
||||
tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
} else if (rb != 31) {
|
||||
tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
} else
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], (int32_t)lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x02:
|
||||
/* S4ADDL */
|
||||
gen_arith3(ctx, &gen_s4addl, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit || rb != 31) {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
|
||||
if (islit)
|
||||
tcg_gen_addi_i64(tmp, tmp, lit);
|
||||
else
|
||||
tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
|
||||
tcg_temp_free(tmp);
|
||||
} else {
|
||||
tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
}
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x09:
|
||||
/* SUBL */
|
||||
gen_arith3(ctx, &gen_op_subl, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit) {
|
||||
tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
} else if (rb != 31) {
|
||||
tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
} else
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], -lit);
|
||||
else if (rb != 31) {
|
||||
tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
} else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0B:
|
||||
/* S4SUBL */
|
||||
gen_arith3(ctx, &gen_s4subl, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit || rb != 31) {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
|
||||
if (islit)
|
||||
tcg_gen_subi_i64(tmp, tmp, lit);
|
||||
else
|
||||
tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
|
||||
tcg_temp_free(tmp);
|
||||
} else {
|
||||
tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
}
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], -lit);
|
||||
else if (rb != 31) {
|
||||
tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
} else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0F:
|
||||
/* CMPBGE */
|
||||
@ -636,11 +672,58 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
break;
|
||||
case 0x12:
|
||||
/* S8ADDL */
|
||||
gen_arith3(ctx, &gen_s8addl, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit || rb != 31) {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
|
||||
if (islit)
|
||||
tcg_gen_addi_i64(tmp, tmp, lit);
|
||||
else
|
||||
tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
|
||||
tcg_temp_free(tmp);
|
||||
} else {
|
||||
tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
}
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x1B:
|
||||
/* S8SUBL */
|
||||
gen_arith3(ctx, &gen_s8subl, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit || rb != 31) {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
|
||||
if (islit)
|
||||
tcg_gen_subi_i64(tmp, tmp, lit);
|
||||
else
|
||||
tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
|
||||
tcg_temp_free(tmp);
|
||||
} else {
|
||||
tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
}
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], -lit);
|
||||
else if (rb != 31) {
|
||||
tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
} else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x1D:
|
||||
/* CMPULT */
|
||||
@ -648,19 +731,91 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
break;
|
||||
case 0x20:
|
||||
/* ADDQ */
|
||||
gen_arith3(ctx, &gen_op_addq, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit)
|
||||
tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x22:
|
||||
/* S4ADDQ */
|
||||
gen_arith3(ctx, &gen_s4addq, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit || rb != 31) {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
|
||||
if (islit)
|
||||
tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
|
||||
else
|
||||
tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
|
||||
tcg_temp_free(tmp);
|
||||
} else
|
||||
tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x29:
|
||||
/* SUBQ */
|
||||
gen_arith3(ctx, &gen_op_subq, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit)
|
||||
tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], -lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2B:
|
||||
/* S4SUBQ */
|
||||
gen_arith3(ctx, &gen_s4subq, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit || rb != 31) {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
|
||||
if (islit)
|
||||
tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
|
||||
else
|
||||
tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
|
||||
tcg_temp_free(tmp);
|
||||
} else
|
||||
tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], -lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2D:
|
||||
/* CMPEQ */
|
||||
@ -668,11 +823,51 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
break;
|
||||
case 0x32:
|
||||
/* S8ADDQ */
|
||||
gen_arith3(ctx, &gen_s8addq, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit || rb != 31) {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
|
||||
if (islit)
|
||||
tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
|
||||
else
|
||||
tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
|
||||
tcg_temp_free(tmp);
|
||||
} else
|
||||
tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x3B:
|
||||
/* S8SUBQ */
|
||||
gen_arith3(ctx, &gen_s8subq, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit || rb != 31) {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
|
||||
if (islit)
|
||||
tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
|
||||
else
|
||||
tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
|
||||
tcg_temp_free(tmp);
|
||||
} else
|
||||
tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], -lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x3D:
|
||||
/* CMPULE */
|
||||
@ -710,11 +905,31 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
switch (fn7) {
|
||||
case 0x00:
|
||||
/* AND */
|
||||
gen_arith3(ctx, &gen_op_and, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra == 31 || (rb == 31 && !islit))
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
else if (islit)
|
||||
tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
|
||||
else
|
||||
tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
|
||||
}
|
||||
break;
|
||||
case 0x08:
|
||||
/* BIC */
|
||||
gen_arith3(ctx, &gen_op_bic, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit)
|
||||
tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
|
||||
else if (rb != 31) {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_not_i64(tmp, cpu_ir[rb]);
|
||||
tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], tmp);
|
||||
tcg_temp_free(tmp);
|
||||
} else
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
break;
|
||||
case 0x14:
|
||||
/* CMOVLBS */
|
||||
@ -726,21 +941,22 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
break;
|
||||
case 0x20:
|
||||
/* BIS */
|
||||
if (ra == rb || ra == 31 || rb == 31) {
|
||||
if (ra == 31 && rc == 31) {
|
||||
/* NOP */
|
||||
gen_op_nop();
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit)
|
||||
tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else {
|
||||
/* MOV */
|
||||
if (rc != 31) {
|
||||
if (rb != 31)
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
} else {
|
||||
gen_arith3(ctx, &gen_op_bis, ra, rb, rc, islit, lit);
|
||||
}
|
||||
break;
|
||||
case 0x24:
|
||||
@ -753,11 +969,45 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
break;
|
||||
case 0x28:
|
||||
/* ORNOT */
|
||||
gen_arith3(ctx, &gen_op_ornot, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (rb == 31 && !islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], ~0);
|
||||
else if (ra != 31) {
|
||||
if (islit)
|
||||
tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
|
||||
else {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_not_i64(tmp, cpu_ir[rb]);
|
||||
tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], tmp);
|
||||
tcg_temp_free(tmp);
|
||||
}
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], ~lit);
|
||||
else
|
||||
tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x40:
|
||||
/* XOR */
|
||||
gen_arith3(ctx, &gen_op_xor, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit)
|
||||
tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x44:
|
||||
/* CMOVLT */
|
||||
@ -769,7 +1019,26 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
break;
|
||||
case 0x48:
|
||||
/* EQV */
|
||||
gen_arith3(ctx, &gen_op_eqv, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit)
|
||||
tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
|
||||
else if (rb != 31) {
|
||||
TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_not_i64(tmp, cpu_ir[rb]);
|
||||
tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], tmp);
|
||||
tcg_temp_free(tmp);
|
||||
} else
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else {
|
||||
if (islit)
|
||||
tcg_gen_movi_i64(cpu_ir[rc], ~lit);
|
||||
else if (rb != 31)
|
||||
tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||
else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], ~0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x61:
|
||||
/* AMASK */
|
||||
@ -852,7 +1121,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
break;
|
||||
case 0x34:
|
||||
/* SRL */
|
||||
gen_arith3(ctx, &gen_op_srl, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit)
|
||||
tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
|
||||
else if (rb != 31) {
|
||||
TCGv shift = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
|
||||
tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
|
||||
tcg_temp_free(shift);
|
||||
} else
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
break;
|
||||
case 0x36:
|
||||
/* EXTQL */
|
||||
@ -860,7 +1142,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
break;
|
||||
case 0x39:
|
||||
/* SLL */
|
||||
gen_arith3(ctx, &gen_op_sll, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit)
|
||||
tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
|
||||
else if (rb != 31) {
|
||||
TCGv shift = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
|
||||
tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
|
||||
tcg_temp_free(shift);
|
||||
} else
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
break;
|
||||
case 0x3B:
|
||||
/* INSQL */
|
||||
@ -868,7 +1163,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
break;
|
||||
case 0x3C:
|
||||
/* SRA */
|
||||
gen_arith3(ctx, &gen_op_sra, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra != 31) {
|
||||
if (islit)
|
||||
tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
|
||||
else if (rb != 31) {
|
||||
TCGv shift = tcg_temp_new(TCG_TYPE_I64);
|
||||
tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
|
||||
tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
|
||||
tcg_temp_free(shift);
|
||||
} else
|
||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
|
||||
} else
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
}
|
||||
break;
|
||||
case 0x52:
|
||||
/* MSKWH */
|
||||
@ -914,11 +1222,28 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||
switch (fn7) {
|
||||
case 0x00:
|
||||
/* MULL */
|
||||
gen_arith3(ctx, &gen_op_mull, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra == 31 || (rb == 31 && !islit))
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
else {
|
||||
if (islit)
|
||||
tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
|
||||
else
|
||||
tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
|
||||
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x20:
|
||||
/* MULQ */
|
||||
gen_arith3(ctx, &gen_op_mulq, ra, rb, rc, islit, lit);
|
||||
if (likely(rc != 31)) {
|
||||
if (ra == 31 || (rb == 31 && !islit))
|
||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||
else if (islit)
|
||||
tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
|
||||
else
|
||||
tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
|
||||
}
|
||||
break;
|
||||
case 0x30:
|
||||
/* UMULH */
|
||||
|
Loading…
Reference in New Issue
Block a user