diff options
Diffstat (limited to 'qemu/target-tricore')
-rw-r--r-- | qemu/target-tricore/Makefile.objs | 2 | ||||
-rw-r--r-- | qemu/target-tricore/cpu.c | 8 | ||||
-rw-r--r-- | qemu/target-tricore/cpu.h | 12 | ||||
-rw-r--r-- | qemu/target-tricore/fpu_helper.c | 217 | ||||
-rw-r--r-- | qemu/target-tricore/helper.c | 31 | ||||
-rw-r--r-- | qemu/target-tricore/helper.h | 10 | ||||
-rw-r--r-- | qemu/target-tricore/op_helper.c | 161 | ||||
-rw-r--r-- | qemu/target-tricore/translate.c | 632 | ||||
-rw-r--r-- | qemu/target-tricore/tricore-opcodes.h | 18 |
9 files changed, 972 insertions, 119 deletions
diff --git a/qemu/target-tricore/Makefile.objs b/qemu/target-tricore/Makefile.objs index 21e820d8f..7a0567071 100644 --- a/qemu/target-tricore/Makefile.objs +++ b/qemu/target-tricore/Makefile.objs @@ -1 +1 @@ -obj-y += translate.o helper.o cpu.o op_helper.o +obj-y += translate.o helper.o cpu.o op_helper.o fpu_helper.o diff --git a/qemu/target-tricore/cpu.c b/qemu/target-tricore/cpu.c index 2029ef651..69fca8c06 100644 --- a/qemu/target-tricore/cpu.c +++ b/qemu/target-tricore/cpu.c @@ -17,6 +17,8 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" @@ -170,6 +172,12 @@ static void tricore_cpu_class_init(ObjectClass *c, void *data) cc->set_pc = tricore_cpu_set_pc; cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb; + /* + * Reason: tricore_cpu_initfn() calls cpu_exec_init(), which saves + * the object in cpus -> dangling pointer after final + * object_unref(). + */ + dc->cannot_destroy_with_object_finalize_yet = true; } static void cpu_register(const TriCoreCPUInfo *info) diff --git a/qemu/target-tricore/cpu.h b/qemu/target-tricore/cpu.h index 916ee27ad..90045a93d 100644 --- a/qemu/target-tricore/cpu.h +++ b/qemu/target-tricore/cpu.h @@ -20,13 +20,10 @@ #define __TRICORE_CPU_H__ #include "tricore-defs.h" -#include "config.h" #include "qemu-common.h" #include "exec/cpu-defs.h" #include "fpu/softfloat.h" -#define ELF_MACHINE EM_TRICORE - #define CPUArchState struct CPUTriCoreState struct CPUTriCoreState; @@ -186,8 +183,7 @@ struct CPUTriCoreState { uint32_t M2CNT; uint32_t M3CNT; /* Floating Point Registers */ - /* XXX: */ - + float_status fp_status; /* QEMU */ int error_code; uint32_t hflags; /* CPU State */ @@ -220,6 +216,7 @@ struct CPUTriCoreState { #define MASK_PSW_GW 0x00000100 #define MASK_PSW_CDE 0x00000080 #define MASK_PSW_CDC 0x0000007f +#define MASK_PSW_FPU_RM 0x3000000 #define MASK_SYSCON_PRO_TEN 0x2 #define MASK_SYSCON_FCD_SF 0x1 @@ -273,6 +270,7 @@ enum { TRAPC_ASSERT = 5, TRAPC_SYSCALL = 6, TRAPC_NMI = 7, + TRAPC_IRQ = 8 }; /* Class 0 TIN */ @@ -341,6 +339,8 @@ enum { uint32_t psw_read(CPUTriCoreState *env); void psw_write(CPUTriCoreState *env, uint32_t val); +void fpu_set_state(CPUTriCoreState *env); + #include "cpu-qom.h" #define MMU_USER_IDX 2 @@ -350,7 +350,7 @@ void tricore_cpu_list(FILE *f, fprintf_function cpu_fprintf); #define cpu_signal_handler cpu_tricore_signal_handler #define cpu_list tricore_cpu_list -static inline int cpu_mmu_index(CPUTriCoreState *env) +static inline int cpu_mmu_index(CPUTriCoreState *env, bool ifetch) { return 0; } diff --git a/qemu/target-tricore/fpu_helper.c b/qemu/target-tricore/fpu_helper.c new file mode 100644 index 000000000..98fe9472b --- /dev/null +++ b/qemu/target-tricore/fpu_helper.c @@ -0,0 +1,217 @@ +/* + * TriCore emulation for qemu: fpu helper. + * + * Copyright (c) 2016 Bastian Koppelmann University of Paderborn + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" + +#define ADD_NAN 0x7cf00001 +#define DIV_NAN 0x7fc00008 +#define MUL_NAN 0x7fc00002 +#define FPU_FS PSW_USB_C +#define FPU_FI PSW_USB_V +#define FPU_FV PSW_USB_SV +#define FPU_FZ PSW_USB_AV +#define FPU_FU PSW_USB_SAV + +/* we don't care about input_denormal */ +static inline uint8_t f_get_excp_flags(CPUTriCoreState *env) +{ + return get_float_exception_flags(&env->fp_status) + & (float_flag_invalid + | float_flag_overflow + | float_flag_underflow + | float_flag_output_denormal + | float_flag_divbyzero + | float_flag_inexact); +} + +static inline bool f_is_denormal(float32 arg) +{ + return float32_is_zero_or_denormal(arg) && !float32_is_zero(arg); +} + +static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags) +{ + uint8_t some_excp = 0; + set_float_exception_flags(0, &env->fp_status); + + if (flags & float_flag_invalid) { + env->FPU_FI = 1 << 31; + some_excp = 1; + } + + if (flags & float_flag_overflow) { + env->FPU_FV = 1 << 31; + some_excp = 1; + } + + if (flags & float_flag_underflow || flags & float_flag_output_denormal) { + env->FPU_FU = 1 << 31; + some_excp = 1; + } + + if (flags & float_flag_divbyzero) { + env->FPU_FZ = 1 << 31; + some_excp = 1; + } + + if (flags & float_flag_inexact || flags & float_flag_output_denormal) { + env->PSW |= 1 << 26; + some_excp = 1; + } + + env->FPU_FS = some_excp; +} + +#define FADD_SUB(op) \ +uint32_t helper_f##op(CPUTriCoreState *env, uint32_t r1, uint32_t r2) \ +{ \ + float32 arg1 = make_float32(r1); \ + float32 arg2 = make_float32(r2); \ + uint32_t flags; \ + float32 f_result; \ + \ + f_result = float32_##op(arg2, arg1, &env->fp_status); \ + flags = f_get_excp_flags(env); \ + if (flags) { \ + /* If the output is a NaN, but the inputs aren't, \ + we return a unique value. */ \ + if ((flags & float_flag_invalid) \ + && !float32_is_any_nan(arg1) \ + && !float32_is_any_nan(arg2)) { \ + f_result = ADD_NAN; \ + } \ + f_update_psw_flags(env, flags); \ + } else { \ + env->FPU_FS = 0; \ + } \ + return (uint32_t)f_result; \ +} +FADD_SUB(add) +FADD_SUB(sub) + +uint32_t helper_fmul(CPUTriCoreState *env, uint32_t r1, uint32_t r2) +{ + uint32_t flags; + float32 arg1 = make_float32(r1); + float32 arg2 = make_float32(r2); + float32 f_result; + + f_result = float32_mul(arg1, arg2, &env->fp_status); + + flags = f_get_excp_flags(env); + if (flags) { + /* If the output is a NaN, but the inputs aren't, + we return a unique value. */ + if ((flags & float_flag_invalid) + && !float32_is_any_nan(arg1) + && !float32_is_any_nan(arg2)) { + f_result = MUL_NAN; + } + f_update_psw_flags(env, flags); + } else { + env->FPU_FS = 0; + } + return (uint32_t)f_result; + +} + +uint32_t helper_fdiv(CPUTriCoreState *env, uint32_t r1, uint32_t r2) +{ + uint32_t flags; + float32 arg1 = make_float32(r1); + float32 arg2 = make_float32(r2); + float32 f_result; + + f_result = float32_div(arg1, arg2 , &env->fp_status); + + flags = f_get_excp_flags(env); + if (flags) { + /* If the output is a NaN, but the inputs aren't, + we return a unique value. */ + if ((flags & float_flag_invalid) + && !float32_is_any_nan(arg1) + && !float32_is_any_nan(arg2)) { + f_result = DIV_NAN; + } + f_update_psw_flags(env, flags); + } else { + env->FPU_FS = 0; + } + + return (uint32_t)f_result; +} + +uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, uint32_t r2) +{ + uint32_t result, flags; + float32 arg1 = make_float32(r1); + float32 arg2 = make_float32(r2); + + set_flush_inputs_to_zero(0, &env->fp_status); + + result = 1 << (float32_compare_quiet(arg1, arg2, &env->fp_status) + 1); + result |= f_is_denormal(arg1) << 4; + result |= f_is_denormal(arg2) << 5; + + flags = f_get_excp_flags(env); + if (flags) { + f_update_psw_flags(env, flags); + } else { + env->FPU_FS = 0; + } + + set_flush_inputs_to_zero(1, &env->fp_status); + return result; +} + +uint32_t helper_ftoi(CPUTriCoreState *env, uint32_t arg) +{ + float32 f_arg = make_float32(arg); + int32_t result, flags; + + result = float32_to_int32(f_arg, &env->fp_status); + + flags = f_get_excp_flags(env); + if (flags) { + if (float32_is_any_nan(f_arg)) { + result = 0; + } + f_update_psw_flags(env, flags); + } else { + env->FPU_FS = 0; + } + return (uint32_t)result; +} + +uint32_t helper_itof(CPUTriCoreState *env, uint32_t arg) +{ + float32 f_result; + uint32_t flags; + f_result = int32_to_float32(arg, &env->fp_status); + + flags = f_get_excp_flags(env); + if (flags) { + f_update_psw_flags(env, flags); + } else { + env->FPU_FS = 0; + } + return (uint32_t)f_result; +} diff --git a/qemu/target-tricore/helper.c b/qemu/target-tricore/helper.c index f52504c9f..71b31cdb9 100644 --- a/qemu/target-tricore/helper.c +++ b/qemu/target-tricore/helper.c @@ -15,12 +15,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <inttypes.h> -#include <signal.h> +#include "qemu/osdep.h" #include "cpu.h" @@ -66,8 +61,8 @@ int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong address, access_type = ACCESS_INT; ret = get_physical_address(env, &physical, &prot, address, rw, access_type); - qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx - " prot %d\n", __func__, address, ret, physical, prot); + qemu_log_mask(CPU_LOG_MMU, "%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx + " prot %d\n", __func__, address, ret, physical, prot); if (ret == TLBRET_MATCH) { tlb_set_page(cs, address & TARGET_PAGE_MASK, @@ -115,10 +110,18 @@ void tricore_cpu_list(FILE *f, fprintf_function cpu_fprintf) g_slist_free(list); } +void fpu_set_state(CPUTriCoreState *env) +{ + set_float_rounding_mode(env->PSW & MASK_PSW_FPU_RM, &env->fp_status); + set_flush_inputs_to_zero(1, &env->fp_status); + set_flush_to_zero(1, &env->fp_status); + set_default_nan_mode(1, &env->fp_status); +} + uint32_t psw_read(CPUTriCoreState *env) { /* clear all USB bits */ - env->PSW &= 0xffffff; + env->PSW &= 0x6ffffff; /* now set them from the cache */ env->PSW |= ((env->PSW_USB_C != 0) << 31); env->PSW |= ((env->PSW_USB_V & (1 << 31)) >> 1); @@ -132,9 +135,11 @@ uint32_t psw_read(CPUTriCoreState *env) void psw_write(CPUTriCoreState *env, uint32_t val) { env->PSW_USB_C = (val & MASK_USB_C); - env->PSW_USB_V = (val & MASK_USB_V << 1); - env->PSW_USB_SV = (val & MASK_USB_SV << 2); - env->PSW_USB_AV = ((val & MASK_USB_AV) << 3); - env->PSW_USB_SAV = ((val & MASK_USB_SAV) << 4); + env->PSW_USB_V = (val & MASK_USB_V) << 1; + env->PSW_USB_SV = (val & MASK_USB_SV) << 2; + env->PSW_USB_AV = (val & MASK_USB_AV) << 3; + env->PSW_USB_SAV = (val & MASK_USB_SAV) << 4; env->PSW = val; + + fpu_set_state(env); } diff --git a/qemu/target-tricore/helper.h b/qemu/target-tricore/helper.h index cc221f1a9..9333e161a 100644 --- a/qemu/target-tricore/helper.h +++ b/qemu/target-tricore/helper.h @@ -105,6 +105,13 @@ DEF_HELPER_FLAGS_1(parity, TCG_CALL_NO_RWG_SE, i32, i32) /* float */ DEF_HELPER_FLAGS_4(pack, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32) DEF_HELPER_1(unpack, i64, i32) +DEF_HELPER_3(fadd, i32, env, i32, i32) +DEF_HELPER_3(fsub, i32, env, i32, i32) +DEF_HELPER_3(fmul, i32, env, i32, i32) +DEF_HELPER_3(fdiv, i32, env, i32, i32) +DEF_HELPER_3(fcmp, i32, env, i32, i32) +DEF_HELPER_2(ftoi, i32, env, i32) +DEF_HELPER_2(itof, i32, env, i32) /* dvinit */ DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32) DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32) @@ -132,6 +139,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 +147,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/qemu/target-tricore/op_helper.c b/qemu/target-tricore/op_helper.c index 53edbdae1..40656c357 100644 --- a/qemu/target-tricore/op_helper.c +++ b/qemu/target-tricore/op_helper.c @@ -14,13 +14,100 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#include <stdlib.h> +#include "qemu/osdep.h" #include "cpu.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" #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, uint32_t fcd_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 run out of CSAs after saving a context a FCD trap is taken + and the return address is the start of the trap handler which used + the last CSA */ + env->gpr_a[11] = fcd_pc; + } 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); + /* Update PC using the trap vector table */ + env->PC = env->BTV | (class << 5); + + 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, 0); +} + +static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class, + uint32_t tin, uintptr_t pc) +{ + raise_exception_sync_internal(env, class, tin, pc, 0); +} + /* Addressing mode helper */ static uint16_t reverse16(uint16_t val) @@ -958,6 +1045,8 @@ uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, } else { result = INT64_MIN; } + } else { + env->PSW_USB_V = 0; } } else { if (ovf < 0) { @@ -2279,7 +2368,7 @@ static bool cdc_zero(target_ulong *psw) static void save_context_upper(CPUTriCoreState *env, int ea) { cpu_stl_data(env, ea, env->PCXI); - cpu_stl_data(env, ea+4, env->PSW); + cpu_stl_data(env, ea+4, psw_read(env)); cpu_stl_data(env, ea+8, env->gpr_a[10]); cpu_stl_data(env, ea+12, env->gpr_a[11]); cpu_stl_data(env, ea+16, env->gpr_d[8]); @@ -2369,11 +2458,13 @@ void helper_call(CPUTriCoreState *env, uint32_t next_pc) /* if (FCX == 0) trap(FCU); */ if (env->FCX == 0) { /* FCU trap */ + raise_exception_sync_helper(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_helper(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC()); } } /* PSW.CDE = 1;*/ @@ -2409,6 +2500,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_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); } psw_write(env, psw); } @@ -2421,18 +2513,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_helper(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_helper(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_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC()); } /* PC = {A11 [31: 1], 1’b0}; */ env->PC = env->gpr_a[11] & 0xfffffffe; @@ -2467,6 +2566,7 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9) if (env->FCX == 0) { /* FCU trap */ + raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); } tmp_FCX = env->FCX; @@ -2498,6 +2598,7 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9) if (tmp_FCX == env->LCX) { /* FCD trap */ + raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); } } @@ -2509,14 +2610,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_helper(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_helper(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_helper(env, TRAPC_CTX_MNG, TIN3_NEST, GETPC()); } env->PC = env->gpr_a[11] & ~0x1; /* ICR.IE = PCXI.PIE; */ @@ -2592,6 +2696,7 @@ void helper_svlcx(CPUTriCoreState *env) if (env->FCX == 0) { /* FCU trap */ + raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); } /* tmp_FCX = FCX; */ tmp_FCX = env->FCX; @@ -2622,6 +2727,50 @@ void helper_svlcx(CPUTriCoreState *env) /* if (tmp_FCX == LCX) trap(FCD);*/ if (tmp_FCX == env->LCX) { /* FCD trap */ + raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); + } +} + +void helper_svucx(CPUTriCoreState *env) +{ + target_ulong tmp_FCX; + target_ulong ea; + target_ulong new_FCX; + + if (env->FCX == 0) { + /* FCU trap */ + raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); + } + /* 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 */ + raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); } } @@ -2632,10 +2781,12 @@ void helper_rslcx(CPUTriCoreState *env) /* if (PCXI[19: 0] == 0) then trap(CSU); */ if ((env->PCXI & 0xfffff) == 0) { /* CSU trap */ + raise_exception_sync_helper(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_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC()); } /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + diff --git a/qemu/target-tricore/translate.c b/qemu/target-tricore/translate.c index 7dc7a325b..912bf226b 100644 --- a/qemu/target-tricore/translate.c +++ b/qemu/target-tricore/translate.c @@ -18,6 +18,7 @@ */ +#include "qemu/osdep.h" #include "cpu.h" #include "disas/disas.h" #include "tcg-op.h" @@ -27,6 +28,7 @@ #include "exec/helper-gen.h" #include "tricore-opcodes.h" +#include "exec/log.h" /* * TCG registers @@ -45,7 +47,7 @@ static TCGv cpu_PSW_SV; static TCGv cpu_PSW_AV; static TCGv cpu_PSW_SAV; /* CPU env */ -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; #include "exec/gen-icount.h" @@ -214,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, @@ -299,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]) */ @@ -457,11 +469,11 @@ gen_add64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2) tcg_gen_xor_i64(t1, result, r1); tcg_gen_xor_i64(t0, r1, r2); tcg_gen_andc_i64(t1, t1, t0); - tcg_gen_trunc_shr_i64_i32(cpu_PSW_V, t1, 32); + tcg_gen_extrh_i64_i32(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_trunc_shr_i64_i32(temp, result, 32); + tcg_gen_extrh_i64_i32(temp, result); tcg_gen_add_tl(cpu_PSW_AV, temp, temp); tcg_gen_xor_tl(cpu_PSW_AV, temp, cpu_PSW_AV); /* calc SAV */ @@ -540,14 +552,14 @@ static inline void gen_madd32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3) tcg_gen_mul_i64(t1, t1, t3); tcg_gen_add_i64(t1, t2, t1); - tcg_gen_trunc_i64_i32(ret, t1); + tcg_gen_extrl_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_extrl_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); @@ -621,7 +633,7 @@ gen_maddu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high, /* 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_extrl_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); @@ -1110,12 +1122,12 @@ gen_madd32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n, tcg_gen_sari_i64(t2, t2, up_shift); tcg_gen_add_i64(t3, t1, t2); - tcg_gen_trunc_i64_i32(temp3, t3); + tcg_gen_extrl_i64_i32(temp3, t3); /* calc v bit */ tcg_gen_setcondi_i64(TCG_COND_GT, t1, t3, 0x7fffffffLL); tcg_gen_setcondi_i64(TCG_COND_LT, t2, t3, -0x80000000LL); tcg_gen_or_i64(t1, t1, t2); - tcg_gen_trunc_i64_i32(cpu_PSW_V, t1); + tcg_gen_extrl_i64_i32(cpu_PSW_V, t1); tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31); /* We produce an overflow on the host if the mul before was (0x80000000 * 0x80000000) << 1). If this is the @@ -1273,7 +1285,7 @@ gen_madd64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2, tcg_gen_xor_i64(t3, t4, t1); tcg_gen_xor_i64(t2, t1, t2); tcg_gen_andc_i64(t3, t3, t2); - tcg_gen_trunc_shr_i64_i32(cpu_PSW_V, t3, 32); + tcg_gen_extrh_i64_i32(cpu_PSW_V, t3); /* We produce an overflow on the host if the mul before was (0x80000000 * 0x80000000) << 1). If this is the case, we negate the ovf. */ @@ -1356,14 +1368,14 @@ static inline void gen_msub32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3) tcg_gen_mul_i64(t1, t1, t3); tcg_gen_sub_i64(t1, t2, t1); - tcg_gen_trunc_i64_i32(ret, t1); + tcg_gen_extrl_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_extrl_i64_i32(cpu_PSW_V, t2); tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31); /* Calc SV bit */ @@ -1445,7 +1457,7 @@ gen_msubu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high, 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_extrl_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); @@ -1630,11 +1642,11 @@ gen_sub64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2) tcg_gen_xor_i64(t1, result, r1); tcg_gen_xor_i64(t0, r1, r2); tcg_gen_and_i64(t1, t1, t0); - tcg_gen_trunc_shr_i64_i32(cpu_PSW_V, t1, 32); + tcg_gen_extrh_i64_i32(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_trunc_shr_i64_i32(temp, result, 32); + tcg_gen_extrh_i64_i32(temp, result); tcg_gen_add_tl(cpu_PSW_AV, temp, temp); tcg_gen_xor_tl(cpu_PSW_AV, temp, cpu_PSW_AV); /* calc SAV */ @@ -1973,12 +1985,12 @@ gen_msub32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n, tcg_gen_add_i64(t2, t2, t4); tcg_gen_sub_i64(t3, t1, t2); - tcg_gen_trunc_i64_i32(temp3, t3); + tcg_gen_extrl_i64_i32(temp3, t3); /* calc v bit */ tcg_gen_setcondi_i64(TCG_COND_GT, t1, t3, 0x7fffffffLL); tcg_gen_setcondi_i64(TCG_COND_LT, t2, t3, -0x80000000LL); tcg_gen_or_i64(t1, t1, t2); - tcg_gen_trunc_i64_i32(cpu_PSW_V, t1); + tcg_gen_extrl_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); @@ -2126,7 +2138,7 @@ gen_msub64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2, tcg_gen_xor_i64(t3, t4, t1); tcg_gen_xor_i64(t2, t1, t2); tcg_gen_and_i64(t3, t3, t2); - tcg_gen_trunc_shr_i64_i32(cpu_PSW_V, t3, 32); + tcg_gen_extrh_i64_i32(cpu_PSW_V, t3); /* We produce an overflow on the host if the mul before was (0x80000000 * 0x80000000) << 1). If this is the case, we negate the ovf. */ @@ -3242,6 +3254,19 @@ 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_save_pc(ctx->pc); + 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) { @@ -3540,7 +3565,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; } @@ -3615,7 +3640,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); @@ -3623,6 +3650,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); } } @@ -3706,6 +3735,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); } } @@ -3745,6 +3776,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); } } @@ -3782,6 +3815,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); } } @@ -3822,6 +3857,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); } } @@ -3859,6 +3896,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); } } @@ -3883,6 +3922,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); } } @@ -3925,6 +3967,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); } } @@ -4135,6 +4179,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); } } @@ -4161,14 +4207,18 @@ 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: 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); @@ -4200,6 +4250,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); @@ -4225,6 +4277,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); @@ -4251,6 +4305,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); } } @@ -4272,15 +4328,18 @@ 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: 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); } @@ -4305,6 +4364,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); } @@ -4347,6 +4408,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); } } @@ -4379,6 +4442,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); } } @@ -4436,6 +4501,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); } } @@ -4475,6 +4542,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); } } @@ -4511,6 +4580,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); @@ -4550,6 +4621,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); @@ -4594,20 +4667,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); @@ -4632,14 +4710,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); @@ -4647,14 +4728,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); @@ -4703,6 +4787,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); } } @@ -4722,7 +4808,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); @@ -4754,10 +4840,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); @@ -4767,10 +4855,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); @@ -4805,6 +4895,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); @@ -4859,14 +4951,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); @@ -4874,14 +4969,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); @@ -4935,6 +5033,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); } } @@ -4955,7 +5055,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); @@ -4986,10 +5086,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); @@ -4999,10 +5101,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); @@ -5045,6 +5149,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); @@ -5137,6 +5243,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); @@ -5159,7 +5267,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); @@ -5196,6 +5304,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); @@ -5233,7 +5343,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: @@ -5243,44 +5353,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); } } @@ -5346,6 +5458,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); } @@ -5544,6 +5658,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); } @@ -5563,6 +5679,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); } } @@ -5583,6 +5701,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: @@ -5590,12 +5709,15 @@ 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: 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); } } @@ -5617,6 +5739,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); @@ -5631,6 +5754,8 @@ static void decode_rcpw_insert(CPUTriCoreState *env, DisasContext *ctx) tcg_temp_free(temp); } break; + default: + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } } @@ -5672,6 +5797,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); @@ -5718,6 +5845,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); } } @@ -5739,6 +5868,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; @@ -5746,10 +5877,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); @@ -5759,10 +5894,14 @@ 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); break; + default: + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } } @@ -5784,6 +5923,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; @@ -5791,10 +5932,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); @@ -5804,10 +5949,14 @@ 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); break; + default: + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } } @@ -5842,13 +5991,11 @@ 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 { - /* TODO: raise illegal opcode trap */ + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; case OPC1_32_RLC_MOV_U: @@ -5865,6 +6012,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); } } @@ -6181,6 +6330,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); } } @@ -6255,6 +6406,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); } @@ -6322,6 +6475,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); } } @@ -6349,6 +6504,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; @@ -6371,9 +6528,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; @@ -6381,7 +6540,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); @@ -6411,6 +6570,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; @@ -6418,7 +6578,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); @@ -6449,6 +6609,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); @@ -6485,25 +6646,49 @@ 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: 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; + case OPC2_32_RR_MUL_F: + gen_helper_fmul(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]); break; + case OPC2_32_RR_DIV_F: + gen_helper_fdiv(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC2_32_RR_CMP_F: + gen_helper_fcmp(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]); + break; + case OPC2_32_RR_FTOI: + gen_helper_ftoi(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]); + break; + case OPC2_32_RR_ITOF: + gen_helper_itof(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]); + break; + default: + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } } @@ -6525,6 +6710,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]); @@ -6532,6 +6718,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]); @@ -6539,6 +6726,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]); @@ -6546,6 +6734,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]); @@ -6553,6 +6742,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 */ @@ -6563,6 +6753,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 */ @@ -6573,6 +6764,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 */ @@ -6583,6 +6775,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 */ @@ -6608,6 +6801,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); } @@ -6634,6 +6829,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; @@ -6642,6 +6838,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; @@ -6650,6 +6847,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; @@ -6673,6 +6871,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); @@ -6693,6 +6893,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; @@ -6701,6 +6902,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; @@ -6708,6 +6910,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); } } @@ -6748,6 +6952,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); @@ -6759,6 +6964,8 @@ static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx) width, pos); } break; + default: + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } } @@ -6804,6 +7011,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); } } @@ -6821,37 +7030,60 @@ static void decode_rrr_divide(CPUTriCoreState *env, DisasContext *ctx) switch (op2) { case OPC2_32_RRR_DVADJ: + CHECK_REG_PAIR(r3); + 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(r3); + 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(r3); + 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(r3); + 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(r3); + 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(r3); + 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(r3); + 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; case OPC2_32_RRR_PACK: + CHECK_REG_PAIR(r3); gen_helper_pack(cpu_gpr_d[r4], cpu_PSW_C, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]); break; + case OPC2_32_RRR_ADD_F: + gen_helper_fadd(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]); + break; + case OPC2_32_RRR_SUB_F: + gen_helper_fsub(cpu_gpr_d[r4], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r3]); + break; + default: + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } } @@ -6872,6 +7104,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; @@ -6880,10 +7114,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; @@ -6892,9 +7130,13 @@ 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; + default: + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } } @@ -6915,6 +7157,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; @@ -6923,6 +7167,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; @@ -6935,9 +7181,13 @@ 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; + default: + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } } @@ -6956,66 +7206,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; @@ -7051,6 +7333,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); } } @@ -7076,6 +7360,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); @@ -7086,6 +7372,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, @@ -7097,6 +7385,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, @@ -7108,6 +7398,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], @@ -7119,6 +7411,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], @@ -7129,6 +7423,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); @@ -7139,6 +7435,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, @@ -7150,6 +7448,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, @@ -7161,6 +7461,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], @@ -7172,16 +7474,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; @@ -7205,6 +7511,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); @@ -7224,77 +7532,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); @@ -7331,6 +7671,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); } } @@ -7348,66 +7690,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; @@ -7443,6 +7817,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); } } @@ -7468,6 +7844,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); @@ -7478,6 +7856,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, @@ -7489,6 +7869,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, @@ -7500,6 +7882,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], @@ -7511,6 +7895,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], @@ -7521,6 +7907,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); @@ -7531,6 +7919,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, @@ -7542,6 +7932,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, @@ -7553,6 +7945,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], @@ -7564,16 +7958,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; @@ -7597,6 +7995,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); @@ -7616,77 +8016,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); @@ -7723,6 +8155,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); } } @@ -7756,6 +8190,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); @@ -7769,11 +8204,14 @@ 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, tmp_pos); break; + default: + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } tcg_temp_free(tmp_pos); tcg_temp_free(tmp_width); @@ -7834,6 +8272,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); } @@ -7905,14 +8345,24 @@ 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 */ + l1 = gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_GE, cpu_PSW_SV, 0, l1); + generate_trap(ctx, TRAPC_ASSERT, TIN5_SOVF); + gen_set_label(l1); break; case OPC2_32_SYS_TRAPV: - /* TODO: raise overflow trap */ + l1 = gen_new_label(); + tcg_gen_brcondi_tl(TCG_COND_GE, cpu_PSW_V, 0, l1); + generate_trap(ctx, TRAPC_ASSERT, TIN5_OVF); + gen_set_label(l1); break; + default: + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } } @@ -8119,6 +8569,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); @@ -8207,6 +8659,7 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) break; case OPCM_32_RRR_DIVIDE: decode_rrr_divide(env, ctx); + break; /* RRR2 Format */ case OPCM_32_RRR2_MADD: decode_rrr2_madd(env, ctx); @@ -8236,6 +8689,7 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx) /* RRRR format */ case OPCM_32_RRRR_EXTRACT_INSERT: decode_rrrr_extract_insert(env, ctx); + break; /* RRRW format */ case OPCM_32_RRRW_EXTRACT_INSERT: decode_rrrw_extract_insert(env, ctx); @@ -8250,6 +8704,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); } } @@ -8266,43 +8722,44 @@ static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch) } } -static inline void -gen_intermediate_code_internal(TriCoreCPU *cpu, struct TranslationBlock *tb, - int search_pc) +void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb) { + TriCoreCPU *cpu = tricore_env_get_cpu(env); CPUState *cs = CPU(cpu); - CPUTriCoreState *env = &cpu->env; DisasContext ctx; target_ulong pc_start; - int num_insns; + int num_insns, max_insns; - if (search_pc) { - qemu_log("search pc %d\n", search_pc); + num_insns = 0; + max_insns = tb->cflags & CF_COUNT_MASK; + if (max_insns == 0) { + max_insns = CF_COUNT_MASK; + } + if (singlestep) { + max_insns = 1; + } + if (max_insns > TCG_MAX_INSNS) { + max_insns = TCG_MAX_INSNS; } - num_insns = 0; pc_start = tb->pc; ctx.pc = pc_start; ctx.saved_pc = -1; ctx.tb = tb; ctx.singlestep_enabled = cs->singlestep_enabled; ctx.bstate = BS_NONE; - ctx.mem_idx = cpu_mmu_index(env); + ctx.mem_idx = cpu_mmu_index(env, false); tcg_clear_temp_count(); gen_tb_start(tb); while (ctx.bstate == BS_NONE) { + tcg_gen_insn_start(ctx.pc); + num_insns++; + ctx.opcode = cpu_ldl_code(env, ctx.pc); decode_opc(env, &ctx, 0); - num_insns++; - - if (tcg_op_buf_full()) { - gen_save_pc(ctx.next_pc); - tcg_gen_exit_tb(0); - break; - } - if (singlestep) { + if (num_insns >= max_insns || tcg_op_buf_full()) { gen_save_pc(ctx.next_pc); tcg_gen_exit_tb(0); break; @@ -8311,12 +8768,9 @@ gen_intermediate_code_internal(TriCoreCPU *cpu, struct TranslationBlock *tb, } gen_tb_end(tb, num_insns); - if (search_pc) { - printf("done_generating search pc\n"); - } else { - tb->size = ctx.pc - pc_start; - tb->icount = num_insns; - } + tb->size = ctx.pc - pc_start; + tb->icount = num_insns; + if (tcg_check_temp_count()) { printf("LEAK at %08x\n", env->PC); } @@ -8331,21 +8785,10 @@ gen_intermediate_code_internal(TriCoreCPU *cpu, struct TranslationBlock *tb, } void -gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb) -{ - gen_intermediate_code_internal(tricore_env_get_cpu(env), tb, false); -} - -void -gen_intermediate_code_pc(CPUTriCoreState *env, struct TranslationBlock *tb) -{ - gen_intermediate_code_internal(tricore_env_get_cpu(env), tb, true); -} - -void -restore_state_to_opc(CPUTriCoreState *env, TranslationBlock *tb, int pc_pos) +restore_state_to_opc(CPUTriCoreState *env, TranslationBlock *tb, + target_ulong *data) { - env->PC = tcg_ctx.gen_opc_pc[pc_pos]; + env->PC = data[0]; } /* * @@ -8357,17 +8800,18 @@ void cpu_state_reset(CPUTriCoreState *env) { /* Reset Regs to Default Value */ env->PSW = 0xb80; + fpu_set_state(env); } static void tricore_tcg_init_csfr(void) { - cpu_PCXI = tcg_global_mem_new(TCG_AREG0, + cpu_PCXI = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, PCXI), "PCXI"); - cpu_PSW = tcg_global_mem_new(TCG_AREG0, + cpu_PSW = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, PSW), "PSW"); - cpu_PC = tcg_global_mem_new(TCG_AREG0, + cpu_PC = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, PC), "PC"); - cpu_ICR = tcg_global_mem_new(TCG_AREG0, + cpu_ICR = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, ICR), "ICR"); } @@ -8381,30 +8825,30 @@ void tricore_tcg_init(void) cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); /* reg init */ for (i = 0 ; i < 16 ; i++) { - cpu_gpr_a[i] = tcg_global_mem_new(TCG_AREG0, + cpu_gpr_a[i] = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, gpr_a[i]), regnames_a[i]); } for (i = 0 ; i < 16 ; i++) { - cpu_gpr_d[i] = tcg_global_mem_new(TCG_AREG0, + cpu_gpr_d[i] = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, gpr_d[i]), regnames_d[i]); } tricore_tcg_init_csfr(); /* init PSW flag cache */ - cpu_PSW_C = tcg_global_mem_new(TCG_AREG0, + cpu_PSW_C = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, PSW_USB_C), "PSW_C"); - cpu_PSW_V = tcg_global_mem_new(TCG_AREG0, + cpu_PSW_V = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, PSW_USB_V), "PSW_V"); - cpu_PSW_SV = tcg_global_mem_new(TCG_AREG0, + cpu_PSW_SV = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, PSW_USB_SV), "PSW_SV"); - cpu_PSW_AV = tcg_global_mem_new(TCG_AREG0, + cpu_PSW_AV = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, PSW_USB_AV), "PSW_AV"); - cpu_PSW_SAV = tcg_global_mem_new(TCG_AREG0, + cpu_PSW_SAV = tcg_global_mem_new(cpu_env, offsetof(CPUTriCoreState, PSW_USB_SAV), "PSW_SAV"); } diff --git a/qemu/target-tricore/tricore-opcodes.h b/qemu/target-tricore/tricore-opcodes.h index 1bfed0ce4..df666b081 100644 --- a/qemu/target-tricore/tricore-opcodes.h +++ b/qemu/target-tricore/tricore-opcodes.h @@ -1126,6 +1126,20 @@ enum { OPC2_32_RR_CRC32 = 0x03, OPC2_32_RR_DIV = 0x20, OPC2_32_RR_DIV_U = 0x21, + OPC2_32_RR_MUL_F = 0x04, + OPC2_32_RR_DIV_F = 0x05, + OPC2_32_RR_FTOI = 0x10, + OPC2_32_RR_ITOF = 0x14, + OPC2_32_RR_CMP_F = 0x00, + OPC2_32_RR_FTOIZ = 0x13, + OPC2_32_RR_FTOQ31 = 0x11, + OPC2_32_RR_FTOQ31Z = 0x18, + OPC2_32_RR_FTOU = 0x12, + OPC2_32_RR_FTOUZ = 0x17, + OPC2_32_RR_Q31TOF = 0x15, + OPC2_32_RR_QSEED_F = 0x19, + OPC2_32_RR_UPDFL = 0x0c, + OPC2_32_RR_UTOF = 0x16, }; /* OPCM_32_RR_IDIRECT */ enum { @@ -1209,6 +1223,10 @@ enum { OPC2_32_RRR_IXMIN = 0x08, OPC2_32_RRR_IXMIN_U = 0x09, OPC2_32_RRR_PACK = 0x00, + OPC2_32_RRR_ADD_F = 0x02, + OPC2_32_RRR_SUB_F = 0x03, + OPC2_32_RRR_MADD_F = 0x06, + OPC2_32_RRR_MSUB_F = 0x07, }; /* * RRR1 Format |