aboutsummaryrefslogtreecommitdiff
path: root/target-alpha
diff options
context:
space:
mode:
authoraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2008-09-16 22:44:10 +0000
committeraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2008-09-16 22:44:10 +0000
commit30c7183b676076c940538b838c330c854a7995a9 (patch)
treef99113f17d4f576890fe300443500f499cd93c08 /target-alpha
parentae8ecd423150456e238a9d45f107b97e94957b78 (diff)
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
Diffstat (limited to 'target-alpha')
-rw-r--r--target-alpha/op.c90
-rw-r--r--target-alpha/translate.c491
2 files changed, 408 insertions, 173 deletions
diff --git a/target-alpha/op.c b/target-alpha/op.c
index 651900fbab..b07b3d969c 100644
--- a/target-alpha/op.c
+++ b/target-alpha/op.c
@@ -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();
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 804cfcc3b1..54fe986ce0 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -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 */