Add instructions of SRR opcode format. Add helper for add/sub_ssov. Signed-off-by: Bastian Koppelmann <kbast...@mail.uni-paderborn.de> --- v1 -> v2: - Replace gen_ssov with helper for add_ssov and sub_ssov. - Move SRR instructions to one decode function.
target-tricore/helper.h | 2 + target-tricore/op_helper.c | 44 +++++++++++++++++ target-tricore/translate.c | 121 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) diff --git a/target-tricore/helper.h b/target-tricore/helper.h index 87c423c..3426419 100644 --- a/target-tricore/helper.h +++ b/target-tricore/helper.h @@ -17,3 +17,5 @@ /* Arithmetic */ DEF_HELPER_4(shac, i32, env, i32, i32, i32) +DEF_HELPER_3(add_ssov, i32, env, i32, i32) +DEF_HELPER_3(sub_ssov, i32, env, i32, i32) diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c index 1d1c9d8..4dfaf70 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -52,6 +52,50 @@ target_ulong helper_shac(CPUTRICOREState *env, target_ulong r1, return ret; } +#define SSOV(env, ret, arg, len) do { \ + int64_t max_pos = INT##len ##_MAX; \ + int64_t max_neg = INT##len ##_MIN; \ + if (arg > max_pos) { \ + env->PSW |= MASK_USB_V; \ + env->PSW |= MASK_USB_SV; \ + ret = (target_ulong)max_pos; \ + } else { \ + if (arg < max_neg) { \ + env->PSW |= MASK_USB_V; \ + env->PSW |= MASK_USB_SV; \ + ret = (target_ulong)max_neg; \ + } else { \ + env->PSW &= ~MASK_USB_V; \ + ret = (target_ulong)arg; \ + } \ + } \ + if ((arg & 0x80000000) | (arg & 0x40000000)) { \ + env->PSW |= MASK_USB_AV; \ + env->PSW |= MASK_USB_SAV; \ + } else { \ + env->PSW &= ~MASK_USB_AV; \ + } \ +} while (0) + +target_ulong helper_add_ssov(CPUTRICOREState *env, target_ulong r1, + target_ulong r2) +{ + target_ulong ret; + int64_t result = (int64_t)r1 + (int64_t)r2; + SSOV(env, ret, result, 32); + return ret; +} + +target_ulong helper_sub_ssov(CPUTRICOREState *env, target_ulong r1, + target_ulong r2) +{ + target_ulong ret; + int64_t result = (int64_t)r1 - (int64_t)r2; + SSOV(env, ret, result, 32); + return ret; +} + + 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 3d59709..20ff6d7 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -156,6 +156,20 @@ static void gen_shaci(TCGv ret, TCGv r1, int32_t con, int len) tcg_temp_free(temp); } +static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2) +{ + TCGv temp = tcg_const_i32(32); + gen_helper_add_ssov(ret, cpu_env, r1, r2); + tcg_temp_free(temp); +} + +static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2) +{ + TCGv temp = tcg_const_i32(32); + gen_helper_sub_ssov(ret, cpu_env, r1, r2); + tcg_temp_free(temp); +} + /* * Functions for decoding instructions */ @@ -233,6 +247,89 @@ static void decode_src_opc(DisasContext *ctx, int op1) } } +static void decode_srr_opc(DisasContext *ctx, int op1) +{ + int r1, r2; + TCGv temp; + + r1 = MASK_OP_SRR_S1D(ctx->opcode); + r2 = MASK_OP_SRR_S2(ctx->opcode); + + switch (op1) { + case OPC1_16_SRR_ADD: + tcg_gen_add_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_ADD_A15: + tcg_gen_add_tl(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_ADD_15A: + tcg_gen_add_tl(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_ADD_A: + tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], cpu_gpr_a[r2]); + break; + case OPC1_16_SRR_ADDS: + gen_adds(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_AND: + tcg_gen_and_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_CMOV: + temp = tcg_const_tl(0); + tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp, + cpu_gpr_d[r2], cpu_gpr_d[r1]); + tcg_temp_free(temp); + break; + case OPC1_16_SRR_CMOVN: + temp = tcg_const_tl(0); + tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp, + cpu_gpr_d[r2], cpu_gpr_d[r1]); + tcg_temp_free(temp); + break; + case OPC1_16_SRR_EQ: + tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1], + cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_LT: + tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1], + cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_MOV: + tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_MOV_A: + tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_MOV_AA: + tcg_gen_mov_tl(cpu_gpr_a[r2], cpu_gpr_a[r1]); + break; + case OPC1_16_SRR_MOV_D: + tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_a[r2]); + break; + case OPC1_16_SRR_MUL: + tcg_gen_mul_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_OR: + tcg_gen_or_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_SUB: + tcg_gen_sub_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_SUB_A15B: + tcg_gen_sub_tl(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_SUB_15AB: + tcg_gen_sub_tl(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_SUBS: + gen_subs(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_XOR: + tcg_gen_xor_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + } +} + static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) { int op1; @@ -257,6 +354,30 @@ static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx) case OPC1_16_SRC_SHA: decode_src_opc(ctx, op1); break; +/* SRR-format */ + case OPC1_16_SRR_ADD: + case OPC1_16_SRR_ADD_A15: + case OPC1_16_SRR_ADD_15A: + case OPC1_16_SRR_ADD_A: + case OPC1_16_SRR_ADDS: + case OPC1_16_SRR_AND: + case OPC1_16_SRR_CMOV: + case OPC1_16_SRR_CMOVN: + case OPC1_16_SRR_EQ: + case OPC1_16_SRR_LT: + case OPC1_16_SRR_MOV: + case OPC1_16_SRR_MOV_A: + case OPC1_16_SRR_MOV_AA: + case OPC1_16_SRR_MOV_D: + case OPC1_16_SRR_MUL: + case OPC1_16_SRR_OR: + case OPC1_16_SRR_SUB: + case OPC1_16_SRR_SUB_A15B: + case OPC1_16_SRR_SUB_15AB: + case OPC1_16_SRR_SUBS: + case OPC1_16_SRR_XOR: + decode_srr_opc(ctx, op1); + break; } } -- 2.0.1