mirror of
https://github.com/yuzu-emu/unicorn
synced 2024-11-25 18:16:19 +00:00
target/mips: Decode microMIPS EVA load & store instructions
Implement decoding of microMIPS EVA load and store instruction groups in the POOL31C pool. These use the same gen_ld(), gen_st(), gen_st_cond() helpers as the MIPS32 decoding, passing the equivalent MIPS32 opcodes as opc. Backports commit 8fffc64696783b1ff1d17262d098976479895660 from qemu
This commit is contained in:
parent
8fadc55db3
commit
54b349aee5
1 changed files with 115 additions and 4 deletions
|
@ -12636,19 +12636,45 @@ enum {
|
|||
LWR = 0x1,
|
||||
SWR = 0x9,
|
||||
PREF = 0x2,
|
||||
/* 0xa is reserved */
|
||||
ST_EVA = 0xa,
|
||||
LL = 0x3,
|
||||
SC = 0xb,
|
||||
LDL = 0x4,
|
||||
SDL = 0xc,
|
||||
LDR = 0x5,
|
||||
SDR = 0xd,
|
||||
/* 0x6 is reserved */
|
||||
LD_EVA = 0x6,
|
||||
LWU = 0xe,
|
||||
LLD = 0x7,
|
||||
SCD = 0xf
|
||||
};
|
||||
|
||||
/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
|
||||
|
||||
enum {
|
||||
LBUE = 0x0,
|
||||
LHUE = 0x1,
|
||||
LWLE = 0x2,
|
||||
LWRE = 0x3,
|
||||
LBE = 0x4,
|
||||
LHE = 0x5,
|
||||
LLE = 0x6,
|
||||
LWE = 0x7,
|
||||
};
|
||||
|
||||
/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
|
||||
|
||||
enum {
|
||||
SWLE = 0x0,
|
||||
SWRE = 0x1,
|
||||
PREFE = 0x2,
|
||||
CACHEE = 0x3,
|
||||
SBE = 0x4,
|
||||
SHE = 0x5,
|
||||
SCE = 0x6,
|
||||
SWE = 0x7,
|
||||
};
|
||||
|
||||
/* POOL32F encoding of minor opcode field (bits 5..0) */
|
||||
|
||||
enum {
|
||||
|
@ -13950,7 +13976,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
|||
uint16_t insn;
|
||||
int rt, rs, rd, rr;
|
||||
int16_t imm;
|
||||
uint32_t op, minor, mips32_op;
|
||||
uint32_t op, minor, minor2, mips32_op;
|
||||
uint32_t cond, fmt, cc;
|
||||
|
||||
insn = cpu_lduw_code(env, ctx->pc + 2);
|
||||
|
@ -14895,7 +14921,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
|||
gen_ld(ctx, mips32_op, rt, rs, offset);
|
||||
break;
|
||||
do_st_lr:
|
||||
gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
|
||||
gen_st(ctx, mips32_op, rt, rs, offset);
|
||||
break;
|
||||
case SC:
|
||||
gen_st_cond(ctx, OPC_SC, rt, rs, offset);
|
||||
|
@ -14907,6 +14933,91 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
|
|||
gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
|
||||
break;
|
||||
#endif
|
||||
case LD_EVA:
|
||||
if (!ctx->eva) {
|
||||
MIPS_INVAL("pool32c ld-eva");
|
||||
generate_exception_end(ctx, EXCP_RI);
|
||||
break;
|
||||
}
|
||||
check_cp0_enabled(ctx);
|
||||
|
||||
minor2 = (ctx->opcode >> 9) & 0x7;
|
||||
offset = sextract32(ctx->opcode, 0, 9);
|
||||
switch (minor2) {
|
||||
case LBUE:
|
||||
mips32_op = OPC_LBUE;
|
||||
goto do_ld_lr;
|
||||
case LHUE:
|
||||
mips32_op = OPC_LHUE;
|
||||
goto do_ld_lr;
|
||||
case LWLE:
|
||||
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
||||
mips32_op = OPC_LWLE;
|
||||
goto do_ld_lr;
|
||||
case LWRE:
|
||||
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
||||
mips32_op = OPC_LWRE;
|
||||
goto do_ld_lr;
|
||||
case LBE:
|
||||
mips32_op = OPC_LBE;
|
||||
goto do_ld_lr;
|
||||
case LHE:
|
||||
mips32_op = OPC_LHE;
|
||||
goto do_ld_lr;
|
||||
case LLE:
|
||||
mips32_op = OPC_LLE;
|
||||
goto do_ld_lr;
|
||||
case LWE:
|
||||
mips32_op = OPC_LWE;
|
||||
goto do_ld_lr;
|
||||
};
|
||||
break;
|
||||
case ST_EVA:
|
||||
if (!ctx->eva) {
|
||||
MIPS_INVAL("pool32c st-eva");
|
||||
generate_exception_end(ctx, EXCP_RI);
|
||||
break;
|
||||
}
|
||||
check_cp0_enabled(ctx);
|
||||
|
||||
minor2 = (ctx->opcode >> 9) & 0x7;
|
||||
offset = sextract32(ctx->opcode, 0, 9);
|
||||
switch (minor2) {
|
||||
case SWLE:
|
||||
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
||||
mips32_op = OPC_SWLE;
|
||||
goto do_st_lr;
|
||||
case SWRE:
|
||||
check_insn_opc_removed(ctx, ISA_MIPS32R6);
|
||||
mips32_op = OPC_SWRE;
|
||||
goto do_st_lr;
|
||||
case PREFE:
|
||||
/* Treat as no-op */
|
||||
if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
|
||||
/* hint codes 24-31 are reserved and signal RI */
|
||||
generate_exception(ctx, EXCP_RI);
|
||||
}
|
||||
break;
|
||||
case CACHEE:
|
||||
/* Treat as no-op */
|
||||
if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
|
||||
gen_cache_operation(ctx, rt, rs, offset);
|
||||
}
|
||||
break;
|
||||
case SBE:
|
||||
mips32_op = OPC_SBE;
|
||||
goto do_st_lr;
|
||||
case SHE:
|
||||
mips32_op = OPC_SHE;
|
||||
goto do_st_lr;
|
||||
case SCE:
|
||||
gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
|
||||
break;
|
||||
case SWE:
|
||||
mips32_op = OPC_SWE;
|
||||
goto do_st_lr;
|
||||
};
|
||||
break;
|
||||
case PREF:
|
||||
/* Treat as no-op */
|
||||
if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
|
||||
|
|
Loading…
Reference in a new issue