From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34012) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XOPHU-0003Q9-4M for qemu-devel@nongnu.org; Mon, 01 Sep 2014 06:56:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XOPHN-0008Ve-DV for qemu-devel@nongnu.org; Mon, 01 Sep 2014 06:56:16 -0400 Received: from mail.uni-paderborn.de ([131.234.142.9]:8295) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XOPHN-0008VW-3v for qemu-devel@nongnu.org; Mon, 01 Sep 2014 06:56:09 -0400 From: Bastian Koppelmann Date: Mon, 1 Sep 2014 12:59:52 +0100 Message-Id: <1409572800-4116-8-git-send-email-kbastian@mail.uni-paderborn.de> In-Reply-To: <1409572800-4116-1-git-send-email-kbastian@mail.uni-paderborn.de> References: <1409572800-4116-1-git-send-email-kbastian@mail.uni-paderborn.de> Subject: [Qemu-devel] [PATCH v7 07/15] target-tricore: Add instructions of SRR opcode format List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, rth@twiddle.net Add instructions of SRR opcode format. Add helper for add/sub_ssov. Signed-off-by: Bastian Koppelmann --- v6 -> v7: - CPUTRICOREState -> CPUTriCoreState. target-tricore/helper.h | 4 ++ target-tricore/op_helper.c | 43 ++++++++++++ target-tricore/translate.c | 164 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+) diff --git a/target-tricore/helper.h b/target-tricore/helper.h index 5884240..299bd77 100644 --- a/target-tricore/helper.h +++ b/target-tricore/helper.h @@ -14,3 +14,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ + +/* Arithmetic */ +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 c1342e9..664a100 100644 --- a/target-tricore/op_helper.c +++ b/target-tricore/op_helper.c @@ -20,6 +20,49 @@ #include "exec/helper-proto.h" #include "exec/cpu_ldst.h" +#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_USB_V = (1 << 31); \ + env->PSW_USB_SV = (1 << 31); \ + ret = (target_ulong)max_pos; \ + } else { \ + if (arg < max_neg) { \ + env->PSW_USB_V = (1 << 31); \ + env->PSW_USB_SV = (1 << 31); \ + ret = (target_ulong)max_neg; \ + } else { \ + env->PSW_USB_V = 0; \ + ret = (target_ulong)arg; \ + } \ + } \ + env->PSW_USB_AV = arg ^ arg * 2u; \ + env->PSW_USB_SAV |= env->PSW_USB_AV; \ +} while (0) + +target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1, + target_ulong r2) +{ + target_ulong ret; + int64_t t1 = sextract64(r1, 0, 32); + int64_t t2 = sextract64(r2, 0, 32); + int64_t result = t1 + t2; + 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 t1 = sextract64(r1, 0, 32); + int64_t t2 = sextract64(r2, 0, 32); + int64_t result = t1 - t2; + 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 607a066..717a42d 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -187,6 +187,53 @@ static inline void gen_condi_add(TCGCond cond, TCGv r1, int32_t r2, tcg_temp_free(temp); } +static inline void gen_sub_d(TCGv ret, TCGv r1, TCGv r2) +{ + TCGv temp = tcg_temp_new_i32(); + TCGv result = tcg_temp_new_i32(); + + tcg_gen_sub_tl(result, r1, r2); + /* calc V bit */ + tcg_gen_xor_tl(cpu_PSW_V, result, r1); + tcg_gen_xor_tl(temp, r1, r2); + tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp); + /* calc SV bit */ + tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V); + /* Calc AV bit */ + tcg_gen_add_tl(cpu_PSW_AV, result, result); + tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV); + /* calc SAV bit */ + tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV); + /* write back result */ + tcg_gen_mov_tl(ret, result); + + tcg_temp_free(temp); + tcg_temp_free(result); +} + +static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2) +{ + TCGv high = tcg_temp_new(); + TCGv low = tcg_temp_new(); + + tcg_gen_muls2_tl(low, high, r1, r2); + tcg_gen_mov_tl(ret, low); + /* calc V bit */ + tcg_gen_sari_tl(low, low, 31); + tcg_gen_setcond_tl(TCG_COND_NE, cpu_PSW_V, high, low); + tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31); + /* calc SV bit */ + tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V); + /* Calc AV bit */ + tcg_gen_add_tl(cpu_PSW_AV, ret, ret); + tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV); + /* calc SAV bit */ + tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV); + + tcg_temp_free(high); + tcg_temp_free(low); +} + static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count) { if (shift_count == -32) { @@ -257,6 +304,16 @@ static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count) tcg_temp_free(t_0); } +static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2) +{ + gen_helper_add_ssov(ret, cpu_env, r1, r2); +} + +static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2) +{ + gen_helper_sub_ssov(ret, cpu_env, r1, r2); +} + /* * Functions for decoding instructions */ @@ -331,6 +388,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: + gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_ADD_A15: + gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_ADD_15A: + gen_add_d(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_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_CMOVN: + 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_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[r1], cpu_gpr_a[r2]); + 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: + gen_mul_i32s(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: + gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_SUB_A15B: + gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]); + break; + case OPC1_16_SRR_SUB_15AB: + gen_sub_d(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; @@ -354,6 +494,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.1.0