Add instructions of BO opcode format.
Add microcode generator functions gen_swap, gen_ldmst.
Add microcode generator functions gen_st/ld_preincr, which write back the
address after the memory access.
Add helper for circular and bit reverse addr mode calculation.
Add sign extended bitmask for BO_OFF10 field.
Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de
---
v2 - v3:
- Add microcode generator functions gen_st/ld_preincr, which write back the
address after the memory access.
- ST/LD_PREINC insn now use gen_st/ld_preincr or write back the address
after
after the memory access.
target-tricore/helper.h | 3 +
target-tricore/op_helper.c | 36 +++
target-tricore/translate.c | 663 +++
target-tricore/tricore-opcodes.h | 2 +
4 files changed, 704 insertions(+)
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index fbabbd5..b3fc33c 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -27,3 +27,6 @@ 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)
+/* Address mode helper */
+DEF_HELPER_1(br_update, i32, i32)
+DEF_HELPER_2(circ_update, i32, i32, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 94b5d8e..a36988a 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,6 +20,42 @@
#include exec/helper-proto.h
#include exec/cpu_ldst.h
+/* Addressing mode helper */
+
+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;
+}
+
+uint32_t helper_br_update(uint32_t reg)
+{
+uint32_t index = reg 0x;
+uint32_t incr = reg 16;
+uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
+return reg - index + new_index;
+}
+
+uint32_t helper_circ_update(uint32_t reg, uint32_t off)
+{
+uint32_t index = reg 0x;
+uint32_t length = reg 16;
+int32_t new_index = index + off;
+if (new_index 0) {
+new_index += length;
+} else {
+new_index %= length;
+}
+return reg - index + new_index;
+}
+
#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 ddbabc4..d5a9596 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();
@@ -160,6 +169,35 @@ 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);
+}
+
+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)
{
@@ -1635,6 +1673,612 @@ 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);
+
+