[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v8 32/87] target/mips: Add emulation of some common
From: |
Aleksandar Markovic |
Subject: |
[Qemu-devel] [PATCH v8 32/87] target/mips: Add emulation of some common nanoMIPS 32-bit instructions |
Date: |
Mon, 13 Aug 2018 19:52:57 +0200 |
From: Yongbok Kim <address@hidden>
Add emulation of SIGRIE, SYSCALL, BREAK, SDBBP, ADDIU, ADDIUPC,
ADDIUGP.W, LWGP, SWGP, ORI, XORI, ANDI, and other instructions.
Reviewed-by: Aleksandar Markovic <address@hidden>
Signed-off-by: Yongbok Kim <address@hidden>
Signed-off-by: Aleksandar Markovic <address@hidden>
Signed-off-by: Stefan Markovic <address@hidden>
---
target/mips/translate.c | 270 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 269 insertions(+), 1 deletion(-)
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 868535c..6cd8cec 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16768,6 +16768,274 @@ static void gen_pool16c_nanomips_insn(DisasContext
*ctx)
}
}
+static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
+{
+ uint16_t insn;
+ uint32_t op;
+ int rt, rs;
+ int offset;
+ int imm;
+
+ insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
+ ctx->opcode = (ctx->opcode << 16) | insn;
+
+ rt = extract32(ctx->opcode, 21, 5);
+ rs = extract32(ctx->opcode, 16, 5);
+
+ op = extract32(ctx->opcode, 26, 6);
+ switch (op) {
+ case NM_P_ADDIU:
+ if (rt == 0) {
+ /* P.RI */
+ switch (extract32(ctx->opcode, 19, 2)) {
+ case NM_SIGRIE:
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ case NM_P_SYSCALL:
+ if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
+ generate_exception_end(ctx, EXCP_SYSCALL);
+ } else {
+ generate_exception_end(ctx, EXCP_RI);
+ }
+ break;
+ case NM_BREAK:
+ generate_exception_end(ctx, EXCP_BREAK);
+ break;
+ case NM_SDBBP:
+ if (is_uhi(extract32(ctx->opcode, 0, 19))) {
+ gen_helper_do_semihosting(cpu_env);
+ } else {
+ if (ctx->hflags & MIPS_HFLAG_SBRI) {
+ generate_exception_end(ctx, EXCP_RI);
+ } else {
+ generate_exception_end(ctx, EXCP_DBp);
+ }
+ }
+ break;
+ }
+ } else {
+ imm = extract32(ctx->opcode, 0, 16);
+ if (rs != 0) {
+ tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
+ tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
+ } else {
+ tcg_gen_movi_tl(cpu_gpr[rt], imm);
+ }
+ }
+ break;
+ case NM_ADDIUPC:
+ if (rt != 0) {
+ offset = sextract32(ctx->opcode, 0, 1) << 21 |
+ extract32(ctx->opcode, 1, 20) << 1;
+ target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
+ tcg_gen_movi_tl(cpu_gpr[rt], addr);
+ }
+ break;
+ case NM_POOL32A:
+ break;
+ case NM_P_GP_W:
+ switch (ctx->opcode & 0x03) {
+ case NM_ADDIUGP_W:
+ if (rt != 0) {
+ offset = extract32(ctx->opcode, 0, 21);
+ gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
+ }
+ break;
+ case NM_LWGP:
+ gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
+ break;
+ case NM_SWGP:
+ gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
+ break;
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ break;
+ case NM_P48I:
+ return 6;
+ case NM_P_U12:
+ switch (extract32(ctx->opcode, 12, 4)) {
+ case NM_ORI:
+ gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
+ break;
+ case NM_XORI:
+ gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0,
12));
+ break;
+ case NM_ANDI:
+ gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0,
12));
+ break;
+ case NM_P_SR:
+ switch (extract32(ctx->opcode, 20, 1)) {
+ case NM_PP_SR:
+ switch (ctx->opcode & 3) {
+ case NM_SAVE:
+ gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
+ extract32(ctx->opcode, 2, 1),
+ extract32(ctx->opcode, 3, 9) << 3);
+ break;
+ case NM_RESTORE:
+ case NM_RESTORE_JRC:
+ gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
+ extract32(ctx->opcode, 2, 1),
+ extract32(ctx->opcode, 3, 9) << 3);
+ if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
+ gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
+ }
+ break;
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ break;
+ case NM_P_SR_F:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ break;
+ case NM_SLTI:
+ gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
+ break;
+ case NM_SLTIU:
+ gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
+ break;
+ case NM_SEQI:
+ {
+ TCGv t0 = tcg_temp_new();
+
+ imm = extract32(ctx->opcode, 0, 12);
+ gen_load_gpr(t0, rs);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
+ gen_store_gpr(t0, rt);
+
+ tcg_temp_free(t0);
+ }
+ break;
+ case NM_ADDIUNEG:
+ imm = (int16_t) extract32(ctx->opcode, 0, 12);
+ gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
+ break;
+ case NM_P_SHIFT:
+ {
+ int shift = extract32(ctx->opcode, 0, 5);
+ switch (extract32(ctx->opcode, 5, 4)) {
+ case NM_P_SLL:
+ if (rt == 0 && shift == 0) {
+ /* NOP */
+ } else if (rt == 0 && shift == 3) {
+ /* EHB treat as NOP */
+ } else if (rt == 0 && shift == 5) {
+ /* PAUSE */
+ if (ctx->hflags & MIPS_HFLAG_BMASK) {
+ generate_exception_end(ctx, EXCP_RI);
+ }
+ } else if (rt == 0 && shift == 6) {
+ /* SYNC */
+ gen_sync(extract32(ctx->opcode, 16, 5));
+ } else {
+ /* SLL */
+ gen_shift_imm(ctx, OPC_SLL, rt, rs,
+ extract32(ctx->opcode, 0, 5));
+ }
+ break;
+ case NM_SRL:
+ gen_shift_imm(ctx, OPC_SRL, rt, rs,
+ extract32(ctx->opcode, 0, 5));
+ break;
+ case NM_SRA:
+ gen_shift_imm(ctx, OPC_SRA, rt, rs,
+ extract32(ctx->opcode, 0, 5));
+ break;
+ case NM_ROTR:
+ gen_shift_imm(ctx, OPC_ROTR, rt, rs,
+ extract32(ctx->opcode, 0, 5));
+ break;
+ }
+ }
+ break;
+ case NM_P_ROTX:
+ break;
+ case NM_P_INS:
+ switch (((ctx->opcode >> 10) & 2) |
+ (extract32(ctx->opcode, 5, 1))) {
+ case NM_INS:
+ gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
+ extract32(ctx->opcode, 6, 5));
+ break;
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ break;
+ case NM_P_EXT:
+ switch (((ctx->opcode >> 10) & 2) |
+ (extract32(ctx->opcode, 5, 1))) {
+ case NM_EXT:
+ gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
+ extract32(ctx->opcode, 6, 5));
+ break;
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ break;
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ break;
+ case NM_POOL32F:
+ break;
+ case NM_POOL32S:
+ break;
+ case NM_P_LUI:
+ switch (extract32(ctx->opcode, 1, 1)) {
+ case NM_LUI:
+ if (rt != 0) {
+ tcg_gen_movi_tl(cpu_gpr[rt],
+ sextract32(ctx->opcode, 0, 1) << 31 |
+ extract32(ctx->opcode, 2, 10) << 21 |
+ extract32(ctx->opcode, 12, 9) << 12);
+ }
+ break;
+ case NM_ALUIPC:
+ if (rt != 0) {
+ offset = sextract32(ctx->opcode, 0, 1) << 31 |
+ extract32(ctx->opcode, 2, 10) << 21 |
+ extract32(ctx->opcode, 12, 9) << 12;
+ target_long addr;
+ addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
+ tcg_gen_movi_tl(cpu_gpr[rt], addr);
+ }
+ break;
+ }
+ break;
+ case NM_P_GP_BH:
+ break;
+ case NM_P_LS_U12:
+ break;
+ case NM_P_LS_S9:
+ break;
+ case NM_MOVE_BALC:
+ break;
+ case NM_P_BAL:
+ break;
+ case NM_P_J:
+ break;
+ case NM_P_BR1:
+ break;
+ case NM_P_BR2:
+ break;
+ case NM_P_BRI:
+ break;
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ return 4;
+}
+
static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
{
uint32_t op;
@@ -17085,7 +17353,7 @@ static int decode_nanomips_opc(CPUMIPSState *env,
DisasContext *ctx)
case NM_MOVEPREV:
break;
default:
- break;
+ return decode_nanomips_32_48_opc(env, ctx);
}
return 2;
--
2.7.4
- [Qemu-devel] [PATCH v8 75/87] linux-user: Add target_structs.h header for nanoMIPS, (continued)
- [Qemu-devel] [PATCH v8 75/87] linux-user: Add target_structs.h header for nanoMIPS, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 74/87] linux-user: Add target_cpu.h header for nanoMIPS, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 60/87] elf: Don't check FCR31_NAN2008 bit for nanoMIPS, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 71/87] linux-user: Add target_fcntl.h header for nanoMIPS, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 80/87] linux-user: Amend support for sigaction() syscall for nanoMIPS, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 70/87] linux-user: Update syscall_defs.h header for nanoMIPS, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 73/87] linux-user: Add target_syscall.h header for nanoMIPS, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 85/87] gdbstub: Disable handling of nanoMIPS ISA bit in the MIPS gdbstub, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 67/87] linux-user: Add syscall numbers for nanoMIPS, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 32/87] target/mips: Add emulation of some common nanoMIPS 32-bit instructions,
Aleksandar Markovic <=
- [Qemu-devel] [PATCH v8 44/87] target/mips: Implement MT ASE support for nanoMIPS, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 48/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 4, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 66/87] elf: Add nanoMIPS specific variations in ELF header fields, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 76/87] linux-user: Add target_elf.h header for nanoMIPS, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 78/87] linux-user: Add support for nanoMIPS signal trampoline, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 87/87] qemu-doc: Add nanoMIPS-related items, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 45/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 1, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 82/87] linux-user: Add support for nanoMIPS core files, Aleksandar Markovic, 2018/08/13
- [Qemu-devel] [PATCH v8 84/87] linux-user: Add nanoMIPS support in scripts/qemu-binfmt-conf.sh, Aleksandar Markovic, 2018/08/13