diff options
Diffstat (limited to 'target-tricore/translate.c')
| -rw-r--r-- | target-tricore/translate.c | 1305 |
1 files changed, 1305 insertions, 0 deletions
diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 4f654deb65..d5a95969bb 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -115,6 +115,10 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f, tcg_temp_free_i32(helper_tmp); \ } while (0) +#define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF)) +#define EA_B_ABSOLUT(con) (((offset & 0xf00000) << 8) | \ + ((offset & 0x0fffff) << 1)) + /* Functions for load/save to/from memory */ static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2, @@ -135,6 +139,100 @@ static inline void gen_offset_st(DisasContext *ctx, TCGv r1, TCGv r2, tcg_temp_free(temp); } +static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx) +{ + TCGv_i64 temp = tcg_temp_new_i64(); + + tcg_gen_concat_i32_i64(temp, rl, rh); + tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEQ); + + tcg_temp_free_i64(temp); +} + +static void gen_offset_st_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con, + DisasContext *ctx) +{ + TCGv temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, base, con); + gen_st_2regs_64(rh, rl, temp, ctx); + tcg_temp_free(temp); +} + +static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx) +{ + TCGv_i64 temp = tcg_temp_new_i64(); + + tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEQ); + /* write back to two 32 bit regs */ + tcg_gen_extr_i64_i32(rl, rh, temp); + + tcg_temp_free_i64(temp); +} + +static void gen_offset_ld_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con, + DisasContext *ctx) +{ + TCGv temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, base, con); + gen_ld_2regs_64(rh, rl, temp, ctx); + tcg_temp_free(temp); +} + +static void gen_st_preincr(DisasContext *ctx, TCGv r1, TCGv r2, int16_t off, + TCGMemOp mop) +{ + TCGv temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, r2, off); + tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop); + tcg_gen_mov_tl(r2, temp); + tcg_temp_free(temp); +} + +static void gen_ld_preincr(DisasContext *ctx, TCGv r1, TCGv r2, int16_t off, + TCGMemOp mop) +{ + TCGv temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, r2, off); + tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop); + tcg_gen_mov_tl(r2, temp); + tcg_temp_free(temp); +} + +/* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */ +static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea) +{ + TCGv temp = tcg_temp_new(); + TCGv temp2 = tcg_temp_new(); + + /* temp = (M(EA, word) */ + tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL); + /* temp = temp & ~E[a][63:32]) */ + tcg_gen_andc_tl(temp, temp, cpu_gpr_d[ereg+1]); + /* temp2 = (E[a][31:0] & E[a][63:32]); */ + tcg_gen_and_tl(temp2, cpu_gpr_d[ereg], cpu_gpr_d[ereg+1]); + /* temp = temp | temp2; */ + tcg_gen_or_tl(temp, temp, temp2); + /* M(EA, word) = temp; */ + tcg_gen_qemu_st_tl(temp, ea, ctx->mem_idx, MO_LEUL); + + tcg_temp_free(temp); + tcg_temp_free(temp2); +} + +/* tmp = M(EA, word); + M(EA, word) = D[a]; + D[a] = tmp[31:0];*/ +static void gen_swap(DisasContext *ctx, int reg, TCGv ea) +{ + TCGv temp = tcg_temp_new(); + + tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL); + tcg_gen_qemu_st_tl(cpu_gpr_d[reg], ea, ctx->mem_idx, MO_LEUL); + tcg_gen_mov_tl(cpu_gpr_d[reg], temp); + + tcg_temp_free(temp); +} + /* Functions for arithmetic instructions */ static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2) @@ -365,6 +463,49 @@ static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2) gen_helper_sub_ssov(ret, cpu_env, r1, r2); } +static inline void gen_bit_2op(TCGv ret, TCGv r1, TCGv r2, + int pos1, int pos2, + void(*op1)(TCGv, TCGv, TCGv), + void(*op2)(TCGv, TCGv, TCGv)) +{ + TCGv temp1, temp2; + + temp1 = tcg_temp_new(); + temp2 = tcg_temp_new(); + + tcg_gen_shri_tl(temp2, r2, pos2); + tcg_gen_shri_tl(temp1, r1, pos1); + + (*op1)(temp1, temp1, temp2); + (*op2)(temp1 , ret, temp1); + + tcg_gen_deposit_tl(ret, ret, temp1, 0, 1); + + tcg_temp_free(temp1); + tcg_temp_free(temp2); +} + +/* ret = r1[pos1] op1 r2[pos2]; */ +static inline void gen_bit_1op(TCGv ret, TCGv r1, TCGv r2, + int pos1, int pos2, + void(*op1)(TCGv, TCGv, TCGv)) +{ + TCGv temp1, temp2; + + temp1 = tcg_temp_new(); + temp2 = tcg_temp_new(); + + tcg_gen_shri_tl(temp2, r2, pos2); + tcg_gen_shri_tl(temp1, r1, pos1); + + (*op1)(ret, temp1, temp2); + + tcg_gen_andi_tl(ret, ret, 0x1); + + tcg_temp_free(temp1); + tcg_temp_free(temp2); +} + /* helpers for generating program flow micro-ops */ static inline void gen_save_pc(target_ulong pc) @@ -434,6 +575,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, case OPC1_32_B_J: gen_goto_tb(ctx, 0, ctx->pc + offset * 2); break; + case OPC1_32_B_CALL: case OPC1_16_SB_CALL: gen_helper_1arg(call, ctx->next_pc); gen_goto_tb(ctx, 0, ctx->pc + offset * 2); @@ -509,6 +651,20 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, gen_helper_ret(cpu_env); tcg_gen_exit_tb(0); break; +/* B-format */ + case OPC1_32_B_CALLA: + gen_helper_1arg(call, ctx->next_pc); + gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset)); + break; + case OPC1_32_B_JLA: + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc); + case OPC1_32_B_JA: + gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset)); + break; + case OPC1_32_B_JL: + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc); + gen_goto_tb(ctx, 0, ctx->pc + offset * 2); + break; default: printf("Branch Error at %x\n", ctx->pc); } @@ -1099,8 +1255,1157 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx) } } +/* + * 32 bit instructions + */ + +/* ABS-format */ +static void decode_abs_ldw(CPUTriCoreState *env, DisasContext *ctx) +{ + int32_t op2; + int32_t r1; + uint32_t address; + TCGv temp; + + r1 = MASK_OP_ABS_S1D(ctx->opcode); + address = MASK_OP_ABS_OFF18(ctx->opcode); + op2 = MASK_OP_ABS_OP2(ctx->opcode); + + temp = tcg_const_i32(EA_ABS_FORMAT(address)); + + switch (op2) { + case OPC2_32_ABS_LD_A: + tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL); + break; + case OPC2_32_ABS_LD_D: + gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx); + break; + case OPC2_32_ABS_LD_DA: + gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx); + break; + case OPC2_32_ABS_LD_W: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL); + break; + } + + tcg_temp_free(temp); +} + +static void decode_abs_ldb(CPUTriCoreState *env, DisasContext *ctx) +{ + int32_t op2; + int32_t r1; + uint32_t address; + TCGv temp; + + r1 = MASK_OP_ABS_S1D(ctx->opcode); + address = MASK_OP_ABS_OFF18(ctx->opcode); + op2 = MASK_OP_ABS_OP2(ctx->opcode); + + temp = tcg_const_i32(EA_ABS_FORMAT(address)); + + switch (op2) { + case OPC2_32_ABS_LD_B: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_SB); + break; + case OPC2_32_ABS_LD_BU: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB); + break; + case OPC2_32_ABS_LD_H: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESW); + break; + case OPC2_32_ABS_LD_HU: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW); + break; + } + + tcg_temp_free(temp); +} + +static void decode_abs_ldst_swap(CPUTriCoreState *env, DisasContext *ctx) +{ + int32_t op2; + int32_t r1; + uint32_t address; + TCGv temp; + + r1 = MASK_OP_ABS_S1D(ctx->opcode); + address = MASK_OP_ABS_OFF18(ctx->opcode); + op2 = MASK_OP_ABS_OP2(ctx->opcode); + + temp = tcg_const_i32(EA_ABS_FORMAT(address)); + + switch (op2) { + case OPC2_32_ABS_LDMST: + gen_ldmst(ctx, r1, temp); + break; + case OPC2_32_ABS_SWAP_W: + gen_swap(ctx, r1, temp); + break; + } + + tcg_temp_free(temp); +} + +static void decode_abs_ldst_context(CPUTriCoreState *env, DisasContext *ctx) +{ + uint32_t op2; + int32_t off18; + + off18 = MASK_OP_ABS_OFF18(ctx->opcode); + op2 = MASK_OP_ABS_OP2(ctx->opcode); + + switch (op2) { + case OPC2_32_ABS_LDLCX: + gen_helper_1arg(ldlcx, EA_ABS_FORMAT(off18)); + break; + case OPC2_32_ABS_LDUCX: + gen_helper_1arg(lducx, EA_ABS_FORMAT(off18)); + break; + case OPC2_32_ABS_STLCX: + gen_helper_1arg(stlcx, EA_ABS_FORMAT(off18)); + break; + case OPC2_32_ABS_STUCX: + gen_helper_1arg(stucx, EA_ABS_FORMAT(off18)); + break; + } +} + +static void decode_abs_store(CPUTriCoreState *env, DisasContext *ctx) +{ + int32_t op2; + int32_t r1; + uint32_t address; + TCGv temp; + + r1 = MASK_OP_ABS_S1D(ctx->opcode); + address = MASK_OP_ABS_OFF18(ctx->opcode); + op2 = MASK_OP_ABS_OP2(ctx->opcode); + + temp = tcg_const_i32(EA_ABS_FORMAT(address)); + + switch (op2) { + case OPC2_32_ABS_ST_A: + tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL); + break; + case OPC2_32_ABS_ST_D: + gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx); + break; + case OPC2_32_ABS_ST_DA: + gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx); + break; + case OPC2_32_ABS_ST_W: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL); + break; + + } + tcg_temp_free(temp); +} + +static void decode_abs_storeb_h(CPUTriCoreState *env, DisasContext *ctx) +{ + int32_t op2; + int32_t r1; + uint32_t address; + TCGv temp; + + r1 = MASK_OP_ABS_S1D(ctx->opcode); + address = MASK_OP_ABS_OFF18(ctx->opcode); + op2 = MASK_OP_ABS_OP2(ctx->opcode); + + temp = tcg_const_i32(EA_ABS_FORMAT(address)); + + switch (op2) { + case OPC2_32_ABS_ST_B: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB); + break; + case OPC2_32_ABS_ST_H: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW); + break; + } + tcg_temp_free(temp); +} + +/* Bit-format */ + +static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx) +{ + uint32_t op2; + int r1, r2, r3; + int pos1, pos2; + + r1 = MASK_OP_BIT_S1(ctx->opcode); + r2 = MASK_OP_BIT_S2(ctx->opcode); + r3 = MASK_OP_BIT_D(ctx->opcode); + pos1 = MASK_OP_BIT_POS1(ctx->opcode); + pos2 = MASK_OP_BIT_POS2(ctx->opcode); + op2 = MASK_OP_BIT_OP2(ctx->opcode); + + + switch (op2) { + case OPC2_32_BIT_AND_AND_T: + gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_and_tl, &tcg_gen_and_tl); + break; + case OPC2_32_BIT_AND_ANDN_T: + gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl); + break; + case OPC2_32_BIT_AND_NOR_T: + if (TCG_TARGET_HAS_andc_i32) { + gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl); + } else { + gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_and_tl); + } + break; + case OPC2_32_BIT_AND_OR_T: + gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl); + break; + } +} + +static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx) +{ + uint32_t op2; + int r1, r2, r3; + int pos1, pos2; + r1 = MASK_OP_BIT_S1(ctx->opcode); + r2 = MASK_OP_BIT_S2(ctx->opcode); + r3 = MASK_OP_BIT_D(ctx->opcode); + pos1 = MASK_OP_BIT_POS1(ctx->opcode); + pos2 = MASK_OP_BIT_POS2(ctx->opcode); + op2 = MASK_OP_BIT_OP2(ctx->opcode); + + switch (op2) { + case OPC2_32_BIT_AND_T: + gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_and_tl); + break; + case OPC2_32_BIT_ANDN_T: + gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_andc_tl); + break; + case OPC2_32_BIT_NOR_T: + gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_nor_tl); + break; + case OPC2_32_BIT_OR_T: + gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_or_tl); + break; + } +} + +static void decode_bit_insert(CPUTriCoreState *env, DisasContext *ctx) +{ + uint32_t op2; + int r1, r2, r3; + int pos1, pos2; + TCGv temp; + op2 = MASK_OP_BIT_OP2(ctx->opcode); + r1 = MASK_OP_BIT_S1(ctx->opcode); + r2 = MASK_OP_BIT_S2(ctx->opcode); + r3 = MASK_OP_BIT_D(ctx->opcode); + pos1 = MASK_OP_BIT_POS1(ctx->opcode); + pos2 = MASK_OP_BIT_POS2(ctx->opcode); + + temp = tcg_temp_new(); + + tcg_gen_shri_tl(temp, cpu_gpr_d[r2], pos2); + if (op2 == OPC2_32_BIT_INSN_T) { + tcg_gen_not_tl(temp, temp); + } + tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], temp, pos1, 1); + tcg_temp_free(temp); +} + +static void decode_bit_logical_t2(CPUTriCoreState *env, DisasContext *ctx) +{ + uint32_t op2; + + int r1, r2, r3; + int pos1, pos2; + + op2 = MASK_OP_BIT_OP2(ctx->opcode); + r1 = MASK_OP_BIT_S1(ctx->opcode); + r2 = MASK_OP_BIT_S2(ctx->opcode); + r3 = MASK_OP_BIT_D(ctx->opcode); + pos1 = MASK_OP_BIT_POS1(ctx->opcode); + pos2 = MASK_OP_BIT_POS2(ctx->opcode); + + switch (op2) { + case OPC2_32_BIT_NAND_T: + gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_nand_tl); + break; + case OPC2_32_BIT_ORN_T: + gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_orc_tl); + break; + case OPC2_32_BIT_XNOR_T: + gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_eqv_tl); + break; + case OPC2_32_BIT_XOR_T: + gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_xor_tl); + break; + } +} + +static void decode_bit_orand(CPUTriCoreState *env, DisasContext *ctx) +{ + uint32_t op2; + + int r1, r2, r3; + int pos1, pos2; + + op2 = MASK_OP_BIT_OP2(ctx->opcode); + r1 = MASK_OP_BIT_S1(ctx->opcode); + r2 = MASK_OP_BIT_S2(ctx->opcode); + r3 = MASK_OP_BIT_D(ctx->opcode); + pos1 = MASK_OP_BIT_POS1(ctx->opcode); + pos2 = MASK_OP_BIT_POS2(ctx->opcode); + + switch (op2) { + case OPC2_32_BIT_OR_AND_T: + gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_and_tl, &tcg_gen_or_tl); + break; + case OPC2_32_BIT_OR_ANDN_T: + gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_or_tl); + break; + case OPC2_32_BIT_OR_NOR_T: + if (TCG_TARGET_HAS_orc_i32) { + gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_or_tl, &tcg_gen_orc_tl); + } else { + gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_or_tl); + } + break; + case OPC2_32_BIT_OR_OR_T: + gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_or_tl, &tcg_gen_or_tl); + break; + } +} + +static void decode_bit_sh_logic1(CPUTriCoreState *env, DisasContext *ctx) +{ + uint32_t op2; + int r1, r2, r3; + int pos1, pos2; + TCGv temp; + + op2 = MASK_OP_BIT_OP2(ctx->opcode); + r1 = MASK_OP_BIT_S1(ctx->opcode); + r2 = MASK_OP_BIT_S2(ctx->opcode); + r3 = MASK_OP_BIT_D(ctx->opcode); + pos1 = MASK_OP_BIT_POS1(ctx->opcode); + pos2 = MASK_OP_BIT_POS2(ctx->opcode); + + temp = tcg_temp_new(); + + switch (op2) { + case OPC2_32_BIT_SH_AND_T: + gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_and_tl); + break; + case OPC2_32_BIT_SH_ANDN_T: + gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_andc_tl); + break; + case OPC2_32_BIT_SH_NOR_T: + gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_nor_tl); + break; + case OPC2_32_BIT_SH_OR_T: + gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_or_tl); + break; + } + tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 1); + tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp); + tcg_temp_free(temp); +} + +static void decode_bit_sh_logic2(CPUTriCoreState *env, DisasContext *ctx) +{ + uint32_t op2; + int r1, r2, r3; + int pos1, pos2; + TCGv temp; + + op2 = MASK_OP_BIT_OP2(ctx->opcode); + r1 = MASK_OP_BIT_S1(ctx->opcode); + r2 = MASK_OP_BIT_S2(ctx->opcode); + r3 = MASK_OP_BIT_D(ctx->opcode); + pos1 = MASK_OP_BIT_POS1(ctx->opcode); + pos2 = MASK_OP_BIT_POS2(ctx->opcode); + + temp = tcg_temp_new(); + + switch (op2) { + case OPC2_32_BIT_SH_NAND_T: + gen_bit_1op(temp, cpu_gpr_d[r1] , cpu_gpr_d[r2] , + pos1, pos2, &tcg_gen_nand_tl); + break; + case OPC2_32_BIT_SH_ORN_T: + gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_orc_tl); + break; + case OPC2_32_BIT_SH_XNOR_T: + gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_eqv_tl); + break; + case OPC2_32_BIT_SH_XOR_T: + gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], + pos1, pos2, &tcg_gen_xor_tl); + break; + } + tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 1); + tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp); + tcg_temp_free(temp); +} + +/* BO-format */ + + +static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env, + DisasContext *ctx) +{ + uint32_t op2; + uint32_t off10; + int32_t r1, r2; + TCGv temp; + + r1 = MASK_OP_BO_S1D(ctx->opcode); + r2 = MASK_OP_BO_S2(ctx->opcode); + off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode); + op2 = MASK_OP_BO_OP2(ctx->opcode); + + switch (op2) { + case OPC2_32_BO_CACHEA_WI_SHORTOFF: + case OPC2_32_BO_CACHEA_W_SHORTOFF: + case OPC2_32_BO_CACHEA_I_SHORTOFF: + /* instruction to access the cache */ + break; + case OPC2_32_BO_CACHEA_WI_POSTINC: + case OPC2_32_BO_CACHEA_W_POSTINC: + case OPC2_32_BO_CACHEA_I_POSTINC: + /* instruction to access the cache, but we still need to handle + the addressing mode */ + tcg_gen_addi_tl(cpu_gpr_d[r2], cpu_gpr_d[r2], off10); + break; + case OPC2_32_BO_CACHEA_WI_PREINC: + case OPC2_32_BO_CACHEA_W_PREINC: + case OPC2_32_BO_CACHEA_I_PREINC: + /* instruction to access the cache, but we still need to handle + the addressing mode */ + tcg_gen_addi_tl(cpu_gpr_d[r2], cpu_gpr_d[r2], off10); + break; + case OPC2_32_BO_CACHEI_WI_SHORTOFF: + case OPC2_32_BO_CACHEI_W_SHORTOFF: + /* TODO: Raise illegal opcode trap, + if tricore_feature(TRICORE_FEATURE_13) */ + break; + case OPC2_32_BO_CACHEI_W_POSTINC: + case OPC2_32_BO_CACHEI_WI_POSTINC: + if (!tricore_feature(env, TRICORE_FEATURE_13)) { + tcg_gen_addi_tl(cpu_gpr_d[r2], cpu_gpr_d[r2], off10); + } /* TODO: else raise illegal opcode trap */ + break; + case OPC2_32_BO_CACHEI_W_PREINC: + case OPC2_32_BO_CACHEI_WI_PREINC: + if (!tricore_feature(env, TRICORE_FEATURE_13)) { + tcg_gen_addi_tl(cpu_gpr_d[r2], cpu_gpr_d[r2], off10); + } /* TODO: else raise illegal opcode trap */ + break; + case OPC2_32_BO_ST_A_SHORTOFF: + gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL); + break; + case OPC2_32_BO_ST_A_POSTINC: + tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_LESL); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_ST_A_PREINC: + gen_st_preincr(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL); + break; + case OPC2_32_BO_ST_B_SHORTOFF: + gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB); + break; + case OPC2_32_BO_ST_B_POSTINC: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_UB); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_ST_B_PREINC: + gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB); + break; + case OPC2_32_BO_ST_D_SHORTOFF: + gen_offset_st_2regs(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], + off10, ctx); + break; + case OPC2_32_BO_ST_D_POSTINC: + gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_ST_D_PREINC: + temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10); + gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx); + tcg_gen_mov_tl(cpu_gpr_a[r2], temp); + tcg_temp_free(temp); + break; + case OPC2_32_BO_ST_DA_SHORTOFF: + gen_offset_st_2regs(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], + off10, ctx); + break; + case OPC2_32_BO_ST_DA_POSTINC: + gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_ST_DA_PREINC: + temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10); + gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx); + tcg_gen_mov_tl(cpu_gpr_a[r2], temp); + tcg_temp_free(temp); + break; + case OPC2_32_BO_ST_H_SHORTOFF: + gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW); + break; + case OPC2_32_BO_ST_H_POSTINC: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_LEUW); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_ST_H_PREINC: + gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW); + break; + case OPC2_32_BO_ST_Q_SHORTOFF: + temp = tcg_temp_new(); + tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16); + gen_offset_st(ctx, temp, cpu_gpr_a[r2], off10, MO_LEUW); + tcg_temp_free(temp); + break; + case OPC2_32_BO_ST_Q_POSTINC: + temp = tcg_temp_new(); + tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16); + tcg_gen_qemu_st_tl(temp, cpu_gpr_a[r2], ctx->mem_idx, + MO_LEUW); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + tcg_temp_free(temp); + break; + case OPC2_32_BO_ST_Q_PREINC: + temp = tcg_temp_new(); + tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16); + gen_st_preincr(ctx, temp, cpu_gpr_a[r2], off10, MO_LEUW); + tcg_temp_free(temp); + break; + case OPC2_32_BO_ST_W_SHORTOFF: + gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL); + break; + case OPC2_32_BO_ST_W_POSTINC: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_LEUL); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_ST_W_PREINC: + gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL); + break; + } +} + +static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env, + DisasContext *ctx) +{ + uint32_t op2; + uint32_t off10; + int32_t r1, r2; + TCGv temp, temp2, temp3; + + r1 = MASK_OP_BO_S1D(ctx->opcode); + r2 = MASK_OP_BO_S2(ctx->opcode); + off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode); + op2 = MASK_OP_BO_OP2(ctx->opcode); + + temp = tcg_temp_new(); + temp2 = tcg_temp_new(); + temp3 = tcg_const_i32(off10); + + tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]); + tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp); + + switch (op2) { + case OPC2_32_BO_CACHEA_WI_BR: + case OPC2_32_BO_CACHEA_W_BR: + case OPC2_32_BO_CACHEA_I_BR: + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_CACHEA_WI_CIRC: + case OPC2_32_BO_CACHEA_W_CIRC: + case OPC2_32_BO_CACHEA_I_CIRC: + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_ST_A_BR: + tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_ST_A_CIRC: + tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_ST_B_BR: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_ST_B_CIRC: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_ST_D_BR: + gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp2, ctx); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_ST_D_CIRC: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL); + tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16); + tcg_gen_addi_tl(temp, temp, 4); + tcg_gen_rem_tl(temp, temp, temp2); + tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp); + tcg_gen_qemu_st_tl(cpu_gpr_d[r1+1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_ST_DA_BR: + gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp2, ctx); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_ST_DA_CIRC: + tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL); + tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16); + tcg_gen_addi_tl(temp, temp, 4); + tcg_gen_rem_tl(temp, temp, temp2); + tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp); + tcg_gen_qemu_st_tl(cpu_gpr_a[r1+1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_ST_H_BR: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_ST_H_CIRC: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_ST_Q_BR: + tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16); + tcg_gen_qemu_st_tl(temp, temp2, ctx->mem_idx, MO_LEUW); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_ST_Q_CIRC: + tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16); + tcg_gen_qemu_st_tl(temp, temp2, ctx->mem_idx, MO_LEUW); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_ST_W_BR: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_ST_W_CIRC: + tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + } + tcg_temp_free(temp); + tcg_temp_free(temp2); + tcg_temp_free(temp3); +} + +static void decode_bo_addrmode_ld_post_pre_base(CPUTriCoreState *env, + DisasContext *ctx) +{ + uint32_t op2; + uint32_t off10; + int32_t r1, r2; + TCGv temp; + + r1 = MASK_OP_BO_S1D(ctx->opcode); + r2 = MASK_OP_BO_S2(ctx->opcode); + off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode); + op2 = MASK_OP_BO_OP2(ctx->opcode); + + switch (op2) { + case OPC2_32_BO_LD_A_SHORTOFF: + gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LEUL); + break; + case OPC2_32_BO_LD_A_POSTINC: + tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_LEUL); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_LD_A_PREINC: + gen_ld_preincr(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LEUL); + break; + case OPC2_32_BO_LD_B_SHORTOFF: + gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB); + break; + case OPC2_32_BO_LD_B_POSTINC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_SB); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_LD_B_PREINC: + gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB); + break; + case OPC2_32_BO_LD_BU_SHORTOFF: + gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB); + break; + case OPC2_32_BO_LD_BU_POSTINC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_UB); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_LD_BU_PREINC: + gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB); + break; + case OPC2_32_BO_LD_D_SHORTOFF: + gen_offset_ld_2regs(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], + off10, ctx); + break; + case OPC2_32_BO_LD_D_POSTINC: + gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_LD_D_PREINC: + temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10); + gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx); + tcg_gen_mov_tl(cpu_gpr_a[r2], temp); + tcg_temp_free(temp); + break; + case OPC2_32_BO_LD_DA_SHORTOFF: + gen_offset_ld_2regs(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], + off10, ctx); + break; + case OPC2_32_BO_LD_DA_POSTINC: + gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_LD_DA_PREINC: + temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10); + gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx); + tcg_gen_mov_tl(cpu_gpr_a[r2], temp); + tcg_temp_free(temp); + break; + case OPC2_32_BO_LD_H_SHORTOFF: + gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LESW); + break; + case OPC2_32_BO_LD_H_POSTINC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_LESW); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_LD_H_PREINC: + gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LESW); + break; + case OPC2_32_BO_LD_HU_SHORTOFF: + gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW); + break; + case OPC2_32_BO_LD_HU_POSTINC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_LEUW); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_LD_HU_PREINC: + gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW); + break; + case OPC2_32_BO_LD_Q_SHORTOFF: + gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW); + tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16); + break; + case OPC2_32_BO_LD_Q_POSTINC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_LEUW); + tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_LD_Q_PREINC: + gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW); + tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16); + break; + case OPC2_32_BO_LD_W_SHORTOFF: + gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL); + break; + case OPC2_32_BO_LD_W_POSTINC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, + MO_LEUL); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_LD_W_PREINC: + gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL); + break; + } +} + +static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env, + DisasContext *ctx) +{ + uint32_t op2; + uint32_t off10; + int r1, r2; + + TCGv temp, temp2, temp3; + + r1 = MASK_OP_BO_S1D(ctx->opcode); + r2 = MASK_OP_BO_S2(ctx->opcode); + off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode); + op2 = MASK_OP_BO_OP2(ctx->opcode); + + temp = tcg_temp_new(); + temp2 = tcg_temp_new(); + temp3 = tcg_const_i32(off10); + + tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]); + tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp); + + + switch (op2) { + case OPC2_32_BO_LD_A_BR: + tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_LD_A_CIRC: + tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_LD_B_BR: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_SB); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_LD_B_CIRC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_SB); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_LD_BU_BR: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_LD_BU_CIRC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_UB); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_LD_D_BR: + gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp2, ctx); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_LD_D_CIRC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL); + tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16); + tcg_gen_addi_tl(temp, temp, 4); + tcg_gen_rem_tl(temp, temp, temp2); + tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp); + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1+1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_LD_DA_BR: + gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp2, ctx); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_LD_DA_CIRC: + tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL); + tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16); + tcg_gen_addi_tl(temp, temp, 4); + tcg_gen_rem_tl(temp, temp, temp2); + tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp); + tcg_gen_qemu_ld_tl(cpu_gpr_a[r1+1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_LD_H_BR: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LESW); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_LD_H_CIRC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LESW); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_LD_HU_BR: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_LD_HU_CIRC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_LD_Q_BR: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW); + tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_LD_Q_CIRC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUW); + tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_LD_W_BR: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_LD_W_CIRC: + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + } + tcg_temp_free(temp); + tcg_temp_free(temp2); + tcg_temp_free(temp3); +} + +static void decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env, + DisasContext *ctx) +{ + uint32_t op2; + uint32_t off10; + int r1, r2; + + TCGv temp, temp2; + + r1 = MASK_OP_BO_S1D(ctx->opcode); + r2 = MASK_OP_BO_S2(ctx->opcode); + off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode); + op2 = MASK_OP_BO_OP2(ctx->opcode); + + + temp = tcg_temp_new(); + temp2 = tcg_temp_new(); + + switch (op2) { + case OPC2_32_BO_LDLCX_SHORTOFF: + tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10); + gen_helper_ldlcx(cpu_env, temp); + break; + case OPC2_32_BO_LDMST_SHORTOFF: + tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10); + gen_ldmst(ctx, r1, temp); + break; + case OPC2_32_BO_LDMST_POSTINC: + gen_ldmst(ctx, r1, cpu_gpr_a[r2]); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_LDMST_PREINC: + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + gen_ldmst(ctx, r1, cpu_gpr_a[r2]); + break; + case OPC2_32_BO_LDUCX_SHORTOFF: + tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10); + gen_helper_lducx(cpu_env, temp); + break; + case OPC2_32_BO_LEA_SHORTOFF: + tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_STLCX_SHORTOFF: + tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10); + gen_helper_stlcx(cpu_env, temp); + break; + case OPC2_32_BO_STUCX_SHORTOFF: + tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10); + gen_helper_stucx(cpu_env, temp); + break; + case OPC2_32_BO_SWAP_W_SHORTOFF: + tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10); + gen_swap(ctx, r1, temp); + break; + case OPC2_32_BO_SWAP_W_POSTINC: + gen_swap(ctx, r1, cpu_gpr_a[r2]); + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + break; + case OPC2_32_BO_SWAP_W_PREINC: + tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10); + gen_swap(ctx, r1, cpu_gpr_a[r2]); + break; + } + tcg_temp_free(temp); + tcg_temp_free(temp2); +} + +static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env, + DisasContext *ctx) +{ + uint32_t op2; + uint32_t off10; + int r1, r2; + + TCGv temp, temp2, temp3; + + r1 = MASK_OP_BO_S1D(ctx->opcode); + r2 = MASK_OP_BO_S2(ctx->opcode); + off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode); + op2 = MASK_OP_BO_OP2(ctx->opcode); + + temp = tcg_temp_new(); + temp2 = tcg_temp_new(); + temp3 = tcg_const_i32(off10); + + tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]); + tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp); + + switch (op2) { + case OPC2_32_BO_LDMST_BR: + gen_ldmst(ctx, r1, temp2); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_LDMST_CIRC: + gen_ldmst(ctx, r1, temp2); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + case OPC2_32_BO_SWAP_W_BR: + gen_swap(ctx, r1, temp2); + gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]); + break; + case OPC2_32_BO_SWAP_W_CIRC: + gen_swap(ctx, r1, temp2); + gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3); + break; + } + tcg_temp_free(temp); + tcg_temp_free(temp2); + tcg_temp_free(temp3); +} + static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) { + int op1; + int32_t r1; + int32_t address; + int8_t b; + int32_t bpos; + TCGv temp, temp2; + + op1 = MASK_OP_MAJOR(ctx->opcode); + + switch (op1) { +/* ABS-format */ + case OPCM_32_ABS_LDW: + decode_abs_ldw(env, ctx); + break; + case OPCM_32_ABS_LDB: + decode_abs_ldb(env, ctx); + break; + case OPCM_32_ABS_LDMST_SWAP: + decode_abs_ldst_swap(env, ctx); + break; + case OPCM_32_ABS_LDST_CONTEXT: + decode_abs_ldst_context(env, ctx); + break; + case OPCM_32_ABS_STORE: + decode_abs_store(env, ctx); + break; + case OPCM_32_ABS_STOREB_H: + decode_abs_storeb_h(env, ctx); + break; + case OPC1_32_ABS_STOREQ: + address = MASK_OP_ABS_OFF18(ctx->opcode); + r1 = MASK_OP_ABS_S1D(ctx->opcode); + temp = tcg_const_i32(EA_ABS_FORMAT(address)); + temp2 = tcg_temp_new(); + + tcg_gen_shri_tl(temp2, cpu_gpr_d[r1], 16); + tcg_gen_qemu_st_tl(temp2, temp, ctx->mem_idx, MO_LEUW); + + tcg_temp_free(temp2); + tcg_temp_free(temp); + break; + case OPC1_32_ABS_LD_Q: + address = MASK_OP_ABS_OFF18(ctx->opcode); + r1 = MASK_OP_ABS_S1D(ctx->opcode); + temp = tcg_const_i32(EA_ABS_FORMAT(address)); + + tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW); + tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16); + + tcg_temp_free(temp); + break; + case OPC1_32_ABS_LEA: + address = MASK_OP_ABS_OFF18(ctx->opcode); + r1 = MASK_OP_ABS_S1D(ctx->opcode); + tcg_gen_movi_tl(cpu_gpr_a[r1], EA_ABS_FORMAT(address)); + break; +/* ABSB-format */ + case OPC1_32_ABSB_ST_T: + address = MASK_OP_ABS_OFF18(ctx->opcode); + b = MASK_OP_ABSB_B(ctx->opcode); + bpos = MASK_OP_ABSB_BPOS(ctx->opcode); + + temp = tcg_const_i32(EA_ABS_FORMAT(address)); + temp2 = tcg_temp_new(); + + tcg_gen_qemu_ld_tl(temp2, temp, ctx->mem_idx, MO_UB); + tcg_gen_andi_tl(temp2, temp2, ~(0x1u << bpos)); + tcg_gen_ori_tl(temp2, temp2, (b << bpos)); + tcg_gen_qemu_st_tl(temp2, temp, ctx->mem_idx, MO_UB); + + tcg_temp_free(temp); + tcg_temp_free(temp2); + break; +/* B-format */ + case OPC1_32_B_CALL: + case OPC1_32_B_CALLA: + case OPC1_32_B_J: + case OPC1_32_B_JA: + case OPC1_32_B_JL: + case OPC1_32_B_JLA: + address = MASK_OP_B_DISP24(ctx->opcode); + gen_compute_branch(ctx, op1, 0, 0, 0, address); + break; +/* Bit-format */ + case OPCM_32_BIT_ANDACC: + decode_bit_andacc(env, ctx); + break; + case OPCM_32_BIT_LOGICAL_T1: + decode_bit_logical_t(env, ctx); + break; + case OPCM_32_BIT_INSERT: + decode_bit_insert(env, ctx); + break; + case OPCM_32_BIT_LOGICAL_T2: + decode_bit_logical_t2(env, ctx); + break; + case OPCM_32_BIT_ORAND: + decode_bit_orand(env, ctx); + break; + case OPCM_32_BIT_SH_LOGIC1: + decode_bit_sh_logic1(env, ctx); + break; + case OPCM_32_BIT_SH_LOGIC2: + decode_bit_sh_logic2(env, ctx); + break; + /* BO Format */ + case OPCM_32_BO_ADDRMODE_POST_PRE_BASE: + decode_bo_addrmode_post_pre_base(env, ctx); + break; + case OPCM_32_BO_ADDRMODE_BITREVERSE_CIRCULAR: + decode_bo_addrmode_bitreverse_circular(env, ctx); + break; + case OPCM_32_BO_ADDRMODE_LD_POST_PRE_BASE: + decode_bo_addrmode_ld_post_pre_base(env, ctx); + break; + case OPCM_32_BO_ADDRMODE_LD_BITREVERSE_CIRCULAR: + decode_bo_addrmode_ld_bitreverse_circular(env, ctx); + break; + case OPCM_32_BO_ADDRMODE_STCTX_POST_PRE_BASE: + decode_bo_addrmode_stctx_post_pre_base(env, ctx); + break; + case OPCM_32_BO_ADDRMODE_LDMST_BITREVERSE_CIRCULAR: + decode_bo_addrmode_ldmst_bitreverse_circular(env, ctx); + break; + } } static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch) |