diff options
-rw-r--r-- | .mailmap | 7 | ||||
-rw-r--r-- | MAINTAINERS | 9 | ||||
-rw-r--r-- | include/elf.h | 24 | ||||
-rw-r--r-- | linux-user/mips/syscall_nr.h | 9 | ||||
-rw-r--r-- | linux-user/mips64/syscall_nr.h | 18 | ||||
-rw-r--r-- | linux-user/strace.c | 14 | ||||
-rw-r--r-- | linux-user/syscall.c | 29 | ||||
-rw-r--r-- | qemu-doc.texi | 13 | ||||
-rw-r--r-- | target/mips/cpu.h | 158 | ||||
-rw-r--r-- | target/mips/helper.c | 4 | ||||
-rw-r--r-- | target/mips/machine.c | 5 | ||||
-rw-r--r-- | target/mips/op_helper.c | 12 | ||||
-rw-r--r-- | target/mips/translate.c | 374 |
13 files changed, 526 insertions, 150 deletions
@@ -12,8 +12,11 @@ Fabrice Bellard <fabrice@bellard.org> bellard <bellard@c046a42c-6fe2-441c-8c8c-7 James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com> Jocelyn Mayer <l_indien@magic.fr> j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> Paul Brook <paul@codesourcery.com> pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> -Paul Burton <paul.burton@mips.com> <paul.burton@imgtec.com> -Paul Burton <paul.burton@mips.com> <paul@archlinuxmips.org> +Aleksandar Markovic <amarkovic@wavecomp.com> <aleksandar.markovic@mips.com> +Aleksandar Markovic <amarkovic@wavecomp.com> <aleksandar.markovic@imgtec.com> +Paul Burton <pburton@wavecomp.com> <paul.burton@mips.com> +Paul Burton <pburton@wavecomp.com> <paul.burton@imgtec.com> +Paul Burton <pburton@wavecomp.com> <paul@archlinuxmips.org> Thiemo Seufer <ths@networkno.de> ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> malc <av1474@comtv.ru> malc <malc@c046a42c-6fe2-441c-8c8c-71466251a162> diff --git a/MAINTAINERS b/MAINTAINERS index c48d9271cf..272a534ca0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -187,7 +187,7 @@ F: disas/microblaze.c MIPS M: Aurelien Jarno <aurelien@aurel32.net> -M: Aleksandar Markovic <aleksandar.markovic@mips.com> +M: Aleksandar Markovic <amarkovic@wavecomp.com> S: Maintained F: target/mips/ F: hw/mips/ @@ -718,7 +718,7 @@ S: Maintained F: hw/mips/mips_malta.c Mipssim -M: Aleksandar Markovic <aleksandar.markovic@mips.com> +M: Aleksandar Markovic <amarkovic@wavecomp.com> S: Odd Fixes F: hw/mips/mips_mipssim.c F: hw/net/mipsnet.c @@ -729,14 +729,15 @@ S: Maintained F: hw/mips/mips_r4k.c Fulong 2E -M: Aleksandar Markovic <aleksandar.markovic@mips.com> +M: Aleksandar Markovic <amarkovic@wavecomp.com> S: Odd Fixes F: hw/mips/mips_fulong2e.c F: hw/isa/vt82c686.c + F: include/hw/isa/vt82c686.h Boston -M: Paul Burton <paul.burton@mips.com> +M: Paul Burton <pburton@wavecomp.com> S: Maintained F: hw/core/loader-fit.c F: hw/mips/boston.c diff --git a/include/elf.h b/include/elf.h index 934dbbd6b3..28a5a638e0 100644 --- a/include/elf.h +++ b/include/elf.h @@ -61,7 +61,29 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_ABI 0x0000f000 #define EF_MIPS_FP64 0x00000200 #define EF_MIPS_NAN2008 0x00000400 -#define EF_MIPS_ARCH 0xf0000000 + +/* MIPS machine variant */ +#define EF_MIPS_MACH_NONE 0x00000000 /* A standard MIPS implementation */ +#define EF_MIPS_MACH_3900 0x00810000 /* Toshiba R3900 */ +#define EF_MIPS_MACH_4010 0x00820000 /* LSI R4010 */ +#define EF_MIPS_MACH_4100 0x00830000 /* NEC VR4100 */ +#define EF_MIPS_MACH_4650 0x00850000 /* MIPS R4650 */ +#define EF_MIPS_MACH_4120 0x00870000 /* NEC VR4120 */ +#define EF_MIPS_MACH_4111 0x00880000 /* NEC VR4111/VR4181 */ +#define EF_MIPS_MACH_SB1 0x008a0000 /* Broadcom SB-1 */ +#define EF_MIPS_MACH_OCTEON 0x008b0000 /* Cavium Networks Octeon */ +#define EF_MIPS_MACH_XLR 0x008c0000 /* RMI Xlr */ +#define EF_MIPS_MACH_OCTEON2 0x008d0000 /* Cavium Networks Octeon2 */ +#define EF_MIPS_MACH_OCTEON3 0x008e0000 /* Cavium Networks Octeon3 */ +#define EF_MIPS_MACH_5400 0x00910000 /* NEC VR5400 */ +#define EF_MIPS_MACH_5900 0x00920000 /* MIPS R5900 */ +#define EF_MIPS_MACH_5500 0x00980000 /* NEC VR5500 */ +#define EF_MIPS_MACH_9000 0x00990000 /* PMC-Sierra's RM9000 */ +#define EF_MIPS_MACH_LS2E 0x00a00000 /* ST Microelectronics Loongson 2E */ +#define EF_MIPS_MACH_LS2F 0x00a10000 /* ST Microelectronics Loongson 2F */ +#define EF_MIPS_MACH_LS3A 0x00a20000 /* ST Microelectronics Loongson 3A */ +#define EF_MIPS_MACH 0x00ff0000 /* EF_MIPS_MACH_xxx selection mask */ + /* These constants define the different elf file types */ #define ET_NONE 0 diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h index ced32806ea..e70adfc2fe 100644 --- a/linux-user/mips/syscall_nr.h +++ b/linux-user/mips/syscall_nr.h @@ -363,3 +363,12 @@ #define TARGET_NR_userfaultfd (TARGET_NR_Linux + 357) #define TARGET_NR_membarrier (TARGET_NR_Linux + 358) #define TARGET_NR_mlock2 (TARGET_NR_Linux + 359) +#define TARGET_NR_copy_file_range (TARGET_NR_Linux + 360) +#define TARGET_NR_preadv2 (TARGET_NR_Linux + 361) +#define TARGET_NR_pwritev2 (TARGET_NR_Linux + 362) +#define TARGET_NR_pkey_mprotect (TARGET_NR_Linux + 363) +#define TARGET_NR_pkey_alloc (TARGET_NR_Linux + 364) +#define TARGET_NR_pkey_free (TARGET_NR_Linux + 365) +#define TARGET_NR_statx (TARGET_NR_Linux + 366) +#define TARGET_NR_rseq (TARGET_NR_Linux + 367) +#define TARGET_NR_io_pgetevents (TARGET_NR_Linux + 368) diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h index 746cc267e9..ff218a9bf2 100644 --- a/linux-user/mips64/syscall_nr.h +++ b/linux-user/mips64/syscall_nr.h @@ -327,6 +327,15 @@ #define TARGET_NR_userfaultfd (TARGET_NR_Linux + 321) #define TARGET_NR_membarrier (TARGET_NR_Linux + 322) #define TARGET_NR_mlock2 (TARGET_NR_Linux + 323) +#define TARGET_NR_copy_file_range (TARGET_NR_Linux + 324) +#define TARGET_NR_preadv2 (TARGET_NR_Linux + 325) +#define TARGET_NR_pwritev2 (TARGET_NR_Linux + 326) +#define TARGET_NR_pkey_mprotect (TARGET_NR_Linux + 327) +#define TARGET_NR_pkey_alloc (TARGET_NR_Linux + 328) +#define TARGET_NR_pkey_free (TARGET_NR_Linux + 329) +#define TARGET_NR_statx (TARGET_NR_Linux + 330) +#define TARGET_NR_rseq (TARGET_NR_Linux + 331) +#define TARGET_NR_io_pgetevents (TARGET_NR_Linux + 332) #else /* @@ -653,4 +662,13 @@ #define TARGET_NR_userfaultfd (TARGET_NR_Linux + 317) #define TARGET_NR_membarrier (TARGET_NR_Linux + 318) #define TARGET_NR_mlock2 (TARGET_NR_Linux + 319) +#define TARGET_NR_copy_file_range (TARGET_NR_Linux + 320) +#define TARGET_NR_preadv2 (TARGET_NR_Linux + 321) +#define TARGET_NR_pwritev2 (TARGET_NR_Linux + 322) +#define TARGET_NR_pkey_mprotect (TARGET_NR_Linux + 323) +#define TARGET_NR_pkey_alloc (TARGET_NR_Linux + 324) +#define TARGET_NR_pkey_free (TARGET_NR_Linux + 325) +#define TARGET_NR_statx (TARGET_NR_Linux + 326) +#define TARGET_NR_rseq (TARGET_NR_Linux + 327) +#define TARGET_NR_io_pgetevents (TARGET_NR_Linux + 328) #endif diff --git a/linux-user/strace.c b/linux-user/strace.c index bd897a3f20..33f4a506a2 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -2304,7 +2304,19 @@ print_statfs(const struct syscallname *name, print_pointer(arg1, 1); print_syscall_epilogue(name); } -#define print_statfs64 print_statfs +#endif + +#ifdef TARGET_NR_statfs64 +static void +print_statfs64(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + print_syscall_prologue(name); + print_string(arg0, 0); + print_pointer(arg1, 1); + print_syscall_epilogue(name); +} #endif #ifdef TARGET_NR_symlink diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5a4af76c03..bb42a225eb 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7286,6 +7286,9 @@ static inline int target_to_host_mlockall_arg(int arg) } #endif +#if (defined(TARGET_NR_stat64) || defined(TARGET_NR_lstat64) || \ + defined(TARGET_NR_fstat64) || defined(TARGET_NR_fstatat64) || \ + defined(TARGET_NR_newfstatat)) static inline abi_long host_to_target_stat64(void *cpu_env, abi_ulong target_addr, struct stat *host_st) @@ -7348,6 +7351,7 @@ static inline abi_long host_to_target_stat64(void *cpu_env, return 0; } +#endif /* ??? Using host futex calls even when target atomic operations are not really atomic probably breaks things. However implementing @@ -7996,8 +8000,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, { CPUState *cpu = ENV_GET_CPU(cpu_env); abi_long ret; +#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) \ + || defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) \ + || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64) struct stat st; +#endif +#if defined(TARGET_NR_statfs) || defined(TARGET_NR_statfs64) \ + || defined(TARGET_NR_fstatfs) struct statfs stfs; +#endif void *p; #if defined(DEBUG_ERESTARTSYS) @@ -8365,9 +8376,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_oldstat: goto unimplemented; #endif +#ifdef TARGET_NR_lseek case TARGET_NR_lseek: ret = get_errno(lseek(arg1, arg2, arg3)); break; +#endif #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA) /* Alpha specific */ case TARGET_NR_getxpid: @@ -9251,6 +9264,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(sethostname(p, arg2)); unlock_user(p, arg1, 0); break; +#ifdef TARGET_NR_setrlimit case TARGET_NR_setrlimit: { int resource = target_to_host_resource(arg1); @@ -9264,6 +9278,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(setrlimit(resource, &rlim)); } break; +#endif +#ifdef TARGET_NR_getrlimit case TARGET_NR_getrlimit: { int resource = target_to_host_resource(arg1); @@ -9280,6 +9296,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } } break; +#endif case TARGET_NR_getrusage: { struct rusage rusage; @@ -9644,15 +9661,19 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(munlockall()); break; #endif +#ifdef TARGET_NR_truncate case TARGET_NR_truncate: if (!(p = lock_user_string(arg1))) goto efault; ret = get_errno(truncate(p, arg2)); unlock_user(p, arg1, 0); break; +#endif +#ifdef TARGET_NR_ftruncate case TARGET_NR_ftruncate: ret = get_errno(ftruncate(arg1, arg2)); break; +#endif case TARGET_NR_fchmod: ret = get_errno(fchmod(arg1, arg2)); break; @@ -9688,6 +9709,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_profil: goto unimplemented; #endif +#ifdef TARGET_NR_statfs case TARGET_NR_statfs: if (!(p = lock_user_string(arg1))) goto efault; @@ -9719,9 +9741,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, unlock_user_struct(target_stfs, arg2, 1); } break; +#endif +#ifdef TARGET_NR_fstatfs case TARGET_NR_fstatfs: ret = get_errno(fstatfs(arg1, &stfs)); goto convert_statfs; +#endif #ifdef TARGET_NR_statfs64 case TARGET_NR_statfs64: if (!(p = lock_user_string(arg1))) @@ -9969,6 +9994,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, unlock_user(p, arg1, 0); goto do_stat; #endif +#ifdef TARGET_NR_fstat case TARGET_NR_fstat: { ret = get_errno(fstat(arg1, &st)); @@ -9998,6 +10024,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } } break; +#endif #ifdef TARGET_NR_olduname case TARGET_NR_olduname: goto unimplemented; @@ -11004,6 +11031,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #ifdef CONFIG_SENDFILE +#ifdef TARGET_NR_sendfile case TARGET_NR_sendfile: { off_t *offp = NULL; @@ -11024,6 +11052,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; } +#endif #ifdef TARGET_NR_sendfile64 case TARGET_NR_sendfile64: { diff --git a/qemu-doc.texi b/qemu-doc.texi index abfd2db546..b8809177be 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2693,8 +2693,17 @@ The binary format is detected automatically. @command{qemu-microblaze} TODO. @cindex user mode (MIPS) -@command{qemu-mips} TODO. -@command{qemu-mipsel} TODO. +@command{qemu-mips} executes 32-bit big endian MIPS binaries (MIPS O32 ABI). + +@command{qemu-mipsel} executes 32-bit little endian MIPS binaries (MIPS O32 ABI). + +@command{qemu-mips64} executes 64-bit big endian MIPS binaries (MIPS N64 ABI). + +@command{qemu-mips64el} executes 64-bit little endian MIPS binaries (MIPS N64 ABI). + +@command{qemu-mipsn32} executes 32-bit big endian MIPS binaries (MIPS N32 ABI). + +@command{qemu-mipsn32el} executes 32-bit little endian MIPS binaries (MIPS N32 ABI). @cindex user mode (NiosII) @command{qemu-nios2} TODO. diff --git a/target/mips/cpu.h b/target/mips/cpu.h index cfe1735e0e..009202cf64 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -323,6 +323,7 @@ struct CPUMIPSState { target_ulong CP0_BadVAddr; uint32_t CP0_BadInstr; uint32_t CP0_BadInstrP; + uint32_t CP0_BadInstrX; int32_t CP0_Count; target_ulong CP0_EntryHi; #define CP0EnHi_EHINV 10 @@ -388,26 +389,27 @@ struct CPUMIPSState { target_ulong CP0_CMGCRBase; int32_t CP0_Config0; #define CP0C0_M 31 -#define CP0C0_K23 28 -#define CP0C0_KU 25 +#define CP0C0_K23 28 /* 30..28 */ +#define CP0C0_KU 25 /* 27..25 */ #define CP0C0_MDU 20 #define CP0C0_MM 18 #define CP0C0_BM 16 +#define CP0C0_Impl 16 /* 24..16 */ #define CP0C0_BE 15 -#define CP0C0_AT 13 -#define CP0C0_AR 10 -#define CP0C0_MT 7 +#define CP0C0_AT 13 /* 14..13 */ +#define CP0C0_AR 10 /* 12..10 */ +#define CP0C0_MT 7 /* 9..7 */ #define CP0C0_VI 3 -#define CP0C0_K0 0 +#define CP0C0_K0 0 /* 2..0 */ int32_t CP0_Config1; #define CP0C1_M 31 -#define CP0C1_MMU 25 -#define CP0C1_IS 22 -#define CP0C1_IL 19 -#define CP0C1_IA 16 -#define CP0C1_DS 13 -#define CP0C1_DL 10 -#define CP0C1_DA 7 +#define CP0C1_MMU 25 /* 30..25 */ +#define CP0C1_IS 22 /* 24..22 */ +#define CP0C1_IL 19 /* 21..19 */ +#define CP0C1_IA 16 /* 18..16 */ +#define CP0C1_DS 13 /* 15..13 */ +#define CP0C1_DL 10 /* 12..10 */ +#define CP0C1_DA 7 /* 9..7 */ #define CP0C1_C2 6 #define CP0C1_MD 5 #define CP0C1_PC 4 @@ -417,67 +419,85 @@ struct CPUMIPSState { #define CP0C1_FP 0 int32_t CP0_Config2; #define CP0C2_M 31 -#define CP0C2_TU 28 -#define CP0C2_TS 24 -#define CP0C2_TL 20 -#define CP0C2_TA 16 -#define CP0C2_SU 12 -#define CP0C2_SS 8 -#define CP0C2_SL 4 -#define CP0C2_SA 0 +#define CP0C2_TU 28 /* 30..28 */ +#define CP0C2_TS 24 /* 27..24 */ +#define CP0C2_TL 20 /* 23..20 */ +#define CP0C2_TA 16 /* 19..16 */ +#define CP0C2_SU 12 /* 15..12 */ +#define CP0C2_SS 8 /* 11..8 */ +#define CP0C2_SL 4 /* 7..4 */ +#define CP0C2_SA 0 /* 3..0 */ int32_t CP0_Config3; -#define CP0C3_M 31 -#define CP0C3_BPG 30 -#define CP0C3_CMGCR 29 -#define CP0C3_MSAP 28 -#define CP0C3_BP 27 -#define CP0C3_BI 26 -#define CP0C3_SC 25 -#define CP0C3_IPLW 21 -#define CP0C3_MMAR 18 -#define CP0C3_MCU 17 -#define CP0C3_ISA_ON_EXC 16 -#define CP0C3_ISA 14 -#define CP0C3_ULRI 13 -#define CP0C3_RXI 12 -#define CP0C3_DSP2P 11 -#define CP0C3_DSPP 10 -#define CP0C3_LPA 7 -#define CP0C3_VEIC 6 -#define CP0C3_VInt 5 -#define CP0C3_SP 4 -#define CP0C3_CDMM 3 -#define CP0C3_MT 2 -#define CP0C3_SM 1 -#define CP0C3_TL 0 +#define CP0C3_M 31 +#define CP0C3_BPG 30 +#define CP0C3_CMGCR 29 +#define CP0C3_MSAP 28 +#define CP0C3_BP 27 +#define CP0C3_BI 26 +#define CP0C3_SC 25 +#define CP0C3_PW 24 +#define CP0C3_VZ 23 +#define CP0C3_IPLV 21 /* 22..21 */ +#define CP0C3_MMAR 18 /* 20..18 */ +#define CP0C3_MCU 17 +#define CP0C3_ISA_ON_EXC 16 +#define CP0C3_ISA 14 /* 15..14 */ +#define CP0C3_ULRI 13 +#define CP0C3_RXI 12 +#define CP0C3_DSP2P 11 +#define CP0C3_DSPP 10 +#define CP0C3_CTXTC 9 +#define CP0C3_ITL 8 +#define CP0C3_LPA 7 +#define CP0C3_VEIC 6 +#define CP0C3_VInt 5 +#define CP0C3_SP 4 +#define CP0C3_CDMM 3 +#define CP0C3_MT 2 +#define CP0C3_SM 1 +#define CP0C3_TL 0 int32_t CP0_Config4; int32_t CP0_Config4_rw_bitmask; -#define CP0C4_M 31 -#define CP0C4_IE 29 -#define CP0C4_AE 28 -#define CP0C4_KScrExist 16 -#define CP0C4_MMUExtDef 14 -#define CP0C4_FTLBPageSize 8 -#define CP0C4_FTLBWays 4 -#define CP0C4_FTLBSets 0 -#define CP0C4_MMUSizeExt 0 +#define CP0C4_M 31 +#define CP0C4_IE 29 /* 30..29 */ +#define CP0C4_AE 28 +#define CP0C4_VTLBSizeExt 24 /* 27..24 */ +#define CP0C4_KScrExist 16 +#define CP0C4_MMUExtDef 14 +#define CP0C4_FTLBPageSize 8 /* 12..8 */ +/* bit layout if MMUExtDef=1 */ +#define CP0C4_MMUSizeExt 0 /* 7..0 */ +/* bit layout if MMUExtDef=2 */ +#define CP0C4_FTLBWays 4 /* 7..4 */ +#define CP0C4_FTLBSets 0 /* 3..0 */ int32_t CP0_Config5; int32_t CP0_Config5_rw_bitmask; -#define CP0C5_M 31 -#define CP0C5_K 30 -#define CP0C5_CV 29 -#define CP0C5_EVA 28 -#define CP0C5_MSAEn 27 -#define CP0C5_XNP 13 -#define CP0C5_UFE 9 -#define CP0C5_FRE 8 -#define CP0C5_VP 7 -#define CP0C5_SBRI 6 -#define CP0C5_MVH 5 -#define CP0C5_LLB 4 -#define CP0C5_MRP 3 -#define CP0C5_UFR 2 -#define CP0C5_NFExists 0 +#define CP0C5_M 31 +#define CP0C5_K 30 +#define CP0C5_CV 29 +#define CP0C5_EVA 28 +#define CP0C5_MSAEn 27 +#define CP0C5_PMJ 23 /* 25..23 */ +#define CP0C5_WR2 22 +#define CP0C5_NMS 21 +#define CP0C5_ULS 20 +#define CP0C5_XPA 19 +#define CP0C5_CRCP 18 +#define CP0C5_MI 17 +#define CP0C5_GI 15 /* 16..15 */ +#define CP0C5_CA2 14 +#define CP0C5_XNP 13 +#define CP0C5_DEC 11 +#define CP0C5_L2C 10 +#define CP0C5_UFE 9 +#define CP0C5_FRE 8 +#define CP0C5_VP 7 +#define CP0C5_SBRI 6 +#define CP0C5_MVH 5 +#define CP0C5_LLB 4 +#define CP0C5_MRP 3 +#define CP0C5_UFR 2 +#define CP0C5_NFExists 0 int32_t CP0_Config6; int32_t CP0_Config7; uint64_t CP0_MAAR[MIPS_MAAR_MAX]; diff --git a/target/mips/helper.c b/target/mips/helper.c index 8cf91ce339..e215af9a41 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -502,7 +502,9 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, break; } /* Raise exception */ - env->CP0_BadVAddr = address; + if (!(env->hflags & MIPS_HFLAG_DM)) { + env->CP0_BadVAddr = address; + } env->CP0_Context = (env->CP0_Context & ~0x007fffff) | ((address >> 9) & 0x007ffff0); env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) | diff --git a/target/mips/machine.c b/target/mips/machine.c index 20100d5adb..5ba78acd6d 100644 --- a/target/mips/machine.c +++ b/target/mips/machine.c @@ -212,8 +212,8 @@ const VMStateDescription vmstate_tlb = { const VMStateDescription vmstate_mips_cpu = { .name = "cpu", - .version_id = 10, - .minimum_version_id = 10, + .version_id = 11, + .minimum_version_id = 11, .post_load = cpu_post_load, .fields = (VMStateField[]) { /* Active TC */ @@ -266,6 +266,7 @@ const VMStateDescription vmstate_mips_cpu = { VMSTATE_UINTTL(env.CP0_BadVAddr, MIPSCPU), VMSTATE_UINT32(env.CP0_BadInstr, MIPSCPU), VMSTATE_UINT32(env.CP0_BadInstrP, MIPSCPU), + VMSTATE_UINT32(env.CP0_BadInstrX, MIPSCPU), VMSTATE_INT32(env.CP0_Count, MIPSCPU), VMSTATE_UINTTL(env.CP0_EntryHi, MIPSCPU), VMSTATE_INT32(env.CP0_Compare, MIPSCPU), diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 41d3634289..0b2663b73a 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -271,7 +271,9 @@ static inline hwaddr do_translate_address(CPUMIPSState *env, target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx) \ { \ if (arg & almask) { \ - env->CP0_BadVAddr = arg; \ + if (!(env->hflags & MIPS_HFLAG_DM)) { \ + env->CP0_BadVAddr = arg; \ + } \ do_raise_exception(env, EXCP_AdEL, GETPC()); \ } \ env->lladdr = do_translate_address(env, arg, 0, GETPC()); \ @@ -291,7 +293,9 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1, \ target_long tmp; \ \ if (arg2 & almask) { \ - env->CP0_BadVAddr = arg2; \ + if (!(env->hflags & MIPS_HFLAG_DM)) { \ + env->CP0_BadVAddr = arg2; \ + } \ do_raise_exception(env, EXCP_AdES, GETPC()); \ } \ if (do_translate_address(env, arg2, 1, GETPC()) == env->lladdr) { \ @@ -2437,7 +2441,9 @@ void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr, int error_code = 0; int excp; - env->CP0_BadVAddr = addr; + if (!(env->hflags & MIPS_HFLAG_DM)) { + env->CP0_BadVAddr = addr; + } if (access_type == MMU_DATA_STORE) { excp = EXCP_AdES; diff --git a/target/mips/translate.c b/target/mips/translate.c index 20b43c0337..bdd880bb77 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -902,8 +902,21 @@ enum { OPC_MTTR = (0x0C << 21) | OPC_CP0, OPC_WRPGPR = (0x0E << 21) | OPC_CP0, OPC_C0 = (0x10 << 21) | OPC_CP0, - OPC_C0_FIRST = (0x10 << 21) | OPC_CP0, - OPC_C0_LAST = (0x1F << 21) | OPC_CP0, + OPC_C0_1 = (0x11 << 21) | OPC_CP0, + OPC_C0_2 = (0x12 << 21) | OPC_CP0, + OPC_C0_3 = (0x13 << 21) | OPC_CP0, + OPC_C0_4 = (0x14 << 21) | OPC_CP0, + OPC_C0_5 = (0x15 << 21) | OPC_CP0, + OPC_C0_6 = (0x16 << 21) | OPC_CP0, + OPC_C0_7 = (0x17 << 21) | OPC_CP0, + OPC_C0_8 = (0x18 << 21) | OPC_CP0, + OPC_C0_9 = (0x19 << 21) | OPC_CP0, + OPC_C0_A = (0x1A << 21) | OPC_CP0, + OPC_C0_B = (0x1B << 21) | OPC_CP0, + OPC_C0_C = (0x1C << 21) | OPC_CP0, + OPC_C0_D = (0x1D << 21) | OPC_CP0, + OPC_C0_E = (0x1E << 21) | OPC_CP0, + OPC_C0_F = (0x1F << 21) | OPC_CP0, }; /* MFMC0 opcodes */ @@ -4884,12 +4897,11 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) { const char *rn = "invalid"; - CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); - switch (reg) { case 2: switch (sel) { case 0: + CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); rn = "EntryLo0"; break; @@ -4900,6 +4912,7 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 3: switch (sel) { case 0: + CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); rn = "EntryLo1"; break; @@ -4952,12 +4965,11 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) const char *rn = "invalid"; uint64_t mask = ctx->PAMask >> 36; - CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); - switch (reg) { case 2: switch (sel) { case 0: + CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); tcg_gen_andi_tl(arg, arg, mask); gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); rn = "EntryLo0"; @@ -4969,6 +4981,7 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 3: switch (sel) { case 0: + CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); tcg_gen_andi_tl(arg, arg, mask); gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); rn = "EntryLo1"; @@ -5315,7 +5328,13 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); rn = "BadInstrP"; break; - default: + case 3: + CP0_CHECK(ctx->bi); + gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); + tcg_gen_andi_tl(arg, arg, ~0xffff); + rn = "BadInstrX"; + break; + default: goto cp0_unimplemented; } break; @@ -5494,7 +5513,15 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 18: switch (sel) { - case 0 ... 7: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(mfc0_watchlo, arg, sel); rn = "WatchLo"; break; @@ -5504,7 +5531,15 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 19: switch (sel) { - case 0 ...7: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(mfc0_watchhi, arg, sel); rn = "WatchHi"; break; @@ -5630,7 +5665,10 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 27: switch (sel) { - case 0 ... 3: + case 0: + case 1: + case 2: + case 3: tcg_gen_movi_tl(arg, 0); /* unimplemented */ rn = "CacheErr"; break; @@ -5701,7 +5739,12 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); rn = "DESAVE"; break; - case 2 ... 7: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_KScratch[sel-2])); @@ -5984,6 +6027,10 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) /* ignored */ rn = "BadInstrP"; break; + case 3: + /* ignored */ + rn = "BadInstrX"; + break; default: goto cp0_unimplemented; } @@ -6167,7 +6214,15 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 18: switch (sel) { - case 0 ... 7: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchlo, arg, sel); rn = "WatchLo"; break; @@ -6177,7 +6232,15 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 19: switch (sel) { - case 0 ... 7: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchhi, arg, sel); rn = "WatchHi"; break; @@ -6315,7 +6378,10 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 27: switch (sel) { - case 0 ... 3: + case 0: + case 1: + case 2: + case 3: /* ignored */ rn = "CacheErr"; break; @@ -6381,7 +6447,12 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); rn = "DESAVE"; break; - case 2 ... 7: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_KScratch[sel-2])); @@ -6667,6 +6738,12 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); rn = "BadInstrP"; break; + case 3: + CP0_CHECK(ctx->bi); + gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); + tcg_gen_andi_tl(arg, arg, ~0xffff); + rn = "BadInstrX"; + break; default: goto cp0_unimplemented; } @@ -6842,7 +6919,15 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 18: switch (sel) { - case 0 ... 7: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(dmfc0_watchlo, arg, sel); rn = "WatchLo"; break; @@ -6852,7 +6937,15 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 19: switch (sel) { - case 0 ... 7: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_1e0i(mfc0_watchhi, arg, sel); rn = "WatchHi"; break; @@ -6975,7 +7068,10 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 27: switch (sel) { /* ignored */ - case 0 ... 3: + case 0: + case 1: + case 2: + case 3: tcg_gen_movi_tl(arg, 0); /* unimplemented */ rn = "CacheErr"; break; @@ -7040,7 +7136,12 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); rn = "DESAVE"; break; - case 2 ... 7: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_KScratch[sel-2])); @@ -7319,6 +7420,10 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) /* ignored */ rn = "BadInstrP"; break; + case 3: + /* ignored */ + rn = "BadInstrX"; + break; default: goto cp0_unimplemented; } @@ -7497,7 +7602,15 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 18: switch (sel) { - case 0 ... 7: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchlo, arg, sel); rn = "WatchLo"; break; @@ -7507,7 +7620,15 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 19: switch (sel) { - case 0 ... 7: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); gen_helper_0e1i(mtc0_watchhi, arg, sel); rn = "WatchHi"; break; @@ -7641,7 +7762,10 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case 27: switch (sel) { - case 0 ... 3: + case 0: + case 1: + case 2: + case 3: /* ignored */ rn = "CacheErr"; break; @@ -7707,7 +7831,12 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); rn = "DESAVE"; break; - case 2 ... 7: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_KScratch[sel-2])); @@ -7843,7 +7972,14 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, break; case 16: switch (sel) { - case 0 ... 7: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel)); break; default: @@ -12395,10 +12531,22 @@ enum { /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */ enum { ADDIUPC_00 = 0x00, + ADDIUPC_01 = 0x01, + ADDIUPC_02 = 0x02, + ADDIUPC_03 = 0x03, + ADDIUPC_04 = 0x04, + ADDIUPC_05 = 0x05, + ADDIUPC_06 = 0x06, ADDIUPC_07 = 0x07, AUIPC = 0x1e, ALUIPC = 0x1f, LWPC_08 = 0x08, + LWPC_09 = 0x09, + LWPC_0A = 0x0A, + LWPC_0B = 0x0B, + LWPC_0C = 0x0C, + LWPC_0D = 0x0D, + LWPC_0E = 0x0E, LWPC_0F = 0x0F, }; @@ -12833,12 +12981,16 @@ enum { R6_LWM16 = 0x02, R6_JRC16 = 0x03, MOVEP = 0x04, + MOVEP_05 = 0x05, + MOVEP_06 = 0x06, MOVEP_07 = 0x07, R6_XOR16 = 0x08, R6_OR16 = 0x09, R6_SWM16 = 0x0a, JALRC16 = 0x0b, MOVEP_0C = 0x0c, + MOVEP_0D = 0x0d, + MOVEP_0E = 0x0e, MOVEP_0F = 0x0f, JRCADDIUSP = 0x13, R6_BREAK16 = 0x1b, @@ -13152,12 +13304,18 @@ static void gen_pool16c_r6_insn(DisasContext *ctx) gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2); } else { /* JRC16 */ - int rs = extract32(ctx->opcode, 5, 5); + rs = extract32(ctx->opcode, 5, 5); gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0); } break; - case MOVEP ... MOVEP_07: - case MOVEP_0C ... MOVEP_0F: + case MOVEP: + case MOVEP_05: + case MOVEP_06: + case MOVEP_07: + case MOVEP_0C: + case MOVEP_0D: + case MOVEP_0E: + case MOVEP_0F: { int enc_dest = uMIPS_RD(ctx->opcode); int enc_rt = uMIPS_RS2(ctx->opcode); @@ -14160,8 +14318,8 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) case SDP: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); - /* Fallthrough */ #endif + /* fall through */ case LWP: case SWP: gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12)); @@ -14171,8 +14329,8 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) case SDM: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); - /* Fallthrough */ #endif + /* fall through */ case LWM32: case SWM32: gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12)); @@ -15135,7 +15293,14 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) if (ctx->insn_flags & ISA_MIPS32R6) { /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */ switch ((ctx->opcode >> 16) & 0x1f) { - case ADDIUPC_00 ... ADDIUPC_07: + case ADDIUPC_00: + case ADDIUPC_01: + case ADDIUPC_02: + case ADDIUPC_03: + case ADDIUPC_04: + case ADDIUPC_05: + case ADDIUPC_06: + case ADDIUPC_07: gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt); break; case AUIPC: @@ -15144,7 +15309,14 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) case ALUIPC: gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt); break; - case LWPC_08 ... LWPC_0F: + case LWPC_08: + case LWPC_09: + case LWPC_0A: + case LWPC_0B: + case LWPC_0C: + case LWPC_0D: + case LWPC_0E: + case LWPC_0F: gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt); break; default: @@ -15154,7 +15326,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) } else { /* ADDIUPC */ int reg = mmreg(ZIMM(ctx->opcode, 23, 3)); - int offset = SIMM(ctx->opcode, 0, 23) << 2; + offset = SIMM(ctx->opcode, 0, 23) << 2; gen_addiupc(ctx, reg, offset, 0, 0); } @@ -17231,7 +17403,10 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) case OPC_LSA: gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2)); break; - case OPC_MULT ... OPC_DIVU: + case OPC_MULT: + case OPC_MULTU: + case OPC_DIV: + case OPC_DIVU: op2 = MASK_R6_MULDIV(ctx->opcode); switch (op2) { case R6_OPC_MUL: @@ -17291,7 +17466,11 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) generate_exception_end(ctx, EXCP_RI); } break; - case OPC_DMULT ... OPC_DDIVU: + case OPC_DMULT: + case OPC_DMULTU: + case OPC_DDIV: + case OPC_DDIVU: + op2 = MASK_R6_MULDIV(ctx->opcode); switch (op2) { case R6_OPC_DMUL: @@ -17370,7 +17549,10 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) gen_muldiv(ctx, op1, 0, rs, rt); break; #if defined(TARGET_MIPS64) - case OPC_DMULT ... OPC_DDIVU: + case OPC_DMULT: + case OPC_DMULTU: + case OPC_DDIV: + case OPC_DDIVU: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); gen_muldiv(ctx, op1, 0, rs, rt); @@ -17437,7 +17619,10 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) break; } break; - case OPC_ADD ... OPC_SUBU: + case OPC_ADD: + case OPC_ADDU: + case OPC_SUB: + case OPC_SUBU: gen_arith(ctx, op1, rd, rs, rt); break; case OPC_SLLV: /* Shifts */ @@ -17473,7 +17658,11 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) case OPC_JALR: gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); break; - case OPC_TGE ... OPC_TEQ: /* Traps */ + case OPC_TGE: /* Traps */ + case OPC_TGEU: + case OPC_TLT: + case OPC_TLTU: + case OPC_TEQ: case OPC_TNE: check_insn(ctx, ISA_MIPS2); gen_trap(ctx, op1, rs, rt, -1); @@ -17549,7 +17738,10 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) break; } break; - case OPC_DADD ... OPC_DSUBU: + case OPC_DADD: + case OPC_DADDU: + case OPC_DSUB: + case OPC_DSUBU: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); gen_arith(ctx, op1, rd, rs, rt); @@ -17607,8 +17799,10 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) op1 = MASK_SPECIAL2(ctx->opcode); switch (op1) { - case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */ - case OPC_MSUB ... OPC_MSUBU: + case OPC_MADD: /* Multiply and add/sub */ + case OPC_MADDU: + case OPC_MSUB: + case OPC_MSUBU: check_insn(ctx, ISA_MIPS32); gen_muldiv(ctx, op1, rd & 3, rs, rt); break; @@ -17705,7 +17899,8 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) } op2 = MASK_BSHFL(ctx->opcode); switch (op2) { - case OPC_ALIGN ... OPC_ALIGN_END: + case OPC_ALIGN: + case OPC_ALIGN_END: gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3); break; case OPC_BITSWAP: @@ -17730,7 +17925,8 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) } op2 = MASK_DBSHFL(ctx->opcode); switch (op2) { - case OPC_DALIGN ... OPC_DALIGN_END: + case OPC_DALIGN: + case OPC_DALIGN_END: gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7); break; case OPC_DBITSWAP: @@ -17759,9 +17955,12 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) op1 = MASK_SPECIAL3(ctx->opcode); switch (op1) { - case OPC_DIV_G_2E ... OPC_DIVU_G_2E: - case OPC_MOD_G_2E ... OPC_MODU_G_2E: - case OPC_MULT_G_2E ... OPC_MULTU_G_2E: + case OPC_DIV_G_2E: + case OPC_DIVU_G_2E: + case OPC_MOD_G_2E: + case OPC_MODU_G_2E: + case OPC_MULT_G_2E: + case OPC_MULTU_G_2E: /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have * the same mask and op1. */ if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) { @@ -18025,9 +18224,12 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) } break; #if defined(TARGET_MIPS64) - case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E: - case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E: - case OPC_DMOD_G_2E ... OPC_DMODU_G_2E: + case OPC_DDIV_G_2E: + case OPC_DDIVU_G_2E: + case OPC_DMULT_G_2E: + case OPC_DMULTU_G_2E: + case OPC_DMOD_G_2E: + case OPC_DMODU_G_2E: check_insn(ctx, INSN_LOONGSON2E); gen_loongson_integer(ctx, op1, rd, rs, rt); break; @@ -18289,18 +18491,25 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) */ if (ctx->eva) { switch (op1) { - case OPC_LWLE ... OPC_LWRE: + case OPC_LWLE: + case OPC_LWRE: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* fall through */ - case OPC_LBUE ... OPC_LHUE: - case OPC_LBE ... OPC_LWE: + case OPC_LBUE: + case OPC_LHUE: + case OPC_LBE: + case OPC_LHE: + case OPC_LLE: + case OPC_LWE: check_cp0_enabled(ctx); gen_ld(ctx, op1, rt, rs, imm); return; - case OPC_SWLE ... OPC_SWRE: + case OPC_SWLE: + case OPC_SWRE: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* fall through */ - case OPC_SBE ... OPC_SHE: + case OPC_SBE: + case OPC_SHE: case OPC_SWE: check_cp0_enabled(ctx); gen_st(ctx, op1, rt, rs, imm); @@ -18332,7 +18541,8 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) case OPC_BSHFL: op2 = MASK_BSHFL(ctx->opcode); switch (op2) { - case OPC_ALIGN ... OPC_ALIGN_END: + case OPC_ALIGN: + case OPC_ALIGN_END: case OPC_BITSWAP: check_insn(ctx, ISA_MIPS32R6); decode_opc_special3_r6(env, ctx); @@ -18344,8 +18554,12 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) } break; #if defined(TARGET_MIPS64) - case OPC_DEXTM ... OPC_DEXT: - case OPC_DINSM ... OPC_DINS: + case OPC_DEXTM: + case OPC_DEXTU: + case OPC_DEXT: + case OPC_DINSM: + case OPC_DINSU: + case OPC_DINS: check_insn(ctx, ISA_MIPS64R2); check_mips_64(ctx); gen_bitops(ctx, op1, rt, rs, sa, rd); @@ -18353,7 +18567,8 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) case OPC_DBSHFL: op2 = MASK_DBSHFL(ctx->opcode); switch (op2) { - case OPC_DALIGN ... OPC_DALIGN_END: + case OPC_DALIGN: + case OPC_DALIGN_END: case OPC_DBITSWAP: check_insn(ctx, ISA_MIPS32R6); decode_opc_special3_r6(env, ctx); @@ -19584,7 +19799,12 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); } break; - case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */ + case OPC_TGEI: /* REGIMM traps */ + case OPC_TGEIU: + case OPC_TLTI: + case OPC_TLTIU: + case OPC_TEQI: + case OPC_TNEI: check_insn(ctx, ISA_MIPS2); check_insn_opc_removed(ctx, ISA_MIPS32R6); @@ -19647,7 +19867,22 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) gen_cp0(env, ctx, op1, rt, rd); #endif /* !CONFIG_USER_ONLY */ break; - case OPC_C0_FIRST ... OPC_C0_LAST: + case OPC_C0: + case OPC_C0_1: + case OPC_C0_2: + case OPC_C0_3: + case OPC_C0_4: + case OPC_C0_5: + case OPC_C0_6: + case OPC_C0_7: + case OPC_C0_8: + case OPC_C0_9: + case OPC_C0_A: + case OPC_C0_B: + case OPC_C0_C: + case OPC_C0_D: + case OPC_C0_E: + case OPC_C0_F: #ifndef CONFIG_USER_ONLY gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); #endif /* !CONFIG_USER_ONLY */ @@ -19759,7 +19994,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_XORI: gen_logic_imm(ctx, op, rt, rs, imm); break; - case OPC_J ... OPC_JAL: /* Jump */ + case OPC_J: /* Jump */ + case OPC_JAL: offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); break; @@ -19826,15 +20062,20 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_LWR: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* Fallthrough */ - case OPC_LB ... OPC_LH: - case OPC_LW ... OPC_LHU: + case OPC_LB: + case OPC_LH: + case OPC_LW: + case OPC_LWPC: + case OPC_LBU: + case OPC_LHU: gen_ld(ctx, op, rt, rs, imm); break; case OPC_SWL: case OPC_SWR: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* fall through */ - case OPC_SB ... OPC_SH: + case OPC_SB: + case OPC_SH: case OPC_SW: gen_st(ctx, op, rt, rs, imm); break; @@ -19874,6 +20115,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_MTHC1: check_cp1_enabled(ctx); check_insn(ctx, ISA_MIPS32R2); + /* fall through */ case OPC_MFC1: case OPC_CFC1: case OPC_MTC1: @@ -20105,7 +20347,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) #if defined(TARGET_MIPS64) /* MIPS64 opcodes */ - case OPC_LDL ... OPC_LDR: + case OPC_LDL: + case OPC_LDR: case OPC_LLD: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* fall through */ @@ -20115,7 +20358,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) check_mips_64(ctx); gen_ld(ctx, op, rt, rs, imm); break; - case OPC_SDL ... OPC_SDR: + case OPC_SDL: + case OPC_SDR: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* fall through */ case OPC_SD: |