mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-10 11:04:58 -06:00
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
2 changed files with 408 additions and 173 deletions
|
@ -198,72 +198,36 @@ void OPPROTO op_clear_irf (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Arithmetic */
|
/* Arithmetic */
|
||||||
void OPPROTO op_addq (void)
|
|
||||||
{
|
|
||||||
T0 += T1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OPPROTO op_addqv (void)
|
void OPPROTO op_addqv (void)
|
||||||
{
|
{
|
||||||
helper_addqv();
|
helper_addqv();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OPPROTO op_addl (void)
|
|
||||||
{
|
|
||||||
T0 = (int64_t)((int32_t)(T0 + T1));
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OPPROTO op_addlv (void)
|
void OPPROTO op_addlv (void)
|
||||||
{
|
{
|
||||||
helper_addlv();
|
helper_addlv();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OPPROTO op_subq (void)
|
|
||||||
{
|
|
||||||
T0 -= T1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OPPROTO op_subqv (void)
|
void OPPROTO op_subqv (void)
|
||||||
{
|
{
|
||||||
helper_subqv();
|
helper_subqv();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OPPROTO op_subl (void)
|
|
||||||
{
|
|
||||||
T0 = (int64_t)((int32_t)(T0 - T1));
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OPPROTO op_sublv (void)
|
void OPPROTO op_sublv (void)
|
||||||
{
|
{
|
||||||
helper_sublv();
|
helper_sublv();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OPPROTO op_mull (void)
|
|
||||||
{
|
|
||||||
T0 = (int64_t)((int32_t)T0 * (int32_t)T1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OPPROTO op_mullv (void)
|
void OPPROTO op_mullv (void)
|
||||||
{
|
{
|
||||||
helper_mullv();
|
helper_mullv();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OPPROTO op_mulq (void)
|
|
||||||
{
|
|
||||||
T0 = (int64_t)T0 * (int64_t)T1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OPPROTO op_mulqv (void)
|
void OPPROTO op_mulqv (void)
|
||||||
{
|
{
|
||||||
helper_mulqv();
|
helper_mulqv();
|
||||||
|
@ -280,60 +244,6 @@ void OPPROTO op_umulh (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Logical */
|
/* 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)
|
void OPPROTO op_mskbl (void)
|
||||||
{
|
{
|
||||||
helper_mskbl();
|
helper_mskbl();
|
||||||
|
|
|
@ -440,54 +440,6 @@ static always_inline void gen_itf (DisasContext *ctx,
|
||||||
gen_store_fir(ctx, rc, 0);
|
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)
|
static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
{
|
{
|
||||||
uint32_t palcode;
|
uint32_t palcode;
|
||||||
|
@ -616,19 +568,103 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
switch (fn7) {
|
switch (fn7) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
/* ADDL */
|
/* 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;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
/* S4ADDL */
|
/* 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;
|
break;
|
||||||
case 0x09:
|
case 0x09:
|
||||||
/* SUBL */
|
/* 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;
|
break;
|
||||||
case 0x0B:
|
case 0x0B:
|
||||||
/* S4SUBL */
|
/* 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;
|
break;
|
||||||
case 0x0F:
|
case 0x0F:
|
||||||
/* CMPBGE */
|
/* CMPBGE */
|
||||||
|
@ -636,11 +672,58 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x12:
|
case 0x12:
|
||||||
/* S8ADDL */
|
/* 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;
|
break;
|
||||||
case 0x1B:
|
case 0x1B:
|
||||||
/* S8SUBL */
|
/* 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;
|
break;
|
||||||
case 0x1D:
|
case 0x1D:
|
||||||
/* CMPULT */
|
/* CMPULT */
|
||||||
|
@ -648,19 +731,91 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x20:
|
case 0x20:
|
||||||
/* ADDQ */
|
/* 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;
|
break;
|
||||||
case 0x22:
|
case 0x22:
|
||||||
/* S4ADDQ */
|
/* 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;
|
break;
|
||||||
case 0x29:
|
case 0x29:
|
||||||
/* SUBQ */
|
/* 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;
|
break;
|
||||||
case 0x2B:
|
case 0x2B:
|
||||||
/* S4SUBQ */
|
/* 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;
|
break;
|
||||||
case 0x2D:
|
case 0x2D:
|
||||||
/* CMPEQ */
|
/* CMPEQ */
|
||||||
|
@ -668,11 +823,51 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x32:
|
case 0x32:
|
||||||
/* S8ADDQ */
|
/* 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;
|
break;
|
||||||
case 0x3B:
|
case 0x3B:
|
||||||
/* S8SUBQ */
|
/* 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;
|
break;
|
||||||
case 0x3D:
|
case 0x3D:
|
||||||
/* CMPULE */
|
/* CMPULE */
|
||||||
|
@ -710,11 +905,31 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
switch (fn7) {
|
switch (fn7) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
/* AND */
|
/* 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;
|
break;
|
||||||
case 0x08:
|
case 0x08:
|
||||||
/* BIC */
|
/* 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;
|
break;
|
||||||
case 0x14:
|
case 0x14:
|
||||||
/* CMOVLBS */
|
/* CMOVLBS */
|
||||||
|
@ -726,21 +941,22 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x20:
|
case 0x20:
|
||||||
/* BIS */
|
/* BIS */
|
||||||
if (ra == rb || ra == 31 || rb == 31) {
|
if (likely(rc != 31)) {
|
||||||
if (ra == 31 && rc == 31) {
|
if (ra != 31) {
|
||||||
/* NOP */
|
if (islit)
|
||||||
gen_op_nop();
|
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 {
|
} else {
|
||||||
/* MOV */
|
if (islit)
|
||||||
if (rc != 31) {
|
tcg_gen_movi_i64(cpu_ir[rc], lit);
|
||||||
if (rb != 31)
|
else if (rb != 31)
|
||||||
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
|
tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
|
||||||
else
|
else
|
||||||
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
tcg_gen_movi_i64(cpu_ir[rc], 0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
gen_arith3(ctx, &gen_op_bis, ra, rb, rc, islit, lit);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x24:
|
case 0x24:
|
||||||
|
@ -753,11 +969,45 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x28:
|
case 0x28:
|
||||||
/* ORNOT */
|
/* 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;
|
break;
|
||||||
case 0x40:
|
case 0x40:
|
||||||
/* XOR */
|
/* 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;
|
break;
|
||||||
case 0x44:
|
case 0x44:
|
||||||
/* CMOVLT */
|
/* CMOVLT */
|
||||||
|
@ -769,7 +1019,26 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x48:
|
case 0x48:
|
||||||
/* EQV */
|
/* 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;
|
break;
|
||||||
case 0x61:
|
case 0x61:
|
||||||
/* AMASK */
|
/* AMASK */
|
||||||
|
@ -852,7 +1121,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x34:
|
case 0x34:
|
||||||
/* SRL */
|
/* 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;
|
break;
|
||||||
case 0x36:
|
case 0x36:
|
||||||
/* EXTQL */
|
/* EXTQL */
|
||||||
|
@ -860,7 +1142,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x39:
|
case 0x39:
|
||||||
/* SLL */
|
/* 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;
|
break;
|
||||||
case 0x3B:
|
case 0x3B:
|
||||||
/* INSQL */
|
/* INSQL */
|
||||||
|
@ -868,7 +1163,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x3C:
|
case 0x3C:
|
||||||
/* SRA */
|
/* 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;
|
break;
|
||||||
case 0x52:
|
case 0x52:
|
||||||
/* MSKWH */
|
/* MSKWH */
|
||||||
|
@ -914,11 +1222,28 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
|
||||||
switch (fn7) {
|
switch (fn7) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
/* MULL */
|
/* 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;
|
break;
|
||||||
case 0x20:
|
case 0x20:
|
||||||
/* MULQ */
|
/* 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;
|
break;
|
||||||
case 0x30:
|
case 0x30:
|
||||||
/* UMULH */
|
/* UMULH */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue