summaryrefslogtreecommitdiffstats
path: root/target-tricore
diff options
context:
space:
mode:
authorBastian Koppelmann <kbastian@mail.uni-paderborn.de>2015-02-25 11:34:55 +0000
committerBastian Koppelmann <kbastian@mail.uni-paderborn.de>2015-03-16 15:44:48 +0000
commitf4aef476afc4cab9bb594975401f6902a57aa9b9 (patch)
treefac6d2783d25f5832682f9c8ffed57eee7f3fade /target-tricore
parent307146cb9359ad6d4544e00af073088772d165eb (diff)
downloadhqemu-f4aef476afc4cab9bb594975401f6902a57aa9b9.zip
hqemu-f4aef476afc4cab9bb594975401f6902a57aa9b9.tar.gz
target-tricore: Add instructions of RRR1 opcode format, which have 0xa3 as first opcode
Add helpers: * sub64_ssov: subs two 64 bit values and saturates the result. * subr_h/_ssov: subs two halfwords from two words in q-format with rounding / and saturates each result independetly. Add microcode generator: * gen_sub64_d: adds two 64 bit values. * gen_msub_h/s_h: multiply four halfwords, sub each result left justfied from two word values / and saturate each result. * gen_msubm_h/s_h: multiply four halfwords, sub each result left justfied from two words values in q-format / and saturate each result. * gen_msubr32/64_h/s_h: multiply four halfwords, sub each result left justfied from two halftwords/words values in q-format / and saturate each result. Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Diffstat (limited to 'target-tricore')
-rw-r--r--target-tricore/helper.h3
-rw-r--r--target-tricore/op_helper.c109
-rw-r--r--target-tricore/translate.c357
-rw-r--r--target-tricore/tricore-opcodes.h48
4 files changed, 493 insertions, 24 deletions
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 4c82346..0aa7438 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -24,9 +24,11 @@ DEF_HELPER_3(add_h_suov, i32, env, i32, i32)
DEF_HELPER_4(addr_h_ssov, i32, env, i64, i32, i32)
DEF_HELPER_4(addsur_h_ssov, i32, env, i64, i32, i32)
DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
+DEF_HELPER_3(sub64_ssov, i64, env, i64, i64)
DEF_HELPER_3(sub_suov, i32, env, i32, i32)
DEF_HELPER_3(sub_h_ssov, i32, env, i32, i32)
DEF_HELPER_3(sub_h_suov, i32, env, i32, i32)
+DEF_HELPER_4(subr_h_ssov, i32, env, i64, i32, i32)
DEF_HELPER_3(mul_ssov, i32, env, i32, i32)
DEF_HELPER_3(mul_suov, i32, env, i32, i32)
DEF_HELPER_3(sha_ssov, i32, env, i32, i32)
@@ -57,6 +59,7 @@ DEF_HELPER_3(add_b, i32, env, i32, i32)
DEF_HELPER_3(add_h, i32, env, i32, i32)
DEF_HELPER_3(sub_b, i32, env, i32, i32)
DEF_HELPER_3(sub_h, i32, env, i32, i32)
+DEF_HELPER_4(subr_h, i32, env, i64, i32, i32)
DEF_HELPER_FLAGS_2(eq_b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
DEF_HELPER_FLAGS_2(eq_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
DEF_HELPER_FLAGS_2(eqany_b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 40d32af..d6b01c3 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -340,6 +340,31 @@ target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
return ssov32(env, result);
}
+uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
+{
+ uint64_t result;
+ int64_t ovf;
+
+ result = r1 - r2;
+ ovf = (result ^ r1) & (r1 ^ r2);
+ env->PSW_USB_AV = (result ^ result * 2u) >> 32;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+ if (ovf < 0) {
+ env->PSW_USB_V = (1 << 31);
+ env->PSW_USB_SV = (1 << 31);
+ /* ext_ret > MAX_INT */
+ if ((int64_t)r1 >= 0) {
+ result = INT64_MAX;
+ /* ext_ret < MIN_INT */
+ } else {
+ result = INT64_MIN;
+ }
+ } else {
+ env->PSW_USB_V = 0;
+ }
+ return result;
+}
+
target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
target_ulong r2)
{
@@ -350,6 +375,52 @@ target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
return ssov16(env, ret_hw0, ret_hw1);
}
+uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
+ uint32_t r2_h)
+{
+ int64_t mul_res0 = sextract64(r1, 0, 32);
+ int64_t mul_res1 = sextract64(r1, 32, 32);
+ int64_t r2_low = sextract64(r2_l, 0, 32);
+ int64_t r2_high = sextract64(r2_h, 0, 32);
+ int64_t result0, result1;
+ uint32_t ovf0, ovf1;
+ uint32_t avf0, avf1;
+
+ ovf0 = ovf1 = 0;
+
+ result0 = r2_low - mul_res0 + 0x8000;
+ result1 = r2_high - mul_res1 + 0x8000;
+
+ avf0 = result0 * 2u;
+ avf0 = result0 ^ avf0;
+ avf1 = result1 * 2u;
+ avf1 = result1 ^ avf1;
+
+ if (result0 > INT32_MAX) {
+ ovf0 = (1 << 31);
+ result0 = INT32_MAX;
+ } else if (result0 < INT32_MIN) {
+ ovf0 = (1 << 31);
+ result0 = INT32_MIN;
+ }
+
+ if (result1 > INT32_MAX) {
+ ovf1 = (1 << 31);
+ result1 = INT32_MAX;
+ } else if (result1 < INT32_MIN) {
+ ovf1 = (1 << 31);
+ result1 = INT32_MIN;
+ }
+
+ env->PSW_USB_V = ovf0 | ovf1;
+ env->PSW_USB_SV |= env->PSW_USB_V;
+
+ env->PSW_USB_AV = avf0 | avf1;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+
+ return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
+}
+
target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
target_ulong r2)
{
@@ -1017,6 +1088,44 @@ uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
return ret;
}
+uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
+ uint32_t r2_h)
+{
+ int64_t mul_res0 = sextract64(r1, 0, 32);
+ int64_t mul_res1 = sextract64(r1, 32, 32);
+ int64_t r2_low = sextract64(r2_l, 0, 32);
+ int64_t r2_high = sextract64(r2_h, 0, 32);
+ int64_t result0, result1;
+ uint32_t ovf0, ovf1;
+ uint32_t avf0, avf1;
+
+ ovf0 = ovf1 = 0;
+
+ result0 = r2_low - mul_res0 + 0x8000;
+ result1 = r2_high - mul_res1 + 0x8000;
+
+ if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
+ ovf0 = (1 << 31);
+ }
+
+ if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
+ ovf1 = (1 << 31);
+ }
+
+ env->PSW_USB_V = ovf0 | ovf1;
+ env->PSW_USB_SV |= env->PSW_USB_V;
+
+ avf0 = result0 * 2u;
+ avf0 = result0 ^ avf0;
+ avf1 = result1 * 2u;
+ avf1 = result1 ^ avf1;
+
+ env->PSW_USB_AV = avf0 | avf1;
+ env->PSW_USB_SAV |= env->PSW_USB_AV;
+
+ return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
+}
+
uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
{
int32_t b, i;
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 27777be..65dc4ad 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -1575,6 +1575,37 @@ static inline void gen_sub_d(TCGv ret, TCGv r1, TCGv r2)
tcg_temp_free(result);
}
+static inline void
+gen_sub64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2)
+{
+ TCGv temp = tcg_temp_new();
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 result = tcg_temp_new_i64();
+
+ tcg_gen_sub_i64(result, r1, r2);
+ /* calc v bit */
+ tcg_gen_xor_i64(t1, result, r1);
+ tcg_gen_xor_i64(t0, r1, r2);
+ tcg_gen_and_i64(t1, t1, t0);
+ tcg_gen_trunc_shr_i64_i32(cpu_PSW_V, t1, 32);
+ /* calc SV bit */
+ tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+ /* calc AV/SAV bits */
+ tcg_gen_trunc_shr_i64_i32(temp, result, 32);
+ tcg_gen_add_tl(cpu_PSW_AV, temp, temp);
+ tcg_gen_xor_tl(cpu_PSW_AV, temp, cpu_PSW_AV);
+ /* calc SAV */
+ tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+ /* write back result */
+ tcg_gen_mov_i64(ret, result);
+
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(result);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
+}
+
static inline void gen_sub_CC(TCGv ret, TCGv r1, TCGv r2)
{
TCGv result = tcg_temp_new();
@@ -1648,6 +1679,217 @@ static inline void gen_cond_sub(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
tcg_temp_free(mask);
}
+static inline void
+gen_msub_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
+ TCGv r3, uint32_t n, uint32_t mode)
+{
+ TCGv temp = tcg_const_i32(n);
+ TCGv temp2 = tcg_temp_new();
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ switch (mode) {
+ case MODE_LL:
+ GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_LU:
+ GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UL:
+ GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UU:
+ GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
+ break;
+ }
+ tcg_gen_extr_i64_i32(temp, temp2, temp64);
+ gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
+ tcg_gen_sub_tl, tcg_gen_sub_tl);
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+ tcg_temp_free_i64(temp64);
+}
+
+static inline void
+gen_msubs_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
+ TCGv r3, uint32_t n, uint32_t mode)
+{
+ TCGv temp = tcg_const_i32(n);
+ TCGv temp2 = tcg_temp_new();
+ TCGv temp3 = tcg_temp_new();
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+
+ switch (mode) {
+ case MODE_LL:
+ GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_LU:
+ GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UL:
+ GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UU:
+ GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
+ break;
+ }
+ tcg_gen_extr_i64_i32(temp, temp2, temp64);
+ gen_subs(ret_low, r1_low, temp);
+ tcg_gen_mov_tl(temp, cpu_PSW_V);
+ tcg_gen_mov_tl(temp3, cpu_PSW_AV);
+ gen_subs(ret_high, r1_high, temp2);
+ /* combine v bits */
+ tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp);
+ /* combine av bits */
+ tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp3);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+ tcg_temp_free(temp3);
+ tcg_temp_free_i64(temp64);
+}
+
+static inline void
+gen_msubm_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
+ TCGv r3, uint32_t n, uint32_t mode)
+{
+ TCGv temp = tcg_const_i32(n);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ TCGv_i64 temp64_2 = tcg_temp_new_i64();
+ TCGv_i64 temp64_3 = tcg_temp_new_i64();
+ switch (mode) {
+ case MODE_LL:
+ GEN_HELPER_LL(mulm_h, temp64, r2, r3, temp);
+ break;
+ case MODE_LU:
+ GEN_HELPER_LU(mulm_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UL:
+ GEN_HELPER_UL(mulm_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UU:
+ GEN_HELPER_UU(mulm_h, temp64, r2, r3, temp);
+ break;
+ }
+ tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
+ gen_sub64_d(temp64_3, temp64_2, temp64);
+ /* write back result */
+ tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_3);
+
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+ tcg_temp_free_i64(temp64_2);
+ tcg_temp_free_i64(temp64_3);
+}
+
+static inline void
+gen_msubms_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
+ TCGv r3, uint32_t n, uint32_t mode)
+{
+ TCGv temp = tcg_const_i32(n);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ TCGv_i64 temp64_2 = tcg_temp_new_i64();
+ switch (mode) {
+ case MODE_LL:
+ GEN_HELPER_LL(mulm_h, temp64, r2, r3, temp);
+ break;
+ case MODE_LU:
+ GEN_HELPER_LU(mulm_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UL:
+ GEN_HELPER_UL(mulm_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UU:
+ GEN_HELPER_UU(mulm_h, temp64, r2, r3, temp);
+ break;
+ }
+ tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
+ gen_helper_sub64_ssov(temp64, cpu_env, temp64_2, temp64);
+ tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+ tcg_temp_free_i64(temp64_2);
+}
+
+static inline void
+gen_msubr64_h(TCGv ret, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3, uint32_t n,
+ uint32_t mode)
+{
+ TCGv temp = tcg_const_i32(n);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ switch (mode) {
+ case MODE_LL:
+ GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_LU:
+ GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UL:
+ GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UU:
+ GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
+ break;
+ }
+ gen_helper_subr_h(ret, cpu_env, temp64, r1_low, r1_high);
+
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+}
+
+static inline void
+gen_msubr32_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
+{
+ TCGv temp = tcg_temp_new();
+ TCGv temp2 = tcg_temp_new();
+
+ tcg_gen_andi_tl(temp2, r1, 0xffff0000);
+ tcg_gen_shli_tl(temp, r1, 16);
+ gen_msubr64_h(ret, temp, temp2, r2, r3, n, mode);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
+
+static inline void
+gen_msubr64s_h(TCGv ret, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3,
+ uint32_t n, uint32_t mode)
+{
+ TCGv temp = tcg_const_i32(n);
+ TCGv_i64 temp64 = tcg_temp_new_i64();
+ switch (mode) {
+ case MODE_LL:
+ GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_LU:
+ GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UL:
+ GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
+ break;
+ case MODE_UU:
+ GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
+ break;
+ }
+ gen_helper_subr_h_ssov(ret, cpu_env, temp64, r1_low, r1_high);
+
+ tcg_temp_free(temp);
+ tcg_temp_free_i64(temp64);
+}
+
+static inline void
+gen_msubr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
+{
+ TCGv temp = tcg_temp_new();
+ TCGv temp2 = tcg_temp_new();
+
+ tcg_gen_andi_tl(temp2, r1, 0xffff0000);
+ tcg_gen_shli_tl(temp, r1, 16);
+ gen_msubr64s_h(ret, temp, temp2, r2, r3, n, mode);
+
+ tcg_temp_free(temp);
+ tcg_temp_free(temp2);
+}
+
static inline void gen_abs(TCGv ret, TCGv r1)
{
TCGv temp = tcg_temp_new();
@@ -6468,6 +6710,118 @@ static void decode_rrr1_maddsu_h(CPUTriCoreState *env, DisasContext *ctx)
}
}
+static void decode_rrr1_msub(CPUTriCoreState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ uint32_t r1, r2, r3, r4, n;
+
+ op2 = MASK_OP_RRR1_OP2(ctx->opcode);
+ r1 = MASK_OP_RRR1_S1(ctx->opcode);
+ r2 = MASK_OP_RRR1_S2(ctx->opcode);
+ r3 = MASK_OP_RRR1_S3(ctx->opcode);
+ r4 = MASK_OP_RRR1_D(ctx->opcode);
+ n = MASK_OP_RRR1_N(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_32_RRR1_MSUB_H_LL:
+ gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
+ break;
+ case OPC2_32_RRR1_MSUB_H_LU:
+ gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
+ break;
+ case OPC2_32_RRR1_MSUB_H_UL:
+ gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
+ break;
+ case OPC2_32_RRR1_MSUB_H_UU:
+ gen_msub_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
+ break;
+ case OPC2_32_RRR1_MSUBS_H_LL:
+ gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
+ break;
+ case OPC2_32_RRR1_MSUBS_H_LU:
+ gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
+ break;
+ case OPC2_32_RRR1_MSUBS_H_UL:
+ gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
+ break;
+ case OPC2_32_RRR1_MSUBS_H_UU:
+ gen_msubs_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
+ break;
+ case OPC2_32_RRR1_MSUBM_H_LL:
+ gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
+ break;
+ case OPC2_32_RRR1_MSUBM_H_LU:
+ gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
+ break;
+ case OPC2_32_RRR1_MSUBM_H_UL:
+ gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
+ break;
+ case OPC2_32_RRR1_MSUBM_H_UU:
+ gen_msubm_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
+ break;
+ case OPC2_32_RRR1_MSUBMS_H_LL:
+ gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LL);
+ break;
+ case OPC2_32_RRR1_MSUBMS_H_LU:
+ gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_LU);
+ break;
+ case OPC2_32_RRR1_MSUBMS_H_UL:
+ gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UL);
+ break;
+ case OPC2_32_RRR1_MSUBMS_H_UU:
+ gen_msubms_h(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+ cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2], n, MODE_UU);
+ break;
+ case OPC2_32_RRR1_MSUBR_H_LL:
+ gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
+ cpu_gpr_d[r2], n, MODE_LL);
+ break;
+ case OPC2_32_RRR1_MSUBR_H_LU:
+ gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
+ cpu_gpr_d[r2], n, MODE_LU);
+ break;
+ case OPC2_32_RRR1_MSUBR_H_UL:
+ gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
+ cpu_gpr_d[r2], n, MODE_UL);
+ break;
+ case OPC2_32_RRR1_MSUBR_H_UU:
+ gen_msubr32_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
+ cpu_gpr_d[r2], n, MODE_UU);
+ break;
+ case OPC2_32_RRR1_MSUBRS_H_LL:
+ gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
+ cpu_gpr_d[r2], n, MODE_LL);
+ break;
+ case OPC2_32_RRR1_MSUBRS_H_LU:
+ gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
+ cpu_gpr_d[r2], n, MODE_LU);
+ break;
+ case OPC2_32_RRR1_MSUBRS_H_UL:
+ gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
+ cpu_gpr_d[r2], n, MODE_UL);
+ break;
+ case OPC2_32_RRR1_MSUBRS_H_UU:
+ gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
+ cpu_gpr_d[r2], n, MODE_UU);
+ break;
+ }
+}
+
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
{
int op1;
@@ -6774,6 +7128,9 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
case OPCM_32_RRR1_MADDSU_H:
decode_rrr1_maddsu_h(env, ctx);
break;
+ case OPCM_32_RRR1_MSUB_H:
+ decode_rrr1_msub(env, ctx);
+ break;
}
}
diff --git a/target-tricore/tricore-opcodes.h b/target-tricore/tricore-opcodes.h
index 41c9ef6..e65696d 100644
--- a/target-tricore/tricore-opcodes.h
+++ b/target-tricore/tricore-opcodes.h
@@ -1281,30 +1281,30 @@ enum {
};
/* OPCM_32_RRR1_MSUB_H */
enum {
- OPC2_32_RRR1_MSUB_H_32_LL = 0x1a,
- OPC2_32_RRR1_MSUB_H_32_LU = 0x19,
- OPC2_32_RRR1_MSUB_H_32_UL = 0x18,
- OPC2_32_RRR1_MSUB_H_32_UU = 0x1b,
- OPC2_32_RRR1_MSUBS_H_32_LL = 0x3a,
- OPC2_32_RRR1_MSUBS_H_32_LU = 0x39,
- OPC2_32_RRR1_MSUBS_H_32_UL = 0x38,
- OPC2_32_RRR1_MSUBS_H_32_UU = 0x3b,
- OPC2_32_RRR1_MSUBM_H_64_LL = 0x1e,
- OPC2_32_RRR1_MSUBM_H_64_LU = 0x1d,
- OPC2_32_RRR1_MSUBM_H_64_UL = 0x1c,
- OPC2_32_RRR1_MSUBM_H_64_UU = 0x1f,
- OPC2_32_RRR1_MSUBMS_H_64_LL = 0x3e,
- OPC2_32_RRR1_MSUBMS_H_64_LU = 0x3d,
- OPC2_32_RRR1_MSUBMS_H_64_UL = 0x3c,
- OPC2_32_RRR1_MSUBMS_H_64_UU = 0x3f,
- OPC2_32_RRR1_MSUBR_H_16_LL = 0x0e,
- OPC2_32_RRR1_MSUBR_H_16_LU = 0x0d,
- OPC2_32_RRR1_MSUBR_H_16_UL = 0x0c,
- OPC2_32_RRR1_MSUBR_H_16_UU = 0x0f,
- OPC2_32_RRR1_MSUBRS_H_16_LL = 0x2e,
- OPC2_32_RRR1_MSUBRS_H_16_LU = 0x2d,
- OPC2_32_RRR1_MSUBRS_H_16_UL = 0x2c,
- OPC2_32_RRR1_MSUBRS_H_16_UU = 0x2f,
+ OPC2_32_RRR1_MSUB_H_LL = 0x1a,
+ OPC2_32_RRR1_MSUB_H_LU = 0x19,
+ OPC2_32_RRR1_MSUB_H_UL = 0x18,
+ OPC2_32_RRR1_MSUB_H_UU = 0x1b,
+ OPC2_32_RRR1_MSUBS_H_LL = 0x3a,
+ OPC2_32_RRR1_MSUBS_H_LU = 0x39,
+ OPC2_32_RRR1_MSUBS_H_UL = 0x38,
+ OPC2_32_RRR1_MSUBS_H_UU = 0x3b,
+ OPC2_32_RRR1_MSUBM_H_LL = 0x1e,
+ OPC2_32_RRR1_MSUBM_H_LU = 0x1d,
+ OPC2_32_RRR1_MSUBM_H_UL = 0x1c,
+ OPC2_32_RRR1_MSUBM_H_UU = 0x1f,
+ OPC2_32_RRR1_MSUBMS_H_LL = 0x3e,
+ OPC2_32_RRR1_MSUBMS_H_LU = 0x3d,
+ OPC2_32_RRR1_MSUBMS_H_UL = 0x3c,
+ OPC2_32_RRR1_MSUBMS_H_UU = 0x3f,
+ OPC2_32_RRR1_MSUBR_H_LL = 0x0e,
+ OPC2_32_RRR1_MSUBR_H_LU = 0x0d,
+ OPC2_32_RRR1_MSUBR_H_UL = 0x0c,
+ OPC2_32_RRR1_MSUBR_H_UU = 0x0f,
+ OPC2_32_RRR1_MSUBRS_H_LL = 0x2e,
+ OPC2_32_RRR1_MSUBRS_H_LU = 0x2d,
+ OPC2_32_RRR1_MSUBRS_H_UL = 0x2c,
+ OPC2_32_RRR1_MSUBRS_H_UU = 0x2f,
};
/* OPCM_32_RRR1_MSUB_Q */
enum {
OpenPOWER on IntegriCloud