]> Git Repo - qemu.git/blobdiff - target-tricore/translate.c
acpi: add aml_string() term
[qemu.git] / target-tricore / translate.c
index fdc9ade428fbe39ad51e292c0034569032949306..996435dbd0d04c3edd0fd9941d2196035a22225f 100644 (file)
@@ -85,22 +85,31 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
 {
     TriCoreCPU *cpu = TRICORE_CPU(cs);
     CPUTriCoreState *env = &cpu->env;
+    uint32_t psw;
     int i;
 
-    cpu_fprintf(f, "PC=%08x\n", env->PC);
+    psw = psw_read(env);
+
+    cpu_fprintf(f, "PC: " TARGET_FMT_lx, env->PC);
+    cpu_fprintf(f, " PSW: " TARGET_FMT_lx, psw);
+    cpu_fprintf(f, " ICR: " TARGET_FMT_lx, env->ICR);
+    cpu_fprintf(f, "\nPCXI: " TARGET_FMT_lx, env->PCXI);
+    cpu_fprintf(f, " FCX: " TARGET_FMT_lx, env->FCX);
+    cpu_fprintf(f, " LCX: " TARGET_FMT_lx, env->LCX);
+
     for (i = 0; i < 16; ++i) {
         if ((i & 3) == 0) {
-            cpu_fprintf(f, "GPR A%02d:", i);
+            cpu_fprintf(f, "\nGPR A%02d:", i);
         }
-        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames_a[i], env->gpr_a[i]);
+        cpu_fprintf(f, " " TARGET_FMT_lx, env->gpr_a[i]);
     }
     for (i = 0; i < 16; ++i) {
         if ((i & 3) == 0) {
-            cpu_fprintf(f, "GPR D%02d:", i);
+            cpu_fprintf(f, "\nGPR D%02d:", i);
         }
-        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames_d[i], env->gpr_d[i]);
+        cpu_fprintf(f, " " TARGET_FMT_lx, env->gpr_d[i]);
     }
-
+    cpu_fprintf(f, "\n");
 }
 
 /*
@@ -115,6 +124,76 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
     tcg_temp_free_i32(helper_tmp);                                \
     } while (0)
 
+#define GEN_HELPER_LL(name, ret, arg0, arg1, n) do {         \
+    TCGv arg00 = tcg_temp_new();                             \
+    TCGv arg01 = tcg_temp_new();                             \
+    TCGv arg11 = tcg_temp_new();                             \
+    tcg_gen_sari_tl(arg00, arg0, 16);                        \
+    tcg_gen_ext16s_tl(arg01, arg0);                          \
+    tcg_gen_ext16s_tl(arg11, arg1);                          \
+    gen_helper_##name(ret, arg00, arg01, arg11, arg11, n);   \
+    tcg_temp_free(arg00);                                    \
+    tcg_temp_free(arg01);                                    \
+    tcg_temp_free(arg11);                                    \
+} while (0)
+
+#define GEN_HELPER_LU(name, ret, arg0, arg1, n) do {         \
+    TCGv arg00 = tcg_temp_new();                             \
+    TCGv arg01 = tcg_temp_new();                             \
+    TCGv arg10 = tcg_temp_new();                             \
+    TCGv arg11 = tcg_temp_new();                             \
+    tcg_gen_sari_tl(arg00, arg0, 16);                        \
+    tcg_gen_ext16s_tl(arg01, arg0);                          \
+    tcg_gen_sari_tl(arg11, arg1, 16);                        \
+    tcg_gen_ext16s_tl(arg10, arg1);                          \
+    gen_helper_##name(ret, arg00, arg01, arg10, arg11, n);   \
+    tcg_temp_free(arg00);                                    \
+    tcg_temp_free(arg01);                                    \
+    tcg_temp_free(arg10);                                    \
+    tcg_temp_free(arg11);                                    \
+} while (0)
+
+#define GEN_HELPER_UL(name, ret, arg0, arg1, n) do {         \
+    TCGv arg00 = tcg_temp_new();                             \
+    TCGv arg01 = tcg_temp_new();                             \
+    TCGv arg10 = tcg_temp_new();                             \
+    TCGv arg11 = tcg_temp_new();                             \
+    tcg_gen_sari_tl(arg00, arg0, 16);                        \
+    tcg_gen_ext16s_tl(arg01, arg0);                          \
+    tcg_gen_sari_tl(arg10, arg1, 16);                        \
+    tcg_gen_ext16s_tl(arg11, arg1);                          \
+    gen_helper_##name(ret, arg00, arg01, arg10, arg11, n);   \
+    tcg_temp_free(arg00);                                    \
+    tcg_temp_free(arg01);                                    \
+    tcg_temp_free(arg10);                                    \
+    tcg_temp_free(arg11);                                    \
+} while (0)
+
+#define GEN_HELPER_UU(name, ret, arg0, arg1, n) do {         \
+    TCGv arg00 = tcg_temp_new();                             \
+    TCGv arg01 = tcg_temp_new();                             \
+    TCGv arg11 = tcg_temp_new();                             \
+    tcg_gen_sari_tl(arg01, arg0, 16);                        \
+    tcg_gen_ext16s_tl(arg00, arg0);                          \
+    tcg_gen_sari_tl(arg11, arg1, 16);                        \
+    gen_helper_##name(ret, arg00, arg01, arg11, arg11, n);   \
+    tcg_temp_free(arg00);                                    \
+    tcg_temp_free(arg01);                                    \
+    tcg_temp_free(arg11);                                    \
+} while (0)
+
+#define GEN_HELPER_RRR(name, rl, rh, al1, ah1, arg2) do {    \
+    TCGv_i64 ret = tcg_temp_new_i64();                       \
+    TCGv_i64 arg1 = tcg_temp_new_i64();                      \
+                                                             \
+    tcg_gen_concat_i32_i64(arg1, al1, ah1);                  \
+    gen_helper_##name(ret, arg1, arg2);                      \
+    tcg_gen_extr_i64_i32(rl, rh, ret);                       \
+                                                             \
+    tcg_temp_free_i64(ret);                                  \
+    tcg_temp_free_i64(arg1);                                 \
+} while (0)
+
 #define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
 #define EA_B_ABSOLUT(con) (((offset & 0xf00000) << 8) | \
                            ((offset & 0x0fffff) << 1))
@@ -276,7 +355,7 @@ static inline void gen_mfcr(CPUTriCoreState *env, TCGv ret, int32_t offset)
 static inline void gen_mtcr(CPUTriCoreState *env, DisasContext *ctx, TCGv r1,
                             int32_t offset)
 {
-    if (ctx->hflags & TRICORE_HFLAG_SM) {
+    if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) {
         /* since we're caching PSW make this a special case */
         if (offset == 0xfe04) {
             gen_helper_psw_write(cpu_env, r1);
@@ -316,6 +395,261 @@ static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
     tcg_temp_free(t0);
 }
 
+/* ret = r2 + (r1 * r3); */
+static inline void gen_madd32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+    TCGv_i64 t3 = tcg_temp_new_i64();
+
+    tcg_gen_ext_i32_i64(t1, r1);
+    tcg_gen_ext_i32_i64(t2, r2);
+    tcg_gen_ext_i32_i64(t3, r3);
+
+    tcg_gen_mul_i64(t1, t1, t3);
+    tcg_gen_add_i64(t1, t2, t1);
+
+    tcg_gen_trunc_i64_i32(ret, t1);
+    /* calc V
+       t1 > 0x7fffffff */
+    tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
+    /* t1 < -0x80000000 */
+    tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
+    tcg_gen_or_i64(t2, t2, t3);
+    tcg_gen_trunc_i64_i32(cpu_PSW_V, t2);
+    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/SAV bits */
+    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+    /* calc SAV */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t2);
+    tcg_temp_free_i64(t3);
+}
+
+static inline void gen_maddi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    gen_madd32_d(ret, r1, r2, temp);
+    tcg_temp_free(temp);
+}
+
+static inline void
+gen_madd64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+             TCGv r3)
+{
+    TCGv t1 = tcg_temp_new();
+    TCGv t2 = tcg_temp_new();
+    TCGv t3 = tcg_temp_new();
+    TCGv t4 = tcg_temp_new();
+
+    tcg_gen_muls2_tl(t1, t2, r1, r3);
+    /* only the add can overflow */
+    tcg_gen_add2_tl(t3, t4, r2_low, r2_high, t1, t2);
+    /* calc V bit */
+    tcg_gen_xor_tl(cpu_PSW_V, t4, r2_high);
+    tcg_gen_xor_tl(t1, r2_high, t2);
+    tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t1);
+    /* Calc SV bit */
+    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+    /* Calc AV/SAV bits */
+    tcg_gen_add_tl(cpu_PSW_AV, t4, t4);
+    tcg_gen_xor_tl(cpu_PSW_AV, t4, cpu_PSW_AV);
+    /* calc SAV */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+    /* write back the result */
+    tcg_gen_mov_tl(ret_low, t3);
+    tcg_gen_mov_tl(ret_high, t4);
+
+    tcg_temp_free(t1);
+    tcg_temp_free(t2);
+    tcg_temp_free(t3);
+    tcg_temp_free(t4);
+}
+
+static inline void
+gen_maddu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+              TCGv r3)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+    TCGv_i64 t3 = tcg_temp_new_i64();
+
+    tcg_gen_extu_i32_i64(t1, r1);
+    tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
+    tcg_gen_extu_i32_i64(t3, r3);
+
+    tcg_gen_mul_i64(t1, t1, t3);
+    tcg_gen_add_i64(t2, t2, t1);
+    /* write back result */
+    tcg_gen_extr_i64_i32(ret_low, ret_high, t2);
+    /* only the add overflows, if t2 < t1
+       calc V bit */
+    tcg_gen_setcond_i64(TCG_COND_LTU, t2, t2, t1);
+    tcg_gen_trunc_i64_i32(cpu_PSW_V, t2);
+    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/SAV bits */
+    tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
+    tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
+    /* calc SAV */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t2);
+    tcg_temp_free_i64(t3);
+}
+
+static inline void
+gen_maddi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+              int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    gen_madd64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+    tcg_temp_free(temp);
+}
+
+static inline void
+gen_maddui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+               int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    gen_maddu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+    tcg_temp_free(temp);
+}
+
+/* ret = r2 - (r1 * r3); */
+static inline void gen_msub32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+    TCGv_i64 t3 = tcg_temp_new_i64();
+
+    tcg_gen_ext_i32_i64(t1, r1);
+    tcg_gen_ext_i32_i64(t2, r2);
+    tcg_gen_ext_i32_i64(t3, r3);
+
+    tcg_gen_mul_i64(t1, t1, t3);
+    tcg_gen_sub_i64(t1, t2, t1);
+
+    tcg_gen_trunc_i64_i32(ret, t1);
+    /* calc V
+       t2 > 0x7fffffff */
+    tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
+    /* result < -0x80000000 */
+    tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
+    tcg_gen_or_i64(t2, t2, t3);
+    tcg_gen_trunc_i64_i32(cpu_PSW_V, t2);
+    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/SAV bits */
+    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+    /* calc SAV */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t2);
+    tcg_temp_free_i64(t3);
+}
+
+static inline void gen_msubi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    gen_msub32_d(ret, r1, r2, temp);
+    tcg_temp_free(temp);
+}
+
+static inline void
+gen_msub64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+             TCGv r3)
+{
+    TCGv t1 = tcg_temp_new();
+    TCGv t2 = tcg_temp_new();
+    TCGv t3 = tcg_temp_new();
+    TCGv t4 = tcg_temp_new();
+
+    tcg_gen_muls2_tl(t1, t2, r1, r3);
+    /* only the sub can overflow */
+    tcg_gen_sub2_tl(t3, t4, r2_low, r2_high, t1, t2);
+    /* calc V bit */
+    tcg_gen_xor_tl(cpu_PSW_V, t4, r2_high);
+    tcg_gen_xor_tl(t1, r2_high, t2);
+    tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, t1);
+    /* Calc SV bit */
+    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+    /* Calc AV/SAV bits */
+    tcg_gen_add_tl(cpu_PSW_AV, t4, t4);
+    tcg_gen_xor_tl(cpu_PSW_AV, t4, cpu_PSW_AV);
+    /* calc SAV */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+    /* write back the result */
+    tcg_gen_mov_tl(ret_low, t3);
+    tcg_gen_mov_tl(ret_high, t4);
+
+    tcg_temp_free(t1);
+    tcg_temp_free(t2);
+    tcg_temp_free(t3);
+    tcg_temp_free(t4);
+}
+
+static inline void
+gen_msubi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+              int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    gen_msub64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+    tcg_temp_free(temp);
+}
+
+static inline void
+gen_msubu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+              TCGv r3)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+    TCGv_i64 t3 = tcg_temp_new_i64();
+
+    tcg_gen_extu_i32_i64(t1, r1);
+    tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
+    tcg_gen_extu_i32_i64(t3, r3);
+
+    tcg_gen_mul_i64(t1, t1, t3);
+    tcg_gen_sub_i64(t3, t2, t1);
+    tcg_gen_extr_i64_i32(ret_low, ret_high, t3);
+    /* calc V bit, only the sub can overflow, if t1 > t2 */
+    tcg_gen_setcond_i64(TCG_COND_GTU, t1, t1, t2);
+    tcg_gen_trunc_i64_i32(cpu_PSW_V, t1);
+    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/SAV bits */
+    tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
+    tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
+    /* calc SAV */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t2);
+    tcg_temp_free_i64(t3);
+}
+
+static inline void
+gen_msubui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+               int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    gen_msubu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
+    tcg_temp_free(temp);
+}
+
 static inline void gen_addi_d(TCGv ret, TCGv r1, target_ulong r2)
 {
     TCGv temp = tcg_const_i32(r2);
@@ -423,7 +757,7 @@ static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
     tcg_gen_and_tl(temp, temp, mask);
     tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV);
     /* write back result */
-    tcg_gen_movcond_tl(cond, r3, r4, t0, result, r3);
+    tcg_gen_movcond_tl(cond, r3, r4, t0, result, r1);
 
     tcg_temp_free(t0);
     tcg_temp_free(temp);
@@ -464,6 +798,101 @@ static inline void gen_sub_d(TCGv ret, TCGv r1, TCGv r2)
     tcg_temp_free(result);
 }
 
+static inline void gen_sub_CC(TCGv ret, TCGv r1, TCGv r2)
+{
+    TCGv result = tcg_temp_new();
+    TCGv temp = tcg_temp_new();
+
+    tcg_gen_sub_tl(result, r1, r2);
+    /* calc C bit */
+    tcg_gen_setcond_tl(TCG_COND_GEU, cpu_PSW_C, 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(result);
+    tcg_temp_free(temp);
+}
+
+static inline void gen_subc_CC(TCGv ret, TCGv r1, TCGv r2)
+{
+    TCGv temp = tcg_temp_new();
+    tcg_gen_not_tl(temp, r2);
+    gen_addc_CC(ret, r1, temp);
+    tcg_temp_free(temp);
+}
+
+static inline void gen_cond_sub(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
+                                TCGv r4)
+{
+    TCGv temp = tcg_temp_new();
+    TCGv temp2 = tcg_temp_new();
+    TCGv result = tcg_temp_new();
+    TCGv mask = tcg_temp_new();
+    TCGv t0 = tcg_const_i32(0);
+
+    /* create mask for sticky bits */
+    tcg_gen_setcond_tl(cond, mask, r4, t0);
+    tcg_gen_shli_tl(mask, mask, 31);
+
+    tcg_gen_sub_tl(result, r1, r2);
+    /* Calc PSW_V */
+    tcg_gen_xor_tl(temp, result, r1);
+    tcg_gen_xor_tl(temp2, r1, r2);
+    tcg_gen_and_tl(temp, temp, temp2);
+    tcg_gen_movcond_tl(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
+    /* Set PSW_SV */
+    tcg_gen_and_tl(temp, temp, mask);
+    tcg_gen_or_tl(cpu_PSW_SV, temp, cpu_PSW_SV);
+    /* calc AV bit */
+    tcg_gen_add_tl(temp, result, result);
+    tcg_gen_xor_tl(temp, temp, result);
+    tcg_gen_movcond_tl(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
+    /* calc SAV bit */
+    tcg_gen_and_tl(temp, temp, mask);
+    tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV);
+    /* write back result */
+    tcg_gen_movcond_tl(cond, r3, r4, t0, result, r1);
+
+    tcg_temp_free(t0);
+    tcg_temp_free(temp);
+    tcg_temp_free(temp2);
+    tcg_temp_free(result);
+    tcg_temp_free(mask);
+}
+
+static inline void gen_abs(TCGv ret, TCGv r1)
+{
+    TCGv temp = tcg_temp_new();
+    TCGv t0 = tcg_const_i32(0);
+
+    tcg_gen_neg_tl(temp, r1);
+    tcg_gen_movcond_tl(TCG_COND_GE, ret, r1, t0, r1, temp);
+    /* overflow can only happen, if r1 = 0x80000000 */
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, r1, 0x80000000);
+    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(temp);
+    tcg_temp_free(t0);
+}
+
 static inline void gen_absdif(TCGv ret, TCGv r1, TCGv r2)
 {
     TCGv temp = tcg_temp_new_i32();
@@ -594,44 +1023,237 @@ static inline void gen_mulsui_i32(TCGv ret, TCGv r1, int32_t con)
     gen_helper_mul_suov(ret, cpu_env, r1, temp);
     tcg_temp_free(temp);
 }
+/* gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9); */
+static inline void gen_maddsi_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    gen_helper_madd32_ssov(ret, cpu_env, r1, r2, temp);
+    tcg_temp_free(temp);
+}
 
-static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
+static inline void gen_maddsui_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
 {
-    TCGv sat_neg = tcg_const_i32(low);
-    TCGv temp = tcg_const_i32(up);
+    TCGv temp = tcg_const_i32(con);
+    gen_helper_madd32_suov(ret, cpu_env, r1, r2, temp);
+    tcg_temp_free(temp);
+}
 
-    /* sat_neg = (arg < low ) ? low : arg; */
-    tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg);
+static void
+gen_mul_q(TCGv rl, TCGv rh, TCGv arg1, TCGv arg2, uint32_t n, uint32_t up_shift)
+{
+    TCGv temp = tcg_temp_new();
+    TCGv_i64 temp_64 = tcg_temp_new_i64();
+    TCGv_i64 temp2_64 = tcg_temp_new_i64();
+
+    if (n == 0) {
+        if (up_shift == 32) {
+            tcg_gen_muls2_tl(rh, rl, arg1, arg2);
+        } else if (up_shift == 16) {
+            tcg_gen_ext_i32_i64(temp_64, arg1);
+            tcg_gen_ext_i32_i64(temp2_64, arg2);
+
+            tcg_gen_mul_i64(temp_64, temp_64, temp2_64);
+            tcg_gen_shri_i64(temp_64, temp_64, up_shift);
+            tcg_gen_extr_i64_i32(rl, rh, temp_64);
+        } else {
+            tcg_gen_muls2_tl(rl, rh, arg1, arg2);
+        }
+        /* reset v bit */
+        tcg_gen_movi_tl(cpu_PSW_V, 0);
+    } else { /* n is exspected to be 1 */
+        tcg_gen_ext_i32_i64(temp_64, arg1);
+        tcg_gen_ext_i32_i64(temp2_64, arg2);
 
-    /* ret = (sat_neg > up ) ? up  : sat_neg; */
-    tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg);
+        tcg_gen_mul_i64(temp_64, temp_64, temp2_64);
 
-    tcg_temp_free(sat_neg);
+        if (up_shift == 0) {
+            tcg_gen_shli_i64(temp_64, temp_64, 1);
+        } else {
+            tcg_gen_shri_i64(temp_64, temp_64, up_shift - 1);
+        }
+        tcg_gen_extr_i64_i32(rl, rh, temp_64);
+        /* overflow only occours if r1 = r2 = 0x8000 */
+        if (up_shift == 0) {/* result is 64 bit */
+            tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, rh,
+                                0x80000000);
+        } else { /* result is 32 bit */
+            tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, rl,
+                                0x80000000);
+        }
+        tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+        /* calc sv overflow bit */
+        tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+    }
+    /* calc av overflow bit */
+    if (up_shift == 0) {
+        tcg_gen_add_tl(cpu_PSW_AV, rh, rh);
+        tcg_gen_xor_tl(cpu_PSW_AV, rh, cpu_PSW_AV);
+    } else {
+        tcg_gen_add_tl(cpu_PSW_AV, rl, rl);
+        tcg_gen_xor_tl(cpu_PSW_AV, rl, cpu_PSW_AV);
+    }
+    /* calc sav overflow bit */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
     tcg_temp_free(temp);
+    tcg_temp_free_i64(temp_64);
+    tcg_temp_free_i64(temp2_64);
 }
 
-static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up)
+static void
+gen_mul_q_16(TCGv ret, TCGv arg1, TCGv arg2, uint32_t n)
 {
-    TCGv temp = tcg_const_i32(up);
-    /* sat_neg = (arg > up ) ? up : arg; */
-    tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg);
+    TCGv temp = tcg_temp_new();
+    if (n == 0) {
+        tcg_gen_mul_tl(ret, arg1, arg2);
+    } else { /* n is exspected to be 1 */
+        tcg_gen_mul_tl(ret, arg1, arg2);
+        tcg_gen_shli_tl(ret, ret, 1);
+        /* catch special case r1 = r2 = 0x8000 */
+        tcg_gen_setcondi_tl(TCG_COND_EQ, temp, ret, 0x80000000);
+        tcg_gen_sub_tl(ret, ret, temp);
+    }
+    /* reset v bit */
+    tcg_gen_movi_tl(cpu_PSW_V, 0);
+    /* calc av overflow bit */
+    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+    /* calc sav overflow bit */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
     tcg_temp_free(temp);
 }
 
-static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
+static void gen_mulr_q(TCGv ret, TCGv arg1, TCGv arg2, uint32_t n)
 {
-    if (shift_count == -32) {
-        tcg_gen_movi_tl(ret, 0);
-    } else if (shift_count >= 0) {
-        tcg_gen_shli_tl(ret, r1, shift_count);
+    TCGv temp = tcg_temp_new();
+    if (n == 0) {
+        tcg_gen_mul_tl(ret, arg1, arg2);
+        tcg_gen_addi_tl(ret, ret, 0x8000);
     } else {
-        tcg_gen_shri_tl(ret, r1, -shift_count);
+        tcg_gen_mul_tl(ret, arg1, arg2);
+        tcg_gen_shli_tl(ret, ret, 1);
+        tcg_gen_addi_tl(ret, ret, 0x8000);
+        /* catch special case r1 = r2 = 0x8000 */
+        tcg_gen_setcondi_tl(TCG_COND_EQ, temp, ret, 0x80008000);
+        tcg_gen_muli_tl(temp, temp, 0x8001);
+        tcg_gen_sub_tl(ret, ret, temp);
     }
+    /* reset v bit */
+    tcg_gen_movi_tl(cpu_PSW_V, 0);
+    /* calc av overflow bit */
+    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+    /* calc sav overflow bit */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+    /* cut halfword off */
+    tcg_gen_andi_tl(ret, ret, 0xffff0000);
+
+    tcg_temp_free(temp);
 }
 
-static void gen_sh_hi(TCGv ret, TCGv r1, int32_t shiftcount)
+static inline void
+gen_maddsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+              int32_t con)
 {
-    TCGv temp_low, temp_high;
+    TCGv temp = tcg_const_i32(con);
+    TCGv_i64 temp64 = tcg_temp_new_i64();
+    tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+    gen_helper_madd64_ssov(temp64, cpu_env, r1, temp64, temp);
+    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+    tcg_temp_free(temp);
+    tcg_temp_free_i64(temp64);
+}
+
+static inline void
+gen_maddsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+               int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    TCGv_i64 temp64 = tcg_temp_new_i64();
+    tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+    gen_helper_madd64_suov(temp64, cpu_env, r1, temp64, temp);
+    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+    tcg_temp_free(temp);
+    tcg_temp_free_i64(temp64);
+}
+
+static inline void gen_msubsi_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    gen_helper_msub32_ssov(ret, cpu_env, r1, r2, temp);
+    tcg_temp_free(temp);
+}
+
+static inline void gen_msubsui_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    gen_helper_msub32_suov(ret, cpu_env, r1, r2, temp);
+    tcg_temp_free(temp);
+}
+
+static inline void
+gen_msubsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+              int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    TCGv_i64 temp64 = tcg_temp_new_i64();
+    tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+    gen_helper_msub64_ssov(temp64, cpu_env, r1, temp64, temp);
+    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+    tcg_temp_free(temp);
+    tcg_temp_free_i64(temp64);
+}
+
+static inline void
+gen_msubsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
+               int32_t con)
+{
+    TCGv temp = tcg_const_i32(con);
+    TCGv_i64 temp64 = tcg_temp_new_i64();
+    tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
+    gen_helper_msub64_suov(temp64, cpu_env, r1, temp64, temp);
+    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
+    tcg_temp_free(temp);
+    tcg_temp_free_i64(temp64);
+}
+
+static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
+{
+    TCGv sat_neg = tcg_const_i32(low);
+    TCGv temp = tcg_const_i32(up);
+
+    /* sat_neg = (arg < low ) ? low : arg; */
+    tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg);
+
+    /* ret = (sat_neg > up ) ? up  : sat_neg; */
+    tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg);
+
+    tcg_temp_free(sat_neg);
+    tcg_temp_free(temp);
+}
+
+static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up)
+{
+    TCGv temp = tcg_const_i32(up);
+    /* sat_neg = (arg > up ) ? up : arg; */
+    tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg);
+    tcg_temp_free(temp);
+}
+
+static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
+{
+    if (shift_count == -32) {
+        tcg_gen_movi_tl(ret, 0);
+    } else if (shift_count >= 0) {
+        tcg_gen_shli_tl(ret, r1, shift_count);
+    } else {
+        tcg_gen_shri_tl(ret, r1, -shift_count);
+    }
+}
+
+static void gen_sh_hi(TCGv ret, TCGv r1, int32_t shiftcount)
+{
+    TCGv temp_low, temp_high;
 
     if (shiftcount == -16) {
         tcg_gen_movi_tl(ret, 0);
@@ -873,6 +1495,13 @@ gen_accumulating_condi(int cond, TCGv ret, TCGv r1, int32_t con,
     tcg_temp_free(temp);
 }
 
+/* ret = (r1 cond r2) ? 0xFFFFFFFF ? 0x00000000;*/
+static inline void gen_cond_w(TCGCond cond, TCGv ret, TCGv r1, TCGv r2)
+{
+    tcg_gen_setcond_tl(cond, ret, r1, r2);
+    tcg_gen_neg_tl(ret, ret);
+}
+
 static inline void gen_eqany_bi(TCGv ret, TCGv r1, int32_t con)
 {
     TCGv b0 = tcg_temp_new();
@@ -949,6 +1578,86 @@ static inline void gen_insert(TCGv ret, TCGv r1, TCGv r2, TCGv width, TCGv pos)
     tcg_temp_free(temp2);
 }
 
+static inline void gen_bsplit(TCGv rl, TCGv rh, TCGv r1)
+{
+    TCGv_i64 temp = tcg_temp_new_i64();
+
+    gen_helper_bsplit(temp, r1);
+    tcg_gen_extr_i64_i32(rl, rh, temp);
+
+    tcg_temp_free_i64(temp);
+}
+
+static inline void gen_unpack(TCGv rl, TCGv rh, TCGv r1)
+{
+    TCGv_i64 temp = tcg_temp_new_i64();
+
+    gen_helper_unpack(temp, r1);
+    tcg_gen_extr_i64_i32(rl, rh, temp);
+
+    tcg_temp_free_i64(temp);
+}
+
+static inline void
+gen_dvinit_b(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
+{
+    TCGv_i64 ret = tcg_temp_new_i64();
+
+    if (!tricore_feature(env, TRICORE_FEATURE_131)) {
+        gen_helper_dvinit_b_13(ret, cpu_env, r1, r2);
+    } else {
+        gen_helper_dvinit_b_131(ret, cpu_env, r1, r2);
+    }
+    tcg_gen_extr_i64_i32(rl, rh, ret);
+
+    tcg_temp_free_i64(ret);
+}
+
+static inline void
+gen_dvinit_h(CPUTriCoreState *env, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
+{
+    TCGv_i64 ret = tcg_temp_new_i64();
+
+    if (!tricore_feature(env, TRICORE_FEATURE_131)) {
+        gen_helper_dvinit_h_13(ret, cpu_env, r1, r2);
+    } else {
+        gen_helper_dvinit_h_131(ret, cpu_env, r1, r2);
+    }
+    tcg_gen_extr_i64_i32(rl, rh, ret);
+
+    tcg_temp_free_i64(ret);
+}
+
+static void gen_calc_usb_mul_h(TCGv arg_low, TCGv arg_high)
+{
+    TCGv temp = tcg_temp_new();
+    /* calc AV bit */
+    tcg_gen_add_tl(temp, arg_low, arg_low);
+    tcg_gen_xor_tl(temp, temp, arg_low);
+    tcg_gen_add_tl(cpu_PSW_AV, arg_high, arg_high);
+    tcg_gen_xor_tl(cpu_PSW_AV, cpu_PSW_AV, arg_high);
+    tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp);
+    /* calc SAV bit */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+    tcg_gen_movi_tl(cpu_PSW_V, 0);
+    tcg_temp_free(temp);
+}
+
+static void gen_calc_usb_mulr_h(TCGv arg)
+{
+    TCGv temp = tcg_temp_new();
+    /* calc AV bit */
+    tcg_gen_add_tl(temp, arg, arg);
+    tcg_gen_xor_tl(temp, temp, arg);
+    tcg_gen_shli_tl(cpu_PSW_AV, temp, 16);
+    tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp);
+    /* calc SAV bit */
+    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+    /* clear V bit */
+    tcg_gen_movi_tl(cpu_PSW_V, 0);
+    tcg_temp_free(temp);
+}
+
 /* helpers for generating program flow micro-ops */
 
 static inline void gen_save_pc(target_ulong pc)
@@ -1102,6 +1811,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
         break;
     case OPC1_32_B_JLA:
         tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+        /* fall through */
     case OPC1_32_B_JA:
         gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
         break;
@@ -2868,7 +3578,7 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
         tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LEUL);
         tcg_temp_free(temp);
         break;
-    case OPC1_32_BOL_LD_W_LONFOFF:
+    case OPC1_32_BOL_LD_W_LONGOFF:
         temp = tcg_temp_new();
         tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);
         tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUL);
@@ -2887,8 +3597,49 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
     case OPC1_32_BOL_ST_W_LONGOFF:
         gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUL);
         break;
+    case OPC1_32_BOL_LD_B_LONGOFF:
+        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+            gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);
+        } else {
+            /* raise illegal opcode trap */
+        }
+        break;
+    case OPC1_32_BOL_LD_BU_LONGOFF:
+        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+            gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_UB);
+        } else {
+            /* raise illegal opcode trap */
+        }
+        break;
+    case OPC1_32_BOL_LD_H_LONGOFF:
+        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+            gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
+        } else {
+            /* raise illegal opcode trap */
+        }
+        break;
+    case OPC1_32_BOL_LD_HU_LONGOFF:
+        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+            gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUW);
+        } else {
+            /* raise illegal opcode trap */
+        }
+        break;
+    case OPC1_32_BOL_ST_B_LONGOFF:
+        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+            gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);
+        } else {
+            /* raise illegal opcode trap */
+        }
+        break;
+    case OPC1_32_BOL_ST_H_LONGOFF:
+        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+            gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
+        } else {
+            /* raise illegal opcode trap */
+        }
+        break;
     }
-
 }
 
 /* RC format */
@@ -3284,6 +4035,140 @@ static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx)
     tcg_temp_free(temp2);
 }
 
+/* RCR format */
+
+static void decode_rcr_cond_select(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r1, r3, r4;
+    int32_t const9;
+
+    TCGv temp, temp2;
+
+    op2 = MASK_OP_RCR_OP2(ctx->opcode);
+    r1 = MASK_OP_RCR_S1(ctx->opcode);
+    const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
+    r3 = MASK_OP_RCR_S3(ctx->opcode);
+    r4 = MASK_OP_RCR_D(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RCR_CADD:
+        gen_condi_add(TCG_COND_NE, cpu_gpr_d[r1], const9, cpu_gpr_d[r3],
+                      cpu_gpr_d[r4]);
+        break;
+    case OPC2_32_RCR_CADDN:
+        gen_condi_add(TCG_COND_EQ, cpu_gpr_d[r1], const9, cpu_gpr_d[r3],
+                      cpu_gpr_d[r4]);
+        break;
+    case OPC2_32_RCR_SEL:
+        temp = tcg_const_i32(0);
+        temp2 = tcg_const_i32(const9);
+        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
+                           cpu_gpr_d[r1], temp2);
+        tcg_temp_free(temp);
+        tcg_temp_free(temp2);
+        break;
+    case OPC2_32_RCR_SELN:
+        temp = tcg_const_i32(0);
+        temp2 = tcg_const_i32(const9);
+        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
+                           cpu_gpr_d[r1], temp2);
+        tcg_temp_free(temp);
+        tcg_temp_free(temp2);
+        break;
+    }
+}
+
+static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r1, r3, r4;
+    int32_t const9;
+
+
+    op2 = MASK_OP_RCR_OP2(ctx->opcode);
+    r1 = MASK_OP_RCR_S1(ctx->opcode);
+    const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
+    r3 = MASK_OP_RCR_S3(ctx->opcode);
+    r4 = MASK_OP_RCR_D(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RCR_MADD_32:
+        gen_maddi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+        break;
+    case OPC2_32_RCR_MADD_64:
+        gen_maddi64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+                      cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+        break;
+    case OPC2_32_RCR_MADDS_32:
+        gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+        break;
+    case OPC2_32_RCR_MADDS_64:
+        gen_maddsi_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+                      cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+        break;
+    case OPC2_32_RCR_MADD_U_64:
+        const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+        gen_maddui64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+                       cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+        break;
+    case OPC2_32_RCR_MADDS_U_32:
+        const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+        gen_maddsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+        break;
+    case OPC2_32_RCR_MADDS_U_64:
+        const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+        gen_maddsui_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+                       cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+        break;
+    }
+}
+
+static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r1, r3, r4;
+    int32_t const9;
+
+
+    op2 = MASK_OP_RCR_OP2(ctx->opcode);
+    r1 = MASK_OP_RCR_S1(ctx->opcode);
+    const9 = MASK_OP_RCR_CONST9_SEXT(ctx->opcode);
+    r3 = MASK_OP_RCR_S3(ctx->opcode);
+    r4 = MASK_OP_RCR_D(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RCR_MSUB_32:
+        gen_msubi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+        break;
+    case OPC2_32_RCR_MSUB_64:
+        gen_msubi64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+                      cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+        break;
+    case OPC2_32_RCR_MSUBS_32:
+        gen_msubsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+        break;
+    case OPC2_32_RCR_MSUBS_64:
+        gen_msubsi_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+                      cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+        break;
+    case OPC2_32_RCR_MSUB_U_64:
+        const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+        gen_msubui64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+                       cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+        break;
+    case OPC2_32_RCR_MSUBS_U_32:
+        const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+        gen_msubsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
+        break;
+    case OPC2_32_RCR_MSUBS_U_64:
+        const9 = MASK_OP_RCR_CONST9(ctx->opcode);
+        gen_msubsui_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
+                       cpu_gpr_d[r3], cpu_gpr_d[r3+1], const9);
+        break;
+    }
+}
+
 /* RLC format */
 
 static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
@@ -3307,11 +4192,23 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
         tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r1], const16 << 16);
         break;
     case OPC1_32_RLC_MFCR:
+        const16 = MASK_OP_RLC_CONST16(ctx->opcode);
         gen_mfcr(env, cpu_gpr_d[r2], const16);
         break;
     case OPC1_32_RLC_MOV:
         tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
         break;
+    case OPC1_32_RLC_MOV_64:
+        if (tricore_feature(env, TRICORE_FEATURE_16)) {
+            if ((r2 & 0x1) != 0) {
+                /* TODO: raise OPD trap */
+            }
+            tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
+            tcg_gen_movi_tl(cpu_gpr_d[r2+1], const16 >> 15);
+        } else {
+            /* TODO: raise illegal opcode trap */
+        }
+        break;
     case OPC1_32_RLC_MOV_U:
         const16 = MASK_OP_RLC_CONST16(ctx->opcode);
         tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
@@ -3323,61 +4220,1022 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
         tcg_gen_movi_tl(cpu_gpr_a[r2], const16 << 16);
         break;
     case OPC1_32_RLC_MTCR:
-        gen_mtcr(env, ctx, cpu_gpr_d[r2], const16);
+        const16 = MASK_OP_RLC_CONST16(ctx->opcode);
+        gen_mtcr(env, ctx, cpu_gpr_d[r1], const16);
         break;
     }
 }
 
-static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
+/* RR format */
+static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx)
 {
-    int op1;
-    int32_t r1, r2, r3;
-    int32_t address, const16;
-    int8_t b, const4;
-    int32_t bpos;
-    TCGv temp, temp2, temp3;
-
-    op1 = MASK_OP_MAJOR(ctx->opcode);
+    uint32_t op2;
+    int r3, r2, r1;
 
-    /* handle JNZ.T opcode only being 6 bit long */
-    if (unlikely((op1 & 0x3f) == OPCM_32_BRN_JTT)) {
-        op1 = OPCM_32_BRN_JTT;
-    }
+    r3 = MASK_OP_RR_D(ctx->opcode);
+    r2 = MASK_OP_RR_S2(ctx->opcode);
+    r1 = MASK_OP_RR_S1(ctx->opcode);
+    op2 = MASK_OP_RR_OP2(ctx->opcode);
 
-    switch (op1) {
-/* ABS-format */
-    case OPCM_32_ABS_LDW:
-        decode_abs_ldw(env, ctx);
+    switch (op2) {
+    case OPC2_32_RR_ABS:
+        gen_abs(cpu_gpr_d[r3], cpu_gpr_d[r2]);
         break;
-    case OPCM_32_ABS_LDB:
-        decode_abs_ldb(env, ctx);
+    case OPC2_32_RR_ABS_B:
+        gen_helper_abs_b(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r2]);
         break;
-    case OPCM_32_ABS_LDMST_SWAP:
-        decode_abs_ldst_swap(env, ctx);
+    case OPC2_32_RR_ABS_H:
+        gen_helper_abs_h(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r2]);
         break;
-    case OPCM_32_ABS_LDST_CONTEXT:
-        decode_abs_ldst_context(env, ctx);
+    case OPC2_32_RR_ABSDIF:
+        gen_absdif(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
         break;
-    case OPCM_32_ABS_STORE:
-        decode_abs_store(env, ctx);
+    case OPC2_32_RR_ABSDIF_B:
+        gen_helper_absdif_b(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                            cpu_gpr_d[r2]);
         break;
-    case OPCM_32_ABS_STOREB_H:
-        decode_abs_storeb_h(env, ctx);
+    case OPC2_32_RR_ABSDIF_H:
+        gen_helper_absdif_h(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                            cpu_gpr_d[r2]);
         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);
+    case OPC2_32_RR_ABSDIFS:
+        gen_helper_absdif_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                               cpu_gpr_d[r2]);
         break;
-    case OPC1_32_ABS_LD_Q:
-        address = MASK_OP_ABS_OFF18(ctx->opcode);
+    case OPC2_32_RR_ABSDIFS_H:
+        gen_helper_absdif_h_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                                 cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ABSS:
+        gen_helper_abs_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ABSS_H:
+        gen_helper_abs_h_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ADD:
+        gen_add_d(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ADD_B:
+        gen_helper_add_b(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ADD_H:
+        gen_helper_add_h(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ADDC:
+        gen_addc_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ADDS:
+        gen_adds(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ADDS_H:
+        gen_helper_add_h_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                              cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ADDS_HU:
+        gen_helper_add_h_suov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                              cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ADDS_U:
+        gen_helper_add_suov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                            cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ADDX:
+        gen_add_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_AND_EQ:
+        gen_accumulating_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_and_tl);
+        break;
+    case OPC2_32_RR_AND_GE:
+        gen_accumulating_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_and_tl);
+        break;
+    case OPC2_32_RR_AND_GE_U:
+        gen_accumulating_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_and_tl);
+        break;
+    case OPC2_32_RR_AND_LT:
+        gen_accumulating_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_and_tl);
+        break;
+    case OPC2_32_RR_AND_LT_U:
+        gen_accumulating_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_and_tl);
+        break;
+    case OPC2_32_RR_AND_NE:
+        gen_accumulating_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_and_tl);
+        break;
+    case OPC2_32_RR_EQ:
+        tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                           cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_EQ_B:
+        gen_helper_eq_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_EQ_H:
+        gen_helper_eq_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_EQ_W:
+        gen_cond_w(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_EQANY_B:
+        gen_helper_eqany_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_EQANY_H:
+        gen_helper_eqany_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_GE:
+        tcg_gen_setcond_tl(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                           cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_GE_U:
+        tcg_gen_setcond_tl(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                           cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_LT:
+        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                           cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_LT_U:
+        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                           cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_LT_B:
+        gen_helper_lt_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_LT_BU:
+        gen_helper_lt_bu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_LT_H:
+        gen_helper_lt_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_LT_HU:
+        gen_helper_lt_hu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_LT_W:
+        gen_cond_w(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_LT_WU:
+        gen_cond_w(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MAX:
+        tcg_gen_movcond_tl(TCG_COND_GT, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                           cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MAX_U:
+        tcg_gen_movcond_tl(TCG_COND_GTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                           cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MAX_B:
+        gen_helper_max_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MAX_BU:
+        gen_helper_max_bu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MAX_H:
+        gen_helper_max_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MAX_HU:
+        gen_helper_max_hu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MIN:
+        tcg_gen_movcond_tl(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                           cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MIN_U:
+        tcg_gen_movcond_tl(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                           cpu_gpr_d[r2], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MIN_B:
+        gen_helper_min_b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MIN_BU:
+        gen_helper_min_bu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MIN_H:
+        gen_helper_min_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MIN_HU:
+        gen_helper_min_hu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MOV:
+        tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_NE:
+        tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                           cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_OR_EQ:
+        gen_accumulating_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_or_tl);
+        break;
+    case OPC2_32_RR_OR_GE:
+        gen_accumulating_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_or_tl);
+        break;
+    case OPC2_32_RR_OR_GE_U:
+        gen_accumulating_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_or_tl);
+        break;
+    case OPC2_32_RR_OR_LT:
+        gen_accumulating_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_or_tl);
+        break;
+    case OPC2_32_RR_OR_LT_U:
+        gen_accumulating_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_or_tl);
+        break;
+    case OPC2_32_RR_OR_NE:
+        gen_accumulating_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_or_tl);
+        break;
+    case OPC2_32_RR_SAT_B:
+        gen_saturate(cpu_gpr_d[r3], cpu_gpr_d[r1], 0x7f, -0x80);
+        break;
+    case OPC2_32_RR_SAT_BU:
+        gen_saturate_u(cpu_gpr_d[r3], cpu_gpr_d[r1], 0xff);
+        break;
+    case OPC2_32_RR_SAT_H:
+        gen_saturate(cpu_gpr_d[r3], cpu_gpr_d[r1], 0x7fff, -0x8000);
+        break;
+    case OPC2_32_RR_SAT_HU:
+        gen_saturate_u(cpu_gpr_d[r3], cpu_gpr_d[r1], 0xffff);
+        break;
+    case OPC2_32_RR_SH_EQ:
+        gen_sh_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                    cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SH_GE:
+        gen_sh_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                    cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SH_GE_U:
+        gen_sh_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                    cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SH_LT:
+        gen_sh_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                    cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SH_LT_U:
+        gen_sh_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                    cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SH_NE:
+        gen_sh_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                    cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SUB:
+        gen_sub_d(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SUB_B:
+        gen_helper_sub_b(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SUB_H:
+        gen_helper_sub_h(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SUBC:
+        gen_subc_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SUBS:
+        gen_subs(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SUBS_U:
+        gen_subsu(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SUBS_H:
+        gen_helper_sub_h_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                              cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SUBS_HU:
+        gen_helper_sub_h_suov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                              cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SUBX:
+        gen_sub_CC(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_XOR_EQ:
+        gen_accumulating_cond(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_xor_tl);
+        break;
+    case OPC2_32_RR_XOR_GE:
+        gen_accumulating_cond(TCG_COND_GE, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_xor_tl);
+        break;
+    case OPC2_32_RR_XOR_GE_U:
+        gen_accumulating_cond(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_xor_tl);
+        break;
+    case OPC2_32_RR_XOR_LT:
+        gen_accumulating_cond(TCG_COND_LT, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_xor_tl);
+        break;
+    case OPC2_32_RR_XOR_LT_U:
+        gen_accumulating_cond(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_xor_tl);
+        break;
+    case OPC2_32_RR_XOR_NE:
+        gen_accumulating_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
+                              cpu_gpr_d[r2], &tcg_gen_xor_tl);
+        break;
+    }
+}
+
+static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r3, r2, r1;
+    TCGv temp;
+
+    r3 = MASK_OP_RR_D(ctx->opcode);
+    r2 = MASK_OP_RR_S2(ctx->opcode);
+    r1 = MASK_OP_RR_S1(ctx->opcode);
+
+    temp = tcg_temp_new();
+    op2 = MASK_OP_RR_OP2(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RR_AND:
+        tcg_gen_and_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ANDN:
+        tcg_gen_andc_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_CLO:
+        gen_helper_clo(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_CLO_H:
+        gen_helper_clo_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_CLS:
+        gen_helper_cls(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_CLS_H:
+        gen_helper_cls_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_CLZ:
+        gen_helper_clz(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_CLZ_H:
+        gen_helper_clz_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_NAND:
+        tcg_gen_nand_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_NOR:
+        tcg_gen_nor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_OR:
+        tcg_gen_or_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_ORN:
+        tcg_gen_orc_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SH:
+        gen_helper_sh(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SH_H:
+        gen_helper_sh_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SHA:
+        gen_helper_sha(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SHA_H:
+        gen_helper_sha_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_SHAS:
+        gen_shas(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_XNOR:
+        tcg_gen_eqv_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_XOR:
+        tcg_gen_xor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    }
+    tcg_temp_free(temp);
+}
+
+static void decode_rr_address(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2, n;
+    int r1, r2, r3;
+    TCGv temp;
+
+    op2 = MASK_OP_RR_OP2(ctx->opcode);
+    r3 = MASK_OP_RR_D(ctx->opcode);
+    r2 = MASK_OP_RR_S2(ctx->opcode);
+    r1 = MASK_OP_RR_S1(ctx->opcode);
+    n = MASK_OP_RR_N(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RR_ADD_A:
+        tcg_gen_add_tl(cpu_gpr_a[r3], cpu_gpr_a[r1], cpu_gpr_a[r2]);
+        break;
+    case OPC2_32_RR_ADDSC_A:
+        temp = tcg_temp_new();
+        tcg_gen_shli_tl(temp, cpu_gpr_d[r1], n);
+        tcg_gen_add_tl(cpu_gpr_a[r3], cpu_gpr_a[r2], temp);
+        tcg_temp_free(temp);
+        break;
+    case OPC2_32_RR_ADDSC_AT:
+        temp = tcg_temp_new();
+        tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 3);
+        tcg_gen_add_tl(temp, cpu_gpr_a[r2], temp);
+        tcg_gen_andi_tl(cpu_gpr_a[r3], temp, 0xFFFFFFFC);
+        tcg_temp_free(temp);
+        break;
+    case OPC2_32_RR_EQ_A:
+        tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_a[r1],
+                           cpu_gpr_a[r2]);
+        break;
+    case OPC2_32_RR_EQZ:
+        tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[r3], cpu_gpr_a[r1], 0);
+        break;
+    case OPC2_32_RR_GE_A:
+        tcg_gen_setcond_tl(TCG_COND_GEU, cpu_gpr_d[r3], cpu_gpr_a[r1],
+                           cpu_gpr_a[r2]);
+        break;
+    case OPC2_32_RR_LT_A:
+        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr_d[r3], cpu_gpr_a[r1],
+                           cpu_gpr_a[r2]);
+        break;
+    case OPC2_32_RR_MOV_A:
+        tcg_gen_mov_tl(cpu_gpr_a[r3], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_MOV_AA:
+        tcg_gen_mov_tl(cpu_gpr_a[r3], cpu_gpr_a[r2]);
+        break;
+    case OPC2_32_RR_MOV_D:
+        tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_a[r2]);
+        break;
+    case OPC2_32_RR_NE_A:
+        tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_a[r1],
+                           cpu_gpr_a[r2]);
+        break;
+    case OPC2_32_RR_NEZ_A:
+        tcg_gen_setcondi_tl(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_a[r1], 0);
+        break;
+    case OPC2_32_RR_SUB_A:
+        tcg_gen_sub_tl(cpu_gpr_a[r3], cpu_gpr_a[r1], cpu_gpr_a[r2]);
+        break;
+    }
+}
+
+static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r1;
+
+    op2 = MASK_OP_RR_OP2(ctx->opcode);
+    r1 = MASK_OP_RR_S1(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RR_JI:
+        tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
+        break;
+    case OPC2_32_RR_JLI:
+        tcg_gen_movi_tl(cpu_gpr_a[11], ctx->next_pc);
+        tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
+        break;
+    case OPC2_32_RR_CALLI:
+        gen_helper_1arg(call, ctx->next_pc);
+        tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
+        break;
+    }
+    tcg_gen_exit_tb(0);
+    ctx->bstate = BS_BRANCH;
+}
+
+static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r1, r2, r3;
+
+    TCGv temp, temp2;
+
+    op2 = MASK_OP_RR_OP2(ctx->opcode);
+    r3 = MASK_OP_RR_D(ctx->opcode);
+    r2 = MASK_OP_RR_S2(ctx->opcode);
+    r1 = MASK_OP_RR_S1(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RR_BMERGE:
+        gen_helper_bmerge(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_BSPLIT:
+        gen_bsplit(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_DVINIT_B:
+        gen_dvinit_b(env, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
+                     cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_DVINIT_BU:
+        temp = tcg_temp_new();
+        temp2 = tcg_temp_new();
+        /* reset av */
+        tcg_gen_movi_tl(cpu_PSW_AV, 0);
+        if (!tricore_feature(env, TRICORE_FEATURE_131)) {
+            /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
+            tcg_gen_neg_tl(temp, cpu_gpr_d[r3+1]);
+            /* use cpu_PSW_AV to compare against 0 */
+            tcg_gen_movcond_tl(TCG_COND_LT, temp, cpu_gpr_d[r3+1], cpu_PSW_AV,
+                               temp, cpu_gpr_d[r3+1]);
+            tcg_gen_neg_tl(temp2, cpu_gpr_d[r2]);
+            tcg_gen_movcond_tl(TCG_COND_LT, temp2, cpu_gpr_d[r2], cpu_PSW_AV,
+                               temp2, cpu_gpr_d[r2]);
+            tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
+        } else {
+            /* overflow = (D[b] == 0) */
+            tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0);
+        }
+        tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+        /* sv */
+        tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+        /* write result */
+        tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 8);
+        tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], 24);
+        tcg_gen_mov_tl(cpu_gpr_d[r3+1], temp);
+
+        tcg_temp_free(temp);
+        tcg_temp_free(temp2);
+        break;
+    case OPC2_32_RR_DVINIT_H:
+        gen_dvinit_h(env, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
+                     cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR_DVINIT_HU:
+        temp = tcg_temp_new();
+        temp2 = tcg_temp_new();
+        /* reset av */
+        tcg_gen_movi_tl(cpu_PSW_AV, 0);
+        if (!tricore_feature(env, TRICORE_FEATURE_131)) {
+            /* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
+            tcg_gen_neg_tl(temp, cpu_gpr_d[r3+1]);
+            /* use cpu_PSW_AV to compare against 0 */
+            tcg_gen_movcond_tl(TCG_COND_LT, temp, cpu_gpr_d[r3+1], cpu_PSW_AV,
+                               temp, cpu_gpr_d[r3+1]);
+            tcg_gen_neg_tl(temp2, cpu_gpr_d[r2]);
+            tcg_gen_movcond_tl(TCG_COND_LT, temp2, cpu_gpr_d[r2], cpu_PSW_AV,
+                               temp2, cpu_gpr_d[r2]);
+            tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
+        } else {
+            /* overflow = (D[b] == 0) */
+            tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0);
+        }
+        tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+        /* sv */
+        tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+        /* write result */
+        tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
+        tcg_gen_shri_tl(cpu_gpr_d[r3+1], temp, 16);
+        tcg_gen_shli_tl(cpu_gpr_d[r3], temp, 16);
+        tcg_temp_free(temp);
+        tcg_temp_free(temp2);
+        break;
+    case OPC2_32_RR_DVINIT:
+        temp = tcg_temp_new();
+        temp2 = tcg_temp_new();
+        /* overflow = ((D[b] == 0) ||
+                      ((D[b] == 0xFFFFFFFF) && (D[a] == 0x80000000))) */
+        tcg_gen_setcondi_tl(TCG_COND_EQ, temp, cpu_gpr_d[r2], 0xffffffff);
+        tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, cpu_gpr_d[r1], 0x80000000);
+        tcg_gen_and_tl(temp, temp, temp2);
+        tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, cpu_gpr_d[r2], 0);
+        tcg_gen_or_tl(cpu_PSW_V, temp, temp2);
+        tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+        /* sv */
+        tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+        /* reset av */
+       tcg_gen_movi_tl(cpu_PSW_AV, 0);
+        /* write result */
+        tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        /* sign extend to high reg */
+        tcg_gen_sari_tl(cpu_gpr_d[r3+1], cpu_gpr_d[r1], 31);
+        tcg_temp_free(temp);
+        tcg_temp_free(temp2);
+        break;
+    case OPC2_32_RR_DVINIT_U:
+        /* overflow = (D[b] == 0) */
+        tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0);
+        tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+        /* sv */
+        tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+        /* reset av */
+        tcg_gen_movi_tl(cpu_PSW_AV, 0);
+        /* write result */
+        tcg_gen_mov_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        /* zero extend to high reg*/
+        tcg_gen_movi_tl(cpu_gpr_d[r3+1], 0);
+        break;
+    case OPC2_32_RR_PARITY:
+        gen_helper_parity(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+        break;
+    case OPC2_32_RR_UNPACK:
+        gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
+        break;
+    }
+}
+
+/* RR1 Format */
+static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+
+    int r1, r2, r3;
+    TCGv n;
+    TCGv_i64 temp64;
+
+    r1 = MASK_OP_RR1_S1(ctx->opcode);
+    r2 = MASK_OP_RR1_S2(ctx->opcode);
+    r3 = MASK_OP_RR1_D(ctx->opcode);
+    n  = tcg_const_i32(MASK_OP_RR1_N(ctx->opcode));
+    op2 = MASK_OP_RR1_OP2(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RR1_MUL_H_32_LL:
+        temp64 = tcg_temp_new_i64();
+        GEN_HELPER_LL(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MUL_H_32_LU:
+        temp64 = tcg_temp_new_i64();
+        GEN_HELPER_LU(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MUL_H_32_UL:
+        temp64 = tcg_temp_new_i64();
+        GEN_HELPER_UL(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MUL_H_32_UU:
+        temp64 = tcg_temp_new_i64();
+        GEN_HELPER_UU(mul_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        gen_calc_usb_mul_h(cpu_gpr_d[r3], cpu_gpr_d[r3+1]);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MULM_H_64_LL:
+        temp64 = tcg_temp_new_i64();
+        GEN_HELPER_LL(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        /* reset V bit */
+        tcg_gen_movi_tl(cpu_PSW_V, 0);
+        /* reset AV bit */
+        tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MULM_H_64_LU:
+        temp64 = tcg_temp_new_i64();
+        GEN_HELPER_LU(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        /* reset V bit */
+        tcg_gen_movi_tl(cpu_PSW_V, 0);
+        /* reset AV bit */
+        tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MULM_H_64_UL:
+        temp64 = tcg_temp_new_i64();
+        GEN_HELPER_UL(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        /* reset V bit */
+        tcg_gen_movi_tl(cpu_PSW_V, 0);
+        /* reset AV bit */
+        tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
+        tcg_temp_free_i64(temp64);
+        break;
+    case OPC2_32_RR1_MULM_H_64_UU:
+        temp64 = tcg_temp_new_i64();
+        GEN_HELPER_UU(mulm_h, temp64, cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        tcg_gen_extr_i64_i32(cpu_gpr_d[r3], cpu_gpr_d[r3+1], temp64);
+        /* reset V bit */
+        tcg_gen_movi_tl(cpu_PSW_V, 0);
+        /* reset AV bit */
+        tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
+        tcg_temp_free_i64(temp64);
+
+        break;
+    case OPC2_32_RR1_MULR_H_16_LL:
+        GEN_HELPER_LL(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
+        break;
+    case OPC2_32_RR1_MULR_H_16_LU:
+        GEN_HELPER_LU(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
+        break;
+    case OPC2_32_RR1_MULR_H_16_UL:
+        GEN_HELPER_UL(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
+        break;
+    case OPC2_32_RR1_MULR_H_16_UU:
+        GEN_HELPER_UU(mulr_h, cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2], n);
+        gen_calc_usb_mulr_h(cpu_gpr_d[r3]);
+        break;
+    }
+    tcg_temp_free(n);
+}
+
+static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r1, r2, r3;
+    uint32_t n;
+
+    TCGv temp, temp2;
+
+    r1 = MASK_OP_RR1_S1(ctx->opcode);
+    r2 = MASK_OP_RR1_S2(ctx->opcode);
+    r3 = MASK_OP_RR1_D(ctx->opcode);
+    n  = MASK_OP_RR1_N(ctx->opcode);
+    op2 = MASK_OP_RR1_OP2(ctx->opcode);
+
+    temp = tcg_temp_new();
+    temp2 = tcg_temp_new();
+
+    switch (op2) {
+    case OPC2_32_RR1_MUL_Q_32:
+        gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], cpu_gpr_d[r2], n, 32);
+        break;
+    case OPC2_32_RR1_MUL_Q_64:
+        gen_mul_q(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
+                  n, 0);
+        break;
+    case OPC2_32_RR1_MUL_Q_32_L:
+        tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
+        gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], temp, n, 16);
+        break;
+    case OPC2_32_RR1_MUL_Q_64_L:
+        tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
+        gen_mul_q(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, n, 0);
+        break;
+    case OPC2_32_RR1_MUL_Q_32_U:
+        tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
+        gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], temp, n, 16);
+        break;
+    case OPC2_32_RR1_MUL_Q_64_U:
+        tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
+        gen_mul_q(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp, n, 0);
+        break;
+    case OPC2_32_RR1_MUL_Q_32_LL:
+        tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
+        tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
+        gen_mul_q_16(cpu_gpr_d[r3], temp, temp2, n);
+        break;
+    case OPC2_32_RR1_MUL_Q_32_UU:
+        tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
+        tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
+        gen_mul_q_16(cpu_gpr_d[r3], temp, temp2, n);
+        break;
+    case OPC2_32_RR1_MULR_Q_32_L:
+        tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
+        tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
+        gen_mulr_q(cpu_gpr_d[r3], temp, temp2, n);
+        break;
+    case OPC2_32_RR1_MULR_Q_32_U:
+        tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
+        tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
+        gen_mulr_q(cpu_gpr_d[r3], temp, temp2, n);
+        break;
+    }
+    tcg_temp_free(temp);
+    tcg_temp_free(temp2);
+}
+
+/* RR2 format */
+static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r1, r2, r3;
+
+    op2 = MASK_OP_RR2_OP2(ctx->opcode);
+    r1  = MASK_OP_RR2_S1(ctx->opcode);
+    r2  = MASK_OP_RR2_S2(ctx->opcode);
+    r3  = MASK_OP_RR2_D(ctx->opcode);
+    switch (op2) {
+    case OPC2_32_RR2_MUL_32:
+        gen_mul_i32s(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR2_MUL_64:
+        gen_mul_i64s(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
+                     cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR2_MULS_32:
+        gen_helper_mul_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                            cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR2_MUL_U_64:
+        gen_mul_i64u(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
+                     cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RR2_MULS_U_32:
+        gen_helper_mul_suov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+                            cpu_gpr_d[r2]);
+        break;
+    }
+}
+
+/* RRPW format */
+static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r1, r2, r3;
+    int32_t pos, width;
+
+    op2 = MASK_OP_RRPW_OP2(ctx->opcode);
+    r1 = MASK_OP_RRPW_S1(ctx->opcode);
+    r2 = MASK_OP_RRPW_S2(ctx->opcode);
+    r3 = MASK_OP_RRPW_D(ctx->opcode);
+    pos = MASK_OP_RRPW_POS(ctx->opcode);
+    width = MASK_OP_RRPW_WIDTH(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RRPW_EXTR:
+        if (pos + width <= 31) {
+            /* optimize special cases */
+            if ((pos == 0) && (width == 8)) {
+                tcg_gen_ext8s_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+            } else if ((pos == 0) && (width == 16)) {
+                tcg_gen_ext16s_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+            } else {
+                tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], 32 - pos - width);
+                tcg_gen_sari_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 32 - width);
+            }
+        }
+        break;
+    case OPC2_32_RRPW_EXTR_U:
+        if (width == 0) {
+            tcg_gen_movi_tl(cpu_gpr_d[r3], 0);
+        } else {
+            tcg_gen_shri_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], pos);
+            tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], ~0u >> (32-width));
+        }
+        break;
+    case OPC2_32_RRPW_IMASK:
+        if (pos + width <= 31) {
+            tcg_gen_movi_tl(cpu_gpr_d[r3+1], ((1u << width) - 1) << pos);
+            tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r2], pos);
+        }
+        break;
+    case OPC2_32_RRPW_INSERT:
+        if (pos + width <= 31) {
+            tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+                               width, pos);
+        }
+        break;
+    }
+}
+
+/* RRR format */
+static void decode_rrr_cond_select(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+    int r1, r2, r3, r4;
+    TCGv temp;
+
+    op2 = MASK_OP_RRR_OP2(ctx->opcode);
+    r1  = MASK_OP_RRR_S1(ctx->opcode);
+    r2  = MASK_OP_RRR_S2(ctx->opcode);
+    r3  = MASK_OP_RRR_S3(ctx->opcode);
+    r4  = MASK_OP_RRR_D(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RRR_CADD:
+        gen_cond_add(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2],
+                     cpu_gpr_d[r4], cpu_gpr_d[r3]);
+        break;
+    case OPC2_32_RRR_CADDN:
+        gen_cond_add(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
+                     cpu_gpr_d[r3]);
+        break;
+    case OPC2_32_RRR_CSUB:
+        gen_cond_sub(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
+                     cpu_gpr_d[r3]);
+        break;
+    case OPC2_32_RRR_CSUBN:
+        gen_cond_sub(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2], cpu_gpr_d[r4],
+                     cpu_gpr_d[r3]);
+        break;
+    case OPC2_32_RRR_SEL:
+        temp = tcg_const_i32(0);
+        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
+                           cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        tcg_temp_free(temp);
+        break;
+    case OPC2_32_RRR_SELN:
+        temp = tcg_const_i32(0);
+        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r4], cpu_gpr_d[r3], temp,
+                           cpu_gpr_d[r1], cpu_gpr_d[r2]);
+        tcg_temp_free(temp);
+        break;
+    }
+}
+
+static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx)
+{
+    uint32_t op2;
+
+    int r1, r2, r3, r4;
+
+    op2 = MASK_OP_RRR_OP2(ctx->opcode);
+    r1 = MASK_OP_RRR_S1(ctx->opcode);
+    r2 = MASK_OP_RRR_S2(ctx->opcode);
+    r3 = MASK_OP_RRR_S3(ctx->opcode);
+    r4 = MASK_OP_RRR_D(ctx->opcode);
+
+    switch (op2) {
+    case OPC2_32_RRR_DVADJ:
+        GEN_HELPER_RRR(dvadj, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+                       cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RRR_DVSTEP:
+        GEN_HELPER_RRR(dvstep, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+                       cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RRR_DVSTEP_U:
+        GEN_HELPER_RRR(dvstep_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+                       cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RRR_IXMAX:
+        GEN_HELPER_RRR(ixmax, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+                       cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RRR_IXMAX_U:
+        GEN_HELPER_RRR(ixmax_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+                       cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RRR_IXMIN:
+        GEN_HELPER_RRR(ixmin, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+                       cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RRR_IXMIN_U:
+        GEN_HELPER_RRR(ixmin_u, cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
+                       cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
+        break;
+    case OPC2_32_RRR_PACK:
+        gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3],
+                        cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
+        break;
+    }
+}
+
+static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
+{
+    int op1;
+    int32_t r1, r2, r3;
+    int32_t address, const16;
+    int8_t b, const4;
+    int32_t bpos;
+    TCGv temp, temp2, temp3;
+
+    op1 = MASK_OP_MAJOR(ctx->opcode);
+
+    /* handle JNZ.T opcode only being 7 bit long */
+    if (unlikely((op1 & 0x7f) == OPCM_32_BRN_JTT)) {
+        op1 = OPCM_32_BRN_JTT;
+    }
+
+    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));
 
@@ -3415,7 +5273,7 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
     case OPC1_32_B_JA:
     case OPC1_32_B_JL:
     case OPC1_32_B_JLA:
-        address = MASK_OP_B_DISP24(ctx->opcode);
+        address = MASK_OP_B_DISP24_SEXT(ctx->opcode);
         gen_compute_branch(ctx, op1, 0, 0, 0, address);
         break;
 /* Bit-format */
@@ -3461,10 +5319,16 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
         break;
 /* BOL-format */
     case OPC1_32_BOL_LD_A_LONGOFF:
-    case OPC1_32_BOL_LD_W_LONFOFF:
+    case OPC1_32_BOL_LD_W_LONGOFF:
     case OPC1_32_BOL_LEA_LONGOFF:
     case OPC1_32_BOL_ST_W_LONGOFF:
     case OPC1_32_BOL_ST_A_LONGOFF:
+    case OPC1_32_BOL_LD_B_LONGOFF:
+    case OPC1_32_BOL_LD_BU_LONGOFF:
+    case OPC1_32_BOL_LD_H_LONGOFF:
+    case OPC1_32_BOL_LD_HU_LONGOFF:
+    case OPC1_32_BOL_ST_B_LONGOFF:
+    case OPC1_32_BOL_ST_H_LONGOFF:
         decode_bol_opc(env, ctx, op1);
         break;
 /* BRC Format */
@@ -3536,18 +5400,81 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
     case OPCM_32_RCRW_MASK_INSERT:
         decode_rcrw_insert(env, ctx);
         break;
+/* RCR Format */
+    case OPCM_32_RCR_COND_SELECT:
+        decode_rcr_cond_select(env, ctx);
+        break;
+    case OPCM_32_RCR_MADD:
+        decode_rcr_madd(env, ctx);
+        break;
+    case OPCM_32_RCR_MSUB:
+        decode_rcr_msub(env, ctx);
+        break;
 /* RLC Format */
     case OPC1_32_RLC_ADDI:
     case OPC1_32_RLC_ADDIH:
     case OPC1_32_RLC_ADDIH_A:
     case OPC1_32_RLC_MFCR:
     case OPC1_32_RLC_MOV:
+    case OPC1_32_RLC_MOV_64:
     case OPC1_32_RLC_MOV_U:
     case OPC1_32_RLC_MOV_H:
     case OPC1_32_RLC_MOVH_A:
     case OPC1_32_RLC_MTCR:
         decode_rlc_opc(env, ctx, op1);
         break;
+/* RR Format */
+    case OPCM_32_RR_ACCUMULATOR:
+        decode_rr_accumulator(env, ctx);
+        break;
+    case OPCM_32_RR_LOGICAL_SHIFT:
+        decode_rr_logical_shift(env, ctx);
+        break;
+    case OPCM_32_RR_ADDRESS:
+        decode_rr_address(env, ctx);
+        break;
+    case OPCM_32_RR_IDIRECT:
+        decode_rr_idirect(env, ctx);
+        break;
+    case OPCM_32_RR_DIVIDE:
+        decode_rr_divide(env, ctx);
+        break;
+/* RR1 Format */
+    case OPCM_32_RR1_MUL:
+        decode_rr1_mul(env, ctx);
+        break;
+    case OPCM_32_RR1_MULQ:
+        decode_rr1_mulq(env, ctx);
+        break;
+/* RR2 format */
+    case OPCM_32_RR2_MUL:
+        decode_rr2_mul(env, ctx);
+        break;
+/* RRPW format */
+    case OPCM_32_RRPW_EXTRACT_INSERT:
+        decode_rrpw_extract_insert(env, ctx);
+        break;
+    case OPC1_32_RRPW_DEXTR:
+        r1 = MASK_OP_RRPW_S1(ctx->opcode);
+        r2 = MASK_OP_RRPW_S2(ctx->opcode);
+        r3 = MASK_OP_RRPW_D(ctx->opcode);
+        const16 = MASK_OP_RRPW_POS(ctx->opcode);
+        if (r1 == r2) {
+            tcg_gen_rotli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], const16);
+        } else {
+            temp = tcg_temp_new();
+            tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r2], const16);
+            tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 32 - const16);
+            tcg_gen_or_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
+            tcg_temp_free(temp);
+        }
+        break;
+/* RRR Format */
+    case OPCM_32_RRR_COND_SELECT:
+        decode_rrr_cond_select(env, ctx);
+        break;
+    case OPCM_32_RRR_DIVIDE:
+        decode_rrr_divide(env, ctx);
     }
 }
 
@@ -3573,7 +5500,6 @@ gen_intermediate_code_internal(TriCoreCPU *cpu, struct TranslationBlock *tb,
     DisasContext ctx;
     target_ulong pc_start;
     int num_insns;
-    uint16_t *gen_opc_end;
 
     if (search_pc) {
         qemu_log("search pc %d\n", search_pc);
@@ -3581,7 +5507,6 @@ gen_intermediate_code_internal(TriCoreCPU *cpu, struct TranslationBlock *tb,
 
     num_insns = 0;
     pc_start = tb->pc;
-    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
     ctx.pc = pc_start;
     ctx.saved_pc = -1;
     ctx.tb = tb;
@@ -3590,14 +5515,14 @@ gen_intermediate_code_internal(TriCoreCPU *cpu, struct TranslationBlock *tb,
     ctx.mem_idx = cpu_mmu_index(env);
 
     tcg_clear_temp_count();
-    gen_tb_start();
+    gen_tb_start(tb);
     while (ctx.bstate == BS_NONE) {
         ctx.opcode = cpu_ldl_code(env, ctx.pc);
         decode_opc(env, &ctx, 0);
 
         num_insns++;
 
-        if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
+        if (tcg_op_buf_full()) {
             gen_save_pc(ctx.next_pc);
             tcg_gen_exit_tb(0);
             break;
@@ -3611,7 +5536,6 @@ gen_intermediate_code_internal(TriCoreCPU *cpu, struct TranslationBlock *tb,
     }
 
     gen_tb_end(tb, num_insns);
-    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
     if (search_pc) {
         printf("done_generating search pc\n");
     } else {
This page took 0.07494 seconds and 4 git commands to generate.