mirror of https://github.com/xemu-project/xemu.git
target-mips: optimize gen_arith_imm()
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7092 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
b2ee0ce237
commit
324d9e3204
|
@ -57,10 +57,12 @@ enum {
|
||||||
OPC_ADDIU = (0x09 << 26),
|
OPC_ADDIU = (0x09 << 26),
|
||||||
OPC_SLTI = (0x0A << 26),
|
OPC_SLTI = (0x0A << 26),
|
||||||
OPC_SLTIU = (0x0B << 26),
|
OPC_SLTIU = (0x0B << 26),
|
||||||
|
/* logic with immediate */
|
||||||
OPC_ANDI = (0x0C << 26),
|
OPC_ANDI = (0x0C << 26),
|
||||||
OPC_ORI = (0x0D << 26),
|
OPC_ORI = (0x0D << 26),
|
||||||
OPC_XORI = (0x0E << 26),
|
OPC_XORI = (0x0E << 26),
|
||||||
OPC_LUI = (0x0F << 26),
|
OPC_LUI = (0x0F << 26),
|
||||||
|
/* arithmetic with immediate */
|
||||||
OPC_DADDI = (0x18 << 26),
|
OPC_DADDI = (0x18 << 26),
|
||||||
OPC_DADDIU = (0x19 << 26),
|
OPC_DADDIU = (0x19 << 26),
|
||||||
/* Jump and branches */
|
/* Jump and branches */
|
||||||
|
@ -1197,140 +1199,184 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
|
||||||
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
|
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
|
||||||
int rt, int rs, int16_t imm)
|
int rt, int rs, int16_t imm)
|
||||||
{
|
{
|
||||||
target_ulong uimm;
|
target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
|
||||||
const char *opn = "imm arith";
|
const char *opn = "imm arith";
|
||||||
TCGv t0 = tcg_temp_local_new();
|
|
||||||
|
|
||||||
if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
|
if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
|
||||||
/* If no destination, treat it as a NOP.
|
/* If no destination, treat it as a NOP.
|
||||||
For addi, we must generate the overflow exception when needed. */
|
For addi, we must generate the overflow exception when needed. */
|
||||||
MIPS_DEBUG("NOP");
|
MIPS_DEBUG("NOP");
|
||||||
goto out;
|
return;
|
||||||
}
|
|
||||||
uimm = (uint16_t)imm;
|
|
||||||
switch (opc) {
|
|
||||||
case OPC_ADDI:
|
|
||||||
case OPC_ADDIU:
|
|
||||||
#if defined(TARGET_MIPS64)
|
|
||||||
case OPC_DADDI:
|
|
||||||
case OPC_DADDIU:
|
|
||||||
#endif
|
|
||||||
case OPC_SLTI:
|
|
||||||
case OPC_SLTIU:
|
|
||||||
uimm = (target_long)imm; /* Sign extend to 32/64 bits */
|
|
||||||
/* Fall through. */
|
|
||||||
case OPC_ANDI:
|
|
||||||
case OPC_ORI:
|
|
||||||
case OPC_XORI:
|
|
||||||
gen_load_gpr(t0, rs);
|
|
||||||
break;
|
|
||||||
case OPC_LUI:
|
|
||||||
tcg_gen_movi_tl(t0, imm << 16);
|
|
||||||
break;
|
|
||||||
case OPC_SLL:
|
|
||||||
case OPC_SRA:
|
|
||||||
case OPC_SRL:
|
|
||||||
#if defined(TARGET_MIPS64)
|
|
||||||
case OPC_DSLL:
|
|
||||||
case OPC_DSRA:
|
|
||||||
case OPC_DSRL:
|
|
||||||
case OPC_DSLL32:
|
|
||||||
case OPC_DSRA32:
|
|
||||||
case OPC_DSRL32:
|
|
||||||
#endif
|
|
||||||
uimm &= 0x1f;
|
|
||||||
gen_load_gpr(t0, rs);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case OPC_ADDI:
|
case OPC_ADDI:
|
||||||
{
|
{
|
||||||
TCGv r_tmp1 = tcg_temp_new();
|
TCGv t0 = tcg_temp_local_new();
|
||||||
TCGv r_tmp2 = tcg_temp_new();
|
TCGv t1 = tcg_temp_new();
|
||||||
|
TCGv t2 = tcg_temp_new();
|
||||||
int l1 = gen_new_label();
|
int l1 = gen_new_label();
|
||||||
|
|
||||||
save_cpu_state(ctx, 1);
|
gen_load_gpr(t1, rs);
|
||||||
tcg_gen_ext32s_tl(r_tmp1, t0);
|
tcg_gen_addi_tl(t0, t1, uimm);
|
||||||
tcg_gen_addi_tl(t0, r_tmp1, uimm);
|
tcg_gen_ext32s_tl(t0, t0);
|
||||||
|
|
||||||
tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
|
tcg_gen_xori_tl(t1, t1, ~uimm);
|
||||||
tcg_gen_xori_tl(r_tmp2, t0, uimm);
|
tcg_gen_xori_tl(t2, t0, uimm);
|
||||||
tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
|
tcg_gen_and_tl(t1, t1, t2);
|
||||||
tcg_temp_free(r_tmp2);
|
tcg_temp_free(t2);
|
||||||
tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
|
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
|
||||||
|
tcg_temp_free(t1);
|
||||||
/* operands of same sign, result different sign */
|
/* operands of same sign, result different sign */
|
||||||
generate_exception(ctx, EXCP_OVERFLOW);
|
generate_exception(ctx, EXCP_OVERFLOW);
|
||||||
gen_set_label(l1);
|
gen_set_label(l1);
|
||||||
tcg_temp_free(r_tmp1);
|
|
||||||
|
|
||||||
tcg_gen_ext32s_tl(t0, t0);
|
tcg_gen_ext32s_tl(t0, t0);
|
||||||
|
gen_store_gpr(t0, rt);
|
||||||
|
tcg_temp_free(t0);
|
||||||
}
|
}
|
||||||
opn = "addi";
|
opn = "addi";
|
||||||
break;
|
break;
|
||||||
case OPC_ADDIU:
|
case OPC_ADDIU:
|
||||||
tcg_gen_addi_tl(t0, t0, uimm);
|
if (rs != 0) {
|
||||||
tcg_gen_ext32s_tl(t0, t0);
|
tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
|
||||||
|
tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
|
||||||
|
} else {
|
||||||
|
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
|
||||||
|
}
|
||||||
opn = "addiu";
|
opn = "addiu";
|
||||||
break;
|
break;
|
||||||
#if defined(TARGET_MIPS64)
|
#if defined(TARGET_MIPS64)
|
||||||
case OPC_DADDI:
|
case OPC_DADDI:
|
||||||
{
|
{
|
||||||
TCGv r_tmp1 = tcg_temp_new();
|
TCGv t0 = tcg_temp_local_new();
|
||||||
TCGv r_tmp2 = tcg_temp_new();
|
TCGv t1 = tcg_temp_new();
|
||||||
|
TCGv t2 = tcg_temp_new();
|
||||||
int l1 = gen_new_label();
|
int l1 = gen_new_label();
|
||||||
|
|
||||||
save_cpu_state(ctx, 1);
|
gen_load_gpr(t1, rs);
|
||||||
tcg_gen_mov_tl(r_tmp1, t0);
|
tcg_gen_addi_tl(t0, t1, uimm);
|
||||||
tcg_gen_addi_tl(t0, t0, uimm);
|
|
||||||
|
|
||||||
tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
|
tcg_gen_xori_tl(t1, t1, ~uimm);
|
||||||
tcg_gen_xori_tl(r_tmp2, t0, uimm);
|
tcg_gen_xori_tl(t2, t0, uimm);
|
||||||
tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
|
tcg_gen_and_tl(t1, t1, t2);
|
||||||
tcg_temp_free(r_tmp2);
|
tcg_temp_free(t2);
|
||||||
tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
|
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
|
||||||
|
tcg_temp_free(t1);
|
||||||
/* operands of same sign, result different sign */
|
/* operands of same sign, result different sign */
|
||||||
generate_exception(ctx, EXCP_OVERFLOW);
|
generate_exception(ctx, EXCP_OVERFLOW);
|
||||||
gen_set_label(l1);
|
gen_set_label(l1);
|
||||||
tcg_temp_free(r_tmp1);
|
gen_store_gpr(t0, rt);
|
||||||
|
tcg_temp_free(t0);
|
||||||
}
|
}
|
||||||
opn = "daddi";
|
opn = "daddi";
|
||||||
break;
|
break;
|
||||||
case OPC_DADDIU:
|
case OPC_DADDIU:
|
||||||
tcg_gen_addi_tl(t0, t0, uimm);
|
if (rs != 0) {
|
||||||
|
tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
|
||||||
|
} else {
|
||||||
|
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
|
||||||
|
}
|
||||||
opn = "daddiu";
|
opn = "daddiu";
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case OPC_SLTI:
|
}
|
||||||
gen_op_lti(t0, t0, uimm);
|
MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
|
||||||
opn = "slti";
|
}
|
||||||
break;
|
|
||||||
case OPC_SLTIU:
|
/* Logic with immediate operand */
|
||||||
gen_op_ltiu(t0, t0, uimm);
|
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
|
||||||
opn = "sltiu";
|
{
|
||||||
break;
|
target_ulong uimm;
|
||||||
|
const char *opn = "imm logic";
|
||||||
|
|
||||||
|
if (rt == 0) {
|
||||||
|
/* If no destination, treat it as a NOP. */
|
||||||
|
MIPS_DEBUG("NOP");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uimm = (uint16_t)imm;
|
||||||
|
switch (opc) {
|
||||||
case OPC_ANDI:
|
case OPC_ANDI:
|
||||||
tcg_gen_andi_tl(t0, t0, uimm);
|
if (likely(rs != 0))
|
||||||
|
tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
|
||||||
|
else
|
||||||
|
tcg_gen_movi_tl(cpu_gpr[rt], 0);
|
||||||
opn = "andi";
|
opn = "andi";
|
||||||
break;
|
break;
|
||||||
case OPC_ORI:
|
case OPC_ORI:
|
||||||
tcg_gen_ori_tl(t0, t0, uimm);
|
if (rs != 0)
|
||||||
|
tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
|
||||||
|
else
|
||||||
|
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
|
||||||
opn = "ori";
|
opn = "ori";
|
||||||
break;
|
break;
|
||||||
case OPC_XORI:
|
case OPC_XORI:
|
||||||
tcg_gen_xori_tl(t0, t0, uimm);
|
if (likely(rs != 0))
|
||||||
|
tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
|
||||||
|
else
|
||||||
|
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
|
||||||
opn = "xori";
|
opn = "xori";
|
||||||
break;
|
break;
|
||||||
case OPC_LUI:
|
case OPC_LUI:
|
||||||
|
tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
|
||||||
opn = "lui";
|
opn = "lui";
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set on less than with immediate operand */
|
||||||
|
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
|
||||||
|
{
|
||||||
|
target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
|
||||||
|
const char *opn = "imm arith";
|
||||||
|
TCGv t0;
|
||||||
|
|
||||||
|
if (rt == 0) {
|
||||||
|
/* If no destination, treat it as a NOP. */
|
||||||
|
MIPS_DEBUG("NOP");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
t0 = tcg_temp_new();
|
||||||
|
gen_load_gpr(t0, rs);
|
||||||
|
switch (opc) {
|
||||||
|
case OPC_SLTI:
|
||||||
|
gen_op_lti(cpu_gpr[rt], t0, uimm);
|
||||||
|
opn = "slti";
|
||||||
|
break;
|
||||||
|
case OPC_SLTIU:
|
||||||
|
gen_op_ltiu(cpu_gpr[rt], t0, uimm);
|
||||||
|
opn = "sltiu";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
|
||||||
|
tcg_temp_free(t0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shifts with immediate operand */
|
||||||
|
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
|
||||||
|
int rt, int rs, int16_t imm)
|
||||||
|
{
|
||||||
|
target_ulong uimm = ((uint16_t)imm) & 0x1f;
|
||||||
|
const char *opn = "imm shift";
|
||||||
|
TCGv t0;
|
||||||
|
|
||||||
|
if (rt == 0) {
|
||||||
|
/* If no destination, treat it as a NOP. */
|
||||||
|
MIPS_DEBUG("NOP");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
t0 = tcg_temp_new();
|
||||||
|
gen_load_gpr(t0, rs);
|
||||||
|
switch (opc) {
|
||||||
case OPC_SLL:
|
case OPC_SLL:
|
||||||
tcg_gen_shli_tl(t0, t0, uimm);
|
tcg_gen_shli_tl(t0, t0, uimm);
|
||||||
tcg_gen_ext32s_tl(t0, t0);
|
tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
|
||||||
opn = "sll";
|
opn = "sll";
|
||||||
break;
|
break;
|
||||||
case OPC_SRA:
|
case OPC_SRA:
|
||||||
tcg_gen_ext32s_tl(t0, t0);
|
tcg_gen_ext32s_tl(t0, t0);
|
||||||
tcg_gen_sari_tl(t0, t0, uimm);
|
tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
|
||||||
opn = "sra";
|
opn = "sra";
|
||||||
break;
|
break;
|
||||||
case OPC_SRL:
|
case OPC_SRL:
|
||||||
|
@ -1338,9 +1384,9 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
|
||||||
case 0:
|
case 0:
|
||||||
if (uimm != 0) {
|
if (uimm != 0) {
|
||||||
tcg_gen_ext32u_tl(t0, t0);
|
tcg_gen_ext32u_tl(t0, t0);
|
||||||
tcg_gen_shri_tl(t0, t0, uimm);
|
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
|
||||||
} else {
|
} else {
|
||||||
tcg_gen_ext32s_tl(t0, t0);
|
tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
|
||||||
}
|
}
|
||||||
opn = "srl";
|
opn = "srl";
|
||||||
break;
|
break;
|
||||||
|
@ -1352,16 +1398,16 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
|
||||||
|
|
||||||
tcg_gen_trunc_tl_i32(r_tmp1, t0);
|
tcg_gen_trunc_tl_i32(r_tmp1, t0);
|
||||||
tcg_gen_rotri_i32(r_tmp1, r_tmp1, uimm);
|
tcg_gen_rotri_i32(r_tmp1, r_tmp1, uimm);
|
||||||
tcg_gen_ext_i32_tl(t0, r_tmp1);
|
tcg_gen_ext_i32_tl(cpu_gpr[rt], r_tmp1);
|
||||||
tcg_temp_free_i32(r_tmp1);
|
tcg_temp_free_i32(r_tmp1);
|
||||||
}
|
}
|
||||||
opn = "rotr";
|
opn = "rotr";
|
||||||
} else {
|
} else {
|
||||||
if (uimm != 0) {
|
if (uimm != 0) {
|
||||||
tcg_gen_ext32u_tl(t0, t0);
|
tcg_gen_ext32u_tl(t0, t0);
|
||||||
tcg_gen_shri_tl(t0, t0, uimm);
|
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
|
||||||
} else {
|
} else {
|
||||||
tcg_gen_ext32s_tl(t0, t0);
|
tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
|
||||||
}
|
}
|
||||||
opn = "srl";
|
opn = "srl";
|
||||||
}
|
}
|
||||||
|
@ -1374,28 +1420,28 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
|
||||||
break;
|
break;
|
||||||
#if defined(TARGET_MIPS64)
|
#if defined(TARGET_MIPS64)
|
||||||
case OPC_DSLL:
|
case OPC_DSLL:
|
||||||
tcg_gen_shli_tl(t0, t0, uimm);
|
tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
|
||||||
opn = "dsll";
|
opn = "dsll";
|
||||||
break;
|
break;
|
||||||
case OPC_DSRA:
|
case OPC_DSRA:
|
||||||
tcg_gen_sari_tl(t0, t0, uimm);
|
tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
|
||||||
opn = "dsra";
|
opn = "dsra";
|
||||||
break;
|
break;
|
||||||
case OPC_DSRL:
|
case OPC_DSRL:
|
||||||
switch ((ctx->opcode >> 21) & 0x1f) {
|
switch ((ctx->opcode >> 21) & 0x1f) {
|
||||||
case 0:
|
case 0:
|
||||||
tcg_gen_shri_tl(t0, t0, uimm);
|
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
|
||||||
opn = "dsrl";
|
opn = "dsrl";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* drotr is decoded as dsrl on non-R2 CPUs */
|
/* drotr is decoded as dsrl on non-R2 CPUs */
|
||||||
if (env->insn_flags & ISA_MIPS32R2) {
|
if (env->insn_flags & ISA_MIPS32R2) {
|
||||||
if (uimm != 0) {
|
if (uimm != 0) {
|
||||||
tcg_gen_rotri_tl(t0, t0, uimm);
|
tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
|
||||||
}
|
}
|
||||||
opn = "drotr";
|
opn = "drotr";
|
||||||
} else {
|
} else {
|
||||||
tcg_gen_shri_tl(t0, t0, uimm);
|
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
|
||||||
opn = "dsrl";
|
opn = "dsrl";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1406,26 +1452,26 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPC_DSLL32:
|
case OPC_DSLL32:
|
||||||
tcg_gen_shli_tl(t0, t0, uimm + 32);
|
tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
|
||||||
opn = "dsll32";
|
opn = "dsll32";
|
||||||
break;
|
break;
|
||||||
case OPC_DSRA32:
|
case OPC_DSRA32:
|
||||||
tcg_gen_sari_tl(t0, t0, uimm + 32);
|
tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
|
||||||
opn = "dsra32";
|
opn = "dsra32";
|
||||||
break;
|
break;
|
||||||
case OPC_DSRL32:
|
case OPC_DSRL32:
|
||||||
switch ((ctx->opcode >> 21) & 0x1f) {
|
switch ((ctx->opcode >> 21) & 0x1f) {
|
||||||
case 0:
|
case 0:
|
||||||
tcg_gen_shri_tl(t0, t0, uimm + 32);
|
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
|
||||||
opn = "dsrl32";
|
opn = "dsrl32";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* drotr32 is decoded as dsrl32 on non-R2 CPUs */
|
/* drotr32 is decoded as dsrl32 on non-R2 CPUs */
|
||||||
if (env->insn_flags & ISA_MIPS32R2) {
|
if (env->insn_flags & ISA_MIPS32R2) {
|
||||||
tcg_gen_rotri_tl(t0, t0, uimm + 32);
|
tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
|
||||||
opn = "drotr32";
|
opn = "drotr32";
|
||||||
} else {
|
} else {
|
||||||
tcg_gen_shri_tl(t0, t0, uimm + 32);
|
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
|
||||||
opn = "dsrl32";
|
opn = "dsrl32";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1436,14 +1482,8 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
|
||||||
MIPS_INVAL(opn);
|
|
||||||
generate_exception(ctx, EXCP_RI);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
gen_store_gpr(t0, rt);
|
|
||||||
MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
|
MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
|
||||||
out:
|
|
||||||
tcg_temp_free(t0);
|
tcg_temp_free(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7556,9 +7596,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
|
||||||
case OPC_SPECIAL:
|
case OPC_SPECIAL:
|
||||||
op1 = MASK_SPECIAL(ctx->opcode);
|
op1 = MASK_SPECIAL(ctx->opcode);
|
||||||
switch (op1) {
|
switch (op1) {
|
||||||
case OPC_SLL: /* Arithmetic with immediate */
|
case OPC_SLL: /* Shift with immediate */
|
||||||
case OPC_SRL ... OPC_SRA:
|
case OPC_SRA:
|
||||||
gen_arith_imm(env, ctx, op1, rd, rt, sa);
|
case OPC_SRL:
|
||||||
|
gen_shift_imm(env, ctx, op1, rd, rt, sa);
|
||||||
break;
|
break;
|
||||||
case OPC_MOVN: /* Conditional move */
|
case OPC_MOVN: /* Conditional move */
|
||||||
case OPC_MOVZ:
|
case OPC_MOVZ:
|
||||||
|
@ -7648,12 +7689,14 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
|
||||||
#if defined(TARGET_MIPS64)
|
#if defined(TARGET_MIPS64)
|
||||||
/* MIPS64 specific opcodes */
|
/* MIPS64 specific opcodes */
|
||||||
case OPC_DSLL:
|
case OPC_DSLL:
|
||||||
case OPC_DSRL ... OPC_DSRA:
|
case OPC_DSRA:
|
||||||
|
case OPC_DSRL:
|
||||||
case OPC_DSLL32:
|
case OPC_DSLL32:
|
||||||
case OPC_DSRL32 ... OPC_DSRA32:
|
case OPC_DSRA32:
|
||||||
|
case OPC_DSRL32:
|
||||||
check_insn(env, ctx, ISA_MIPS3);
|
check_insn(env, ctx, ISA_MIPS3);
|
||||||
check_mips_64(ctx);
|
check_mips_64(ctx);
|
||||||
gen_arith_imm(env, ctx, op1, rd, rt, sa);
|
gen_shift_imm(env, ctx, op1, rd, rt, sa);
|
||||||
break;
|
break;
|
||||||
case OPC_DADD ... OPC_DSUBU:
|
case OPC_DADD ... OPC_DSUBU:
|
||||||
check_insn(env, ctx, ISA_MIPS3);
|
check_insn(env, ctx, ISA_MIPS3);
|
||||||
|
@ -7928,9 +7971,20 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
|
case OPC_ADDI: /* Arithmetic with immediate opcode */
|
||||||
|
case OPC_ADDIU:
|
||||||
gen_arith_imm(env, ctx, op, rt, rs, imm);
|
gen_arith_imm(env, ctx, op, rt, rs, imm);
|
||||||
break;
|
break;
|
||||||
|
case OPC_SLTI: /* Set on less than with immediate opcode */
|
||||||
|
case OPC_SLTIU:
|
||||||
|
gen_slt_imm(env, op, rt, rs, imm);
|
||||||
|
break;
|
||||||
|
case OPC_ANDI: /* Arithmetic with immediate opcode */
|
||||||
|
case OPC_LUI:
|
||||||
|
case OPC_ORI:
|
||||||
|
case OPC_XORI:
|
||||||
|
gen_logic_imm(env, op, rt, rs, imm);
|
||||||
|
break;
|
||||||
case OPC_J ... OPC_JAL: /* Jump */
|
case OPC_J ... OPC_JAL: /* Jump */
|
||||||
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
|
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
|
||||||
gen_compute_branch(ctx, op, rs, rt, offset);
|
gen_compute_branch(ctx, op, rs, rt, offset);
|
||||||
|
@ -8080,7 +8134,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
|
||||||
check_mips_64(ctx);
|
check_mips_64(ctx);
|
||||||
gen_ldst(ctx, op, rt, rs, imm);
|
gen_ldst(ctx, op, rt, rs, imm);
|
||||||
break;
|
break;
|
||||||
case OPC_DADDI ... OPC_DADDIU:
|
case OPC_DADDI:
|
||||||
|
case OPC_DADDIU:
|
||||||
check_insn(env, ctx, ISA_MIPS3);
|
check_insn(env, ctx, ISA_MIPS3);
|
||||||
check_mips_64(ctx);
|
check_mips_64(ctx);
|
||||||
gen_arith_imm(env, ctx, op, rt, rs, imm);
|
gen_arith_imm(env, ctx, op, rt, rs, imm);
|
||||||
|
|
Loading…
Reference in New Issue