mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-03-28 18:07:04 +00:00
target/mips: Add emulation of nanoMIPS 16-bit load and store instructions
Add emulation of LWXS16, LB16, SB16, LBU16, LH16, SH16, LHU16, LW16, LWSP16, LW4X4, SW4X4, LWGP16, SWSP16, SW16, and SWGP16 instructions. Backports commit 8bdb7029c3b73327ba39a59fdc2c6ee3d64b2b24 from qemu
This commit is contained in:
parent
9e82494344
commit
038cc8df4d
|
@ -16844,6 +16844,14 @@ static inline int decode_gpr_gpr3(int r)
|
|||
return map[r & 0x7];
|
||||
}
|
||||
|
||||
/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
|
||||
static inline int decode_gpr_gpr3_src_store(int r)
|
||||
{
|
||||
static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
|
||||
|
||||
return map[r & 0x7];
|
||||
}
|
||||
|
||||
/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
|
||||
static inline int decode_gpr_gpr4(int r)
|
||||
{
|
||||
|
@ -16853,6 +16861,15 @@ static inline int decode_gpr_gpr4(int r)
|
|||
return map[r & 0xf];
|
||||
}
|
||||
|
||||
/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
|
||||
static inline int decode_gpr_gpr4_zero(int r)
|
||||
{
|
||||
static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
|
||||
16, 17, 18, 19, 20, 21, 22, 23 };
|
||||
|
||||
return map[r & 0xf];
|
||||
}
|
||||
|
||||
|
||||
static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
|
||||
{
|
||||
|
@ -16861,6 +16878,7 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
|
|||
int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
|
||||
int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
|
||||
int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
|
||||
int offset;
|
||||
int imm;
|
||||
|
||||
/* make sure instructions are on a halfword boundary */
|
||||
|
@ -16929,6 +16947,13 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
|
|||
}
|
||||
break;
|
||||
case NM_P16C:
|
||||
switch (ctx->opcode & 1) {
|
||||
case NM_POOL16C_0:
|
||||
break;
|
||||
case NM_LWXS16:
|
||||
gen_ldxs(ctx, rt, rs, rd);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NM_P16_A1:
|
||||
switch (extract32(ctx->opcode, 6, 1)) {
|
||||
|
@ -16993,24 +17018,95 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
|
|||
case NM_ANDI16:
|
||||
break;
|
||||
case NM_P16_LB:
|
||||
offset = extract32(ctx->opcode, 0, 2);
|
||||
switch (extract32(ctx->opcode, 2, 2)) {
|
||||
case NM_LB16:
|
||||
gen_ld(ctx, OPC_LB, rt, rs, offset);
|
||||
break;
|
||||
case NM_SB16:
|
||||
rt = decode_gpr_gpr3_src_store(
|
||||
NANOMIPS_EXTRACT_RD(ctx->opcode));
|
||||
gen_st(ctx, OPC_SB, rt, rs, offset);
|
||||
break;
|
||||
case NM_LBU16:
|
||||
gen_ld(ctx, OPC_LBU, rt, rs, offset);
|
||||
break;
|
||||
default:
|
||||
generate_exception_end(ctx, EXCP_RI);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NM_P16_LH:
|
||||
offset = extract32(ctx->opcode, 1, 2) << 1;
|
||||
switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
|
||||
case NM_LH16:
|
||||
gen_ld(ctx, OPC_LH, rt, rs, offset);
|
||||
break;
|
||||
case NM_SH16:
|
||||
rt = decode_gpr_gpr3_src_store(
|
||||
NANOMIPS_EXTRACT_RD(ctx->opcode));
|
||||
gen_st(ctx, OPC_SH, rt, rs, offset);
|
||||
break;
|
||||
case NM_LHU16:
|
||||
gen_ld(ctx, OPC_LHU, rt, rs, offset);
|
||||
break;
|
||||
default:
|
||||
generate_exception_end(ctx, EXCP_RI);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NM_LW16:
|
||||
offset = extract32(ctx->opcode, 0, 4) << 2;
|
||||
gen_ld(ctx, OPC_LW, rt, rs, offset);
|
||||
break;
|
||||
case NM_LWSP16:
|
||||
rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
|
||||
offset = extract32(ctx->opcode, 0, 5) << 2;
|
||||
gen_ld(ctx, OPC_LW, rt, 29, offset);
|
||||
break;
|
||||
case NM_LW4X4:
|
||||
rt = (extract32(ctx->opcode, 9, 1) << 3) |
|
||||
extract32(ctx->opcode, 5, 3);
|
||||
rs = (extract32(ctx->opcode, 4, 1) << 3) |
|
||||
extract32(ctx->opcode, 0, 3);
|
||||
offset = (extract32(ctx->opcode, 3, 1) << 3) |
|
||||
(extract32(ctx->opcode, 8, 1) << 2);
|
||||
rt = decode_gpr_gpr4(rt);
|
||||
rs = decode_gpr_gpr4(rs);
|
||||
gen_ld(ctx, OPC_LW, rt, rs, offset);
|
||||
break;
|
||||
case NM_SW4X4:
|
||||
rt = (extract32(ctx->opcode, 9, 1) << 3) |
|
||||
extract32(ctx->opcode, 5, 3);
|
||||
rs = (extract32(ctx->opcode, 4, 1) << 3) |
|
||||
extract32(ctx->opcode, 0, 3);
|
||||
offset = (extract32(ctx->opcode, 3, 1) << 3) |
|
||||
(extract32(ctx->opcode, 8, 1) << 2);
|
||||
rt = decode_gpr_gpr4_zero(rt);
|
||||
rs = decode_gpr_gpr4(rs);
|
||||
gen_st(ctx, OPC_SW, rt, rs, offset);
|
||||
break;
|
||||
case NM_LWGP16:
|
||||
offset = extract32(ctx->opcode, 0, 7) << 2;
|
||||
gen_ld(ctx, OPC_LW, rt, 28, offset);
|
||||
break;
|
||||
case NM_SWSP16:
|
||||
rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
|
||||
offset = extract32(ctx->opcode, 0, 5) << 2;
|
||||
gen_st(ctx, OPC_SW, rt, 29, offset);
|
||||
break;
|
||||
case NM_SW16:
|
||||
rt = decode_gpr_gpr3_src_store(
|
||||
NANOMIPS_EXTRACT_RD(ctx->opcode));
|
||||
rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
|
||||
offset = extract32(ctx->opcode, 0, 4) << 2;
|
||||
gen_st(ctx, OPC_SW, rt, rs, offset);
|
||||
break;
|
||||
case NM_SWGP16:
|
||||
rt = decode_gpr_gpr3_src_store(
|
||||
NANOMIPS_EXTRACT_RD(ctx->opcode));
|
||||
offset = extract32(ctx->opcode, 0, 7) << 2;
|
||||
gen_st(ctx, OPC_SW, rt, 28, offset);
|
||||
break;
|
||||
case NM_BC16:
|
||||
gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
|
||||
|
|
Loading…
Reference in a new issue