[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 18/20] target-mips: microMIPS32 R6 Major instructions
From: |
Leon Alrae |
Subject: |
[Qemu-devel] [PULL 18/20] target-mips: microMIPS32 R6 Major instructions |
Date: |
Fri, 26 Jun 2015 11:25:22 +0100 |
From: Yongbok Kim <address@hidden>
Add new microMIPS32 Release 6 Major opcode instructions
Signed-off-by: Yongbok Kim <address@hidden>
Reviewed-by: Aurelien Jarno <address@hidden>
Signed-off-by: Leon Alrae <address@hidden>
---
target-mips/translate.c | 62 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 45 insertions(+), 17 deletions(-)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 1e79c5a..38dcf9e 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -3209,45 +3209,46 @@ static inline void gen_r6_ld(target_long addr, int reg,
int memidx,
tcg_temp_free(t0);
}
-static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
+static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
+ int rs)
{
target_long offset;
target_long addr;
- switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
+ switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
case OPC_ADDIUPC:
if (rs != 0) {
offset = sextract32(ctx->opcode << 2, 0, 21);
- addr = addr_add(ctx, ctx->pc, offset);
+ addr = addr_add(ctx, pc, offset);
tcg_gen_movi_tl(cpu_gpr[rs], addr);
}
break;
case R6_OPC_LWPC:
offset = sextract32(ctx->opcode << 2, 0, 21);
- addr = addr_add(ctx, ctx->pc, offset);
+ addr = addr_add(ctx, pc, offset);
gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
break;
#if defined(TARGET_MIPS64)
case OPC_LWUPC:
check_mips_64(ctx);
offset = sextract32(ctx->opcode << 2, 0, 21);
- addr = addr_add(ctx, ctx->pc, offset);
+ addr = addr_add(ctx, pc, offset);
gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
break;
#endif
default:
- switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
+ switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
case OPC_AUIPC:
if (rs != 0) {
- offset = imm << 16;
- addr = addr_add(ctx, ctx->pc, offset);
+ offset = sextract32(ctx->opcode, 0, 16) << 16;
+ addr = addr_add(ctx, pc, offset);
tcg_gen_movi_tl(cpu_gpr[rs], addr);
}
break;
case OPC_ALUIPC:
if (rs != 0) {
- offset = imm << 16;
- addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
+ offset = sextract32(ctx->opcode, 0, 16) << 16;
+ addr = ~0xFFFF & addr_add(ctx, pc, offset);
tcg_gen_movi_tl(cpu_gpr[rs], addr);
}
break;
@@ -3258,7 +3259,7 @@ static inline void gen_pcrel(DisasContext *ctx, int rs,
int16_t imm)
case R6_OPC_LDPC + (3 << 16):
check_mips_64(ctx);
offset = sextract32(ctx->opcode << 3, 0, 21);
- addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
+ addr = addr_add(ctx, (pc & ~0x7), offset);
gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
break;
#endif
@@ -14837,9 +14838,16 @@ static void decode_micromips32_opc(CPUMIPSState *env,
DisasContext *ctx)
break;
}
break;
- case ADDI32:
- mips32_op = OPC_ADDI;
- goto do_addi;
+ case ADDI32: /* AUI, LUI */
+ if (ctx->insn_flags & ISA_MIPS32R6) {
+ /* AUI, LUI */
+ gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
+ } else {
+ /* ADDI32 */
+ mips32_op = OPC_ADDI;
+ goto do_addi;
+ }
+ break;
case ADDIU32:
mips32_op = OPC_ADDIU;
do_addi:
@@ -14968,8 +14976,28 @@ static void decode_micromips32_opc(CPUMIPSState *env,
DisasContext *ctx)
do_cop1:
gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
break;
- case ADDIUPC:
- {
+ case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
+ if (ctx->insn_flags & ISA_MIPS32R6) {
+ /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
+ switch ((ctx->opcode >> 16) & 0x1f) {
+ case ADDIUPC_00 ... ADDIUPC_07:
+ gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
+ break;
+ case AUIPC:
+ gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
+ break;
+ case ALUIPC:
+ gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
+ break;
+ case LWPC_08 ... LWPC_0F:
+ gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
+ break;
+ default:
+ generate_exception(ctx, EXCP_RI);
+ break;
+ }
+ } else {
+ /* ADDIUPC */
int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
int offset = SIMM(ctx->opcode, 0, 23) << 2;
@@ -19989,7 +20017,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext
*ctx)
break;
case OPC_PCREL:
check_insn(ctx, ISA_MIPS32R6);
- gen_pcrel(ctx, rs, imm);
+ gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
break;
default: /* Invalid */
MIPS_INVAL("major opcode");
--
2.1.0
- [Qemu-devel] [PULL 09/20] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP, (continued)
- [Qemu-devel] [PULL 09/20] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 04/20] target-mips: add Unified Hosting Interface (UHI) support, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 08/20] target-mips: remove an unused argument, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 14/20] target-mips: microMIPS32 R6 branches and jumps, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 11/20] target-mips: raise RI exceptions when FIR.PS = 0, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 13/20] target-mips: add microMIPS32 R6 opcode enum, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 15/20] target-mips: microMIPS32 R6 POOL32A{XF} instructions, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 12/20] target-mips: signal RI for removed instructions in microMIPS R6, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 10/20] target-mips: rearrange gen_compute_compact_branch, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 17/20] target-mips: microMIPS32 R6 POOL32{I, C} instructions, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 18/20] target-mips: microMIPS32 R6 Major instructions,
Leon Alrae <=
- [Qemu-devel] [PULL 19/20] target-mips: microMIPS32 R6 POOL16{A, C} instructions, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 16/20] target-mips: microMIPS32 R6 POOL32F instructions, Leon Alrae, 2015/06/26
- [Qemu-devel] [PULL 20/20] target-mips: add mips32r6-generic CPU definition, Leon Alrae, 2015/06/26
- Re: [Qemu-devel] [PULL 00/20] target-mips queue, Peter Maydell, 2015/06/26