* [Qemu-devel] [PATCH 1/5] target-tricore: Cleanup and Bugfixes
2014-09-27 14:58 [Qemu-devel] [PATCH 0/5] Add TriCore ABS, ABSB, B, BIT, BO instructions Bastian Koppelmann
@ 2014-09-27 14:58 ` Bastian Koppelmann
2014-09-28 6:18 ` Richard Henderson
2014-09-27 14:58 ` [Qemu-devel] [PATCH 2/5] target-tricore: Add instructions of ABS, ABSB opcode format Bastian Koppelmann
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Bastian Koppelmann @ 2014-09-27 14:58 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Move FCX loading of save_context_ to caller functions, for STLCX, STUCX insn to use those functions.
Move FCX storing of restore_context_ to caller functions, for LDLCX, LDUCX insn to use those functions.
Remove do_raise_exception function, which caused clang to emit a warning.
Fix: save_context_lower now saves a[11] instead of PSW.
Fix: MASK_OP_ABSB_BPOS starting at wrong offset.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target-tricore/op_helper.c | 47 ++++++++++++++++++----------------------
target-tricore/tricore-opcodes.h | 2 +-
2 files changed, 22 insertions(+), 27 deletions(-)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 6376f07..f2a5cbc 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -114,10 +114,8 @@ static bool cdc_zero(target_ulong *psw)
return count == 0;
}
-static void save_context_upper(CPUTriCoreState *env, int ea,
- target_ulong *new_FCX)
+static void save_context_upper(CPUTriCoreState *env, int ea)
{
- *new_FCX = cpu_ldl_data(env, ea);
cpu_stl_data(env, ea, env->PCXI);
cpu_stl_data(env, ea+4, env->PSW);
cpu_stl_data(env, ea+8, env->gpr_a[10]);
@@ -134,15 +132,12 @@ static void save_context_upper(CPUTriCoreState *env, int ea,
cpu_stl_data(env, ea+52, env->gpr_d[13]);
cpu_stl_data(env, ea+56, env->gpr_d[14]);
cpu_stl_data(env, ea+60, env->gpr_d[15]);
-
}
-static void save_context_lower(CPUTriCoreState *env, int ea,
- target_ulong *new_FCX)
+static void save_context_lower(CPUTriCoreState *env, int ea)
{
- *new_FCX = cpu_ldl_data(env, ea);
cpu_stl_data(env, ea, env->PCXI);
- cpu_stl_data(env, ea+4, env->PSW);
+ cpu_stl_data(env, ea+4, env->gpr_a[11]);
cpu_stl_data(env, ea+8, env->gpr_a[2]);
cpu_stl_data(env, ea+12, env->gpr_a[3]);
cpu_stl_data(env, ea+16, env->gpr_d[0]);
@@ -178,7 +173,6 @@ static void restore_context_upper(CPUTriCoreState *env, int ea,
env->gpr_d[13] = cpu_ldl_data(env, ea+52);
env->gpr_d[14] = cpu_ldl_data(env, ea+56);
env->gpr_d[15] = cpu_ldl_data(env, ea+60);
- cpu_stl_data(env, ea, env->FCX);
}
void helper_call(CPUTriCoreState *env, uint32_t next_pc)
@@ -206,11 +200,12 @@ void helper_call(CPUTriCoreState *env, uint32_t next_pc)
/* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
((env->FCX & MASK_FCX_FCXO) << 6);
- /* new_FCX = M(EA, word);
- M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
- A[12], A[13], A[14], A[15], D[12], D[13], D[14],
- D[15]}; */
- save_context_upper(env, ea, &new_FCX);
+ /* new_FCX = M(EA, word); */
+ new_FCX = cpu_ldl_data(env, ea);
+ /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
+ A[12], A[13], A[14], A[15], D[12], D[13], D[14],
+ D[15]}; */
+ save_context_upper(env, ea);
/* PCXI.PCPN = ICR.CCPN; */
env->PCXI = (env->PCXI & 0xffffff) +
@@ -263,9 +258,10 @@ void helper_ret(CPUTriCoreState *env)
ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
((env->PCXI & MASK_PCXI_PCXO) << 6);
/* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
- A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
- M(EA, word) = FCX; */
+ A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
restore_context_upper(env, ea, &new_PCXI, &new_PSW);
+ /* M(EA, word) = FCX; */
+ cpu_stl_data(env, ea, env->FCX);
/* FCX[19: 0] = PCXI[19: 0]; */
env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
/* PCXI = new_PCXI; */
@@ -293,7 +289,12 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9)
tmp_FCX = env->FCX;
ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
- save_context_lower(env, ea, &new_FCX);
+ /* new_FCX = M(EA, word); */
+ new_FCX = cpu_ldl_data(env, ea);
+ /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
+ , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
+ save_context_lower(env, ea);
+
/* PCXI.PCPN = ICR.CCPN */
env->PCXI = (env->PCXI & 0xffffff) +
@@ -343,9 +344,10 @@ void helper_rfe(CPUTriCoreState *env)
ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
((env->PCXI & MASK_PCXI_PCXO) << 6);
/*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
- A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
- M(EA, word) = FCX;*/
+ A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
restore_context_upper(env, ea, &new_PCXI, &new_PSW);
+ /* M(EA, word) = FCX;*/
+ cpu_stl_data(env, ea, env->FCX);
/* FCX[19: 0] = PCXI[19: 0]; */
env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
/* PCXI = new_PCXI; */
@@ -371,13 +373,6 @@ static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
cpu_loop_exit(cs);
}
-static inline void QEMU_NORETURN do_raise_exception(CPUTriCoreState *env,
- uint32_t exception,
- uintptr_t pc)
-{
- do_raise_exception_err(env, exception, 0, pc);
-}
-
void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr)
{
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 9c6ec01..342414f 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -89,7 +89,7 @@
#define MASK_OP_ABSB_OFF18(op) MASK_OP_ABS_OFF18(op)
#define MASK_OP_ABSB_OP2(op) MASK_BITS_SHIFT(op, 26, 27)
#define MASK_OP_ABSB_B(op) MASK_BITS_SHIFT(op, 11, 11)
-#define MASK_OP_ABSB_BPOS(op) MASK_BITS_SHIFT(op, 7, 10)
+#define MASK_OP_ABSB_BPOS(op) MASK_BITS_SHIFT(op, 8, 10)
/* B Format */
#define MASK_OP_B_DISP24(op) (MASK_BITS_SHIFT(op, 16, 31) + \
--
2.1.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 2/5] target-tricore: Add instructions of ABS, ABSB opcode format
2014-09-27 14:58 [Qemu-devel] [PATCH 0/5] Add TriCore ABS, ABSB, B, BIT, BO instructions Bastian Koppelmann
2014-09-27 14:58 ` [Qemu-devel] [PATCH 1/5] target-tricore: Cleanup and Bugfixes Bastian Koppelmann
@ 2014-09-27 14:58 ` Bastian Koppelmann
2014-09-28 1:30 ` Richard Henderson
2014-09-27 14:58 ` [Qemu-devel] [PATCH 3/5] target-tricore: Add instructions of B " Bastian Koppelmann
` (2 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Bastian Koppelmann @ 2014-09-27 14:58 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of ABS, ABSB opcode format.
Add microcode generator functions for ld/st of two 32bit reg as one 64bit value.
Add microcode generator functions for ldmst and swap.
Add helper ldlcx, lducx, stlcx and stucx.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target-tricore/helper.h | 4 +
target-tricore/op_helper.c | 45 +++++++
target-tricore/translate.c | 303 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 352 insertions(+)
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 7b7d74b..fbabbd5 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -23,3 +23,7 @@ DEF_HELPER_2(call, void, env, i32)
DEF_HELPER_1(ret, void, env)
DEF_HELPER_2(bisr, void, env, i32)
DEF_HELPER_1(rfe, void, env)
+DEF_HELPER_2(ldlcx, void, env, i32)
+DEF_HELPER_2(lducx, void, env, i32)
+DEF_HELPER_2(stlcx, void, env, i32)
+DEF_HELPER_2(stucx, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index f2a5cbc..7a33afd 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -175,6 +175,27 @@ static void restore_context_upper(CPUTriCoreState *env, int ea,
env->gpr_d[15] = cpu_ldl_data(env, ea+60);
}
+static void restore_context_lower(CPUTriCoreState *env, int ea,
+ target_ulong *ra, target_ulong *pcxi)
+{
+ *pcxi = cpu_ldl_data(env, ea);
+ *ra = cpu_ldl_data(env, ea+4);
+ env->gpr_a[2] = cpu_ldl_data(env, ea+8);
+ env->gpr_a[3] = cpu_ldl_data(env, ea+12);
+ env->gpr_d[0] = cpu_ldl_data(env, ea+16);
+ env->gpr_d[1] = cpu_ldl_data(env, ea+20);
+ env->gpr_d[2] = cpu_ldl_data(env, ea+24);
+ env->gpr_d[3] = cpu_ldl_data(env, ea+28);
+ env->gpr_a[4] = cpu_ldl_data(env, ea+32);
+ env->gpr_a[5] = cpu_ldl_data(env, ea+36);
+ env->gpr_a[6] = cpu_ldl_data(env, ea+40);
+ env->gpr_a[7] = cpu_ldl_data(env, ea+44);
+ env->gpr_d[4] = cpu_ldl_data(env, ea+48);
+ env->gpr_d[5] = cpu_ldl_data(env, ea+52);
+ env->gpr_d[6] = cpu_ldl_data(env, ea+56);
+ env->gpr_d[7] = cpu_ldl_data(env, ea+60);
+}
+
void helper_call(CPUTriCoreState *env, uint32_t next_pc)
{
target_ulong tmp_FCX;
@@ -356,6 +377,30 @@ void helper_rfe(CPUTriCoreState *env)
psw_write(env, new_PSW);
}
+void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
+{
+ uint32_t dummy;
+ /* insn doesn't load PCXI and RA */
+ restore_context_lower(env, ea, &dummy, &dummy);
+}
+
+void helper_lducx(CPUTriCoreState *env, uint32_t ea)
+{
+ uint32_t dummy;
+ /* insn doesn't load PCXI and PSW */
+ restore_context_upper(env, ea, &dummy, &dummy);
+}
+
+void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
+{
+ save_context_lower(env, ea);
+}
+
+void helper_stucx(CPUTriCoreState *env, uint32_t ea)
+{
+ save_context_upper(env, ea);
+}
+
static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
uint32_t exception,
int error_code,
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 4f654de..3ec5ca7 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -115,6 +115,8 @@ 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))
+
/* Functions for load/save to/from memory */
static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
@@ -135,6 +137,64 @@ 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_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_trunc_i64_i32(rl, temp);
+ tcg_gen_shri_i64(temp, temp, 32);
+ tcg_gen_trunc_i64_i32(rh, temp);
+
+ tcg_temp_free_i64(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)
@@ -1099,8 +1159,251 @@ 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);
+}
+
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
{
+ int op1;
+ int32_t r1;
+ int32_t address;
+ 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);
+ int8_t b = MASK_OP_ABSB_B(ctx->opcode);
+ int32_t 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;
+ }
}
static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch)
--
2.1.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 4/5] target-tricore: Add instructions of BIT opcode format
2014-09-27 14:58 [Qemu-devel] [PATCH 0/5] Add TriCore ABS, ABSB, B, BIT, BO instructions Bastian Koppelmann
` (2 preceding siblings ...)
2014-09-27 14:58 ` [Qemu-devel] [PATCH 3/5] target-tricore: Add instructions of B " Bastian Koppelmann
@ 2014-09-27 14:58 ` Bastian Koppelmann
2014-09-28 5:22 ` Richard Henderson
2014-09-27 14:58 ` [Qemu-devel] [PATCH 5/5] target-tricore: Add instructions of BO " Bastian Koppelmann
4 siblings, 1 reply; 13+ messages in thread
From: Bastian Koppelmann @ 2014-09-27 14:58 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of BIT opcode format.
Add microcode generator functions gen_bit_1/2op to do 1/2 bit operations on the last bit.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target-tricore/translate.c | 349 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 349 insertions(+)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 871c3cd..34375a9 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -427,6 +427,56 @@ static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
gen_helper_sub_ssov(ret, cpu_env, r1, r2);
}
+/* D[c] = D[c][0] op1 (D[a][pos1] op2 D[b][pos2]);*/
+static inline void gen_bit_2op(TCGv ret, TCGv r1, TCGv r2, TCGv r3,
+ int pos1, int pos2,
+ void(*op1)(TCGv, TCGv, TCGv),
+ void(*op2)(TCGv, TCGv, TCGv))
+{
+ TCGv temp1, temp2, temp3;
+
+ temp1 = tcg_temp_new();
+ temp2 = tcg_temp_new();
+ temp3 = tcg_temp_new();
+
+ tcg_gen_andi_tl(temp3, r3, 0x1);
+
+ tcg_gen_andi_tl(temp2, r2 , (0x1u << pos2));
+ tcg_gen_shri_tl(temp2, temp2, pos2);
+
+ tcg_gen_andi_tl(temp1, r1, (0x1u << pos1));
+ tcg_gen_shri_tl(temp1, temp1, pos1);
+
+ (*op1)(temp1, temp1, temp2);
+ (*op2)(ret , temp3, temp1);
+
+ tcg_temp_free(temp1);
+ tcg_temp_free(temp2);
+ tcg_temp_free(temp3);
+}
+
+/* result = D[a][pos1] op1 D[b][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_andi_tl(temp2, r2, (0x1u << pos2));
+ tcg_gen_shri_tl(temp2, temp2, pos2);
+
+ tcg_gen_andi_tl(temp1, r1, (0x1u << pos1));
+ tcg_gen_shri_tl(temp1, temp1, pos1);
+
+ (*op1)(ret, temp1, temp2);
+
+ tcg_temp_free(temp1);
+ tcg_temp_free(temp2);
+}
+
/* helpers for generating program flow micro-ops */
static inline void gen_save_pc(target_ulong pc)
@@ -1347,6 +1397,283 @@ static void decode_abs_storeb_h(CPUTriCoreState *env, DisasContext *ctx)
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;
+ TCGv temp;
+
+ 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);
+
+ temp = tcg_temp_new();
+
+ switch (op2) {
+ case OPC2_32_BIT_AND_AND_T:
+ gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+ pos1, pos2, &tcg_gen_and_tl, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_BIT_AND_ANDN_T:
+ gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+ pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl);
+ break;
+ case OPC2_32_BIT_AND_NOR_T:
+ gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+ pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl);
+ break;
+ case OPC2_32_BIT_AND_OR_T:
+ gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+ pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl);
+ break;
+ }
+ tcg_gen_andi_tl(temp, temp, 0x1);
+ tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 0xfffffffe);
+ tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
+ tcg_temp_free(temp);
+}
+
+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);
+ tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 0x1);
+ 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, temp2;
+ 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);
+
+ /* D[c] = {D[a][31:(pos1+1)], D[b][pos2], D[a][(pos1-1):0]}; */
+
+ temp = tcg_temp_new();
+ temp2 = tcg_temp_new();
+
+ /* temp2 = {D[a][31:(pos1+1)], 0} */
+ tcg_gen_andi_tl(temp2, cpu_gpr_d[r1],
+ ((1 << (31 - pos1)) - 1) << (pos1 + 1));
+ /* temp = D[b][pos2] */;
+ tcg_gen_andi_tl(temp, cpu_gpr_d[r2], (1 << pos2));
+
+ if (op2 == OPC2_32_BIT_INSN_T) {
+ tcg_gen_not_tl(temp, temp);
+ tcg_gen_andi_tl(temp, temp, 1 << pos2);
+ }
+ /* temp2 = {D[a][31:(pos1+1)], D[b][pos2], 0} */
+ tcg_gen_shri_tl(temp, temp, pos2);
+ tcg_gen_shli_tl(temp, temp, pos1);
+ tcg_gen_add_tl(temp2, temp2, temp);
+
+ tcg_gen_andi_tl(temp, cpu_gpr_d[r1], (1 << pos1) - 1);
+ tcg_gen_add_tl(cpu_gpr_d[r3], temp2, temp);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
+
+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);
+ tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 0x1);
+ 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);
+ tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 0x1);
+ 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_xor_tl);
+ tcg_gen_not_tl(cpu_gpr_d[r3], cpu_gpr_d[r3]);
+ tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 0x1);
+ 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;
+ 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_OR_AND_T:
+ gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+ pos1, pos2, &tcg_gen_and_tl, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_BIT_OR_ANDN_T:
+ gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+ pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_or_tl);
+ break;
+ case OPC2_32_BIT_OR_NOR_T:
+ gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+ pos1, pos2, &tcg_gen_or_tl, &tcg_gen_orc_tl);
+ break;
+ case OPC2_32_BIT_OR_OR_T:
+ gen_bit_2op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r3],
+ pos1, pos2, &tcg_gen_or_tl, &tcg_gen_or_tl);
+ break;
+ }
+ tcg_gen_andi_tl(temp, temp, 0x1);
+ tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 0xfffffffe);
+ tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
+ tcg_temp_free(temp);
+}
+
+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);
+ tcg_gen_andi_tl(temp, temp, 0x1);
+ 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);
+ tcg_gen_andi_tl(temp, temp, 0x1);
+ 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);
+ tcg_gen_andi_tl(temp, temp, 0x1);
+ break;
+ case OPC2_32_BIT_SH_XNOR_T:
+ gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
+ pos1, pos2, &tcg_gen_xor_tl);
+ tcg_gen_not_tl(temp, temp);
+ tcg_gen_andi_tl(temp, temp, 0x1);
+ 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);
+}
+
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
{
int op1;
@@ -1430,6 +1757,28 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
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;
}
}
--
2.1.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 5/5] target-tricore: Add instructions of BO opcode format
2014-09-27 14:58 [Qemu-devel] [PATCH 0/5] Add TriCore ABS, ABSB, B, BIT, BO instructions Bastian Koppelmann
` (3 preceding siblings ...)
2014-09-27 14:58 ` [Qemu-devel] [PATCH 4/5] target-tricore: Add instructions of BIT " Bastian Koppelmann
@ 2014-09-27 14:58 ` Bastian Koppelmann
2014-09-28 6:17 ` Richard Henderson
4 siblings, 1 reply; 13+ messages in thread
From: Bastian Koppelmann @ 2014-09-27 14:58 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, rth
Add instructions of BO opcode format.
Add microcode generator functions gen_swap, gen_ldmst.
Add helper for loading/storing byte, halfword, upper halfword word, dword in circular and bit reverse addr mode
Add sign extended bitmask for BO_OFF10 field.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target-tricore/helper.h | 42 +++
target-tricore/op_helper.c | 483 ++++++++++++++++++++++++++++++++
target-tricore/translate.c | 582 +++++++++++++++++++++++++++++++++++++++
target-tricore/tricore-opcodes.h | 2 +
4 files changed, 1109 insertions(+)
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index fbabbd5..ee8c9a7 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -27,3 +27,45 @@ DEF_HELPER_2(ldlcx, void, env, i32)
DEF_HELPER_2(lducx, void, env, i32)
DEF_HELPER_2(stlcx, void, env, i32)
DEF_HELPER_2(stucx, void, env, i32)
+/* ld circ */
+DEF_HELPER_4(ld_b_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_bu_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_h_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_hu_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_q_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ldmst_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_a_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_w_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_d_circ, void, env, i32, i32, int)
+DEF_HELPER_4(ld_da_circ, void, env, i32, i32, int)
+/* st circ */
+DEF_HELPER_4(st_a_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_b_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_d_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_da_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_h_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_q_circ, void, env, i32, i32, int)
+DEF_HELPER_4(st_w_circ, void, env, i32, i32, int)
+DEF_HELPER_4(swap_circ, void, env, i32, i32, int)
+DEF_HELPER_3(empty_circ, void, env, i32, int)
+/* ld br */
+DEF_HELPER_3(ld_b_br, void, env, i32, i32)
+DEF_HELPER_3(ld_bu_br, void, env, i32, i32)
+DEF_HELPER_3(ld_h_br, void, env, i32, i32)
+DEF_HELPER_3(ld_hu_br, void, env, i32, i32)
+DEF_HELPER_3(ld_q_br, void, env, i32, i32)
+DEF_HELPER_3(ldmst_br, void, env, i32, i32)
+DEF_HELPER_3(ld_a_br, void, env, i32, i32)
+DEF_HELPER_3(ld_w_br, void, env, i32, i32)
+DEF_HELPER_3(ld_d_br, void, env, i32, i32)
+DEF_HELPER_3(ld_da_br, void, env, i32, i32)
+/* st br */
+DEF_HELPER_3(st_a_br, void, env, i32, i32)
+DEF_HELPER_3(st_b_br, void, env, i32, i32)
+DEF_HELPER_3(st_d_br, void, env, i32, i32)
+DEF_HELPER_3(st_da_br, void, env, i32, i32)
+DEF_HELPER_3(st_h_br, void, env, i32, i32)
+DEF_HELPER_3(st_q_br, void, env, i32, i32)
+DEF_HELPER_3(st_w_br, void, env, i32, i32)
+DEF_HELPER_3(swap_br, void, env, i32, i32)
+DEF_HELPER_2(empty_br, void, env, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 7a33afd..c965a46 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,489 @@
#include "exec/helper-proto.h"
#include "exec/cpu_ldst.h"
+/* Addressing mode helper */
+
+#define CIRC_BR_DEFINES(reg) \
+ uint32_t index = env->gpr_a[reg+1] & 0xffff; \
+ uint32_t length_incr = (env->gpr_a[reg+1] & 0xffff0000) >> 16; \
+
+static uint16_t reverse16(uint16_t val)
+{
+ uint8_t high = (uint8_t)(val >> 8);
+ uint8_t low = (uint8_t)(val & 0xff);
+
+ uint16_t rh, rl;
+
+ rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+ rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
+
+ return (rh << 8) | rl;
+}
+
+#define BR_CALC_INDEX(reg, index, incr) do { \
+ int32_t new_index = reverse16(reverse16(index) + reverse16(incr)); \
+ env->gpr_a[reg+1] = (incr << 16) | new_index; \
+} while (0)
+
+#define CIRC_CALC_INDEX(reg, off, len) do { \
+ int32_t new_index = index + off; \
+ if (new_index < 0) { \
+ new_index = new_index + len; \
+ } else { \
+ new_index = new_index % len; \
+ } \
+ env->gpr_a[reg+1] = (len << 16) | new_index; \
+} while (0)
+
+void helper_ld_b_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_ldsb_data(env, ea);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ld_bu_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
+ int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_ldub_data(env, ea);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ld_h_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_ldsw_data(env, ea);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ld_hu_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
+ int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_lduw_data(env, ea);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ld_q_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_lduw_data(env, ea) << 16;
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ldmst_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
+ int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+ /* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]);
+ */
+ uint32_t data = (cpu_ldl_data(env, ea) & ~(env->gpr_d[r1+1])) |
+ (env->gpr_d[r1] & env->gpr_d[r1+1]);
+ cpu_stl_data(env, ea, data);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ld_a_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_a[r1] = cpu_ldl_data(env, ea);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ld_w_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+ uint32_t ea2 = env->gpr_a[r2] + (index + 2 % length_incr);
+
+ uint32_t hw_ea2 = cpu_lduw_data(env, ea2) << 16;
+ uint32_t lw_ea0 = cpu_lduw_data(env, ea0);
+
+ env->gpr_d[r1] = hw_ea2 | lw_ea0;
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ld_d_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+ uint32_t ea2 = env->gpr_a[r2] + (index + 2 % length_incr);
+ uint32_t ea4 = env->gpr_a[r2] + (index + 4 % length_incr);
+ uint32_t ea6 = env->gpr_a[r2] + (index + 6 % length_incr);
+
+
+ uint32_t hw_ea6 = cpu_lduw_data(env, ea6) << 16;
+ uint32_t lw_ea4 = cpu_lduw_data(env, ea4);
+ uint32_t hw_ea2 = cpu_lduw_data(env, ea2) << 16;
+ uint32_t lw_ea0 = cpu_lduw_data(env, ea0);
+
+ env->gpr_d[r1] = hw_ea6 | lw_ea4;
+ env->gpr_d[r1+1] = hw_ea2 | lw_ea0;
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_ld_da_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
+ int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+ uint32_t ea4 = env->gpr_a[r2] + (index + 4 % length_incr);
+
+ env->gpr_a[r1] = cpu_lduw_data(env, ea4);
+ env->gpr_a[r1+1] = cpu_lduw_data(env, ea0);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_st_a_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+ cpu_stb_data(env, ea0, env->gpr_a[r1]);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_st_b_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+ cpu_stb_data(env, ea0, env->gpr_d[r1]);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_st_d_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+ uint32_t ea2 = env->gpr_a[r2] + (index + 2 % length_incr);
+ uint32_t ea4 = env->gpr_a[r2] + (index + 4 % length_incr);
+ uint32_t ea6 = env->gpr_a[r2] + (index + 6 % length_incr);
+
+ cpu_stw_data(env, ea0, env->gpr_d[r1]);
+ cpu_stw_data(env, ea2, env->gpr_d[r1] >> 16);
+ cpu_stw_data(env, ea4, env->gpr_d[r1+1]);
+ cpu_stw_data(env, ea6, env->gpr_d[r1+1] >> 16);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_st_da_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
+ int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+ uint32_t ea4 = env->gpr_a[r2] + (index + 4 % length_incr);
+
+ cpu_stl_data(env, ea0, env->gpr_d[r1]);
+ cpu_stl_data(env, ea4, env->gpr_d[r1+1]);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_st_h_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+ cpu_stw_data(env, ea0, env->gpr_d[r1]);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_st_q_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+ cpu_stw_data(env, ea0, env->gpr_d[r1] >> 16);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_st_w_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+ uint32_t ea2 = env->gpr_a[r2] + (index + 2 % length_incr);
+
+ cpu_stw_data(env, ea0, env->gpr_d[r1]);
+ cpu_stw_data(env, ea2, env->gpr_d[r1] >> 16);
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+void helper_swap_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea0 = env->gpr_a[r2] + index;
+
+ uint32_t tmp = cpu_ldl_data(env, ea0);
+ cpu_stl_data(env, ea0, env->gpr_d[r1]);
+ env->gpr_d[r1] = tmp;
+
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+/* for cache reads/writes */
+void helper_empty_circ(CPUTriCoreState *env, uint32_t r2, int off10)
+{
+ CIRC_BR_DEFINES(r2)
+ CIRC_CALC_INDEX(r2, off10, length_incr);
+}
+
+/*
+ * Bit reverse helpers
+ */
+
+void helper_ld_b_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_ldsb_data(env, ea);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_ld_bu_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_ldub_data(env, ea);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_ld_h_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_ldsw_data(env, ea);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_ld_hu_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_lduw_data(env, ea);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_ld_q_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_lduw_data(env, ea) << 16;
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_ldmst_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+/* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
+ uint32_t data = (cpu_ldl_data(env, ea) & ~(env->gpr_d[r1+1])) |
+ (env->gpr_d[r1] & env->gpr_d[r1+1]);
+ cpu_stl_data(env, ea, data);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_ld_a_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_a[r1] = cpu_ldl_data(env, ea);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_ld_w_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ env->gpr_d[r1] = cpu_ldl_data(env, ea);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_ld_d_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+ uint64_t data = cpu_ldq_data(env, ea);
+
+ env->gpr_d[r1] = (uint32_t)data;
+ env->gpr_d[r1+1] = (uint32_t)(data >> 32);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_ld_da_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+ uint64_t data = cpu_ldq_data(env, ea);
+
+ env->gpr_a[r1] = (uint32_t)data;
+ env->gpr_a[r1+1] = (uint32_t)(data >> 32);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_st_a_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+ cpu_stl_data(env, ea, env->gpr_a[r1]);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_st_b_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+ cpu_stb_data(env, ea, env->gpr_a[r1]);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_st_d_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+ uint64_t data = ((uint64_t)(env->gpr_d[r1+1]) << 32) | (env->gpr_d[r1]);
+ cpu_stq_data(env, ea, data);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_st_da_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+ uint64_t data = ((uint64_t)(env->gpr_a[r1+1]) << 32) | (env->gpr_a[r1]);
+ cpu_stq_data(env, ea, data);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_st_h_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+ cpu_stw_data(env, ea, env->gpr_d[r1]);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_st_q_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+ cpu_stw_data(env, ea, env->gpr_d[r1] >> 16);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_st_w_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+
+ uint32_t ea = env->gpr_a[r2] + index;
+ cpu_stl_data(env, ea, env->gpr_d[r1]);
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+void helper_swap_br(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+ uint32_t ea = env->gpr_a[r2] + index;
+
+ uint32_t tmp = cpu_ldl_data(env, ea);
+ cpu_stl_data(env, ea, env->gpr_d[r1]);
+ env->gpr_d[r1] = tmp;
+
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
+/* for cache reads/writes */
+void helper_empty_br(CPUTriCoreState *env, uint32_t r2)
+{
+ CIRC_BR_DEFINES(r2)
+ BR_CALC_INDEX(r2, index, length_incr);
+}
+
#define SSOV(env, ret, arg, len) do { \
int64_t max_pos = INT##len ##_MAX; \
int64_t max_neg = INT##len ##_MIN; \
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 34375a9..2bb7309 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -149,6 +149,15 @@ static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
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();
@@ -162,6 +171,15 @@ static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
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);
+}
+
/* 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)
{
@@ -1674,6 +1692,551 @@ static void decode_bit_sh_logic2(CPUTriCoreState *env, DisasContext *ctx)
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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx,
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx);
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx);
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
+ 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);
+ gen_offset_st(ctx, temp, cpu_gpr_a[r2], off10, 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_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ 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_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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
+ 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_const_i32(r1);
+ temp2 = tcg_const_i32(r2);
+ temp3 = tcg_const_i32(off10);
+
+ 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_empty_br(cpu_env, temp2);
+ break;
+ case OPC2_32_BO_CACHEA_WI_CIRC:
+ case OPC2_32_BO_CACHEA_W_CIRC:
+ case OPC2_32_BO_CACHEA_I_CIRC:
+ gen_helper_empty_circ(cpu_env, temp2, temp3);
+ break;
+ case OPC2_32_BO_ST_A_BR:
+ gen_helper_st_a_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_ST_A_CIRC:
+ gen_helper_st_a_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_ST_B_BR:
+ gen_helper_st_b_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_ST_B_CIRC:
+ gen_helper_st_b_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_ST_D_BR:
+ gen_helper_st_d_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_ST_D_CIRC:
+ gen_helper_st_d_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_ST_DA_BR:
+ gen_helper_st_da_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_ST_DA_CIRC:
+ gen_helper_st_da_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_ST_H_BR:
+ gen_helper_st_h_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_ST_H_CIRC:
+ gen_helper_st_h_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_ST_Q_BR:
+ gen_helper_st_q_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_ST_Q_CIRC:
+ gen_helper_st_q_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_ST_W_BR:
+ gen_helper_st_w_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_ST_W_CIRC:
+ gen_helper_st_w_circ(cpu_env, temp, temp2, 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;
+
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx,
+ 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:
+ 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_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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx);
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx);
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ 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);
+ 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:
+ tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
+ tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
+ 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_const_i32(r1);
+ temp2 = tcg_const_i32(r2);
+ temp3 = tcg_const_i32(off10);
+
+ switch (op2) {
+ case OPC2_32_BO_LD_A_BR:
+ gen_helper_ld_a_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_LD_A_CIRC:
+ gen_helper_ld_a_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_LD_B_BR:
+ gen_helper_ld_b_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_LD_B_CIRC:
+ gen_helper_ld_b_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_LD_BU_BR:
+ gen_helper_ld_bu_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_LD_BU_CIRC:
+ gen_helper_ld_bu_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_LD_D_BR:
+ gen_helper_ld_d_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_LD_D_CIRC:
+ gen_helper_ld_d_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_LD_DA_BR:
+ gen_helper_ld_da_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_LD_DA_CIRC:
+ gen_helper_ld_da_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_LD_H_BR:
+ gen_helper_ld_h_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_LD_H_CIRC:
+ gen_helper_ld_h_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_LD_HU_BR:
+ gen_helper_ld_hu_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_LD_HU_CIRC:
+ gen_helper_ld_hu_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_LD_Q_BR:
+ gen_helper_ld_q_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_LD_Q_CIRC:
+ gen_helper_ld_q_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_LD_W_BR:
+ gen_helper_ld_w_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_LD_W_CIRC:
+ gen_helper_ld_w_circ(cpu_env, temp, temp2, 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_const_i32(r1);
+ temp2 = tcg_const_i32(r2);
+ temp3 = tcg_const_i32(off10);
+
+ switch (op2) {
+ case OPC2_32_BO_LDMST_BR:
+ gen_helper_ldmst_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_LDMST_CIRC:
+ gen_helper_ldmst_circ(cpu_env, temp, temp2, temp3);
+ break;
+ case OPC2_32_BO_SWAP_W_BR:
+ gen_helper_swap_br(cpu_env, temp, temp2);
+ break;
+ case OPC2_32_BO_SWAP_W_CIRC:
+ gen_helper_swap_circ(cpu_env, temp, temp2, 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;
@@ -1779,6 +2342,25 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
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;
}
}
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 342414f..7e6f33b 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -105,6 +105,8 @@
/* BO Format */
#define MASK_OP_BO_OFF10(op) (MASK_BITS_SHIFT(op, 16, 21) + \
(MASK_BITS_SHIFT(op, 28, 31) << 6))
+#define MASK_OP_BO_OFF10_SEXT(op) (MASK_BITS_SHIFT_SEXT(op, 16, 21) + \
+ (MASK_BITS_SHIFT_SEXT(op, 28, 31) << 6))
#define MASK_OP_BO_OP2(op) MASK_BITS_SHIFT(op, 22, 27)
#define MASK_OP_BO_S2(op) MASK_BITS_SHIFT(op, 12, 15)
#define MASK_OP_BO_S1D(op) MASK_BITS_SHIFT(op, 8, 11)
--
2.1.1
^ permalink raw reply related [flat|nested] 13+ messages in thread