* [Qemu-devel] [PATCH v2 0/4] TriCore exception patches
@ 2016-02-15 13:10 Bastian Koppelmann
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 1/4] target-tricore: Add trap handling Bastian Koppelmann
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Bastian Koppelmann @ 2016-02-15 13:10 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
Hi,
this series add the infrastructure to generate and handle tricore exceptions
and adds three types of exceptions (context management,illegal opcodes, and
register-pair) which I tested so far. However more patches will follow that add
the missing exceptions that make sense to QEMU.
Richard, am I right that cpu_exec_interrupt() saves the pre-interrupt state
for asynchronous exceptions, like helper_exception_raise_sync() does for
synchronous exceptions in this patch?
Cheers,
Bastian
v1 -> v2:
- replace helper raise_exception_error by raise_exception_sync,
that takes care of saving the pre-interrupt state for synchronous
exceptions.
- rewrite of generate_trap() in translate.c. It directly
calls the raise_exception_sync helper instead of saving the
pre-interrupt state itself.
- drop PATCH[2/5]: target-tricore: Save the pc before CSA operations for exceptions
Bastian Koppelmann (4):
target-tricore: Add trap handling
target-tricore: add context managment trap generation
target-tricore: add illegal opcode trap generation
target-tricore: add opd trap generation
target-tricore/cpu-qom.h | 2 +-
target-tricore/cpu.c | 2 +-
target-tricore/cpu.h | 1 +
target-tricore/helper.c | 16 ++
target-tricore/helper.h | 3 +
target-tricore/op_helper.c | 146 +++++++++++++-
target-tricore/translate.c | 472 ++++++++++++++++++++++++++++++++++++++++++---
7 files changed, 610 insertions(+), 32 deletions(-)
--
2.7.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 1/4] target-tricore: Add trap handling
2016-02-15 13:10 [Qemu-devel] [PATCH v2 0/4] TriCore exception patches Bastian Koppelmann
@ 2016-02-15 13:10 ` Bastian Koppelmann
2016-02-15 20:52 ` Richard Henderson
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 2/4] target-tricore: add context managment trap generation Bastian Koppelmann
` (3 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Bastian Koppelmann @ 2016-02-15 13:10 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
Add the infrastructure needed to generate and handle traps.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
v1 -> v2:
- replace helper raise_exception_error by raise_exception_sync,
that takes care of saving the pre-interrupt state.
- rewrite of generate_trap() in translate.c. It directly
calls the raise_exception_sync helper instead of saving the
pre-interrupt state itself.
target-tricore/cpu-qom.h | 2 +-
target-tricore/cpu.c | 2 +-
target-tricore/cpu.h | 1 +
target-tricore/helper.c | 16 ++++++
target-tricore/helper.h | 3 ++
target-tricore/op_helper.c | 119 +++++++++++++++++++++++++++++++++++++++++++++
target-tricore/translate.c | 12 +++++
7 files changed, 153 insertions(+), 2 deletions(-)
diff --git a/target-tricore/cpu-qom.h b/target-tricore/cpu-qom.h
index 66c9664..0909c0c 100644
--- a/target-tricore/cpu-qom.h
+++ b/target-tricore/cpu-qom.h
@@ -65,6 +65,6 @@ static inline TriCoreCPU *tricore_env_get_cpu(CPUTriCoreState *env)
hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
void tricore_cpu_dump_state(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags);
-
+void tricore_cpu_do_interrupt(CPUState *cs);
#endif /*QEMU_TRICORE_CPU_QOM_H */
diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c
index f8b8518..01e39dc 100644
--- a/target-tricore/cpu.c
+++ b/target-tricore/cpu.c
@@ -166,7 +166,7 @@ static void tricore_cpu_class_init(ObjectClass *c, void *data)
cc->reset = tricore_cpu_reset;
cc->class_by_name = tricore_cpu_class_by_name;
cc->has_work = tricore_cpu_has_work;
-
+ cc->do_interrupt = tricore_cpu_do_interrupt;
cc->dump_state = tricore_cpu_dump_state;
cc->set_pc = tricore_cpu_set_pc;
cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb;
diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
index 20a12f3..b4cc2ef 100644
--- a/target-tricore/cpu.h
+++ b/target-tricore/cpu.h
@@ -271,6 +271,7 @@ enum {
TRAPC_ASSERT = 5,
TRAPC_SYSCALL = 6,
TRAPC_NMI = 7,
+ TRAPC_IRQ = 8
};
/* Class 0 TIN */
diff --git a/target-tricore/helper.c b/target-tricore/helper.c
index a8fd418..c1fc43c 100644
--- a/target-tricore/helper.c
+++ b/target-tricore/helper.c
@@ -133,3 +133,19 @@ void psw_write(CPUTriCoreState *env, uint32_t val)
env->PSW_USB_SAV = ((val & MASK_USB_SAV) << 4);
env->PSW = val;
}
+
+void tricore_cpu_do_interrupt(CPUState *cs)
+{
+ TriCoreCPU *cpu = TRICORE_CPU(cs);
+ CPUTriCoreState *env = &cpu->env;
+
+ if (cs->exception_index <= TRAPC_NMI) {
+ /* The trap vector table is accessed to fetch the first instruction of
+ the trap handler. */
+ env->PC = env->BTV | (cs->exception_index << 5);
+ } else if (cs->exception_index == TRAPC_IRQ) {
+ /* The interrupt vector table is accessed to fetch the first instruction
+ of the interrupt handler. */
+ env->PC = env->BIV | ((env->ICR & MASK_ICR_PIPN) >> 10);
+ }
+}
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index cc221f1..2c8ed78 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -132,6 +132,7 @@ DEF_HELPER_2(lducx, void, env, i32)
DEF_HELPER_2(stlcx, void, env, i32)
DEF_HELPER_2(stucx, void, env, i32)
DEF_HELPER_1(svlcx, void, env)
+DEF_HELPER_1(svucx, void, env)
DEF_HELPER_1(rslcx, void, env)
/* Address mode helper */
DEF_HELPER_1(br_update, i32, i32)
@@ -139,3 +140,5 @@ DEF_HELPER_2(circ_update, i32, i32, i32)
/* PSW cache helper */
DEF_HELPER_2(psw_write, void, env, i32)
DEF_HELPER_1(psw_read, i32, env)
+/* Exceptions */
+DEF_HELPER_3(raise_exception_sync, noreturn, env, i32, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 3aa6326..eaaa591 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -21,6 +21,84 @@
#include "exec/cpu_ldst.h"
#include <zlib.h> /* for crc32 */
+
+/* Exception helpers */
+
+static void QEMU_NORETURN
+raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin,
+ uintptr_t pc)
+{
+ CPUState *cs = CPU(tricore_env_get_cpu(env));
+ /* in case we come from a helper-call we need to restore the PC */
+ if (pc) {
+ cpu_restore_state(cs, pc);
+ }
+
+ /* Tin is loaded into d[15] */
+ env->gpr_d[15] = tin;
+
+ if (class == TRAPC_CTX_MNG && tin == TIN3_FCU) {
+ /* upper context cannot be saved, if the context list is empty */
+ } else {
+ helper_svucx(env);
+ }
+
+ /* The return address in a[11] is updated */
+ if (class == TRAPC_CTX_MNG && tin == TIN3_FCD) {
+ env->SYSCON |= MASK_SYSCON_FCD_SF;
+ /* when we fault here, the return address is the start of the
+ faulting trap handler */
+ env->gpr_a[11] = env->BTV | cs->exception_index << 5;
+ }else if (class == TRAPC_SYSCALL) {
+ env->gpr_a[11] = env->PC + 4;
+ } else {
+ env->gpr_a[11] = env->PC;
+ }
+ /* The stack pointer in A[10] is set to the Interrupt Stack Pointer (ISP)
+ when the processor was not previously using the interrupt stack
+ (in case of PSW.IS = 0). The stack pointer bit is set for using the
+ interrupt stack: PSW.IS = 1. */
+ if ((env->PSW & MASK_PSW_IS) == 0) {
+ env->gpr_a[10] = env->ISP;
+ }
+ env->PSW |= MASK_PSW_IS;
+ /* The I/O mode is set to Supervisor mode, which means all permissions
+ are enabled: PSW.IO = 10 B .*/
+ env->PSW |= (2 << 10);
+
+ /*The current Protection Register Set is set to 0: PSW.PRS = 00 B .*/
+ env->PSW &= ~MASK_PSW_PRS;
+
+ /* The Call Depth Counter (CDC) is cleared, and the call depth limit is
+ set for 64: PSW.CDC = 0000000 B .*/
+ env->PSW &= ~MASK_PSW_CDC;
+
+ /* Call Depth Counter is enabled, PSW.CDE = 1. */
+ env->PSW |= MASK_PSW_CDE;
+
+ /* Write permission to global registers A[0], A[1], A[8], A[9] is
+ disabled: PSW.GW = 0. */
+ env->PSW &= ~MASK_PSW_GW;
+
+ /*The interrupt system is globally disabled: ICR.IE = 0. The ‘old’
+ ICR.IE and ICR.CCPN are saved */
+
+ /* PCXI.PIE = ICR.IE */
+ env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
+ ((env->ICR & MASK_ICR_IE) << 15));
+ /* PCXI.PCPN = ICR.CCPN */
+ env->PCXI = (env->PCXI & 0xffffff) +
+ ((env->ICR & MASK_ICR_CCPN) << 24);
+ cs->exception_index = class;
+ cpu_loop_exit(cs);
+}
+
+void helper_raise_exception_sync(CPUTriCoreState *env, uint32_t class,
+ uint32_t tin)
+{
+ raise_exception_sync_internal(env, class, tin, 0);
+}
+
/* Addressing mode helper */
static uint16_t reverse16(uint16_t val)
@@ -2625,6 +2703,47 @@ void helper_svlcx(CPUTriCoreState *env)
}
}
+void helper_svucx(CPUTriCoreState *env)
+{
+ target_ulong tmp_FCX;
+ target_ulong ea;
+ target_ulong new_FCX;
+
+ if (env->FCX == 0) {
+ /* FCU trap */
+ }
+ /* tmp_FCX = FCX; */
+ tmp_FCX = env->FCX;
+ /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
+ ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
+ ((env->FCX & MASK_FCX_FCXO) << 6);
+ /* new_FCX = M(EA, word); */
+ new_FCX = cpu_ldl_data(env, ea);
+ /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
+ A[12], A[13], A[14], A[15], D[12], D[13], D[14],
+ D[15]}; */
+ save_context_upper(env, ea);
+
+ /* PCXI.PCPN = ICR.CCPN; */
+ env->PCXI = (env->PCXI & 0xffffff) +
+ ((env->ICR & MASK_ICR_CCPN) << 24);
+ /* PCXI.PIE = ICR.IE; */
+ env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
+ ((env->ICR & MASK_ICR_IE) << 15));
+ /* PCXI.UL = 1; */
+ env->PCXI |= MASK_PCXI_UL;
+
+ /* PCXI[19: 0] = FCX[19: 0]; */
+ env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
+ /* FCX[19: 0] = new_FCX[19: 0]; */
+ env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
+
+ /* if (tmp_FCX == LCX) trap(FCD);*/
+ if (tmp_FCX == env->LCX) {
+ /* FCD trap */
+ }
+}
+
void helper_rslcx(CPUTriCoreState *env)
{
target_ulong ea;
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index a70fdf7..4423130 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -3244,6 +3244,18 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
}
}
+static void generate_trap(DisasContext *ctx, int class, int tin)
+{
+ TCGv_i32 classtemp = tcg_const_i32(class);
+ TCGv_i32 tintemp = tcg_const_i32(tin);
+
+ gen_helper_raise_exception_sync(cpu_env, classtemp, tintemp);
+ ctx->bstate = BS_EXCP;
+
+ tcg_temp_free(classtemp);
+ tcg_temp_free(tintemp);
+}
+
static inline void gen_branch_cond(DisasContext *ctx, TCGCond cond, TCGv r1,
TCGv r2, int16_t address)
{
--
2.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 2/4] target-tricore: add context managment trap generation
2016-02-15 13:10 [Qemu-devel] [PATCH v2 0/4] TriCore exception patches Bastian Koppelmann
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 1/4] target-tricore: Add trap handling Bastian Koppelmann
@ 2016-02-15 13:10 ` Bastian Koppelmann
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 3/4] target-tricore: add illegal opcode " Bastian Koppelmann
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Bastian Koppelmann @ 2016-02-15 13:10 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target-tricore/op_helper.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index eaaa591..4996fd5 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -2447,11 +2447,13 @@ void helper_call(CPUTriCoreState *env, uint32_t next_pc)
/* if (FCX == 0) trap(FCU); */
if (env->FCX == 0) {
/* FCU trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
}
/* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
if (psw & MASK_PSW_CDE) {
if (cdc_increment(&psw)) {
/* CDO trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC());
}
}
/* PSW.CDE = 1;*/
@@ -2487,6 +2489,7 @@ void helper_call(CPUTriCoreState *env, uint32_t next_pc)
/* if (tmp_FCX == LCX) trap(FCD);*/
if (tmp_FCX == env->LCX) {
/* FCD trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
}
psw_write(env, psw);
}
@@ -2499,18 +2502,25 @@ void helper_ret(CPUTriCoreState *env)
psw = psw_read(env);
/* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
- if (env->PSW & MASK_PSW_CDE) {
- if (cdc_decrement(&(env->PSW))) {
+ if (psw & MASK_PSW_CDE) {
+ if (cdc_decrement(&psw)) {
/* CDU trap */
+ psw_write(env, psw);
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_CDU, GETPC());
}
}
/* if (PCXI[19: 0] == 0) then trap(CSU); */
if ((env->PCXI & 0xfffff) == 0) {
/* CSU trap */
+ psw_write(env, psw);
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
}
/* if (PCXI.UL == 0) then trap(CTYP); */
if ((env->PCXI & MASK_PCXI_UL) == 0) {
/* CTYP trap */
+ cdc_increment(&psw); /* restore to the start of helper */
+ psw_write(env, psw);
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
}
/* PC = {A11 [31: 1], 1’b0}; */
env->PC = env->gpr_a[11] & 0xfffffffe;
@@ -2545,6 +2555,7 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9)
if (env->FCX == 0) {
/* FCU trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
}
tmp_FCX = env->FCX;
@@ -2576,6 +2587,7 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9)
if (tmp_FCX == env->LCX) {
/* FCD trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
}
}
@@ -2587,14 +2599,17 @@ void helper_rfe(CPUTriCoreState *env)
/* if (PCXI[19: 0] == 0) then trap(CSU); */
if ((env->PCXI & 0xfffff) == 0) {
/* raise csu trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
}
/* if (PCXI.UL == 0) then trap(CTYP); */
if ((env->PCXI & MASK_PCXI_UL) == 0) {
/* raise CTYP trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
}
/* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
- /* raise MNG trap */
+ /* raise NEST trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_NEST, GETPC());
}
env->PC = env->gpr_a[11] & ~0x1;
/* ICR.IE = PCXI.PIE; */
@@ -2670,6 +2685,7 @@ void helper_svlcx(CPUTriCoreState *env)
if (env->FCX == 0) {
/* FCU trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
}
/* tmp_FCX = FCX; */
tmp_FCX = env->FCX;
@@ -2700,6 +2716,7 @@ void helper_svlcx(CPUTriCoreState *env)
/* if (tmp_FCX == LCX) trap(FCD);*/
if (tmp_FCX == env->LCX) {
/* FCD trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
}
}
@@ -2711,6 +2728,7 @@ void helper_svucx(CPUTriCoreState *env)
if (env->FCX == 0) {
/* FCU trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
}
/* tmp_FCX = FCX; */
tmp_FCX = env->FCX;
@@ -2741,6 +2759,7 @@ void helper_svucx(CPUTriCoreState *env)
/* if (tmp_FCX == LCX) trap(FCD);*/
if (tmp_FCX == env->LCX) {
/* FCD trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
}
}
@@ -2751,10 +2770,12 @@ void helper_rslcx(CPUTriCoreState *env)
/* if (PCXI[19: 0] == 0) then trap(CSU); */
if ((env->PCXI & 0xfffff) == 0) {
/* CSU trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
}
/* if (PCXI.UL == 1) then trap(CTYP); */
if ((env->PCXI & MASK_PCXI_UL) != 0) {
/* CTYP trap */
+ raise_exception_sync_internal(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
}
/* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
--
2.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 3/4] target-tricore: add illegal opcode trap generation
2016-02-15 13:10 [Qemu-devel] [PATCH v2 0/4] TriCore exception patches Bastian Koppelmann
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 1/4] target-tricore: Add trap handling Bastian Koppelmann
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 2/4] target-tricore: add context managment trap generation Bastian Koppelmann
@ 2016-02-15 13:10 ` Bastian Koppelmann
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 4/4] target-tricore: add opd " Bastian Koppelmann
2016-02-15 20:52 ` [Qemu-devel] [PATCH v2 0/4] TriCore exception patches Richard Henderson
4 siblings, 0 replies; 7+ messages in thread
From: Bastian Koppelmann @ 2016-02-15 13:10 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target-tricore/translate.c | 175 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 156 insertions(+), 19 deletions(-)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 4423130..b9668a5 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -3554,7 +3554,7 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
}
break;
default:
- printf("Branch Error at %x\n", ctx->pc);
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
ctx->bstate = BS_BRANCH;
}
@@ -3629,7 +3629,9 @@ static void decode_src_opc(CPUTriCoreState *env, DisasContext *ctx, int op1)
if (tricore_feature(env, TRICORE_FEATURE_16)) {
tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31);
- } /* TODO: else raise illegal opcode trap */
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
break;
case OPC1_16_SRC_SH:
gen_shi(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
@@ -3637,6 +3639,8 @@ static void decode_src_opc(CPUTriCoreState *env, DisasContext *ctx, int op1)
case OPC1_16_SRC_SHA:
gen_shaci(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -3720,6 +3724,8 @@ static void decode_srr_opc(DisasContext *ctx, int op1)
case OPC1_16_SRR_XOR:
tcg_gen_xor_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -3759,6 +3765,8 @@ static void decode_ssr_opc(DisasContext *ctx, int op1)
tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -3796,6 +3804,8 @@ static void decode_sc_opc(DisasContext *ctx, int op1)
case OPC1_16_SC_SUB_A:
tcg_gen_subi_tl(cpu_gpr_a[10], cpu_gpr_a[10], const16);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -3836,6 +3846,8 @@ static void decode_slr_opc(DisasContext *ctx, int op1)
tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -3873,6 +3885,8 @@ static void decode_sro_opc(DisasContext *ctx, int op1)
case OPC1_16_SRO_ST_W:
gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -3897,6 +3911,9 @@ static void decode_sr_system(CPUTriCoreState *env, DisasContext *ctx)
break;
case OPC2_16_SR_FRET:
gen_fret(ctx);
+ break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -3939,6 +3956,8 @@ static void decode_sr_accu(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_16_SR_SAT_HU:
gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xffff);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -4149,6 +4168,8 @@ static void decode_16Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
r1 = MASK_OP_SR_S1D(ctx->opcode);
tcg_gen_not_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -4183,6 +4204,8 @@ static void decode_abs_ldw(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_ABS_LD_W:
tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
@@ -4214,6 +4237,8 @@ static void decode_abs_ldb(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_ABS_LD_HU:
tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
@@ -4239,6 +4264,8 @@ static void decode_abs_ldst_swap(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_ABS_SWAP_W:
gen_swap(ctx, r1, temp);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
@@ -4265,6 +4292,8 @@ static void decode_abs_ldst_context(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_ABS_STUCX:
gen_helper_1arg(stucx, EA_ABS_FORMAT(off18));
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -4294,7 +4323,8 @@ static void decode_abs_store(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_ABS_ST_W:
tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
break;
-
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
}
@@ -4319,6 +4349,8 @@ static void decode_abs_storeb_h(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_ABS_ST_H:
tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
}
@@ -4361,6 +4393,8 @@ static void decode_bit_andacc(CPUTriCoreState *env, DisasContext *ctx)
gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -4393,6 +4427,8 @@ static void decode_bit_logical_t(CPUTriCoreState *env, DisasContext *ctx)
gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
pos1, pos2, &tcg_gen_or_tl);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -4450,6 +4486,8 @@ static void decode_bit_logical_t2(CPUTriCoreState *env, DisasContext *ctx)
gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
pos1, pos2, &tcg_gen_xor_tl);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -4489,6 +4527,8 @@ static void decode_bit_orand(CPUTriCoreState *env, DisasContext *ctx)
gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
pos1, pos2, &tcg_gen_or_tl, &tcg_gen_or_tl);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -4525,6 +4565,8 @@ static void decode_bit_sh_logic1(CPUTriCoreState *env, DisasContext *ctx)
gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
pos1, pos2, &tcg_gen_or_tl);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 1);
tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
@@ -4564,6 +4606,8 @@ static void decode_bit_sh_logic2(CPUTriCoreState *env, DisasContext *ctx)
gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
pos1, pos2, &tcg_gen_xor_tl);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 1);
tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
@@ -4608,20 +4652,25 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
break;
case OPC2_32_BO_CACHEI_WI_SHORTOFF:
case OPC2_32_BO_CACHEI_W_SHORTOFF:
- /* TODO: Raise illegal opcode trap,
- if !tricore_feature(TRICORE_FEATURE_131) */
+ if (!tricore_feature(env, TRICORE_FEATURE_131)) {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
break;
case OPC2_32_BO_CACHEI_W_POSTINC:
case OPC2_32_BO_CACHEI_WI_POSTINC:
if (tricore_feature(env, TRICORE_FEATURE_131)) {
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
- } /* TODO: else raise illegal opcode trap */
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
break;
case OPC2_32_BO_CACHEI_W_PREINC:
case OPC2_32_BO_CACHEI_WI_PREINC:
if (tricore_feature(env, TRICORE_FEATURE_131)) {
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
- } /* TODO: else raise illegal opcode trap */
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
break;
case OPC2_32_BO_ST_A_SHORTOFF:
gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL);
@@ -4717,6 +4766,8 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
case OPC2_32_BO_ST_W_PREINC:
gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -4819,6 +4870,8 @@ static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env,
tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
tcg_temp_free(temp2);
@@ -4949,6 +5002,8 @@ static void decode_bo_addrmode_ld_post_pre_base(CPUTriCoreState *env,
case OPC2_32_BO_LD_W_PREINC:
gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUL);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -5059,6 +5114,8 @@ static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env,
tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
tcg_temp_free(temp2);
@@ -5151,6 +5208,8 @@ static void decode_bo_addrmode_stctx_post_pre_base(CPUTriCoreState *env,
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
gen_swapmsk(ctx, r1, cpu_gpr_a[r2]);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
tcg_temp_free(temp2);
@@ -5210,6 +5269,8 @@ static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env,
gen_swapmsk(ctx, r1, temp2);
gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
@@ -5247,7 +5308,7 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
if (tricore_feature(env, TRICORE_FEATURE_16)) {
gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], address, MO_LEUL);
} else {
- /* raise illegal opcode trap */
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
break;
case OPC1_32_BOL_ST_W_LONGOFF:
@@ -5257,44 +5318,46 @@ static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)
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 */
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
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 */
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
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 */
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
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 */
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
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 */
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
break;
case OPC1_32_BOL_ST_H_LONGOFF:
if (tricore_feature(env, TRICORE_FEATURE_16)) {
gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);
} else {
- /* raise illegal opcode trap */
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -5360,6 +5423,8 @@ static void decode_rc_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_RC_XOR:
tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
}
@@ -5558,6 +5623,8 @@ static void decode_rc_accumulator(CPUTriCoreState *env, DisasContext *ctx)
gen_accumulating_condi(TCG_COND_NE, cpu_gpr_d[r2], cpu_gpr_d[r1],
const9, &tcg_gen_xor_tl);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
}
@@ -5577,6 +5644,8 @@ static void decode_rc_serviceroutine(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_RC_SYSCALL:
/* TODO: Add exception generation */
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -5610,6 +5679,8 @@ static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx)
const9 = MASK_OP_RC_CONST9(ctx->opcode);
gen_mulsui_i32(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -5645,6 +5716,8 @@ static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx)
tcg_temp_free(temp);
}
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -5686,6 +5759,8 @@ static void decode_rcrw_insert(CPUTriCoreState *env, DisasContext *ctx)
tcg_temp_free(temp3);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
tcg_temp_free(temp2);
@@ -5732,6 +5807,8 @@ static void decode_rcr_cond_select(CPUTriCoreState *env, DisasContext *ctx)
tcg_temp_free(temp);
tcg_temp_free(temp2);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -5777,6 +5854,8 @@ static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx)
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;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -5822,6 +5901,8 @@ static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx)
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;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -5862,7 +5943,7 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
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 */
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
break;
case OPC1_32_RLC_MOV_U:
@@ -5879,6 +5960,8 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
const16 = MASK_OP_RLC_CONST16(ctx->opcode);
gen_mtcr(env, ctx, cpu_gpr_d[r1], const16);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -6195,6 +6278,8 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx)
gen_accumulating_cond(TCG_COND_NE, cpu_gpr_d[r3], cpu_gpr_d[r1],
cpu_gpr_d[r2], &tcg_gen_xor_tl);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -6269,6 +6354,8 @@ static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_RR_XOR:
tcg_gen_xor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
}
@@ -6336,6 +6423,8 @@ static void decode_rr_address(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_RR_SUB_A:
tcg_gen_sub_tl(cpu_gpr_a[r3], cpu_gpr_a[r1], cpu_gpr_a[r2]);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -6363,6 +6452,8 @@ static void decode_rr_idirect(CPUTriCoreState *env, DisasContext *ctx)
gen_fcall_save_ctx(ctx);
tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_gen_exit_tb(0);
ctx->bstate = BS_BRANCH;
@@ -6504,20 +6595,28 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_RR_CRC32:
if (tricore_feature(env, TRICORE_FEATURE_161)) {
gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
- } /* TODO: else raise illegal opcode trap */
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
break;
case OPC2_32_RR_DIV:
if (tricore_feature(env, TRICORE_FEATURE_16)) {
GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
cpu_gpr_d[r2]);
- } /* TODO: else raise illegal opcode trap */
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
break;
case OPC2_32_RR_DIV_U:
if (tricore_feature(env, TRICORE_FEATURE_16)) {
GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1],
cpu_gpr_d[r1], cpu_gpr_d[r2]);
- } /* TODO: else raise illegal opcode trap */
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -6622,6 +6721,8 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
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;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(n);
}
@@ -6687,6 +6788,8 @@ static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx)
tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
gen_mulr_q(cpu_gpr_d[r3], temp, temp2, n);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
tcg_temp_free(temp2);
@@ -6722,6 +6825,8 @@ static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx)
gen_helper_mul_suov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
cpu_gpr_d[r2]);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -6773,6 +6878,8 @@ static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
width, pos);
}
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -6818,6 +6925,8 @@ static void decode_rrr_cond_select(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r1], cpu_gpr_d[r2]);
tcg_temp_free(temp);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -6866,6 +6975,8 @@ static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx)
gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -6909,6 +7020,8 @@ static void decode_rrr2_madd(CPUTriCoreState *env, DisasContext *ctx)
gen_maddsu_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -6952,6 +7065,8 @@ static void decode_rrr2_msub(CPUTriCoreState *env, DisasContext *ctx)
gen_msubsu_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -7065,6 +7180,8 @@ static void decode_rrr1_madd(CPUTriCoreState *env, DisasContext *ctx)
gen_maddr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
cpu_gpr_d[r2], n, MODE_UU);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -7219,6 +7336,8 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
gen_maddrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
tcg_temp_free(temp2);
@@ -7345,6 +7464,8 @@ static void decode_rrr1_maddsu_h(CPUTriCoreState *env, DisasContext *ctx)
gen_maddsur32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
cpu_gpr_d[r2], n, MODE_UU);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -7457,6 +7578,8 @@ static void decode_rrr1_msub(CPUTriCoreState *env, DisasContext *ctx)
gen_msubr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
cpu_gpr_d[r2], n, MODE_UU);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -7611,6 +7734,8 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
gen_msubrs_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
tcg_temp_free(temp2);
@@ -7737,6 +7862,8 @@ static void decode_rrr1_msubad_h(CPUTriCoreState *env, DisasContext *ctx)
gen_msubadr32s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r1],
cpu_gpr_d[r2], n, MODE_UU);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -7788,6 +7915,8 @@ static void decode_rrrr_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
gen_insert(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2], tmp_width,
tmp_pos);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(tmp_pos);
tcg_temp_free(tmp_width);
@@ -7848,6 +7977,8 @@ static void decode_rrrw_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
tcg_temp_free(temp2);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
tcg_temp_free(temp);
}
@@ -7919,7 +8050,9 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
(ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_UM1) {
tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1);
} /* else raise privilege trap */
- } /* else raise illegal opcode trap */
+ } else {
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
+ }
break;
case OPC2_32_SYS_TRAPSV:
/* TODO: raise sticky overflow trap */
@@ -7927,6 +8060,8 @@ static void decode_sys_interrupts(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_SYS_TRAPV:
/* TODO: raise overflow trap */
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
@@ -8264,6 +8399,8 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
tcg_gen_mov_tl(cpu_PSW_AV, cpu_PSW_V);
tcg_gen_mov_tl(cpu_PSW_SAV, cpu_PSW_V);
break;
+ default:
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
--
2.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v2 4/4] target-tricore: add opd trap generation
2016-02-15 13:10 [Qemu-devel] [PATCH v2 0/4] TriCore exception patches Bastian Koppelmann
` (2 preceding siblings ...)
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 3/4] target-tricore: add illegal opcode " Bastian Koppelmann
@ 2016-02-15 13:10 ` Bastian Koppelmann
2016-02-15 20:52 ` [Qemu-devel] [PATCH v2 0/4] TriCore exception patches Richard Henderson
4 siblings, 0 replies; 7+ messages in thread
From: Bastian Koppelmann @ 2016-02-15 13:10 UTC (permalink / raw)
To: qemu-devel; +Cc: rth
If an instruction uses a 64 bit register which consists of an even-odd pair
of 32 bit registers and if the register specifier in the instruction is
odd an opd trap is raised.
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
---
target-tricore/translate.c | 285 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 277 insertions(+), 8 deletions(-)
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index b9668a5..d28b640 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -216,6 +216,15 @@ void tricore_cpu_dump_state(CPUState *cs, FILE *f,
#define EA_B_ABSOLUT(con) (((offset & 0xf00000) << 8) | \
((offset & 0x0fffff) << 1))
+/* For two 32-bit registers used a 64-bit register, the first
+ registernumber needs to be even. Otherwise we trap. */
+static inline void generate_trap(DisasContext *ctx, int class, int tin);
+#define CHECK_REG_PAIR(reg) do { \
+ if (reg & 0x1) { \
+ generate_trap(ctx, TRAPC_INSN_ERR, TIN2_OPD); \
+ } \
+} while (0)
+
/* Functions for load/save to/from memory */
static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
@@ -301,6 +310,7 @@ static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
TCGv temp = tcg_temp_new();
TCGv temp2 = tcg_temp_new();
+ CHECK_REG_PAIR(ereg);
/* temp = (M(EA, word) */
tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
/* temp = temp & ~E[a][63:32]) */
@@ -4196,9 +4206,11 @@ static void decode_abs_ldw(CPUTriCoreState *env, DisasContext *ctx)
tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
break;
case OPC2_32_ABS_LD_D:
+ CHECK_REG_PAIR(r1);
gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
break;
case OPC2_32_ABS_LD_DA:
+ CHECK_REG_PAIR(r1);
gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
break;
case OPC2_32_ABS_LD_W:
@@ -4315,9 +4327,11 @@ static void decode_abs_store(CPUTriCoreState *env, DisasContext *ctx)
tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
break;
case OPC2_32_ABS_ST_D:
+ CHECK_REG_PAIR(r1);
gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
break;
case OPC2_32_ABS_ST_DA:
+ CHECK_REG_PAIR(r1);
gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
break;
case OPC2_32_ABS_ST_W:
@@ -4695,14 +4709,17 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
break;
case OPC2_32_BO_ST_D_SHORTOFF:
+ CHECK_REG_PAIR(r1);
gen_offset_st_2regs(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2],
off10, ctx);
break;
case OPC2_32_BO_ST_D_POSTINC:
+ CHECK_REG_PAIR(r1);
gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx);
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
break;
case OPC2_32_BO_ST_D_PREINC:
+ CHECK_REG_PAIR(r1);
temp = tcg_temp_new();
tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
@@ -4710,14 +4727,17 @@ static void decode_bo_addrmode_post_pre_base(CPUTriCoreState *env,
tcg_temp_free(temp);
break;
case OPC2_32_BO_ST_DA_SHORTOFF:
+ CHECK_REG_PAIR(r1);
gen_offset_st_2regs(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2],
off10, ctx);
break;
case OPC2_32_BO_ST_DA_POSTINC:
+ CHECK_REG_PAIR(r1);
gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx);
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
break;
case OPC2_32_BO_ST_DA_PREINC:
+ CHECK_REG_PAIR(r1);
temp = tcg_temp_new();
tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
@@ -4787,7 +4807,7 @@ static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env,
temp = tcg_temp_new();
temp2 = tcg_temp_new();
temp3 = tcg_const_i32(off10);
-
+ CHECK_REG_PAIR(r2);
tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]);
tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
@@ -4819,10 +4839,12 @@ static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env,
gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
break;
case OPC2_32_BO_ST_D_BR:
+ CHECK_REG_PAIR(r1);
gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp2, ctx);
gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
break;
case OPC2_32_BO_ST_D_CIRC:
+ CHECK_REG_PAIR(r1);
tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
tcg_gen_addi_tl(temp, temp, 4);
@@ -4832,10 +4854,12 @@ static void decode_bo_addrmode_bitreverse_circular(CPUTriCoreState *env,
gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
break;
case OPC2_32_BO_ST_DA_BR:
+ CHECK_REG_PAIR(r1);
gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp2, ctx);
gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
break;
case OPC2_32_BO_ST_DA_CIRC:
+ CHECK_REG_PAIR(r1);
tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
tcg_gen_addi_tl(temp, temp, 4);
@@ -4926,14 +4950,17 @@ static void decode_bo_addrmode_ld_post_pre_base(CPUTriCoreState *env,
gen_ld_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_SB);
break;
case OPC2_32_BO_LD_D_SHORTOFF:
+ CHECK_REG_PAIR(r1);
gen_offset_ld_2regs(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2],
off10, ctx);
break;
case OPC2_32_BO_LD_D_POSTINC:
+ CHECK_REG_PAIR(r1);
gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx);
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
break;
case OPC2_32_BO_LD_D_PREINC:
+ CHECK_REG_PAIR(r1);
temp = tcg_temp_new();
tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
@@ -4941,14 +4968,17 @@ static void decode_bo_addrmode_ld_post_pre_base(CPUTriCoreState *env,
tcg_temp_free(temp);
break;
case OPC2_32_BO_LD_DA_SHORTOFF:
+ CHECK_REG_PAIR(r1);
gen_offset_ld_2regs(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2],
off10, ctx);
break;
case OPC2_32_BO_LD_DA_POSTINC:
+ CHECK_REG_PAIR(r1);
gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx);
tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
break;
case OPC2_32_BO_LD_DA_PREINC:
+ CHECK_REG_PAIR(r1);
temp = tcg_temp_new();
tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
@@ -5024,7 +5054,7 @@ static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env,
temp = tcg_temp_new();
temp2 = tcg_temp_new();
temp3 = tcg_const_i32(off10);
-
+ CHECK_REG_PAIR(r2);
tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]);
tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
@@ -5055,10 +5085,12 @@ static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env,
gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
break;
case OPC2_32_BO_LD_D_BR:
+ CHECK_REG_PAIR(r1);
gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp2, ctx);
gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
break;
case OPC2_32_BO_LD_D_CIRC:
+ CHECK_REG_PAIR(r1);
tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp2, ctx->mem_idx, MO_LEUL);
tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
tcg_gen_addi_tl(temp, temp, 4);
@@ -5068,10 +5100,12 @@ static void decode_bo_addrmode_ld_bitreverse_circular(CPUTriCoreState *env,
gen_helper_circ_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1], temp3);
break;
case OPC2_32_BO_LD_DA_BR:
+ CHECK_REG_PAIR(r1);
gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp2, ctx);
gen_helper_br_update(cpu_gpr_a[r2+1], cpu_gpr_a[r2+1]);
break;
case OPC2_32_BO_LD_DA_CIRC:
+ CHECK_REG_PAIR(r1);
tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp2, ctx->mem_idx, MO_LEUL);
tcg_gen_shri_tl(temp2, cpu_gpr_a[r2+1], 16);
tcg_gen_addi_tl(temp, temp, 4);
@@ -5232,7 +5266,7 @@ static void decode_bo_addrmode_ldmst_bitreverse_circular(CPUTriCoreState *env,
temp = tcg_temp_new();
temp2 = tcg_temp_new();
temp3 = tcg_const_i32(off10);
-
+ CHECK_REG_PAIR(r2);
tcg_gen_ext16u_tl(temp, cpu_gpr_a[r2+1]);
tcg_gen_add_tl(temp2, cpu_gpr_a[r2], temp);
@@ -5666,6 +5700,7 @@ static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx)
gen_muli_i32s(cpu_gpr_d[r2], cpu_gpr_d[r1], const9);
break;
case OPC2_32_RC_MUL_64:
+ CHECK_REG_PAIR(r2);
gen_muli_i64s(cpu_gpr_d[r2], cpu_gpr_d[r2+1], cpu_gpr_d[r1], const9);
break;
case OPC2_32_RC_MULS_32:
@@ -5673,6 +5708,7 @@ static void decode_rc_mul(CPUTriCoreState *env, DisasContext *ctx)
break;
case OPC2_32_RC_MUL_U_64:
const9 = MASK_OP_RC_CONST9(ctx->opcode);
+ CHECK_REG_PAIR(r2);
gen_muli_i64u(cpu_gpr_d[r2], cpu_gpr_d[r2+1], cpu_gpr_d[r1], const9);
break;
case OPC2_32_RC_MULS_U_32:
@@ -5702,6 +5738,7 @@ static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx)
switch (op2) {
case OPC2_32_RCPW_IMASK:
+ CHECK_REG_PAIR(r2);
/* if pos + width > 31 undefined result */
if (pos + width <= 31) {
tcg_gen_movi_tl(cpu_gpr_d[r2+1], ((1u << width) - 1) << pos);
@@ -5830,6 +5867,8 @@ static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx)
gen_maddi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
break;
case OPC2_32_RCR_MADD_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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;
@@ -5837,10 +5876,14 @@ static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx)
gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
break;
case OPC2_32_RCR_MADDS_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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);
@@ -5850,6 +5893,8 @@ static void decode_rcr_madd(CPUTriCoreState *env, DisasContext *ctx)
gen_maddsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
break;
case OPC2_32_RCR_MADDS_U_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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);
@@ -5877,6 +5922,8 @@ static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx)
gen_msubi32_d(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
break;
case OPC2_32_RCR_MSUB_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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;
@@ -5884,10 +5931,14 @@ static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx)
gen_msubsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
break;
case OPC2_32_RCR_MSUBS_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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);
@@ -5897,6 +5948,8 @@ static void decode_rcr_msub(CPUTriCoreState *env, DisasContext *ctx)
gen_msubsui_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9);
break;
case OPC2_32_RCR_MSUBS_U_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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);
@@ -5937,9 +5990,7 @@ static void decode_rlc_opc(CPUTriCoreState *env, DisasContext *ctx,
break;
case OPC1_32_RLC_MOV_64:
if (tricore_feature(env, TRICORE_FEATURE_16)) {
- if ((r2 & 0x1) != 0) {
- /* TODO: raise OPD trap */
- }
+ CHECK_REG_PAIR(r2);
tcg_gen_movi_tl(cpu_gpr_d[r2], const16);
tcg_gen_movi_tl(cpu_gpr_d[r2+1], const16 >> 15);
} else {
@@ -6476,9 +6527,11 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
gen_helper_bmerge(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
case OPC2_32_RR_BSPLIT:
+ CHECK_REG_PAIR(r3);
gen_bsplit(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
break;
case OPC2_32_RR_DVINIT_B:
+ CHECK_REG_PAIR(r3);
gen_dvinit_b(env, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
cpu_gpr_d[r2]);
break;
@@ -6486,7 +6539,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
temp = tcg_temp_new();
temp2 = tcg_temp_new();
temp3 = tcg_temp_new();
-
+ CHECK_REG_PAIR(r3);
tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 8);
/* reset av */
tcg_gen_movi_tl(cpu_PSW_AV, 0);
@@ -6516,6 +6569,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
tcg_temp_free(temp3);
break;
case OPC2_32_RR_DVINIT_H:
+ CHECK_REG_PAIR(r3);
gen_dvinit_h(env, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
cpu_gpr_d[r2]);
break;
@@ -6523,7 +6577,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
temp = tcg_temp_new();
temp2 = tcg_temp_new();
temp3 = tcg_temp_new();
-
+ CHECK_REG_PAIR(r3);
tcg_gen_shri_tl(temp3, cpu_gpr_d[r1], 16);
/* reset av */
tcg_gen_movi_tl(cpu_PSW_AV, 0);
@@ -6554,6 +6608,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
case OPC2_32_RR_DVINIT:
temp = tcg_temp_new();
temp2 = tcg_temp_new();
+ CHECK_REG_PAIR(r3);
/* overflow = ((D[b] == 0) ||
((D[b] == 0xFFFFFFFF) && (D[a] == 0x80000000))) */
tcg_gen_setcondi_tl(TCG_COND_EQ, temp, cpu_gpr_d[r2], 0xffffffff);
@@ -6590,6 +6645,7 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
gen_helper_parity(cpu_gpr_d[r3], cpu_gpr_d[r1]);
break;
case OPC2_32_RR_UNPACK:
+ CHECK_REG_PAIR(r3);
gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]);
break;
case OPC2_32_RR_CRC32:
@@ -6638,6 +6694,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
switch (op2) {
case OPC2_32_RR1_MUL_H_32_LL:
temp64 = tcg_temp_new_i64();
+ CHECK_REG_PAIR(r3);
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]);
@@ -6645,6 +6702,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
break;
case OPC2_32_RR1_MUL_H_32_LU:
temp64 = tcg_temp_new_i64();
+ CHECK_REG_PAIR(r3);
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]);
@@ -6652,6 +6710,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
break;
case OPC2_32_RR1_MUL_H_32_UL:
temp64 = tcg_temp_new_i64();
+ CHECK_REG_PAIR(r3);
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]);
@@ -6659,6 +6718,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
break;
case OPC2_32_RR1_MUL_H_32_UU:
temp64 = tcg_temp_new_i64();
+ CHECK_REG_PAIR(r3);
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]);
@@ -6666,6 +6726,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
break;
case OPC2_32_RR1_MULM_H_64_LL:
temp64 = tcg_temp_new_i64();
+ CHECK_REG_PAIR(r3);
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 */
@@ -6676,6 +6737,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
break;
case OPC2_32_RR1_MULM_H_64_LU:
temp64 = tcg_temp_new_i64();
+ CHECK_REG_PAIR(r3);
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 */
@@ -6686,6 +6748,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
break;
case OPC2_32_RR1_MULM_H_64_UL:
temp64 = tcg_temp_new_i64();
+ CHECK_REG_PAIR(r3);
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 */
@@ -6696,6 +6759,7 @@ static void decode_rr1_mul(CPUTriCoreState *env, DisasContext *ctx)
break;
case OPC2_32_RR1_MULM_H_64_UU:
temp64 = tcg_temp_new_i64();
+ CHECK_REG_PAIR(r3);
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 */
@@ -6749,6 +6813,7 @@ static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx)
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:
+ CHECK_REG_PAIR(r3);
gen_mul_q(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2],
n, 0);
break;
@@ -6757,6 +6822,7 @@ static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx)
gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], temp, n, 16);
break;
case OPC2_32_RR1_MUL_Q_64_L:
+ CHECK_REG_PAIR(r3);
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;
@@ -6765,6 +6831,7 @@ static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx)
gen_mul_q(cpu_gpr_d[r3], temp, cpu_gpr_d[r1], temp, n, 16);
break;
case OPC2_32_RR1_MUL_Q_64_U:
+ CHECK_REG_PAIR(r3);
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;
@@ -6810,6 +6877,7 @@ static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx)
gen_mul_i32s(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
break;
case OPC2_32_RR2_MUL_64:
+ CHECK_REG_PAIR(r3);
gen_mul_i64s(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
cpu_gpr_d[r2]);
break;
@@ -6818,6 +6886,7 @@ static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r2]);
break;
case OPC2_32_RR2_MUL_U_64:
+ CHECK_REG_PAIR(r3);
gen_mul_i64u(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
cpu_gpr_d[r2]);
break;
@@ -6867,6 +6936,7 @@ static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
}
break;
case OPC2_32_RRPW_IMASK:
+ CHECK_REG_PAIR(r3);
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);
@@ -6942,32 +7012,41 @@ static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx)
r3 = MASK_OP_RRR_S3(ctx->opcode);
r4 = MASK_OP_RRR_D(ctx->opcode);
+ CHECK_REG_PAIR(r3);
+
switch (op2) {
case OPC2_32_RRR_DVADJ:
+ CHECK_REG_PAIR(r4);
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:
+ CHECK_REG_PAIR(r4);
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:
+ CHECK_REG_PAIR(r4);
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:
+ CHECK_REG_PAIR(r4);
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:
+ CHECK_REG_PAIR(r4);
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:
+ CHECK_REG_PAIR(r4);
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:
+ CHECK_REG_PAIR(r4);
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;
@@ -6997,6 +7076,8 @@ static void decode_rrr2_madd(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r2]);
break;
case OPC2_32_RRR2_MADD_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madd64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
@@ -7005,10 +7086,14 @@ static void decode_rrr2_madd(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r3], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR2_MADDS_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madds_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR2_MADD_U_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddu64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
@@ -7017,6 +7102,8 @@ static void decode_rrr2_madd(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r3], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR2_MADDS_U_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsu_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
@@ -7042,6 +7129,8 @@ static void decode_rrr2_msub(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r2]);
break;
case OPC2_32_RRR2_MSUB_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msub64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
@@ -7050,6 +7139,8 @@ static void decode_rrr2_msub(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r3], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR2_MSUBS_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubs_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
@@ -7062,6 +7153,8 @@ static void decode_rrr2_msub(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r3], cpu_gpr_d[r2]);
break;
case OPC2_32_RRR2_MSUBS_U_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubsu_64(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1],
cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]);
break;
@@ -7085,66 +7178,98 @@ static void decode_rrr1_madd(CPUTriCoreState *env, DisasContext *ctx)
switch (op2) {
case OPC2_32_RRR1_MADD_H_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madd_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_MADD_H_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madd_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_MADD_H_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madd_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_MADD_H_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madd_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_MADDS_H_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madds_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_MADDS_H_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madds_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_MADDS_H_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madds_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_MADDS_H_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madds_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_MADDM_H_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddm_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_MADDM_H_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddm_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_MADDM_H_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddm_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_MADDM_H_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddm_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_MADDMS_H_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddms_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_MADDMS_H_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddms_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_MADDMS_H_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddms_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_MADDMS_H_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddms_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;
@@ -7207,6 +7332,8 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r2], n, 32, env);
break;
case OPC2_32_RRR1_MADD_Q_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madd64_q(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, env);
@@ -7217,6 +7344,8 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
temp, n, 16, env);
break;
case OPC2_32_RRR1_MADD_Q_64_L:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
@@ -7228,6 +7357,8 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
temp, n, 16, env);
break;
case OPC2_32_RRR1_MADD_Q_64_U:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
gen_madd64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
@@ -7239,6 +7370,8 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
gen_m16add32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
break;
case OPC2_32_RRR1_MADD_Q_64_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
gen_m16add64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
@@ -7250,6 +7383,8 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
gen_m16add32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
break;
case OPC2_32_RRR1_MADD_Q_64_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
gen_m16add64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
@@ -7260,6 +7395,8 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r2], n, 32);
break;
case OPC2_32_RRR1_MADDS_Q_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_madds64_q(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);
@@ -7270,6 +7407,8 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
temp, n, 16);
break;
case OPC2_32_RRR1_MADDS_Q_64_L:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
@@ -7281,6 +7420,8 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
temp, n, 16);
break;
case OPC2_32_RRR1_MADDS_Q_64_U:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
gen_madds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
@@ -7292,6 +7433,8 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
gen_m16adds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
break;
case OPC2_32_RRR1_MADDS_Q_64_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
gen_m16adds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
@@ -7303,16 +7446,20 @@ static void decode_rrr1_maddq_h(CPUTriCoreState *env, DisasContext *ctx)
gen_m16adds32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
break;
case OPC2_32_RRR1_MADDS_Q_64_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
gen_m16adds64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], temp, temp2, n);
break;
case OPC2_32_RRR1_MADDR_H_64_UL:
+ CHECK_REG_PAIR(r3);
gen_maddr64_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
break;
case OPC2_32_RRR1_MADDRS_H_64_UL:
+ CHECK_REG_PAIR(r3);
gen_maddr64s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
break;
@@ -7357,77 +7504,109 @@ static void decode_rrr1_maddsu_h(CPUTriCoreState *env, DisasContext *ctx)
switch (op2) {
case OPC2_32_RRR1_MADDSU_H_32_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsu_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_MADDSU_H_32_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsu_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_MADDSU_H_32_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsu_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_MADDSU_H_32_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsu_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_MADDSUS_H_32_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsus_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_MADDSUS_H_32_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsus_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_MADDSUS_H_32_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsus_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_MADDSUS_H_32_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsus_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_MADDSUM_H_64_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsum_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_MADDSUM_H_64_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsum_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_MADDSUM_H_64_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsum_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_MADDSUM_H_64_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsum_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_MADDSUMS_H_64_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsums_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_MADDSUMS_H_64_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsums_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_MADDSUMS_H_64_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsums_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_MADDSUMS_H_64_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_maddsums_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);
@@ -7483,66 +7662,98 @@ static void decode_rrr1_msub(CPUTriCoreState *env, DisasContext *ctx)
switch (op2) {
case OPC2_32_RRR1_MSUB_H_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
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;
@@ -7605,6 +7816,8 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r2], n, 32, env);
break;
case OPC2_32_RRR1_MSUB_Q_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msub64_q(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, env);
@@ -7615,6 +7828,8 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
temp, n, 16, env);
break;
case OPC2_32_RRR1_MSUB_Q_64_L:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
@@ -7626,6 +7841,8 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
temp, n, 16, env);
break;
case OPC2_32_RRR1_MSUB_Q_64_U:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
gen_msub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
@@ -7637,6 +7854,8 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
gen_m16sub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
break;
case OPC2_32_RRR1_MSUB_Q_64_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
gen_m16sub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
@@ -7648,6 +7867,8 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
gen_m16sub32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
break;
case OPC2_32_RRR1_MSUB_Q_64_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
gen_m16sub64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
@@ -7658,6 +7879,8 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
cpu_gpr_d[r2], n, 32);
break;
case OPC2_32_RRR1_MSUBS_Q_64:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubs64_q(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);
@@ -7668,6 +7891,8 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
temp, n, 16);
break;
case OPC2_32_RRR1_MSUBS_Q_64_L:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_ext16s_tl(temp, cpu_gpr_d[r2]);
gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
@@ -7679,6 +7904,8 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
temp, n, 16);
break;
case OPC2_32_RRR1_MSUBS_Q_64_U:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_sari_tl(temp, cpu_gpr_d[r2], 16);
gen_msubs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], cpu_gpr_d[r1], temp,
@@ -7690,6 +7917,8 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
gen_m16subs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
break;
case OPC2_32_RRR1_MSUBS_Q_64_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_ext16s_tl(temp, cpu_gpr_d[r1]);
tcg_gen_ext16s_tl(temp2, cpu_gpr_d[r2]);
gen_m16subs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
@@ -7701,16 +7930,20 @@ static void decode_rrr1_msubq_h(CPUTriCoreState *env, DisasContext *ctx)
gen_m16subs32_q(cpu_gpr_d[r4], cpu_gpr_d[r3], temp, temp2, n);
break;
case OPC2_32_RRR1_MSUBS_Q_64_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
tcg_gen_sari_tl(temp, cpu_gpr_d[r1], 16);
tcg_gen_sari_tl(temp2, cpu_gpr_d[r2], 16);
gen_m16subs64_q(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r3],
cpu_gpr_d[r3+1], temp, temp2, n);
break;
case OPC2_32_RRR1_MSUBR_H_64_UL:
+ CHECK_REG_PAIR(r3);
gen_msubr64_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
break;
case OPC2_32_RRR1_MSUBRS_H_64_UL:
+ CHECK_REG_PAIR(r3);
gen_msubr64s_h(cpu_gpr_d[r4], cpu_gpr_d[r3], cpu_gpr_d[r3+1],
cpu_gpr_d[r1], cpu_gpr_d[r2], n, 2);
break;
@@ -7755,77 +7988,109 @@ static void decode_rrr1_msubad_h(CPUTriCoreState *env, DisasContext *ctx)
switch (op2) {
case OPC2_32_RRR1_MSUBAD_H_32_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubad_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_MSUBAD_H_32_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubad_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_MSUBAD_H_32_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubad_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_MSUBAD_H_32_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubad_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_MSUBADS_H_32_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubads_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_MSUBADS_H_32_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubads_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_MSUBADS_H_32_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubads_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_MSUBADS_H_32_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubads_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_MSUBADM_H_64_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubadm_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_MSUBADM_H_64_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubadm_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_MSUBADM_H_64_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubadm_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_MSUBADM_H_64_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubadm_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_MSUBADMS_H_64_LL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubadms_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_MSUBADMS_H_64_LU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubadms_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_MSUBADMS_H_64_UL:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubadms_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_MSUBADMS_H_64_UU:
+ CHECK_REG_PAIR(r4);
+ CHECK_REG_PAIR(r3);
gen_msubadms_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);
@@ -7897,6 +8162,7 @@ static void decode_rrrr_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
break;
case OPC2_32_RRRR_EXTR:
case OPC2_32_RRRR_EXTR_U:
+ CHECK_REG_PAIR(r3);
tcg_gen_andi_tl(tmp_width, cpu_gpr_d[r3+1], 0x1f);
tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
tcg_gen_add_tl(tmp_pos, tmp_pos, tmp_width);
@@ -7910,6 +8176,7 @@ static void decode_rrrr_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
}
break;
case OPC2_32_RRRR_INSERT:
+ CHECK_REG_PAIR(r3);
tcg_gen_andi_tl(tmp_width, cpu_gpr_d[r3+1], 0x1f);
tcg_gen_andi_tl(tmp_pos, cpu_gpr_d[r3], 0x1f);
gen_insert(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r2], tmp_width,
@@ -8268,6 +8535,8 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
temp2 = tcg_temp_new(); /* width*/
temp3 = tcg_temp_new(); /* pos */
+ CHECK_REG_PAIR(r3);
+
tcg_gen_andi_tl(temp2, cpu_gpr_d[r3+1], 0x1f);
tcg_gen_andi_tl(temp3, cpu_gpr_d[r3], 0x1f);
--
2.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/4] target-tricore: Add trap handling
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 1/4] target-tricore: Add trap handling Bastian Koppelmann
@ 2016-02-15 20:52 ` Richard Henderson
0 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2016-02-15 20:52 UTC (permalink / raw)
To: Bastian Koppelmann, qemu-devel
On 02/16/2016 12:10 AM, Bastian Koppelmann wrote:
> +
> +void tricore_cpu_do_interrupt(CPUState *cs)
> +{
> + TriCoreCPU *cpu = TRICORE_CPU(cs);
> + CPUTriCoreState *env = &cpu->env;
> +
> + if (cs->exception_index <= TRAPC_NMI) {
> + /* The trap vector table is accessed to fetch the first instruction of
> + the trap handler. */
> + env->PC = env->BTV | (cs->exception_index << 5);
> + } else if (cs->exception_index == TRAPC_IRQ) {
> + /* The interrupt vector table is accessed to fetch the first instruction
> + of the interrupt handler. */
> + env->PC = env->BIV | ((env->ICR & MASK_ICR_PIPN) >> 10);
> + }
> +}
You've still got a path whereby you modify PC without saving the old one.
I don't think you want to add the do_interrupt hook at all until you're ready
to do real async interrupts.
> + /* PCXI.PCPN = ICR.CCPN */
> + env->PCXI = (env->PCXI & 0xffffff) +
> + ((env->ICR & MASK_ICR_CCPN) << 24);
> + cs->exception_index = class;
> + cpu_loop_exit(cs);
> +}
> +
There's no reason you can't modify PC here at the end of
raise_exception_sync_internal. If you omit the set of exception_index here,
you'll simply exit the cpu loop and immediately re-enter it at the new PC,
without having to go through the do_interrupt hook.
r~
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/4] TriCore exception patches
2016-02-15 13:10 [Qemu-devel] [PATCH v2 0/4] TriCore exception patches Bastian Koppelmann
` (3 preceding siblings ...)
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 4/4] target-tricore: add opd " Bastian Koppelmann
@ 2016-02-15 20:52 ` Richard Henderson
4 siblings, 0 replies; 7+ messages in thread
From: Richard Henderson @ 2016-02-15 20:52 UTC (permalink / raw)
To: Bastian Koppelmann, qemu-devel
On 02/16/2016 12:10 AM, Bastian Koppelmann wrote:
> Bastian Koppelmann (4):
> target-tricore: Add trap handling
> target-tricore: add context managment trap generation
> target-tricore: add illegal opcode trap generation
> target-tricore: add opd trap generation
Comments on patch 1. Patches 2-4:
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-02-15 20:53 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-15 13:10 [Qemu-devel] [PATCH v2 0/4] TriCore exception patches Bastian Koppelmann
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 1/4] target-tricore: Add trap handling Bastian Koppelmann
2016-02-15 20:52 ` Richard Henderson
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 2/4] target-tricore: add context managment trap generation Bastian Koppelmann
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 3/4] target-tricore: add illegal opcode " Bastian Koppelmann
2016-02-15 13:10 ` [Qemu-devel] [PATCH v2 4/4] target-tricore: add opd " Bastian Koppelmann
2016-02-15 20:52 ` [Qemu-devel] [PATCH v2 0/4] TriCore exception patches Richard Henderson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.