mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-25 22:36:56 +00:00
target-mips: microMIPS32 R6 POOL16{A, C} instructions
microMIPS32 Release 6 POOL16A/ POOL16C instructions Backports commit ed7ce6c0f9d4370826557ce33d652beb88ccb3e6 from qemu
This commit is contained in:
parent
6e6ca4dbd4
commit
76ab1f17fb
|
@ -13264,6 +13264,112 @@ static void gen_pool16c_insn(DisasContext *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
|
||||||
|
int enc_rs)
|
||||||
|
{
|
||||||
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
|
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
||||||
|
int rd, rs, re, rt;
|
||||||
|
static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
|
||||||
|
static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
|
||||||
|
static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
|
||||||
|
rd = rd_enc[enc_dest];
|
||||||
|
re = re_enc[enc_dest];
|
||||||
|
rs = rs_rt_enc[enc_rs];
|
||||||
|
rt = rs_rt_enc[enc_rt];
|
||||||
|
if (rs) {
|
||||||
|
tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[rd], *cpu_gpr[rs]);
|
||||||
|
} else {
|
||||||
|
tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rd], 0);
|
||||||
|
}
|
||||||
|
if (rt) {
|
||||||
|
tcg_gen_mov_tl(tcg_ctx, *cpu_gpr[re], *cpu_gpr[rt]);
|
||||||
|
} else {
|
||||||
|
tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[re], 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gen_pool16c_r6_insn(DisasContext *ctx)
|
||||||
|
{
|
||||||
|
int rt = mmreg((ctx->opcode >> 7) & 0x7);
|
||||||
|
int rs = mmreg((ctx->opcode >> 4) & 0x7);
|
||||||
|
|
||||||
|
switch (ctx->opcode & 0xf) {
|
||||||
|
case R6_NOT16:
|
||||||
|
gen_logic(ctx, OPC_NOR, rt, rs, 0);
|
||||||
|
break;
|
||||||
|
case R6_AND16:
|
||||||
|
gen_logic(ctx, OPC_AND, rt, rt, rs);
|
||||||
|
break;
|
||||||
|
case R6_LWM16:
|
||||||
|
{
|
||||||
|
int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
|
||||||
|
int offset = extract32(ctx->opcode, 4, 4);
|
||||||
|
gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case R6_JRC16: /* JRCADDIUSP */
|
||||||
|
if ((ctx->opcode >> 4) & 1) {
|
||||||
|
/* JRCADDIUSP */
|
||||||
|
int imm = extract32(ctx->opcode, 5, 5);
|
||||||
|
gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
|
||||||
|
gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
|
||||||
|
} else {
|
||||||
|
/* JRC16 */
|
||||||
|
int rs = extract32(ctx->opcode, 5, 5);
|
||||||
|
gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MOVEP ... MOVEP_07:
|
||||||
|
case MOVEP_0C ... MOVEP_0F:
|
||||||
|
{
|
||||||
|
int enc_dest = uMIPS_RD(ctx->opcode);
|
||||||
|
int enc_rt = uMIPS_RS2(ctx->opcode);
|
||||||
|
int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
|
||||||
|
gen_movep(ctx, enc_dest, enc_rt, enc_rs);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case R6_XOR16:
|
||||||
|
gen_logic(ctx, OPC_XOR, rt, rt, rs);
|
||||||
|
break;
|
||||||
|
case R6_OR16:
|
||||||
|
gen_logic(ctx, OPC_OR, rt, rt, rs);
|
||||||
|
break;
|
||||||
|
case R6_SWM16:
|
||||||
|
{
|
||||||
|
int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
|
||||||
|
int offset = extract32(ctx->opcode, 4, 4);
|
||||||
|
gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case JALRC16: /* BREAK16, SDBBP16 */
|
||||||
|
switch (ctx->opcode & 0x3f) {
|
||||||
|
case JALRC16:
|
||||||
|
case JALRC16 + 0x20:
|
||||||
|
/* JALRC16 */
|
||||||
|
gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
|
||||||
|
31, 0, 0);
|
||||||
|
break;
|
||||||
|
case R6_BREAK16:
|
||||||
|
/* BREAK16 */
|
||||||
|
generate_exception(ctx, EXCP_BREAK);
|
||||||
|
break;
|
||||||
|
case R6_SDBBP16:
|
||||||
|
/* SDBBP16 */
|
||||||
|
if (ctx->hflags & MIPS_HFLAG_SBRI) {
|
||||||
|
generate_exception(ctx, EXCP_RI);
|
||||||
|
} else {
|
||||||
|
generate_exception(ctx, EXCP_DBp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
generate_exception(ctx, EXCP_RI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
|
static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
|
@ -15284,7 +15390,14 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool *ins
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_arith(ctx, opc, rd, rs1, rs2);
|
if (ctx->insn_flags & ISA_MIPS32R6) {
|
||||||
|
/* In the Release 6 the register number location in
|
||||||
|
* the instruction encoding has changed.
|
||||||
|
*/
|
||||||
|
gen_arith(ctx, opc, rs1, rd, rs2);
|
||||||
|
} else {
|
||||||
|
gen_arith(ctx, opc, rd, rs1, rs2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POOL16B:
|
case POOL16B:
|
||||||
|
@ -15308,7 +15421,11 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool *ins
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POOL16C:
|
case POOL16C:
|
||||||
gen_pool16c_insn(ctx);
|
if (ctx->insn_flags & ISA_MIPS32R6) {
|
||||||
|
gen_pool16c_r6_insn(ctx);
|
||||||
|
} else {
|
||||||
|
gen_pool16c_insn(ctx);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LWGP16:
|
case LWGP16:
|
||||||
{
|
{
|
||||||
|
@ -15328,18 +15445,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool *ins
|
||||||
int enc_dest = uMIPS_RD(ctx->opcode);
|
int enc_dest = uMIPS_RD(ctx->opcode);
|
||||||
int enc_rt = uMIPS_RS2(ctx->opcode);
|
int enc_rt = uMIPS_RS2(ctx->opcode);
|
||||||
int enc_rs = uMIPS_RS1(ctx->opcode);
|
int enc_rs = uMIPS_RS1(ctx->opcode);
|
||||||
int rd, rs, re, rt;
|
gen_movep(ctx, enc_dest, enc_rt, enc_rs);
|
||||||
static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
|
|
||||||
static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
|
|
||||||
static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
|
|
||||||
|
|
||||||
rd = rd_enc[enc_dest];
|
|
||||||
re = re_enc[enc_dest];
|
|
||||||
rs = rs_rt_enc[enc_rs];
|
|
||||||
rt = rs_rt_enc[enc_rt];
|
|
||||||
|
|
||||||
gen_arith(ctx, OPC_ADDU, rd, rs, 0);
|
|
||||||
gen_arith(ctx, OPC_ADDU, re, rt, 0);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LBU16:
|
case LBU16:
|
||||||
|
|
Loading…
Reference in a new issue