Re: [Qemu-devel] [PATCH v2] target/mips: Initial support for MIPS R5900
Thank you, Richard, > > Can QEMU be instructed to emulate > > the FPU only for Linux user space programs as opposed to hardware emulation? > > Yes, that can be done. I would suggest something like > > /* > * Hardware traps to the operating system for emulation. > * For user-only, qemu is the operating system, so we > * emulate the trap and emulate by simply emulating the > * instruction directly. > */ > #ifdef CONFIG_USER_ONLY > # define CP0C1_FP_USER_ONLY (1 << CP0C1_FP) > #else > # define CP0C1_FP_USER_ONLY 0 > #endif > > and include that in your initialization of CP0_Config1. I've made both CP0C1_FP and the LL/SC emulation conditional on user-only, and adjusted the patch after the review by Maciej, as shown below. Aleksandar, Aurelien, Maciej -- are you happy with this initial v2 patch? Fredrik Signed-off-by: Fredrik Noring --- include/elf.h|3 ++ linux-user/mips/target_elf.h |3 ++ target/mips/mips-defs.h |2 + target/mips/translate.c | 31 ++- target/mips/translate_init.inc.c | 44 +++ 5 files changed, 82 insertions(+), 1 deletion(-) --- a/include/elf.h +++ b/include/elf.h @@ -48,6 +48,8 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_ARCH_32R6 0x9000 /* MIPS32r6 code. */ #define EF_MIPS_ARCH_64R6 0xa000 /* MIPS64r6 code. */ +#define EF_MIPS_MACH_5900 0x0092 + /* The ABI of a file. */ #define EF_MIPS_ABI_O320x1000 /* O32 ABI. */ #define EF_MIPS_ABI_O640x2000 /* O32 extended for 64 bit. */ @@ -62,6 +64,7 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_FP64 0x0200 #define EF_MIPS_NAN2008 0x0400 #define EF_MIPS_ARCH 0xf000 +#define EF_MIPS_MACH 0x00ff /* These constants define the different elf file types */ #define ET_NONE 0 --- a/linux-user/mips/target_elf.h +++ b/linux-user/mips/target_elf.h @@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags) if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) { return "mips32r6-generic"; } +if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) { +return "R5900"; +} return "24Kf"; } #endif --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -52,6 +52,7 @@ #define ASE_MSA 0x0100 /* Chip specific instructions. */ +#defineINSN_R5900 0x1000 #defineINSN_LOONGSON2E 0x2000 #defineINSN_LOONGSON2F 0x4000 #defineINSN_VR54XX 0x8000 @@ -62,6 +63,7 @@ #defineCPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) #defineCPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) #defineCPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) +#defineCPU_R5900 (CPU_MIPS4 | INSN_R5900) #defineCPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) #defineCPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -3618,6 +3618,31 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } +static void gen_mul_r5900 (DisasContext *ctx, uint32_t opc, +int rd, int rs, int rt) +{ +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +switch (opc) { +case OPC_MULT: +case OPC_MULTU: +tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); +break; +default: +MIPS_INVAL("mul R5900"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + + out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { @@ -17357,7 +17382,11 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) break; case OPC_MULT: case OPC_MULTU: -if (sa) { +if (ctx->insn_flags & INSN_R5900) { +gen_muldiv(ctx, op1, 0, rs, rt); +if (rd != 0) +gen_mul_r5900(ctx, op1, rd, rs, rt); +} else if (sa) { check_insn(ctx, INSN_VR54XX); op1 = MASK_MUL_VR54XX(ctx->opcode); gen_mul_vr54xx(ctx, op1, rd, rs, rt); --- a/target/mips/translate_init.inc.c +++ b/target/mips/translate_init.inc.c @@ -410,6 +410,50 @@ const mips_def_t mips_defs[] = .insn_flags = CPU_MIPS32R5 | ASE_MSA, .mmu_type = MMU_TYPE_R4000, }, +{ +.name = "R5900", +.CP0_PRid = 0x3800, +/* No L2 cache, icache size 32k, dcache size 32k, uncached coherency. */ +.CP0_Config0 = (1 << 17) | (0x3 <<
Re: [Qemu-devel] [PATCH v3] target/mips: Support R5900 GCC programs in user mode
Hi Aleksandar, > Please: > > - rebase your changes to the latest QEMU code Sure. V2 applied to 3.0.0 and this v3 applies to HEAD (commit 19b599f7664b). > - organize the changes in the form of patch series What kind of granularity do you have in mind? The patch is quite small with 79 insertions and 1 deletion in total. > - provide links to or attach relevant documentation The most relevant manual is probably Toshiba TX System RISC TX79 Core Architecture: http://www.lukasz.dk/files/tx79architecture.pdf > - in cover letter, outline what is needed for full QEMU support of the cpu > in question The primary purpose of this patch is to support programs compiled by GCC for the R5900 target. This enables QEMU to run R5900 Linux distributions, for example Gentoo. In particular, this avoids issues with cross compilation. R5900 hardware is typically limited to 32 MiB of RAM, which is insufficient for running GCC in many cases. > - describe testing and verification This patch has been tested with Gentoo compiled for R5900, including native compilation of several packages under QEMU. During testing of 2.12.50 I discovered two problems which I reported and I believe are unrelated to the patch itself: The error qemu: Unsupported syscall: 4352 (seccomp) was reported during Gentoo package installations, and QEMU crashed with qemu-mipsel: qemu/accel/tcg/cpu-exec.c:634: cpu_loop_exec_tb: Assertion `use_icount' failed. qemu: uncaught target signal 11 (Segmentation fault) - core dumped when compiling Perl under Gentoo. That crash seems to be related to the bug https://bugs.launchpad.net/qemu/+bug/1768246 for SH4, which appears to have a fix for SH4 in commit 5b38d0264064055255db991e29d938491f9e8a32 Author: Laurent Vivier Date: Sat Aug 11 10:23:28 2018 +0200 sh4: fix use_icount with linux-user This fixes java in a linux-user chroot: $ java --version qemu-sh4: .../accel/tcg/cpu-exec.c:634: cpu_loop_exec_tb: Assertion `use_icount' failed. qemu: uncaught target signal 6 (Aborted) - core dumped Aborted (core dumped) In gen_conditional_jump() in the GUSA_EXCLUSIVE part, we must reset base.is_jmp to DISAS_NEXT after the gen_goto_tb() as it is done in gen_delayed_conditional_jump() after the gen_jump(). Bug: https://bugs.launchpad.net/qemu/+bug/1768246 Fixes: 4834871bc95b67343248100e2a75ae0d287bc08b ("target/sh4: Convert to DisasJumpType") Reported-by: John Paul Adrian Glaubitz Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson Reviewed-by: Aurelien Jarno Message-Id: <20180811082328.11268-1-laur...@vivier.eu> > - remove the unclear word 'initial' from the title Sure. > - outline your plan for providing full support - can you commit enough > resources to do the job in a reasonable timeframe? For its intended purpose, to support R5900 GCC programs in user mode, I believe this patch is sufficiently complete as it stands. > Otherwise, I am generally happy with your patch. Good! Fredrik Signed-off-by: Fredrik Noring --- linux-user/mips/target_elf.h |3 ++ target/mips/mips-defs.h |2 + target/mips/translate.c | 31 ++- target/mips/translate_init.inc.c | 44 +++ 4 files changed, 79 insertions(+), 1 deletion(-) --- a/linux-user/mips/target_elf.h +++ b/linux-user/mips/target_elf.h @@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags) if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) { return "mips32r6-generic"; } +if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) { +return "R5900"; +} return "24Kf"; } #endif --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -53,6 +53,7 @@ #define ASE_MSA 0x0100 /* Chip specific instructions. */ +#defineINSN_R5900 0x1000 #defineINSN_LOONGSON2E 0x2000 #defineINSN_LOONGSON2F 0x4000 #defineINSN_VR54XX 0x8000 @@ -63,6 +64,7 @@ #defineCPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) #defineCPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) #defineCPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) +#defineCPU_R5900 (CPU_MIPS4 | INSN_R5900) #defineCPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) #defineCPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -3768,6 +3768,31 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } +static void gen_mul_r5900 (DisasContext *ctx, uint32_t opc, +int rd, int rs, int rt) +{ +TCGv t0 = tcg_temp_new(); +TCGv t1 = tc
Re: [Qemu-devel] [PATCH v3] target/mips: Support R5900 GCC programs in user mode
Many thanks for your review, Maciej, > I have been more thorough on this occasion, and I do hope I have caught > everything. See the notes below, in addition to what the others wrote. > > Please apply to v3 accordingly; I started writing this before you sent > that version. Sure, next version submitted as a patch series will be a lot better, thanks! > I think this has to be (CPU_MIPS3 | INSN_R5900) really. > > While the CPU does support MIPS IV MOVN, MOVZ and PREF instructions, > that's all it has from that ISA. Even the Tx79, which was supposed to > have a regular IEEE-754 FPU, did not have the extra FP condition bits, > MOVN.fmt, MOVZ.fmt or any of the MOVF* or MOVT* instructions, indexed > load/store instructions, multiply-accumulate instructions, etc. defined. > > So I think the R5900 has to be treated as a MIPS III implementation, with > some aberrations. I don't expect it to be a big deal to add INSN_R5900 > qualification to MOVN, MOVZ and PREF instruction emulation code right > away. Trivial to add, in fact. :) > Then presumably you are going to add emulation for all the missing MIPS > III instructions to the Linux kernel eventually, to match the MIPS III > Linux user ABI? Apart from LLD and SCD discussed previously this will > have to include DDIV, DDIVU, DMULT and DMULTU. That sounds reasonable! > Eventually you'll have to remove all these instructions (plus LL and SC) > from the system emulation mode. In fact I think it would make sense to do > that right away, because I believe it will be a reasonably simple update. > However if it turns out to be a can of worms after all, then I think we > can defer it, because we do not have a bare-metal environment ready for > this CPU anyway (or do we?). Indeed, very simple. I added a new check function check_insn_opc_user_only, similar to check_insn_opc_removed, conditional on USER_ONLY and so a simple check_insn_opc_user_only(ctx, INSN_R5900); has to be added for these OPC cases. To test this I tried to build GCC with the target mips64r5900el but it unfortunately didn't work as GCC failed to compile itself: ../sysdeps/mips/mips64/mul_1.S:49: Error: opcode not supported on this processor: r5900 (mips3) `dmultu $8,$7' > I think there is no point in executing the multiplication twice if `rd != > 0' and also we want to continue trapping on `sa != 0' for the non-Vr54xx > case, so how about: > > if (sa) { > check_insn(ctx, INSN_VR54XX); > op1 = MASK_MUL_VR54XX(ctx->opcode); > gen_mul_vr54xx(ctx, op1, rd, rs, rt); > } else if (rd && (ctx->insn_flags & INSN_R5900)) { > gen_mul_r5900(ctx, op1, rd, rs, rt); > } else { > gen_muldiv(ctx, op1, rd & 3, rs, rt); > } > > ? Agreed, that's better. The point was to reuse a bit of code, but now I've folded all of it into gen_mul_r5900. There are also R5900 specific MULT1 and MULTU1 instructions which might use it, so I folded the rd != 0 test into it as well. > > +/* No L2 cache, icache size 32k, dcache size 32k, uncached > > coherency. */ > > +.CP0_Config0 = (1 << 17) | (0x3 << 9) | (0x3 << 6) | (0x2 << > > CP0C0_K0), > > Why ICE set but DCE clear? I guess this corresponds to the incorrect L2 > cache reference as bit #17 is SC on the original R4000. That reference > has to go, obviously, as there's no L2 cache indication in the R5900's > Config register. > > As to ICE and DCE their reset defaults are both 0, so we might as well > use that, as we don't emulate caches anyway. If it turns out to matter to > any software, then we'll have to provide a more correct Config register > emulation as its writable bits are processor-specific. Agreed, thanks for finding this! > > +/* Note: Config1 is only used internally, the R5900 has only > > Config0. */ > > +.CP0_Status_rw_bitmask = 0xF4C79C1F, > > Maybe swap the two lines so that the Config1 register reference does not > confusingly seem to describe the Status r/w bitmask? Done. > > +#ifdef CONFIG_USER_ONLY > > + /* > > +* R5900 hardware traps to the Linux kernel for IEEE 754-1985 and LL/SC > > +* emulation. For user-only, qemu is the kernel, so we emulate the traps > > +* by simply emulating the instructions directly. > > +*/ > > Please use spaces rather than tabs for indentation, as per QEMU's coding > standard. Done. > > +.SEGBITS = 19, > > This has to be 32, as with any MIPS CPU that implements 32-bit virtual > addressing only. Specifically EntryHi register's VPN2 field goes up to > bit #31, which is (SEGBITS - 1). > > > +.PABITS = 20, > > And this has to be 32 as well, reflecting EntryLo0/1 registers' PFN > fields going up to bit #25. This corresponds to bit #31 on the external > address bus, which is (PABITS - 1). Right. I was unaware of these details, thanks! Fredrik
[Qemu-devel] [PATCH v4 0/8] target/mips: Support R5900 GCC programs in user mode
The primary purpose of this change is to support programs compiled by GCC for the R5900 target and thereby run R5900 Linux distributions, for example Gentoo. In particular, this avoids issues with cross compilation. This change has been tested with Gentoo compiled for R5900, including native compilation of several packages under QEMU. The R5900 implements the 64-bit MIPS III instruction set except DMULT, DMULTU, DDIV, DDIVU, LL, SC, LLD and SCD. The MIPS IV instructions MOVN, MOVZ and PREF are implemented. It has the R5900 specific three-operand instructions MADD, MADDU, MULT and MULTU as well as pipeline 1 versions MULT1, MULTU1, DIV1, DIVU1, MADD1, MADDU1, MFHI1, MFLO1, MTHI1 and MTLO1. A set of 93 128-bit multimedia instructions specific to the R5900 is also implemented. The Toshiba TX System RISC TX79 Core Architecture manual describes the R5900 processor: http://www.lukasz.dk/files/tx79architecture.pdf Fredrik Noring (8): target/mips: Define R5900 instructions and CPU preprocessor constants target/mips: Support R5900 specific three-operand MULT and MULTU target/mips: Support R5900 instructions MOVN, MOVZ and PREF from MIPS IV target/mips: Add function to signal RI exception unless user only target/mips: R5900 DMULT[U], DDIV[U], LL, SC, LLD and SCD are user only target/mips: Define the R5900 CPU linux-user/mips: Recognise the R5900 CPU model elf: Toshiba/Sony rather than MIPS are the implementors of the R5900 include/elf.h| 2 +- linux-user/mips/target_elf.h | 3 ++ target/mips/mips-defs.h | 2 + target/mips/translate.c | 80 ++-- target/mips/translate_init.inc.c | 47 +++ 5 files changed, 130 insertions(+), 4 deletions(-) -- 2.16.4
[Qemu-devel] [PATCH v4 1/8] target/mips: Define R5900 instructions and CPU preprocessor constants
The R5900 implements the 64-bit MIPS III instruction set except DMULT, DMULTU, DDIV, DDIVU, LL, SC, LLD and SCD. The MIPS IV instructions MOVN, MOVZ and PREF are implemented. It has the R5900 specific three-operand instructions MADD, MADDU, MULT and MULTU as well as pipeline 1 versions MULT1, MULTU1, DIV1, DIVU1, MADD1, MADDU1, MFHI1, MFLO1, MTHI1 and MTLO1. A set of 93 128-bit multimedia instructions specific to the R5900 is also implemented. The Toshiba TX System RISC TX79 Core Architecture manual describes the R5900 processor: http://www.lukasz.dk/files/tx79architecture.pdf Signed-off-by: Fredrik Noring --- target/mips/mips-defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index c8e99791ad..76550de2da 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -53,6 +53,7 @@ #define ASE_MSA 0x0100 /* Chip specific instructions. */ +#define INSN_R5900 0x1000 #defineINSN_LOONGSON2E 0x2000 #defineINSN_LOONGSON2F 0x4000 #defineINSN_VR54XX 0x8000 @@ -63,6 +64,7 @@ #defineCPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) #defineCPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) #defineCPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) +#define CPU_R5900 (CPU_MIPS3 | INSN_R5900) #defineCPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) #defineCPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) -- 2.16.4
[Qemu-devel] [PATCH v4 7/8] linux-user/mips: Recognise the R5900 CPU model
Signed-off-by: Fredrik Noring --- linux-user/mips/target_elf.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-user/mips/target_elf.h b/linux-user/mips/target_elf.h index fa5d30bf99..a98c9bd6ad 100644 --- a/linux-user/mips/target_elf.h +++ b/linux-user/mips/target_elf.h @@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags) if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) { return "mips32r6-generic"; } +if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) { +return "R5900"; +} return "24Kf"; } #endif -- 2.16.4
[Qemu-devel] [PATCH v4 2/8] target/mips: Support R5900 specific three-operand MULT and MULTU
Signed-off-by: Fredrik Noring --- target/mips/translate.c | 53 + 1 file changed, 53 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index ab16cdb911..fb571e278e 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -3768,6 +3768,57 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } +static void gen_mul_r5900(DisasContext *ctx, uint32_t opc, + int acc, int rd, int rs, int rt) +{ +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +switch (opc) { +case OPC_MULT: +{ +TCGv_i32 t2 = tcg_temp_new_i32(); +TCGv_i32 t3 = tcg_temp_new_i32(); +tcg_gen_trunc_tl_i32(t2, t0); +tcg_gen_trunc_tl_i32(t3, t1); +tcg_gen_muls2_i32(t2, t3, t2, t3); +if (rd) +tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); +tcg_gen_ext_i32_tl(cpu_LO[acc], t2); +tcg_gen_ext_i32_tl(cpu_HI[acc], t3); +tcg_temp_free_i32(t2); +tcg_temp_free_i32(t3); +} +break; +case OPC_MULTU: +{ +TCGv_i32 t2 = tcg_temp_new_i32(); +TCGv_i32 t3 = tcg_temp_new_i32(); +tcg_gen_trunc_tl_i32(t2, t0); +tcg_gen_trunc_tl_i32(t3, t1); +tcg_gen_mulu2_i32(t2, t3, t2, t3); +if (rd) +tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); +tcg_gen_ext_i32_tl(cpu_LO[acc], t2); +tcg_gen_ext_i32_tl(cpu_HI[acc], t3); +tcg_temp_free_i32(t2); +tcg_temp_free_i32(t3); +} +break; +default: +MIPS_INVAL("mul R5900"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + + out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { @@ -22378,6 +22429,8 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) check_insn(ctx, INSN_VR54XX); op1 = MASK_MUL_VR54XX(ctx->opcode); gen_mul_vr54xx(ctx, op1, rd, rs, rt); +} else if (ctx->insn_flags & INSN_R5900) { +gen_mul_r5900(ctx, op1, 0, rd, rs, rt); } else { gen_muldiv(ctx, op1, rd & 3, rs, rt); } -- 2.16.4
[Qemu-devel] [PATCH v4 4/8] target/mips: Add function to signal RI exception unless user only
The Linux kernel traps and emulates certain instructions. For user only, QEMU is the kernel, so we emulate those traps by simply emulating the instructions directly. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index c35be0053b..77d678353e 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1887,6 +1887,20 @@ static inline void check_insn_opc_removed(DisasContext *ctx, int flags) } } +/* + * Unless user only, when the kernel emulates the code, a "reserved + * instruction" exception is generated if the CPU has corresponding + * flag set which indicates that the instruction has been removed. + */ +static inline void check_insn_opc_user_only(DisasContext *ctx, int flags) +{ +#ifndef CONFIG_USER_ONLY +if (unlikely(ctx->insn_flags & flags)) { +generate_exception_end(ctx, EXCP_RI); +} +#endif +} + /* This code generates a "reserved instruction" exception if the CPU does not support 64-bit paired-single (PS) floating point data type */ static inline void check_ps(DisasContext *ctx) -- 2.16.4
[Qemu-devel] [PATCH v4 5/8] target/mips: R5900 DMULT[U], DDIV[U], LL, SC, LLD and SCD are user only
These MIPS III instructions are unavailable and therefore trapped and emulated by the Linux kernel. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 77d678353e..327e96307b 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -22458,6 +22458,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_DMULTU: case OPC_DDIV: case OPC_DDIVU: +check_insn_opc_user_only(ctx, INSN_R5900); check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); gen_muldiv(ctx, op1, 0, rs, rt); @@ -24962,6 +24963,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_LL: /* Load and stores */ check_insn(ctx, ISA_MIPS2); +check_insn_opc_user_only(ctx, INSN_R5900); /* Fallthrough */ case OPC_LWL: case OPC_LWR: @@ -24987,6 +24989,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SC: check_insn(ctx, ISA_MIPS2); check_insn_opc_removed(ctx, ISA_MIPS32R6); +check_insn_opc_user_only(ctx, INSN_R5900); gen_st_cond(ctx, op, rt, rs, imm); break; case OPC_CACHE: @@ -25253,9 +25256,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) #if defined(TARGET_MIPS64) /* MIPS64 opcodes */ +case OPC_LLD: +check_insn_opc_user_only(ctx, INSN_R5900); +/* fall through */ case OPC_LDL: case OPC_LDR: -case OPC_LLD: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* fall through */ case OPC_LWU: @@ -25275,6 +25280,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_SCD: check_insn_opc_removed(ctx, ISA_MIPS32R6); +check_insn_opc_user_only(ctx, INSN_R5900); check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); gen_st_cond(ctx, op, rt, rs, imm); -- 2.16.4
[Qemu-devel] [PATCH v4 6/8] target/mips: Define the R5900 CPU
The primary purpose of this change is to support programs compiled by GCC for the R5900 target and thereby run R5900 Linux distributions, for example Gentoo. In particular, this avoids issues with cross compilation. This change has been tested with Gentoo compiled for R5900, including native compilation of several packages under QEMU. Signed-off-by: Fredrik Noring --- target/mips/translate_init.inc.c | 47 1 file changed, 47 insertions(+) diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c index b3320b9dc7..71fd83de06 100644 --- a/target/mips/translate_init.inc.c +++ b/target/mips/translate_init.inc.c @@ -410,6 +410,53 @@ const mips_def_t mips_defs[] = .insn_flags = CPU_MIPS32R5 | ASE_MSA, .mmu_type = MMU_TYPE_R4000, }, +{ +.name = "R5900", +.CP0_PRid = 0x3800, +/* No L2 cache, icache size 32k, dcache size 32k, uncached coherency. */ +.CP0_Config0 = (0x3 << 9) | (0x3 << 6) | (0x2 << CP0C0_K0), +.CP0_Status_rw_bitmask = 0xF4C79C1F, +#ifdef CONFIG_USER_ONLY +/* + * R5900 hardware traps to the Linux kernel for IEEE 754-1985 and LL/SC + * emulation. For user only, QEMU is the kernel, so we emulate the traps + * by simply emulating the instructions directly. + * + * Note: Config1 is only used internally, the R5900 has only Config0. + */ +.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), +.CP0_LLAddr_rw_bitmask = 0x, +.CP0_LLAddr_shift = 4, +.CP1_fcr0 = (0x38 << FCR0_PRID) | (0x0 << FCR0_REV), +.CP1_fcr31 = 0, +.CP1_fcr31_rw_bitmask = 0x0183, +#else +/* + * The R5900 COP1 FPU implements single-precision floating-point + * operations but is not entirely IEEE 754-1985 compatible. In + * particular, + * + * - NaN (not a number) and plus/minus infinities are not supported; + * - exception mechanisms are not fully supported; + * - denormalized numbers are not supported; + * - rounding towards nearest and plus/minus infinities are not supported; + * - computed results usually differs in the least significant bit; + * - saturating instructions can differ more than the least significant bit. + * + * Since only rounding towards zero is supported, the two least + * significant bits of FCR31 are hardwired to 01. + * + * FPU emulation is disabled here until it is implemented. + * + * Note: Config1 is only used internally, the R5900 has only Config0. + */ +.CP0_Config1 = (47 << CP0C1_MMU), +#endif /* !CONFIG_USER_ONLY */ +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_R5900, +.mmu_type = MMU_TYPE_R4000, +}, { /* A generic CPU supporting MIPS32 Release 6 ISA. FIXME: Support IEEE 754-2008 FP. -- 2.16.4
[Qemu-devel] [PATCH v4 3/8] target/mips: Support R5900 instructions MOVN, MOVZ and PREF from MIPS IV
CPU_R5900 is defined as CPU_MIPS3 but it has the MIPS IV instructions MOVN, MOVZ and PREF as well. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index fb571e278e..c35be0053b 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -22402,7 +22402,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_MOVN: /* Conditional move */ case OPC_MOVZ: check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | - INSN_LOONGSON2E | INSN_LOONGSON2F); + INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900); gen_cond_move(ctx, op1, rd, rs, rt); break; case OPC_MFHI: /* Move from HI/LO */ @@ -24986,7 +24986,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_PREF: check_insn_opc_removed(ctx, ISA_MIPS32R6); -check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); +check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | + INSN_R5900); /* Treat as NOP. */ break; -- 2.16.4
[Qemu-devel] [PATCH v4 8/8] elf: Toshiba/Sony rather than MIPS are the implementors of the R5900
Sources [1][2] indicate that the Emotion Engine was designed by Toshiba and licensed to Sony. Others [3][4] claim it was a joint effort. It may therefore make sense to refer to the CPU as "Toshiba/Sony R5900". [1] http://cs.nyu.edu/courses/spring02/V22.0480-002/projects/aldrich/emotionengine.ppt [2] http://archive.arstechnica.com/reviews/1q00/playstation2/m-ee-3.html [3] http://docencia.ac.upc.edu/ETSETB/SEGPAR/microprocessors/emotionengine%20(mpr).pdf [4] http://www.eetimes.com/document.asp?doc_id=1144055 Reported-by: Maciej W. Rozycki Signed-off-by: Fredrik Noring --- include/elf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/elf.h b/include/elf.h index 312f68af81..2510fc7be4 100644 --- a/include/elf.h +++ b/include/elf.h @@ -76,7 +76,7 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_MACH_OCTEON2 0x008d /* Cavium Networks Octeon2 */ #define EF_MIPS_MACH_OCTEON3 0x008e /* Cavium Networks Octeon3 */ #define EF_MIPS_MACH_5400 0x0091 /* NEC VR5400 */ -#define EF_MIPS_MACH_5900 0x0092 /* MIPS R5900 */ +#define EF_MIPS_MACH_5900 0x0092 /* Toshiba/Sony R5900 */ #define EF_MIPS_MACH_5500 0x0098 /* NEC VR5500 */ #define EF_MIPS_MACH_9000 0x0099 /* PMC-Sierra's RM9000 */ #define EF_MIPS_MACH_LS2E 0x00a0 /* ST Microelectronics Loongson 2E */ -- 2.16.4
Re: [Qemu-devel] [PATCH v4 5/8] target/mips: R5900 DMULT[U], DDIV[U], LL, SC, LLD and SCD are user only
Hi Maciej, Philippe -- thank you for your reviews, On Mon, Sep 17, 2018 at 06:10:27PM +0100, Maciej W. Rozycki wrote: > Nitpicking here, but I think it's what makes code clean and pleasant to > read. I agree, that is important too. I will post an updated v5 soon. Another alternative change is to define check_insn_opc_user_only as static inline void check_insn_opc_user_only(DisasContext *ctx, int flags) { #ifndef CONFIG_USER_ONLY check_insn_opc_removed(ctx, flags); #endif } by referring to check_insn_opc_removed (instead of copying its definition). Would you consider this an improvement for v5 too? > I think it would make sense to keep the order of the checks consistent, > or otherwise code starts looking messy. > > The predominant order appears to be (as applicable) starting with a > check for the lowest ISA membership, followed by a check for the highest > ISA membership (R6 instruction cuts) and ending with processor-specific > special cases. I think this order makes sense in that it starts with > checks that have a wider scope and then moves on to ones of a narrower > scope, and I think keeping it would be good (as would fixing where the > addition of R6 broke it). Mode checks for otherwise existing > instructions then follow, which complements the pattern. Sure, thanks for clarifying the ordering rules! > So please make it: > > check_insn(ctx, ISA_MIPS3); > check_insn_opc_user_only(ctx, INSN_R5900); > check_mips_64(ctx); Done. > > @@ -25275,6 +25280,7 @@ static void decode_opc(CPUMIPSState *env, > > DisasContext *ctx) > > break; > > case OPC_SCD: > > check_insn_opc_removed(ctx, ISA_MIPS32R6); > > +check_insn_opc_user_only(ctx, INSN_R5900); > > check_insn(ctx, ISA_MIPS3); > > check_mips_64(ctx); > > gen_st_cond(ctx, op, rt, rs, imm); > > And please make it: > > check_insn_opc_removed(ctx, ISA_MIPS32R6); > check_insn(ctx, ISA_MIPS3); > check_insn_opc_user_only(ctx, INSN_R5900); > check_mips_64(ctx); Done. > here (and swapping the two former calls ought to be fixed separately; I > haven't checked if there are more cases like this, but if so, then they > would best be amended with a single change). I'll defer other ordering and indentation fixes since I'm not sure whether such changes would be accepted. Fredrik
[Qemu-devel] [PATCH v5 0/8] target/mips: Support R5900 GCC programs in user mode
The primary purpose of this change is to support programs compiled by GCC for the R5900 target and thereby run R5900 Linux distributions, for example Gentoo. In particular, this avoids issues with cross compilation. This change has been tested with Gentoo compiled for R5900, including native compilation of several packages under QEMU. The R5900 implements the 64-bit MIPS III instruction set except DMULT, DMULTU, DDIV, DDIVU, LL, SC, LLD and SCD. The MIPS IV instructions MOVN, MOVZ and PREF are implemented. It has the R5900 specific three-operand instructions MADD, MADDU, MULT and MULTU as well as pipeline 1 versions MULT1, MULTU1, DIV1, DIVU1, MADD1, MADDU1, MFHI1, MFLO1, MTHI1 and MTLO1. A set of 93 128-bit multimedia instructions specific to the R5900 is also implemented. The Toshiba TX System RISC TX79 Core Architecture manual describes the R5900 processor: http://www.lukasz.dk/files/tx79architecture.pdf Changes in v5: - Reorder check_insn_opc_user_only calls - Call check_insn_opc_removed in check_insn_opc_user_only Fredrik Noring (8): target/mips: Define R5900 instructions and CPU preprocessor constants target/mips: Support R5900 specific three-operand MULT and MULTU target/mips: Support R5900 instructions MOVN, MOVZ and PREF from MIPS IV target/mips: Add function to signal RI exception unless user only target/mips: R5900 DMULT[U], DDIV[U], LL[D] and SC[D] are user only target/mips: Define the R5900 CPU linux-user/mips: Recognise the R5900 CPU model elf: Toshiba/Sony rather than MIPS are the implementors of the R5900 include/elf.h| 2 +- linux-user/mips/target_elf.h | 3 ++ target/mips/mips-defs.h | 2 ++ target/mips/translate.c | 78 ++-- target/mips/translate_init.inc.c | 47 5 files changed, 128 insertions(+), 4 deletions(-) -- 2.16.4
[Qemu-devel] [PATCH v5 6/8] target/mips: Define the R5900 CPU
The primary purpose of this change is to support programs compiled by GCC for the R5900 target and thereby run R5900 Linux distributions, for example Gentoo. In particular, this avoids issues with cross compilation. This change has been tested with Gentoo compiled for R5900, including native compilation of several packages under QEMU. Signed-off-by: Fredrik Noring --- target/mips/translate_init.inc.c | 47 1 file changed, 47 insertions(+) diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c index b3320b9dc7..71fd83de06 100644 --- a/target/mips/translate_init.inc.c +++ b/target/mips/translate_init.inc.c @@ -410,6 +410,53 @@ const mips_def_t mips_defs[] = .insn_flags = CPU_MIPS32R5 | ASE_MSA, .mmu_type = MMU_TYPE_R4000, }, +{ +.name = "R5900", +.CP0_PRid = 0x3800, +/* No L2 cache, icache size 32k, dcache size 32k, uncached coherency. */ +.CP0_Config0 = (0x3 << 9) | (0x3 << 6) | (0x2 << CP0C0_K0), +.CP0_Status_rw_bitmask = 0xF4C79C1F, +#ifdef CONFIG_USER_ONLY +/* + * R5900 hardware traps to the Linux kernel for IEEE 754-1985 and LL/SC + * emulation. For user only, QEMU is the kernel, so we emulate the traps + * by simply emulating the instructions directly. + * + * Note: Config1 is only used internally, the R5900 has only Config0. + */ +.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), +.CP0_LLAddr_rw_bitmask = 0x, +.CP0_LLAddr_shift = 4, +.CP1_fcr0 = (0x38 << FCR0_PRID) | (0x0 << FCR0_REV), +.CP1_fcr31 = 0, +.CP1_fcr31_rw_bitmask = 0x0183, +#else +/* + * The R5900 COP1 FPU implements single-precision floating-point + * operations but is not entirely IEEE 754-1985 compatible. In + * particular, + * + * - NaN (not a number) and plus/minus infinities are not supported; + * - exception mechanisms are not fully supported; + * - denormalized numbers are not supported; + * - rounding towards nearest and plus/minus infinities are not supported; + * - computed results usually differs in the least significant bit; + * - saturating instructions can differ more than the least significant bit. + * + * Since only rounding towards zero is supported, the two least + * significant bits of FCR31 are hardwired to 01. + * + * FPU emulation is disabled here until it is implemented. + * + * Note: Config1 is only used internally, the R5900 has only Config0. + */ +.CP0_Config1 = (47 << CP0C1_MMU), +#endif /* !CONFIG_USER_ONLY */ +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_R5900, +.mmu_type = MMU_TYPE_R4000, +}, { /* A generic CPU supporting MIPS32 Release 6 ISA. FIXME: Support IEEE 754-2008 FP. -- 2.16.4
[Qemu-devel] [PATCH v5 1/8] target/mips: Define R5900 instructions and CPU preprocessor constants
The R5900 implements the 64-bit MIPS III instruction set except DMULT, DMULTU, DDIV, DDIVU, LL, SC, LLD and SCD. The MIPS IV instructions MOVN, MOVZ and PREF are implemented. It has the R5900 specific three-operand instructions MADD, MADDU, MULT and MULTU as well as pipeline 1 versions MULT1, MULTU1, DIV1, DIVU1, MADD1, MADDU1, MFHI1, MFLO1, MTHI1 and MTLO1. A set of 93 128-bit multimedia instructions specific to the R5900 is also implemented. The Toshiba TX System RISC TX79 Core Architecture manual describes the R5900 processor: http://www.lukasz.dk/files/tx79architecture.pdf Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/mips-defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index c8e99791ad..76550de2da 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -53,6 +53,7 @@ #define ASE_MSA 0x0100 /* Chip specific instructions. */ +#define INSN_R5900 0x1000 #defineINSN_LOONGSON2E 0x2000 #defineINSN_LOONGSON2F 0x4000 #defineINSN_VR54XX 0x8000 @@ -63,6 +64,7 @@ #defineCPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) #defineCPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) #defineCPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) +#define CPU_R5900 (CPU_MIPS3 | INSN_R5900) #defineCPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) #defineCPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) -- 2.16.4
[Qemu-devel] [PATCH v5 5/8] target/mips: R5900 DMULT[U], DDIV[U], LL[D] and SC[D] are user only
These MIPS III instructions are unavailable and therefore trapped and emulated by the Linux kernel. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/translate.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 2fe46f8775..67a6070e4f 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -22457,6 +22457,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_DDIV: case OPC_DDIVU: check_insn(ctx, ISA_MIPS3); +check_insn_opc_user_only(ctx, INSN_R5900); check_mips_64(ctx); gen_muldiv(ctx, op1, 0, rs, rt); break; @@ -24960,6 +24961,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_LL: /* Load and stores */ check_insn(ctx, ISA_MIPS2); +check_insn_opc_user_only(ctx, INSN_R5900); /* Fallthrough */ case OPC_LWL: case OPC_LWR: @@ -24985,6 +24987,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SC: check_insn(ctx, ISA_MIPS2); check_insn_opc_removed(ctx, ISA_MIPS32R6); +check_insn_opc_user_only(ctx, INSN_R5900); gen_st_cond(ctx, op, rt, rs, imm); break; case OPC_CACHE: @@ -25251,9 +25254,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) #if defined(TARGET_MIPS64) /* MIPS64 opcodes */ +case OPC_LLD: +check_insn_opc_user_only(ctx, INSN_R5900); +/* fall through */ case OPC_LDL: case OPC_LDR: -case OPC_LLD: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* fall through */ case OPC_LWU: @@ -25274,6 +25279,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SCD: check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS3); +check_insn_opc_user_only(ctx, INSN_R5900); check_mips_64(ctx); gen_st_cond(ctx, op, rt, rs, imm); break; -- 2.16.4
[Qemu-devel] [PATCH v5 4/8] target/mips: Add function to signal RI exception unless user only
The Linux kernel traps and emulates certain instructions. For user only, QEMU is the kernel, so we emulate those traps by simply emulating the instructions directly. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/translate.c | 12 1 file changed, 12 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index c35be0053b..2fe46f8775 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1887,6 +1887,18 @@ static inline void check_insn_opc_removed(DisasContext *ctx, int flags) } } +/* + * Unless user only, when the kernel emulates the code, a "reserved + * instruction" exception is generated if the CPU has corresponding + * flag set which indicates that the instruction has been removed. + */ +static inline void check_insn_opc_user_only(DisasContext *ctx, int flags) +{ +#ifndef CONFIG_USER_ONLY +check_insn_opc_removed(ctx, flags); +#endif +} + /* This code generates a "reserved instruction" exception if the CPU does not support 64-bit paired-single (PS) floating point data type */ static inline void check_ps(DisasContext *ctx) -- 2.16.4
[Qemu-devel] [PATCH v5 2/8] target/mips: Support R5900 specific three-operand MULT and MULTU
Signed-off-by: Fredrik Noring --- target/mips/translate.c | 53 + 1 file changed, 53 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index ab16cdb911..fb571e278e 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -3768,6 +3768,57 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } +static void gen_mul_r5900(DisasContext *ctx, uint32_t opc, + int acc, int rd, int rs, int rt) +{ +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +switch (opc) { +case OPC_MULT: +{ +TCGv_i32 t2 = tcg_temp_new_i32(); +TCGv_i32 t3 = tcg_temp_new_i32(); +tcg_gen_trunc_tl_i32(t2, t0); +tcg_gen_trunc_tl_i32(t3, t1); +tcg_gen_muls2_i32(t2, t3, t2, t3); +if (rd) +tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); +tcg_gen_ext_i32_tl(cpu_LO[acc], t2); +tcg_gen_ext_i32_tl(cpu_HI[acc], t3); +tcg_temp_free_i32(t2); +tcg_temp_free_i32(t3); +} +break; +case OPC_MULTU: +{ +TCGv_i32 t2 = tcg_temp_new_i32(); +TCGv_i32 t3 = tcg_temp_new_i32(); +tcg_gen_trunc_tl_i32(t2, t0); +tcg_gen_trunc_tl_i32(t3, t1); +tcg_gen_mulu2_i32(t2, t3, t2, t3); +if (rd) +tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); +tcg_gen_ext_i32_tl(cpu_LO[acc], t2); +tcg_gen_ext_i32_tl(cpu_HI[acc], t3); +tcg_temp_free_i32(t2); +tcg_temp_free_i32(t3); +} +break; +default: +MIPS_INVAL("mul R5900"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + + out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { @@ -22378,6 +22429,8 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) check_insn(ctx, INSN_VR54XX); op1 = MASK_MUL_VR54XX(ctx->opcode); gen_mul_vr54xx(ctx, op1, rd, rs, rt); +} else if (ctx->insn_flags & INSN_R5900) { +gen_mul_r5900(ctx, op1, 0, rd, rs, rt); } else { gen_muldiv(ctx, op1, rd & 3, rs, rt); } -- 2.16.4
[Qemu-devel] [PATCH v5 8/8] elf: Toshiba/Sony rather than MIPS are the implementors of the R5900
Sources [1][2] indicate that the Emotion Engine was designed by Toshiba and licensed to Sony. Others [3][4] claim it was a joint effort. It may therefore make sense to refer to the CPU as "Toshiba/Sony R5900". [1] http://cs.nyu.edu/courses/spring02/V22.0480-002/projects/aldrich/emotionengine.ppt [2] http://archive.arstechnica.com/reviews/1q00/playstation2/m-ee-3.html [3] http://docencia.ac.upc.edu/ETSETB/SEGPAR/microprocessors/emotionengine%20(mpr).pdf [4] http://www.eetimes.com/document.asp?doc_id=1144055 Reported-by: Maciej W. Rozycki Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- include/elf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/elf.h b/include/elf.h index 312f68af81..2510fc7be4 100644 --- a/include/elf.h +++ b/include/elf.h @@ -76,7 +76,7 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_MACH_OCTEON2 0x008d /* Cavium Networks Octeon2 */ #define EF_MIPS_MACH_OCTEON3 0x008e /* Cavium Networks Octeon3 */ #define EF_MIPS_MACH_5400 0x0091 /* NEC VR5400 */ -#define EF_MIPS_MACH_5900 0x0092 /* MIPS R5900 */ +#define EF_MIPS_MACH_5900 0x0092 /* Toshiba/Sony R5900 */ #define EF_MIPS_MACH_5500 0x0098 /* NEC VR5500 */ #define EF_MIPS_MACH_9000 0x0099 /* PMC-Sierra's RM9000 */ #define EF_MIPS_MACH_LS2E 0x00a0 /* ST Microelectronics Loongson 2E */ -- 2.16.4
[Qemu-devel] [PATCH v5 7/8] linux-user/mips: Recognise the R5900 CPU model
Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- linux-user/mips/target_elf.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-user/mips/target_elf.h b/linux-user/mips/target_elf.h index fa5d30bf99..a98c9bd6ad 100644 --- a/linux-user/mips/target_elf.h +++ b/linux-user/mips/target_elf.h @@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags) if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) { return "mips32r6-generic"; } +if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) { +return "R5900"; +} return "24Kf"; } #endif -- 2.16.4
[Qemu-devel] [PATCH v5 3/8] target/mips: Support R5900 instructions MOVN, MOVZ and PREF from MIPS IV
CPU_R5900 is defined as CPU_MIPS3 but it has the MIPS IV instructions MOVN, MOVZ and PREF as well. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/translate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index fb571e278e..c35be0053b 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -22402,7 +22402,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_MOVN: /* Conditional move */ case OPC_MOVZ: check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | - INSN_LOONGSON2E | INSN_LOONGSON2F); + INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900); gen_cond_move(ctx, op1, rd, rs, rt); break; case OPC_MFHI: /* Move from HI/LO */ @@ -24986,7 +24986,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_PREF: check_insn_opc_removed(ctx, ISA_MIPS32R6); -check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); +check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | + INSN_R5900); /* Treat as NOP. */ break; -- 2.16.4
Re: [Qemu-devel] [PATCH v5 0/8] target/mips: Support R5900 GCC programs in user mode
Hi Aleksandar, Thank your for your review comments. Please find clarifications and questions below: > > Subject: [PATCH v5 0/8] target/mips: Support R5900 GCC programs in user mode > > The expression "GCC programs" will raise many eyebrows. What R5900 > programs are not "GCC programs"? That would be programs not compiled by GCC, as explained in the first sentence of the body text. The subject line is very brief by necessity since it is limited to 72 or so characters. It was an attempt to qualify the subject line "initial support for MIPS R5900", which you previously rejected. I agree that there are probably better wordings. > How come (as it is really implied by the title) QEMU suddenly becomes > aware whether it emulates executables compiled by GCC, if its basic > design/architecture principles include being agnostic on the tools used > for compiling executables? Well, no, your implication and conclusion are invalid because the commit message does not say anything about programs that are not compiled by GCC. Nevertheless, it may be helpful to add such a statement. Perhaps that was your point? > Please clarify what is supported by your changes and what is not. I > suspect you actually meant something slightly different than "GCC > programs" or "programs compiled by GCC". The main use case and motivation for this change is to run R5900 Linux distributions compiled by GCC. Other use cases, such as running programs that contain unsupported machine code, or using the FPU in system mode, are secondary. As Maciej noted, it is probably wise to assert exceptions in unsupported cases. GCC, in its current version, by itself, by inspection of the GCC source code and inspection of the generated machine code, for the R5900 target, only emits two instructions that are specific to the R5900: the three- operand MULT and MULTU. GCC and libc also emit certain MIPS III and IV instructions that are not implemented in R5900 hardware. Those are normally trapped and emulated by the Linux kernel, and therefore need to be treated accordingly by QEMU. This is addressed, in turn, by the patch series. "Programs compiled by GCC" was taken to mean source code compiled by GCC under the restrictions above. One can, even with the apparent limitations, with a bit of effort obtain a fully functioning operating system such as R5900 Gentoo. Strictly speaking, programs need not be compiled by GCC under these restrictions, although GCC is very much the target of this change due to its practical importance. > > The primary purpose of this change is to support programs compiled by > > GCC for the R5900 target and thereby run R5900 Linux distributions, for > > example Gentoo. In particular, this avoids issues with cross compilation. > > What issues with cross compilation are avoided by your changes? How are > they avoided? Are they avoided or resolved? Problems with cross-compilation may be related to host and target differences in integer sizes, pointer sizes, machine code, ABI, etc. Sometimes cross-compilation is not even supported by the build script for a given package. One effective way to sidestep ("avoid") these problems is to replace the cross-compiler with a native compiler. This change of methods does not "resolve" the inherent problems with cross-compilation. > > This change has been tested with Gentoo compiled for R5900, including > > native compilation of several packages under QEMU. > > In the preceding paragraph, you mention issues with cross compilation. > Now you mention native compilation. In both cases, the circumstances are > vague. Why such confusion, incompleteness, and unclarity? Well, the native compiler naturally replaces the cross-compiler, because one typically uses one or the other, and preferably the native compiler when circumstances admit this. The native compiler is also a rather good test case for the R5900 QEMU user mode. Additionally, Gentoo is well-known for compiling its packages from sources. > Can you rewrite these couple of paragraphs in a clear way, not omitting > any relevant info that will prevent reader from understanding them, but > at the same time not making explanations too long and complex? I will make a try for v6 of the patch series. > Before your changes are accepted, other people in the community must be > able to test them. In that light, can you provide the repro procedure for > the scenario with Gentoo? I used the Gentoo sys-devel/crossdev package https://wiki.gentoo.org/wiki/Crossdev with a couple of patches mainly to simplify the handling of LL/SC and floating point support, avoiding complications with additional configure and compiler flags. I plan to submit these patches, in some form, for GAS and GCC inclusion. However, building Gentoo for R5900 is quite a bit more than the necessities for R5900 QEMU user mode testing purposes. > And also some other illustrative scenarios, not related to Gentoo. Link > to toolchain used would be useful. If you have prebuilt Gentoo
Re: [Qemu-devel] [PATCH v5 0/8] target/mips: Support R5900 GCC programs in user mode
Hi Philippe, > > That would be programs not compiled by GCC, as explained in the first > > sentence of the body text. The subject line is very brief by necessity > > since it is limited to 72 or so characters. It was an attempt to qualify > > the subject line "initial support for MIPS R5900", which you previously > > rejected. I agree that there are probably better wordings. > > What about "linux-user support for MIPS R5900"? This support comes with limitations which would be appropriate to acknowledge. Aleksandar has rejected both "initial" and "GCC programs" as subject line qualifications. I suppose we need to find other words to express this. > > I used the Gentoo sys-devel/crossdev package > > > > https://wiki.gentoo.org/wiki/Crossdev > > > > with a couple of patches mainly to simplify the handling of LL/SC and > > floating point support, avoiding complications with additional configure and > > compiler flags. I plan to submit these patches, in some form, for GAS and > > GCC inclusion. However, building Gentoo for R5900 is quite a bit more than > > the necessities for R5900 QEMU user mode testing purposes. > > We could manage to build a docker mips-r5900 cross-compiler image, such: > https://lists.gnu.org/archive/html/qemu-devel/2018-06/msg06908.html > > But we'll need your patches. Nice. :) I'm happy to post GAS and GCC patches along with details. Fredrik
Re: [Qemu-devel] [PATCH v5 6/8] target/mips: Define the R5900 CPU
Hi Jürgen, Maciej, > The original website is down, but there is a backup: > http://ps2linux.no-ip.info/playstation2-linux.com/faq.html#Availability__When_Where_and_how_much > > There was also the question to release the documents for free. > http://ps2linux.no-ip.info/playstation2-linux.com/forum/message23e0.html?msg_id=51027 Thanks, Jürgen! > > > > +.CP0_PRid = 0x3800, > > > > > > "The implementation number of the C790 processor is 0x38". > > > > I'll leave the answer to what the values of PRId are for the R5900 vs the > > C790 to Fredrik or Jürgen. I suspect that the difference is in the Rev > > field only. > > According to the documentation tx79architecture.pdf the C790 has 0x3800. > According to the documentation coreum_e.pdf the R5900 has 0x2Exx. > xx depends on the revision. I thought that I have seen several revisions, > but in my log files I found only 0x2e31. I have verified with hardware that model SCPH-77004 is 0x2e42 whereas an older model such as SCPH-50004 is 0x2e31. Someone has made a substantial table of models at http://www.ps2-home.com/forum/app.php/page/ps2ident-database where the columns "EE implementation" and "EE revision" correspond to PRId. Fredrik
Re: [Qemu-devel] Correction needed for R5900 instruction decoding
[ Philippe and Emilio -- thank you for cc-ing me. Good catch, since I'm not subscribed to the QEMU mailing list. Changes to the R5900 emulation are certainly of interest. ] Hi Aleksandar, Philippe, On Thu, Nov 01, 2018 at 03:31:54PM +0100, Philippe Mathieu-Daudé wrote: > Cc'ing Fredrik. > > On 1/11/18 12:06, Aleksandar Markovic wrote: > > Hi, Fridrik, > > > > I did some closer code inspection of R5900 in last few days, and I > > noticed some sub-optimal implementation in the area where R5900-specific > > opcodes overlap with the rest-of-MIPS-CPUs opcodes. > > > > The right implementation should be based on the principle that all such > > cases are covered with if statements involving INSN_R5900 flag, like > > this: > > > > if (ctx->insn_flags & INSN_R5900) { > > > > } else { > > > > } > > > > You followed that principle for OPC_SPECIAL2 and OPC_SPECIAL3, but for > > some other opcodes not. For example, there are lines: > > > > if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 || > > opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) { > > > > or > > > > switch (opc) { > > case OPC_MFHI: > > case TX79_MMI_MFHI1: > > > > Such implementation makes it difficult to discern R5900 and non-R5900 > > cases. Potentialy allows bugs to sneak in and affect non-R5900 support. MFLO1, MFHI1, MTLO1 and MTHI1 for the TX79 and the R5900 are already decoded in the ISA specific decode_tx79_mmi function, and thereby follow your first suggested pattern. They do however reuse the gen_HILO function, but it is a simpel matter to post a patch to make a new gen_tx79_HILO1 variant that is almost identical to the original gen_HILO. The only other case is gen_muldiv that is used for DIV1 and DIVU1. The same argument applies and a TX79 specific variant would be similar to the original, but I can certainly post a variant for that one too. > > The correction is not that difficult, I gather. Worse comme to worst, > > you can remove R5900 MFLO1 and MFHI1 altogether, they are not that > > essential at this moment, but do try correcting the decoding stuff as I > > described. Can you please make these changes in next few days or so > > (given that 3.1 release is getting closer and closer), and send them to > > the list? MFLO1 and MFHI1 are essential for MULT1, MULTU1, DIV1 and DIVU1 as well as MADD1 and MADDU1 in the patch series I posted 25 October "[PATCH 00/11] target/mips: Amend R5900 support". I will post updated patches shortly! > > It is my bad that I didn't spot this during review, but in any case, I > > think this should be fixed in 3.1 to make sure that non-R5900 > > functionalities are intact. It is a common pattern in target/mips/translate.c to cover several ISAs in the same gen_* and decode_* functions, especially when there are only minor differences between them. Fredrik
[Qemu-devel] [PATCH v2 00/12] target/mips: Amend R5900 support
This series amends the R5900 support with the following noncritical features: - R5900 MFLO1, MFHI1, MTLO1 and MTHI1 are generated in gen_HILO1_tx79. - R5900 DIV1 and DIVU1 are generated in gen_div1_tx79. - The R5900 LQ and SQ instructions are now also covered by the Toshiba MMI ASE, as per the TX79 manual[1]. - The three-operand MADD and MADDU instructions specific to the R5900 and the Toshiba TX19, TX39 and TX79 cores are now supported and tested by the R5900 TCG test suite. - The three-operand MADD1 and MADDU1 pipeline 1 instructions specific to the R5900 and the Toshiba TX79 core are now supported and tested by the R5900 TCG test suite. - The membership field of struct mips_opcode is now uint64_t instead of unsigned long, that is too small in 32-bit builds. - R5900 disassembly constants are defined. - The R5900 instructions DIV1, DIVU1, MFLO, MTLO, MFHI, MTHI, MULT1 and MULTU1 are now disassembled. Unfortunately, the opcodes for MADD1 and MADDU1 clash with the opcodes for CLZ and CLO, resulting in incorrect disassembly. MADD1 and MADDU1 are therefore left undefined. This series has been successfully built with the 8 different build configurations {gcc,clang} x -m64 x mips{,64}el-{linux-user,softmmu} in addition successfully completing the R5900 test suite cd tests/tcg/mips/mipsr5900 && make check Reference: [1] "Toshiba TX System RISC TX79 Core Architecture", Toshiba Corporation, section B.3.2, p. B-4, <https://wiki.qemu.org/File:C790.pdf>. Changes in v2: - Drop rejected rename of ASE_MMI to ASE_TOSHIBA_MMI - Generate R5900 DIV1 and DIVU1 in gen_div1_tx79 - Generate R5900 MFLO1, MFHI1, MTLO1 and MTHI1 in gen_HILO1_tx79 Fredrik Noring (10): target/mips: Generate R5900 MFLO1, MFHI1, MTLO1 and MTHI1 in gen_HILO1_tx79 target/mips: Generate R5900 DIV1 and DIVU1 in gen_div1_tx79 target/mips: R5900 LQ and SQ also belong to the Toshiba MMI ASE target/mips: Support R5900 three-operand MADD1 and MADDU1 tests/tcg/mips: Test R5900 three-operand MADD tests/tcg/mips: Test R5900 three-operand MADD1 tests/tcg/mips: Test R5900 three-operand MADDU tests/tcg/mips: Test R5900 three-operand MADDU1 disas/mips: Define R5900 disassembly constants disas/mips: Disassemble R5900 DIV[U]1, M{F,T}{LO,HI}1 and MULT[U]1 Philippe Mathieu-Daudé (2): target/mips: Support Toshiba specific three-operand MADD and MADDU disas/mips: Increase 'member of ISAs' flag holder size disas/mips.c | 22 +++- target/mips/translate.c | 206 ++ tests/tcg/mips/mipsr5900/Makefile | 2 + tests/tcg/mips/mipsr5900/madd.c | 78 +++ tests/tcg/mips/mipsr5900/maddu.c | 70 ++ 5 files changed, 351 insertions(+), 27 deletions(-) create mode 100644 tests/tcg/mips/mipsr5900/madd.c create mode 100644 tests/tcg/mips/mipsr5900/maddu.c -- 2.18.1
[Qemu-devel] [PATCH v2 01/12] target/mips: Generate R5900 MFLO1, MFHI1, MTLO1 and MTHI1 in gen_HILO1_tx79
MFLO1, MFHI1, MTLO1 and MTHI1 are generated in gen_HILO1_tx79 instead of the generic gen_HILO. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 67 ++--- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 60320cbe69..f3993cf7d7 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4359,24 +4359,72 @@ static void gen_shift(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } +/* Move to and from TX79 HI1/LO1 registers. */ +static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg) +{ +if (reg == 0 && (opc == TX79_MMI_MFHI1 || opc == TX79_MMI_MFLO1)) { +/* Treat as NOP. */ +return; +} + +switch (opc) { +case TX79_MMI_MFHI1: +#if defined(TARGET_MIPS64) +tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]); +#else +tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]); +#endif +break; +case TX79_MMI_MFLO1: +#if defined(TARGET_MIPS64) +tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[1]); +#else +tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]); +#endif +break; +case TX79_MMI_MTHI1: +if (reg != 0) { +#if defined(TARGET_MIPS64) +tcg_gen_ext32s_tl(cpu_HI[1], cpu_gpr[reg]); +#else +tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]); +#endif +} else { +tcg_gen_movi_tl(cpu_HI[1], 0); +} +break; +case TX79_MMI_MTLO1: +if (reg != 0) { +#if defined(TARGET_MIPS64) +tcg_gen_ext32s_tl(cpu_LO[1], cpu_gpr[reg]); +#else +tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]); +#endif +} else { +tcg_gen_movi_tl(cpu_LO[1], 0); +} +break; +default: +MIPS_INVAL("MFTHILO TX79"); +generate_exception_end(ctx, EXCP_RI); +break; +} +} + /* Arithmetic on HI/LO registers */ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) { -if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 || - opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) { +if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { /* Treat as NOP. */ return; } if (acc != 0) { -if (!(ctx->insn_flags & INSN_R5900)) { -check_dsp(ctx); -} +check_dsp(ctx); } switch (opc) { case OPC_MFHI: -case TX79_MMI_MFHI1: #if defined(TARGET_MIPS64) if (acc != 0) { tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); @@ -4387,7 +4435,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) } break; case OPC_MFLO: -case TX79_MMI_MFLO1: #if defined(TARGET_MIPS64) if (acc != 0) { tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); @@ -4398,7 +4445,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) } break; case OPC_MTHI: -case TX79_MMI_MTHI1: if (reg != 0) { #if defined(TARGET_MIPS64) if (acc != 0) { @@ -4413,7 +4459,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) } break; case OPC_MTLO: -case TX79_MMI_MTLO1: if (reg != 0) { #if defined(TARGET_MIPS64) if (acc != 0) { @@ -26500,11 +26545,11 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) break; case TX79_MMI_MTLO1: case TX79_MMI_MTHI1: -gen_HILO(ctx, opc, 1, rs); +gen_HILO1_tx79(ctx, opc, rs); break; case TX79_MMI_MFLO1: case TX79_MMI_MFHI1: -gen_HILO(ctx, opc, 1, rd); +gen_HILO1_tx79(ctx, opc, rd); break; case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */ case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */ -- 2.18.1
[Qemu-devel] [PATCH v2 03/12] target/mips: R5900 LQ and SQ also belong to the Toshiba MMI ASE
Signed-off-by: Fredrik Noring --- target/mips/translate.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 6e5a8a2565..624e53644d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -27992,7 +27992,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) } break; case OPC_SPECIAL3: -if (ctx->insn_flags & INSN_R5900) { +if ((ctx->insn_flags & INSN_R5900) && +(ctx->insn_flags & ASE_MMI)) { decode_tx79_sq(env, ctx);/* TX79_SQ */ } else { decode_opc_special3(env, ctx); @@ -28656,7 +28657,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) } break; case OPC_MSA: /* OPC_MDMX */ -if (ctx->insn_flags & INSN_R5900) { +if ((ctx->insn_flags & INSN_R5900) && +(ctx->insn_flags & ASE_MMI)) { decode_tx79_lq(env, ctx);/* TX79_LQ */ } else { /* MDMX: Not implemented. */ -- 2.18.1
[Qemu-devel] [PATCH v2 02/12] target/mips: Generate R5900 DIV1 and DIVU1 in gen_div1_tx79
DIV1 and DIVU1 are generated in gen_div1_tx79 instead of the generic gen_muldiv. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 65 + 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index f3993cf7d7..6e5a8a2565 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4759,6 +4759,63 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) tcg_temp_free(t1); } +static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) +{ +TCGv t0, t1; + +t0 = tcg_temp_new(); +t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +switch (opc) { +case TX79_MMI_DIV1: +{ +TCGv t2 = tcg_temp_new(); +TCGv t3 = tcg_temp_new(); +tcg_gen_ext32s_tl(t0, t0); +tcg_gen_ext32s_tl(t1, t1); +tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); +tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); +tcg_gen_and_tl(t2, t2, t3); +tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); +tcg_gen_or_tl(t2, t2, t3); +tcg_gen_movi_tl(t3, 0); +tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); +tcg_gen_div_tl(cpu_LO[1], t0, t1); +tcg_gen_rem_tl(cpu_HI[1], t0, t1); +tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); +tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); +tcg_temp_free(t3); +tcg_temp_free(t2); +} +break; +case TX79_MMI_DIVU1: +{ +TCGv t2 = tcg_const_tl(0); +TCGv t3 = tcg_const_tl(1); +tcg_gen_ext32u_tl(t0, t0); +tcg_gen_ext32u_tl(t1, t1); +tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); +tcg_gen_divu_tl(cpu_LO[1], t0, t1); +tcg_gen_remu_tl(cpu_HI[1], t0, t1); +tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); +tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); +tcg_temp_free(t3); +tcg_temp_free(t2); +} +break; +default: +MIPS_INVAL("div1 TX79"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + static void gen_muldiv(DisasContext *ctx, uint32_t opc, int acc, int rs, int rt) { @@ -4771,14 +4828,11 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, gen_load_gpr(t1, rt); if (acc != 0) { -if (!(ctx->insn_flags & INSN_R5900)) { -check_dsp(ctx); -} +check_dsp(ctx); } switch (opc) { case OPC_DIV: -case TX79_MMI_DIV1: { TCGv t2 = tcg_temp_new(); TCGv t3 = tcg_temp_new(); @@ -4800,7 +4854,6 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, } break; case OPC_DIVU: -case TX79_MMI_DIVU1: { TCGv t2 = tcg_const_tl(0); TCGv t3 = tcg_const_tl(1); @@ -26541,7 +26594,7 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) break; case TX79_MMI_DIV1: case TX79_MMI_DIVU1: -gen_muldiv(ctx, opc, 1, rs, rt); +gen_div1_tx79(ctx, opc, rs, rt); break; case TX79_MMI_MTLO1: case TX79_MMI_MTHI1: -- 2.18.1
[Qemu-devel] [PATCH v2 12/12] disas/mips: Disassemble R5900 DIV[U]1, M{F, T}{LO, HI}1 and MULT[U]1
Disassemble the R5900 instructions DIV1, DIVU1, MFLO1, MTLO1, MFHI1, MTHI1, MULT1 and MULTU1. The opcodes for MADD1 and MADDU1 clash with the opcodes for CLZ and CLO, resulting in incorrect disassembly. They are therefore omitted here. Signed-off-by: Fredrik Noring --- disas/mips.c | 12 1 file changed, 12 insertions(+) diff --git a/disas/mips.c b/disas/mips.c index 9f01fda8bd..eddfb59325 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -2323,6 +2323,8 @@ const struct mips_opcode mips_builtin_opcodes[] = {"div", "z,t", 0x001a, 0xffe0, RD_s|RD_t|WR_HILO, 0, I1 }, {"div", "d,v,t", 0,(int) M_DIV_3,INSN_MACRO, 0, I1 }, {"div", "d,v,I", 0,(int) M_DIV_3I, INSN_MACRO, 0, I1 }, +{"div1","z,s,t", 0x701a, 0xfc00, RD_s | RD_t | WR_HILO, 0, EE }, +{"div1","z,t",0x701a, 0xffe0, RD_s | RD_t | WR_HILO, 0, EE }, {"div.d", "D,V,T", 0x4623, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,0, I1 }, {"div.s", "D,V,T", 0x4603, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,0, I1 }, {"div.ps", "D,V,T", 0x46c3, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,0, SB1 }, @@ -2331,6 +2333,8 @@ const struct mips_opcode mips_builtin_opcodes[] = {"divu","z,t", 0x001b, 0xffe0, RD_s|RD_t|WR_HILO, 0, I1 }, {"divu","d,v,t", 0,(int) M_DIVU_3, INSN_MACRO, 0, I1 }, {"divu","d,v,I", 0,(int) M_DIVU_3I, INSN_MACRO, 0, I1 }, +{"divu1", "z,s,t", 0x701b, 0xfc00, RD_s | RD_t | WR_HILO, 0, EE }, +{"divu1", "z,t",0x701b, 0xffe0, RD_s | WR_HILO , 0, EE }, {"dla", "t,A(b)", 0,(int) M_DLA_AB, INSN_MACRO, 0, I3 }, {"dlca","t,A(b)", 0,(int) M_DLCA_AB, INSN_MACRO, 0, I3 }, {"dli", "t,j", 0x2400, 0xffe0, WR_t, 0, I3 }, /* addiu */ @@ -2594,8 +2598,10 @@ const struct mips_opcode mips_builtin_opcodes[] = {"mfdr","t,G", 0x703d, 0xffe007ff, LCD|WR_t|RD_C0, 0, N5 }, {"mfhi","d", 0x0010, 0x07ff, WR_d|RD_HI, 0, I1 }, {"mfhi","d,9", 0x0010, 0xff9f07ff, WR_d|RD_HI, 0, D32 }, +{"mfhi1", "d", 0x7010, 0x07ff, WR_d | RD_HI, 0, EE}, {"mflo","d", 0x0012, 0x07ff, WR_d|RD_LO, 0, I1 }, {"mflo","d,9", 0x0012, 0xff9f07ff, WR_d|RD_LO, 0, D32 }, +{"mflo1", "d", 0x7012, 0x07ff, WR_d | RD_LO, 0, EE}, {"mflhxu", "d", 0x0052, 0x07ff, WR_d|MOD_HILO, 0, SMT }, {"min.ob", "X,Y,Q", 0x7806, 0xfc20003f, WR_D|RD_S|RD_T|FP_D,0, MX|SB1 }, {"min.ob", "D,S,T", 0x4ac6, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, @@ -2661,8 +2667,10 @@ const struct mips_opcode mips_builtin_opcodes[] = {"mtdr","t,G", 0x7080003d, 0xffe007ff, COD|RD_t|WR_C0, 0, N5 }, {"mthi","s", 0x0011, 0xfc1f, RD_s|WR_HI, 0, I1 }, {"mthi","s,7", 0x0011, 0xfc1fe7ff, RD_s|WR_HI, 0, D32 }, +{"mthi1", "s", 0x7011, 0xfc1f, RD_s | WR_HI, 0, EE }, {"mtlo","s", 0x0013, 0xfc1f, RD_s|WR_LO, 0, I1 }, {"mtlo","s,7", 0x0013, 0xfc1fe7ff, RD_s|WR_LO, 0, D32 }, +{"mtlo1", "s", 0x7013, 0xfc1f, RD_s | WR_LO, 0, EE }, {"mtlhx", "s", 0x0053, 0xfc1f, RD_s|MOD_HILO, 0, SMT }, {"mttc0", "t,G", 0x4180, 0xffe007ff, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32}, {"mttc0", "t,+D",0x4180, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32}, @@ -2728,10 +2736,14 @@ const struct mips_opcode mips_builtin_opcodes[] = {"mult","s,t", 0x0018, 0xfc0
[Qemu-devel] [PATCH v2 08/12] tests/tcg/mips: Test R5900 three-operand MADDU
Signed-off-by: Fredrik Noring --- tests/tcg/mips/mipsr5900/Makefile | 1 + tests/tcg/mips/mipsr5900/maddu.c | 37 +++ 2 files changed, 38 insertions(+) create mode 100644 tests/tcg/mips/mipsr5900/maddu.c diff --git a/tests/tcg/mips/mipsr5900/Makefile b/tests/tcg/mips/mipsr5900/Makefile index 97ca2a671c..27ee5d5f54 100644 --- a/tests/tcg/mips/mipsr5900/Makefile +++ b/tests/tcg/mips/mipsr5900/Makefile @@ -11,6 +11,7 @@ CFLAGS = -Wall -mabi=32 -march=r5900 -static TESTCASES = div1.tst TESTCASES += divu1.tst TESTCASES += madd.tst +TESTCASES += maddu.tst TESTCASES += mflohi1.tst TESTCASES += mtlohi1.tst TESTCASES += mult.tst diff --git a/tests/tcg/mips/mipsr5900/maddu.c b/tests/tcg/mips/mipsr5900/maddu.c new file mode 100644 index 00..e4e552102d --- /dev/null +++ b/tests/tcg/mips/mipsr5900/maddu.c @@ -0,0 +1,37 @@ +/* + * Test R5900-specific three-operand MADDU. + */ + +#include +#include +#include + +uint64_t maddu(uint64_t a, uint32_t rs, uint32_t rt) +{ +uint32_t lo = a; +uint32_t hi = a >> 32; +uint32_t rd; +uint64_t r; + +__asm__ __volatile__ ( +"mtlo %5\n" +"mthi %6\n" +"maddu %0, %3, %4\n" +"mflo %1\n" +"mfhi %2\n" +: "=r" (rd), "=r" (lo), "=r" (hi) +: "r" (rs), "r" (rt), "r" (lo), "r" (hi)); +r = ((uint64_t)hi << 32) | (uint32_t)lo; + +assert(a + (uint64_t)rs * rt == r); +assert(rd == lo); + +return r; +} + +int main() +{ +assert(maddu(13, 17, 19) == 336); + +return 0; +} -- 2.18.1
[Qemu-devel] [PATCH v2 05/12] target/mips: Support R5900 three-operand MADD1 and MADDU1
Signed-off-by: Fredrik Noring --- target/mips/translate.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 4808cb49c3..57b17ad8f6 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -5021,7 +5021,7 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, * * and * - * MADD[U]rd, rs, rt + * MADD[U][1] rd, rs, rt * * such that * @@ -5083,6 +5083,9 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, tcg_temp_free_i32(t3); } break; +case TX79_MMI_MADD1: +acc = 1; +/* Fall through */ case TX79_MMI_MADD: { TCGv_i64 t2 = tcg_temp_new_i64(); @@ -5102,6 +5105,9 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, tcg_temp_free_i64(t2); } break; +case TX79_MMI_MADDU1: +acc = 1; +/* Fall through */ case TX79_MMI_MADDU: { TCGv_i64 t2 = tcg_temp_new_i64(); @@ -26640,6 +26646,8 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) case TX79_MMI_MULTU1: case TX79_MMI_MADD: case TX79_MMI_MADDU: +case TX79_MMI_MADD1: +case TX79_MMI_MADDU1: gen_mul_txx9(ctx, opc, rd, rs, rt); break; case TX79_MMI_DIV1: @@ -26655,8 +26663,6 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) gen_HILO1_tx79(ctx, opc, rd); break; case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */ -case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */ -case TX79_MMI_MADDU1:/* TODO: TX79_MMI_MADDU1 */ case TX79_MMI_PMFHL: /* TODO: TX79_MMI_PMFHL */ case TX79_MMI_PMTHL: /* TODO: TX79_MMI_PMTHL */ case TX79_MMI_PSLLH: /* TODO: TX79_MMI_PSLLH */ -- 2.18.1
[Qemu-devel] [PATCH v2 10/12] disas/mips: Increase 'member of ISAs' flag holder size
From: Philippe Mathieu-Daudé Increase the size of 'membership' holder size to 64 bits. This is needed for future extensions since existing bits are almost all used. This change is related to commit f9c9cd63e3 "target/mips: Increase 'supported ISAs/ASEs' flag holder size". Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Tested-by: Fredrik Noring Signed-off-by: Fredrik Noring --- disas/mips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/disas/mips.c b/disas/mips.c index 97f661a37e..d73d4094d8 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -301,7 +301,7 @@ struct mips_opcode unsigned long pinfo2; /* A collection of bits describing the instruction sets of which this instruction or macro is a member. */ - unsigned long membership; + uint64_t membership; }; /* These are the characters which may appear in the args field of an -- 2.18.1
[Qemu-devel] [PATCH v2 09/12] tests/tcg/mips: Test R5900 three-operand MADDU1
Signed-off-by: Fredrik Noring --- tests/tcg/mips/mipsr5900/maddu.c | 37 ++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/tests/tcg/mips/mipsr5900/maddu.c b/tests/tcg/mips/mipsr5900/maddu.c index e4e552102d..30936fb2b4 100644 --- a/tests/tcg/mips/mipsr5900/maddu.c +++ b/tests/tcg/mips/mipsr5900/maddu.c @@ -1,5 +1,5 @@ /* - * Test R5900-specific three-operand MADDU. + * Test R5900-specific three-operand MADDU and MADDU1. */ #include @@ -29,9 +29,42 @@ uint64_t maddu(uint64_t a, uint32_t rs, uint32_t rt) return r; } +uint64_t maddu1(uint64_t a, uint32_t rs, uint32_t rt) +{ +uint32_t lo = a; +uint32_t hi = a >> 32; +uint32_t rd; +uint64_t r; + +__asm__ __volatile__ ( +"mtlo1 %5\n" +"mthi1 %6\n" +"maddu1 %0, %3, %4\n" +"mflo1 %1\n" +"mfhi1 %2\n" +: "=r" (rd), "=r" (lo), "=r" (hi) +: "r" (rs), "r" (rt), "r" (lo), "r" (hi)); +r = ((uint64_t)hi << 32) | (uint32_t)lo; + +assert(a + (uint64_t)rs * rt == r); +assert(rd == lo); + +return r; +} + +static int64_t maddu_variants(int64_t a, int32_t rs, int32_t rt) +{ +int64_t rd = maddu(a, rs, rt); +int64_t rd1 = maddu1(a, rs, rt); + +assert(rd == rd1); + +return rd; +} + int main() { -assert(maddu(13, 17, 19) == 336); +assert(maddu_variants(13, 17, 19) == 336); return 0; } -- 2.18.1
[Qemu-devel] [PATCH v2 04/12] target/mips: Support Toshiba specific three-operand MADD and MADDU
From: Philippe Mathieu-Daudé The three-operand MADD and MADDU are specific to the Toshiba TX19/TX39/TX79 cores. The "32-Bit TX System RISC TX39 Family Architecture manual" is available at https://wiki.qemu.org/File:DSAE0022432.pdf Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Fredrik Noring Tested-by: Fredrik Noring --- target/mips/translate.c | 58 + 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 624e53644d..4808cb49c3 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -5009,8 +5009,8 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, } /* - * These MULT and MULTU instructions implemented in for example the - * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core + * These MULT[U] and MADD[U] instructions implemented in for example + * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core * architectures are special three-operand variants with the syntax * * MULT[U][1] rd, rs, rt @@ -5019,6 +5019,14 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, * * (rd, LO, HI) <- rs * rt * + * and + * + * MADD[U]rd, rs, rt + * + * such that + * + * (rd, LO, HI) <- (LO, HI) + rs * rt + * * where the low-order 32-bits of the result is placed into both the * GPR rd and the special register LO. The high-order 32-bits of the * result is placed into the special register HI. @@ -5075,8 +5083,48 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, tcg_temp_free_i32(t3); } break; +case TX79_MMI_MADD: +{ +TCGv_i64 t2 = tcg_temp_new_i64(); +TCGv_i64 t3 = tcg_temp_new_i64(); + +tcg_gen_ext_tl_i64(t2, t0); +tcg_gen_ext_tl_i64(t3, t1); +tcg_gen_mul_i64(t2, t2, t3); +tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); +tcg_gen_add_i64(t2, t2, t3); +tcg_temp_free_i64(t3); +gen_move_low32(cpu_LO[acc], t2); +gen_move_high32(cpu_HI[acc], t2); +if (rd) { +gen_move_low32(cpu_gpr[rd], t2); +} +tcg_temp_free_i64(t2); +} +break; +case TX79_MMI_MADDU: +{ +TCGv_i64 t2 = tcg_temp_new_i64(); +TCGv_i64 t3 = tcg_temp_new_i64(); + +tcg_gen_ext32u_tl(t0, t0); +tcg_gen_ext32u_tl(t1, t1); +tcg_gen_extu_tl_i64(t2, t0); +tcg_gen_extu_tl_i64(t3, t1); +tcg_gen_mul_i64(t2, t2, t3); +tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); +tcg_gen_add_i64(t2, t2, t3); +tcg_temp_free_i64(t3); +gen_move_low32(cpu_LO[acc], t2); +gen_move_high32(cpu_HI[acc], t2); +if (rd) { +gen_move_low32(cpu_gpr[rd], t2); +} +tcg_temp_free_i64(t2); +} +break; default: -MIPS_INVAL("mul TXx9"); +MIPS_INVAL("mul/madd TXx9"); generate_exception_end(ctx, EXCP_RI); goto out; } @@ -26590,6 +26638,8 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) break; case TX79_MMI_MULT1: case TX79_MMI_MULTU1: +case TX79_MMI_MADD: +case TX79_MMI_MADDU: gen_mul_txx9(ctx, opc, rd, rs, rt); break; case TX79_MMI_DIV1: @@ -26604,8 +26654,6 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) case TX79_MMI_MFHI1: gen_HILO1_tx79(ctx, opc, rd); break; -case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */ -case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */ case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */ case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */ case TX79_MMI_MADDU1:/* TODO: TX79_MMI_MADDU1 */ -- 2.18.1
[Qemu-devel] [PATCH v2 11/12] disas/mips: Define R5900 disassembly constants
Signed-off-by: Fredrik Noring --- disas/mips.c | 8 1 file changed, 8 insertions(+) diff --git a/disas/mips.c b/disas/mips.c index d73d4094d8..9f01fda8bd 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -611,6 +611,9 @@ struct mips_opcode /* ST Microelectronics Loongson 2F. */ #define INSN_LOONGSON_2F 0x8000 +/* Sony/Toshiba R5900 */ +#define INSN_5900 0x1 + /* MIPS ISA defines, use instead of hardcoding ISA level. */ #define ISA_UNKNOWN 0 /* Gas internal use. */ @@ -646,6 +649,7 @@ struct mips_opcode #define CPU_R5000 5000 #define CPU_VR5400 5400 #define CPU_VR5500 5500 +#define CPU_R5900 5900 #define CPU_R6000 6000 #define CPU_RM7000 7000 #define CPU_R8000 8000 @@ -1193,6 +1197,7 @@ extern const int bfd_mips16_num_opcodes; #define N5 (INSN_5400 | INSN_5500) #define N54INSN_5400 #define N55INSN_5500 +#define EE INSN_5900/* Emotion Engine */ #define G1 (T3 \ ) @@ -3861,6 +3866,7 @@ struct mips_arch_choice #define bfd_mach_mips5000 5000 #define bfd_mach_mips5400 5400 #define bfd_mach_mips5500 5500 +#define bfd_mach_mips5900 5900 #define bfd_mach_mips6000 6000 #define bfd_mach_mips7000 7000 #define bfd_mach_mips8000 8000 @@ -3908,6 +3914,8 @@ static const struct mips_arch_choice mips_arch_choices[] = mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, + { "r5900",1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, +mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, -- 2.18.1
[Qemu-devel] [PATCH v2 06/12] tests/tcg/mips: Test R5900 three-operand MADD
Signed-off-by: Fredrik Noring --- tests/tcg/mips/mipsr5900/Makefile | 1 + tests/tcg/mips/mipsr5900/madd.c | 45 +++ 2 files changed, 46 insertions(+) create mode 100644 tests/tcg/mips/mipsr5900/madd.c diff --git a/tests/tcg/mips/mipsr5900/Makefile b/tests/tcg/mips/mipsr5900/Makefile index a1c388bc3c..97ca2a671c 100644 --- a/tests/tcg/mips/mipsr5900/Makefile +++ b/tests/tcg/mips/mipsr5900/Makefile @@ -10,6 +10,7 @@ CFLAGS = -Wall -mabi=32 -march=r5900 -static TESTCASES = div1.tst TESTCASES += divu1.tst +TESTCASES += madd.tst TESTCASES += mflohi1.tst TESTCASES += mtlohi1.tst TESTCASES += mult.tst diff --git a/tests/tcg/mips/mipsr5900/madd.c b/tests/tcg/mips/mipsr5900/madd.c new file mode 100644 index 00..9ad2ea6dbb --- /dev/null +++ b/tests/tcg/mips/mipsr5900/madd.c @@ -0,0 +1,45 @@ +/* + * Test R5900-specific three-operand MADD. + */ + +#include +#include +#include + +int64_t madd(int64_t a, int32_t rs, int32_t rt) +{ +int32_t lo = a; +int32_t hi = a >> 32; +int32_t rd; +int64_t r; + +__asm__ __volatile__ ( +"mtlo %5\n" +"mthi %6\n" +"madd %0, %3, %4\n" +"mflo %1\n" +"mfhi %2\n" +: "=r" (rd), "=r" (lo), "=r" (hi) +: "r" (rs), "r" (rt), "r" (lo), "r" (hi)); +r = ((int64_t)hi << 32) | (uint32_t)lo; + +assert(a + (int64_t)rs * rt == r); +assert(rd == lo); + +return r; +} + +static void verify_madd(int64_t a, int32_t rs, int32_t rt, int64_t expected) +{ +assert(madd(a, rs, rt) == expected); +assert(madd(a, -rs, rt) == a + a - expected); +assert(madd(a, rs, -rt) == a + a - expected); +assert(madd(a, -rs, -rt) == expected); +} + +int main() +{ +verify_madd(13, 17, 19, 336); + +return 0; +} -- 2.18.1
[Qemu-devel] [PATCH v2 07/12] tests/tcg/mips: Test R5900 three-operand MADD1
Signed-off-by: Fredrik Noring --- tests/tcg/mips/mipsr5900/madd.c | 43 + 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/tests/tcg/mips/mipsr5900/madd.c b/tests/tcg/mips/mipsr5900/madd.c index 9ad2ea6dbb..f6f215e1c3 100644 --- a/tests/tcg/mips/mipsr5900/madd.c +++ b/tests/tcg/mips/mipsr5900/madd.c @@ -1,5 +1,5 @@ /* - * Test R5900-specific three-operand MADD. + * Test R5900-specific three-operand MADD and MADD1. */ #include @@ -29,12 +29,45 @@ int64_t madd(int64_t a, int32_t rs, int32_t rt) return r; } +int64_t madd1(int64_t a, int32_t rs, int32_t rt) +{ +int32_t lo = a; +int32_t hi = a >> 32; +int32_t rd; +int64_t r; + +__asm__ __volatile__ ( +"mtlo1 %5\n" +"mthi1 %6\n" +"madd1 %0, %3, %4\n" +"mflo1 %1\n" +"mfhi1 %2\n" +: "=r" (rd), "=r" (lo), "=r" (hi) +: "r" (rs), "r" (rt), "r" (lo), "r" (hi)); +r = ((int64_t)hi << 32) | (uint32_t)lo; + +assert(a + (int64_t)rs * rt == r); +assert(rd == lo); + +return r; +} + +static int64_t madd_variants(int64_t a, int32_t rs, int32_t rt) +{ +int64_t rd = madd(a, rs, rt); +int64_t rd1 = madd1(a, rs, rt); + +assert(rd == rd1); + +return rd; +} + static void verify_madd(int64_t a, int32_t rs, int32_t rt, int64_t expected) { -assert(madd(a, rs, rt) == expected); -assert(madd(a, -rs, rt) == a + a - expected); -assert(madd(a, rs, -rt) == a + a - expected); -assert(madd(a, -rs, -rt) == expected); +assert(madd_variants(a, rs, rt) == expected); +assert(madd_variants(a, -rs, rt) == a + a - expected); +assert(madd_variants(a, rs, -rt) == a + a - expected); +assert(madd_variants(a, -rs, -rt) == expected); } int main() -- 2.18.1
Re: [Qemu-devel] Correction needed for R5900 instruction decoding
Hi Aleksandar, > It is now code freeze before 3.1, the code base is being stabilized, and > only important fixes are allowed to be integrated - so, in that light, a > separate patch, or a small series, that addresses only concerns from the > original mail of this thread is needed. Such series should not contain any > additional features (like your v2 of the series "Amend..." does), and its > patch titles should look like "Fix decoding mechanism of ..." or such. > > Could you please provide those appropriate changes in that format? I certainly could, but why not simply apply patch 1 and 2 in the posted v2 series and leave the rest for later? The only difference in a repost would be the cover letter. The two patches would be identical reposts that apply since yesterday. The patch series is ordered with "crucial patches as the first ones", as you wanted it according to: http://lists.nongnu.org/archive/html/qemu-devel/2018-10/msg04946.html Fredrik
Re: [Qemu-devel] Correction needed for R5900 instruction decoding
Hi Peter, > From the other side of things, as a submaintainer around release > time there's often a lot of work to do and it's easy to confuse > different patchsets or forget the status of them, so it's useful > to have a patch series which is exactly the set of patches that > the submitter thinks are suitable to go into the release, and it's > less work to apply those than to fish out a subset of patches > from a series. Understood. Aleksandar previously indicated that he wanted an amendment series with changes ordered by importance, which is why the two patches were part of that series (as the first ones). > So overall, I think my suggestion would be that the best move > from here would be for Fred to send a patchset with the changes > for 3.1 and only those changes. Could you do that, please? Yes, I will post a separate series for review immediately. Fredrik
[Qemu-devel] [PATCH 0/2] target/mips: Fix decoding mechanisms of R5900 M{F, T}{HI, LO}1 and DIV[U]1
This series amends the R5900 support with the following changes: - MFLO1, MFHI1, MTLO1 and MTHI1 are generated in gen_HILO1_tx79 instead of the generic gen_HILO. - DIV1 and DIVU1 are generated in gen_div1_tx79 instead of the generic gen_muldiv. Fredrik Noring (2): target/mips: Fix decoding mechanism of R5900 MFLO1, MFHI1, MTLO1 and MTHI1 target/mips: Fix decoding mechanism of R5900 DIV1 and DIVU1 target/mips/translate.c | 132 ++-- 1 file changed, 115 insertions(+), 17 deletions(-) -- 2.18.1
[Qemu-devel] [PATCH 2/2] target/mips: Fix decoding mechanism of R5900 DIV1 and DIVU1
DIV1 and DIVU1 are generated in gen_div1_tx79 instead of the generic gen_muldiv. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 65 + 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index f3993cf7d7..6e5a8a2565 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4759,6 +4759,63 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) tcg_temp_free(t1); } +static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) +{ +TCGv t0, t1; + +t0 = tcg_temp_new(); +t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +switch (opc) { +case TX79_MMI_DIV1: +{ +TCGv t2 = tcg_temp_new(); +TCGv t3 = tcg_temp_new(); +tcg_gen_ext32s_tl(t0, t0); +tcg_gen_ext32s_tl(t1, t1); +tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); +tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); +tcg_gen_and_tl(t2, t2, t3); +tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); +tcg_gen_or_tl(t2, t2, t3); +tcg_gen_movi_tl(t3, 0); +tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); +tcg_gen_div_tl(cpu_LO[1], t0, t1); +tcg_gen_rem_tl(cpu_HI[1], t0, t1); +tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); +tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); +tcg_temp_free(t3); +tcg_temp_free(t2); +} +break; +case TX79_MMI_DIVU1: +{ +TCGv t2 = tcg_const_tl(0); +TCGv t3 = tcg_const_tl(1); +tcg_gen_ext32u_tl(t0, t0); +tcg_gen_ext32u_tl(t1, t1); +tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); +tcg_gen_divu_tl(cpu_LO[1], t0, t1); +tcg_gen_remu_tl(cpu_HI[1], t0, t1); +tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); +tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); +tcg_temp_free(t3); +tcg_temp_free(t2); +} +break; +default: +MIPS_INVAL("div1 TX79"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + static void gen_muldiv(DisasContext *ctx, uint32_t opc, int acc, int rs, int rt) { @@ -4771,14 +4828,11 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, gen_load_gpr(t1, rt); if (acc != 0) { -if (!(ctx->insn_flags & INSN_R5900)) { -check_dsp(ctx); -} +check_dsp(ctx); } switch (opc) { case OPC_DIV: -case TX79_MMI_DIV1: { TCGv t2 = tcg_temp_new(); TCGv t3 = tcg_temp_new(); @@ -4800,7 +4854,6 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, } break; case OPC_DIVU: -case TX79_MMI_DIVU1: { TCGv t2 = tcg_const_tl(0); TCGv t3 = tcg_const_tl(1); @@ -26541,7 +26594,7 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) break; case TX79_MMI_DIV1: case TX79_MMI_DIVU1: -gen_muldiv(ctx, opc, 1, rs, rt); +gen_div1_tx79(ctx, opc, rs, rt); break; case TX79_MMI_MTLO1: case TX79_MMI_MTHI1: -- 2.18.1
[Qemu-devel] [PATCH 1/2] target/mips: Fix decoding mechanism of R5900 MFLO1, MFHI1, MTLO1 and MTHI1
MFLO1, MFHI1, MTLO1 and MTHI1 are generated in gen_HILO1_tx79 instead of the generic gen_HILO. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 67 ++--- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 60320cbe69..f3993cf7d7 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4359,24 +4359,72 @@ static void gen_shift(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } +/* Move to and from TX79 HI1/LO1 registers. */ +static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg) +{ +if (reg == 0 && (opc == TX79_MMI_MFHI1 || opc == TX79_MMI_MFLO1)) { +/* Treat as NOP. */ +return; +} + +switch (opc) { +case TX79_MMI_MFHI1: +#if defined(TARGET_MIPS64) +tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]); +#else +tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]); +#endif +break; +case TX79_MMI_MFLO1: +#if defined(TARGET_MIPS64) +tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[1]); +#else +tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]); +#endif +break; +case TX79_MMI_MTHI1: +if (reg != 0) { +#if defined(TARGET_MIPS64) +tcg_gen_ext32s_tl(cpu_HI[1], cpu_gpr[reg]); +#else +tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]); +#endif +} else { +tcg_gen_movi_tl(cpu_HI[1], 0); +} +break; +case TX79_MMI_MTLO1: +if (reg != 0) { +#if defined(TARGET_MIPS64) +tcg_gen_ext32s_tl(cpu_LO[1], cpu_gpr[reg]); +#else +tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]); +#endif +} else { +tcg_gen_movi_tl(cpu_LO[1], 0); +} +break; +default: +MIPS_INVAL("MFTHILO TX79"); +generate_exception_end(ctx, EXCP_RI); +break; +} +} + /* Arithmetic on HI/LO registers */ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) { -if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 || - opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) { +if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { /* Treat as NOP. */ return; } if (acc != 0) { -if (!(ctx->insn_flags & INSN_R5900)) { -check_dsp(ctx); -} +check_dsp(ctx); } switch (opc) { case OPC_MFHI: -case TX79_MMI_MFHI1: #if defined(TARGET_MIPS64) if (acc != 0) { tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); @@ -4387,7 +4435,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) } break; case OPC_MFLO: -case TX79_MMI_MFLO1: #if defined(TARGET_MIPS64) if (acc != 0) { tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); @@ -4398,7 +4445,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) } break; case OPC_MTHI: -case TX79_MMI_MTHI1: if (reg != 0) { #if defined(TARGET_MIPS64) if (acc != 0) { @@ -4413,7 +4459,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) } break; case OPC_MTLO: -case TX79_MMI_MTLO1: if (reg != 0) { #if defined(TARGET_MIPS64) if (acc != 0) { @@ -26500,11 +26545,11 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) break; case TX79_MMI_MTLO1: case TX79_MMI_MTHI1: -gen_HILO(ctx, opc, 1, rs); +gen_HILO1_tx79(ctx, opc, rs); break; case TX79_MMI_MFLO1: case TX79_MMI_MFHI1: -gen_HILO(ctx, opc, 1, rd); +gen_HILO1_tx79(ctx, opc, rd); break; case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */ case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */ -- 2.18.1
Re: [Qemu-devel] [PATCH 1/2] target/mips: Fix decoding mechanism of R5900 MFLO1, MFHI1, MTLO1 and MTHI1
Thank you for your reviews, Philippe and Richard, > > +switch (opc) { > > +case TX79_MMI_MFHI1: > > +#if defined(TARGET_MIPS64) > > +tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]); > > +#else > > +tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]); > > +#endif > > You do not need this ifdef. This is already done in tcg/tcg-op.h: > > $ grep tcg_gen_ext32s_tl tcg/tcg-op.h > #define tcg_gen_ext32s_tl tcg_gen_ext32s_i64 > #define tcg_gen_ext32s_tl tcg_gen_mov_i32 It appears the correct function is tcg_gen_mov_tl because the TX79 manual says MFHI: GPR[rd]63..0 <- HI63..0 MFLO: GPR[rd]63..0 <- LO63..0 MTHI: HI63..0 <- GPR[rs]63..0 MTLO: LO63..0 <- GPR[rs]63..0 MFHI1: GPR[rd]63..0 <- HI127..64 MFLO1: GPR[rd]63..0 <- LO127..64 MTHI1: HI127..64 <- GPR[rs]63..0 MTLO1: LO127..64 <- GPR[rs]63..0 so the GPR is copied to/from in full in all cases. This is slightly different to how acc = 1 is handled in gen_HILO. Fredrik
Re: [Qemu-devel] [PATCH 1/2] target/mips: Fix decoding mechanism of R5900 MFLO1, MFHI1, MTLO1 and MTHI1
Thanks for checking this, Maciej, [ Cc-ing Jia Liu, who added MIPS ASE DSP support in commit 4133498f8e532f "Use correct acc value to index cpu_HI/cpu_LO rather than using a fix number", in case there are known ISA deviations. ] > However `gen_HILO' looks wrong to me as it'll truncate the values of > $acc3-$acc1 with the 64-bit DSP ASE. I can post a patch to fix gen_HILO. The best reference I have found so far is "MIPS Architecture for Programmers Volume IV-e: MIPS DSP Module for microMIPS64 Architecture" https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00765-2B-microMIPS64DSP-AFP-03.02.pdf that says MFHI: GPR[rds]63..0 <- HI[ac]63..0 MFLO: GPR[rdt]63..0 <- LO[ac]63..0 MTHI: HI[ac]63..0 <- GPR[rs]63..0 MTLO: LO[ac]63..0 <- GPR[rs]63..0 where ac can range from 0 to 3. Do you have a link to a better reference, by chance, that isn't tied to microMIPS? Fredrik
Re: [Qemu-devel] [PATCH 0/2] target/mips: Fix decoding mechanisms of R5900 M{F, T}{HI, LO}1 and DIV[U]1
Thank you for your review, Aleksandar, > For LL, SC, LLD and SCD instructions, there is a need to properly insulate > their R5900 versions too, similar to this: > > case OPC_SC: > if(ctx->insn_flags & INSN_R5900) { > check_insn_opc_user_only(ctx, INSN_R5900); > } else { > check_insn(ctx, ISA_MIPS2); > } > gen_st_cond(ctx, op, rt, rs, imm); > break; Would you accept the simplification to omit the else clause? Like this: case OPC_SC: if (ctx->insn_flags & INSN_R5900) { check_insn_opc_user_only(ctx, INSN_R5900); } check_insn(ctx, ISA_MIPS2); check_insn_opc_removed(ctx, ISA_MIPS32R6); gen_st_cond(ctx, op, rt, rs, imm); break; The code will, of course, expand into a double-check of INSN_R5900: if (ctx->insn_flags & INSN_R5900) { #ifndef CONFIG_USER_ONLY if (unlikely(ctx->insn_flags & INSN_R5900)) { generate_exception_end(ctx, EXCP_RI); } #endif } > (the code above is just a form of pseudocode illustrating the idea; I > don't guarantee the correctness for build purposes, or if this is the best > code organization) > > Non-R5900 code (for the time being) should never invoke > check_insn_opc_user_only(). *The only way* of distinguishing R5900 code > paths from the other CPUs code paths should be by using > "if(ctx->insn_flags & INSN_R5900)"! OK. > For changes in decode_opc_special_legacy(), there shouldn't be there, but > there should be a separate function decode_opc_special_tx59() or so. Sure, I will copy the 82 line function then, and patch the following: --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -23904,7 +23904,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_MOVN: /* Conditional move */ case OPC_MOVZ: check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | - INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900); + INSN_LOONGSON2E | INSN_LOONGSON2F); gen_cond_move(ctx, op1, rd, rs, rt); break; case OPC_MFHI: /* Move from HI/LO */ @@ -23931,8 +23931,6 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) check_insn(ctx, INSN_VR54XX); op1 = MASK_MUL_VR54XX(ctx->opcode); gen_mul_vr54xx(ctx, op1, rd, rs, rt); -} else if (ctx->insn_flags & INSN_R5900) { -gen_mul_txx9(ctx, op1, rd, rs, rt); } else { gen_muldiv(ctx, op1, rd & 3, rs, rt); } @@ -23947,7 +23945,6 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_DDIV: case OPC_DDIVU: check_insn(ctx, ISA_MIPS3); -check_insn_opc_user_only(ctx, INSN_R5900); check_mips_64(ctx); gen_muldiv(ctx, op1, 0, rs, rt); break; Fredrik
Re: [Qemu-devel] [PATCH v2 12/12] disas/mips: Disassemble R5900 DIV[U]1, M{F, T}{LO, HI}1 and MULT[U]1
Hi Aleksandar, > I am glad that you want to include QEMU disas support for R5900 - this > area usually gets forgotten. > > But, as you can see, this MIPS feature is partially broken - it doesn't > handle well overlapping opcodes, and the field "membership" is not taken > into account at all. I think the feature should be fixed first, and then > R5900 support added. In fact, the disassembler support in QEMU is almost > independent on the emulation support (for the corresponding instructions) > - so, we could add disassembler support for all R5900 instructions in one > clean sweep, instead dividing that in "million" pieces. > > The key to the successful solution would be detecting what CPU is > currently being emulated, and making disassembling decision based on that. > > Let's talk about that later. Yes, the current disassembly table needs to be reworked, so let's postpone the opcodes for the R5900. > P.S. Sorry for misspelling your name on several occasions. No problem! Fredrik
Re: [Qemu-devel] [PATCH 0/2] target/mips: Fix decoding mechanisms of R5900 M{F, T}{HI, LO}1 and DIV[U]1
Hi Aleksandar, > I think the following code would be even better: > > case OPC_SC: > check_insn(ctx, ISA_MIPS2); > check_insn_opc_removed(ctx, ISA_MIPS32R6); > if (ctx->insn_flags & INSN_R5900) { > check_insn_opc_user_only(ctx, INSN_R5900); > } > gen_st_cond(ctx, op, rt, rs, imm); > break; Done. > I don't mind. Later on, we can drop the second argument of > check_insn_opc_user_only() altogether, and the code would expand to the > minimal and clear: > > if (ctx->insn_flags & INSN_R5900) { > #ifndef CONFIG_USER_ONLY > generate_exception_end(ctx, EXCP_RI); > #endif > } > > but at this moment this is not a source of concern to me at all. OK. > No, no, you don't need to copy 82 lines. First, you can assume that you > are already in INSN_R5900 case - no need for frequent check_insn()s. > Further, you can omit everything that is not needed for R5900 (for > example, entire OPC_MOVCI case). Yes, of course. I've made some general updates as well, for example making use of extract32. I will post v2 in a moment. Fredrik
[Qemu-devel] [PATCH v2 1/6] target/mips: Fix decoding mechanism of R5900 MFLO1, MFHI1, MTLO1 and MTHI1
MFLO1, MFHI1, MTLO1 and MTHI1 are generated in gen_HILO1_tx79 instead of the generic gen_HILO. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 51 - 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 60320cbe69..8601333554 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4359,24 +4359,56 @@ static void gen_shift(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } +/* Copy GPR to and from TX79 HI1/LO1 register. */ +static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg) +{ +if (reg == 0 && (opc == TX79_MMI_MFHI1 || opc == TX79_MMI_MFLO1)) { +/* Treat as NOP. */ +return; +} + +switch (opc) { +case TX79_MMI_MFHI1: +tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]); +break; +case TX79_MMI_MFLO1: +tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]); +break; +case TX79_MMI_MTHI1: +if (reg != 0) { +tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]); +} else { +tcg_gen_movi_tl(cpu_HI[1], 0); +} +break; +case TX79_MMI_MTLO1: +if (reg != 0) { +tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]); +} else { +tcg_gen_movi_tl(cpu_LO[1], 0); +} +break; +default: +MIPS_INVAL("mfthilo1 TX79"); +generate_exception_end(ctx, EXCP_RI); +break; +} +} + /* Arithmetic on HI/LO registers */ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) { -if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 || - opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) { +if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { /* Treat as NOP. */ return; } if (acc != 0) { -if (!(ctx->insn_flags & INSN_R5900)) { -check_dsp(ctx); -} +check_dsp(ctx); } switch (opc) { case OPC_MFHI: -case TX79_MMI_MFHI1: #if defined(TARGET_MIPS64) if (acc != 0) { tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); @@ -4387,7 +4419,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) } break; case OPC_MFLO: -case TX79_MMI_MFLO1: #if defined(TARGET_MIPS64) if (acc != 0) { tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); @@ -4398,7 +4429,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) } break; case OPC_MTHI: -case TX79_MMI_MTHI1: if (reg != 0) { #if defined(TARGET_MIPS64) if (acc != 0) { @@ -4413,7 +4443,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) } break; case OPC_MTLO: -case TX79_MMI_MTLO1: if (reg != 0) { #if defined(TARGET_MIPS64) if (acc != 0) { @@ -26500,11 +26529,11 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) break; case TX79_MMI_MTLO1: case TX79_MMI_MTHI1: -gen_HILO(ctx, opc, 1, rs); +gen_HILO1_tx79(ctx, opc, rs); break; case TX79_MMI_MFLO1: case TX79_MMI_MFHI1: -gen_HILO(ctx, opc, 1, rd); +gen_HILO1_tx79(ctx, opc, rd); break; case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */ case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */ -- 2.18.1
[Qemu-devel] [PATCH v2 3/6] target/mips: Fix HI[ac] and LO[ac] 32-bit truncation with MIPS64 DSP ASE
This change removes the 32-bit truncation of the HI[ac] and LO[ac] special purpose registers when ac range from 1 to 3 for the instructions MFHI, MFLO, MTHI and MTLO. The "MIPS Architecture for Programmers Volume IV-e: MIPS DSP Module for MIPS64 Architecture" manual specifies that all 64 bits are copied in all cases: MFHI: GPR[rd]63..0 <- HI[ac]63..0 MFLO: GPR[rd]63..0 <- LO[ac]63..0 MTHI: HI[ac]63..0 <- GPR[rs]63..0 MTLO: LO[ac]63..0 <- GPR[rs]63..0 Fixes: 4133498f8e53 ("Use correct acc value to index cpu_HI/cpu_LO rather than using a fix number") Cc: Jia Liu Reported-by: Maciej W. Rozycki Signed-off-by: Fredrik Noring --- target/mips/translate.c | 36 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 3ddd70043a..19ae7d2f1c 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4409,49 +4409,21 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) switch (opc) { case OPC_MFHI: -#if defined(TARGET_MIPS64) -if (acc != 0) { -tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); -} else -#endif -{ -tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); -} +tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); break; case OPC_MFLO: -#if defined(TARGET_MIPS64) -if (acc != 0) { -tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); -} else -#endif -{ -tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); -} +tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); break; case OPC_MTHI: if (reg != 0) { -#if defined(TARGET_MIPS64) -if (acc != 0) { -tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); -} else -#endif -{ -tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); -} +tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); } else { tcg_gen_movi_tl(cpu_HI[acc], 0); } break; case OPC_MTLO: if (reg != 0) { -#if defined(TARGET_MIPS64) -if (acc != 0) { -tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); -} else -#endif -{ -tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); -} +tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); } else { tcg_gen_movi_tl(cpu_LO[acc], 0); } -- 2.18.1
[Qemu-devel] [PATCH v2 0/6] Fix decoding mechanisms of the R5900
This series amends the R5900 support with the following changes: - MFLO1, MFHI1, MTLO1 and MTHI1 are generated in gen_HILO1_tx79 instead of the generic gen_HILO. - DIV1 and DIVU1 are generated in gen_div1_tx79 instead of the generic gen_muldiv. - MOVN, MOVZ, MFHI, MFLO, MTHI, MTLO, MULT, MULTU, DIV, DIVU, DMULT, DMULTU, DDIV, DDIVU and JR are decoded in decode_opc_special_tx79 instead of the generic decode_opc_special_legacy. - Guard check_insn_opc_user_only with INSN_R5900 check. - Guard check_insn with INSN_R5900 check. - Fix HI[ac] and LO[ac] 32-bit truncation with the MIPS64 DSP ASE. This series has been successfully built with the 8 different build configurations {gcc,clang} x -m64 x mips{,64}el-{linux-user,softmmu} in addition successfully completing the R5900 test suite cd tests/tcg/mips/mipsr5900 && make check Changes in v2: - Fix HI and LO 32-bit truncation with the MIPS64 DSP ASE - Decode special R5900 opcodes in decode_opc_special_tx79 - Guard check_insn_opc_user_only with INSN_R5900 check - Guard check_insn with INSN_R5900 check Fredrik Noring (6): target/mips: Fix decoding mechanism of R5900 MFLO1, MFHI1, MTLO1 and MTHI1 target/mips: Fix decoding mechanism of R5900 DIV1 and DIVU1 target/mips: Fix HI[ac] and LO[ac] 32-bit truncation with MIPS64 DSP ASE target/mips: Fix decoding mechanism of special R5900 opcodes target/mips: Guard check_insn_opc_user_only with INSN_R5900 check target/mips: Guard check_insn with INSN_R5900 check target/mips/translate.c | 229 +--- 1 file changed, 170 insertions(+), 59 deletions(-) -- 2.18.1
[Qemu-devel] [PATCH v2 2/6] target/mips: Fix decoding mechanism of R5900 DIV1 and DIVU1
DIV1 and DIVU1 are generated in gen_div1_tx79 instead of the generic gen_muldiv. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/translate.c | 65 + 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 8601333554..3ddd70043a 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4743,6 +4743,63 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) tcg_temp_free(t1); } +static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) +{ +TCGv t0, t1; + +t0 = tcg_temp_new(); +t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +switch (opc) { +case TX79_MMI_DIV1: +{ +TCGv t2 = tcg_temp_new(); +TCGv t3 = tcg_temp_new(); +tcg_gen_ext32s_tl(t0, t0); +tcg_gen_ext32s_tl(t1, t1); +tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); +tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); +tcg_gen_and_tl(t2, t2, t3); +tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); +tcg_gen_or_tl(t2, t2, t3); +tcg_gen_movi_tl(t3, 0); +tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); +tcg_gen_div_tl(cpu_LO[1], t0, t1); +tcg_gen_rem_tl(cpu_HI[1], t0, t1); +tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); +tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); +tcg_temp_free(t3); +tcg_temp_free(t2); +} +break; +case TX79_MMI_DIVU1: +{ +TCGv t2 = tcg_const_tl(0); +TCGv t3 = tcg_const_tl(1); +tcg_gen_ext32u_tl(t0, t0); +tcg_gen_ext32u_tl(t1, t1); +tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); +tcg_gen_divu_tl(cpu_LO[1], t0, t1); +tcg_gen_remu_tl(cpu_HI[1], t0, t1); +tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); +tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); +tcg_temp_free(t3); +tcg_temp_free(t2); +} +break; +default: +MIPS_INVAL("div1 TX79"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + static void gen_muldiv(DisasContext *ctx, uint32_t opc, int acc, int rs, int rt) { @@ -4755,14 +4812,11 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, gen_load_gpr(t1, rt); if (acc != 0) { -if (!(ctx->insn_flags & INSN_R5900)) { -check_dsp(ctx); -} +check_dsp(ctx); } switch (opc) { case OPC_DIV: -case TX79_MMI_DIV1: { TCGv t2 = tcg_temp_new(); TCGv t3 = tcg_temp_new(); @@ -4784,7 +4838,6 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, } break; case OPC_DIVU: -case TX79_MMI_DIVU1: { TCGv t2 = tcg_const_tl(0); TCGv t3 = tcg_const_tl(1); @@ -26525,7 +26578,7 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) break; case TX79_MMI_DIV1: case TX79_MMI_DIVU1: -gen_muldiv(ctx, opc, 1, rs, rt); +gen_div1_tx79(ctx, opc, rs, rt); break; case TX79_MMI_MTLO1: case TX79_MMI_MTHI1: -- 2.18.1
[Qemu-devel] [PATCH v2 4/6] target/mips: Fix decoding mechanism of special R5900 opcodes
MOVN, MOVZ, MFHI, MFLO, MTHI, MTLO, MULT, MULTU, DIV, DIVU, DMULT, DMULTU, DDIV, DDIVU and JR are decoded in decode_opc_special_tx79 instead of the generic decode_opc_special_legacy. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 54 ++--- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 19ae7d2f1c..45ad70c097 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -23835,6 +23835,53 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) } } +static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) +{ +int rs = extract32(ctx->opcode, 21, 5); +int rt = extract32(ctx->opcode, 16, 5); +int rd = extract32(ctx->opcode, 11, 5); +uint32_t op1 = MASK_SPECIAL(ctx->opcode); + +switch (op1) { +case OPC_MOVN: /* Conditional move */ +case OPC_MOVZ: +gen_cond_move(ctx, op1, rd, rs, rt); +break; +case OPC_MFHI: /* Move from HI/LO */ +case OPC_MFLO: +gen_HILO(ctx, op1, 0, rd); +break; +case OPC_MTHI: +case OPC_MTLO: /* Move to HI/LO */ +gen_HILO(ctx, op1, 0, rs); +break; +case OPC_MULT: +case OPC_MULTU: +gen_mul_txx9(ctx, op1, rd, rs, rt); +break; +case OPC_DIV: +case OPC_DIVU: +gen_muldiv(ctx, op1, 0, rs, rt); +break; +#if defined(TARGET_MIPS64) +case OPC_DMULT: +case OPC_DMULTU: +case OPC_DDIV: +case OPC_DDIVU: +check_insn_opc_user_only(ctx, INSN_R5900); +gen_muldiv(ctx, op1, 0, rs, rt); +break; +#endif +case OPC_JR: +gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); +break; +default:/* Invalid */ +MIPS_INVAL("special_tx79"); +generate_exception_end(ctx, EXCP_RI); +break; +} +} + static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) { int rs, rt, rd, sa; @@ -23850,7 +23897,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_MOVN: /* Conditional move */ case OPC_MOVZ: check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | - INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900); + INSN_LOONGSON2E | INSN_LOONGSON2F); gen_cond_move(ctx, op1, rd, rs, rt); break; case OPC_MFHI: /* Move from HI/LO */ @@ -23877,8 +23924,6 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) check_insn(ctx, INSN_VR54XX); op1 = MASK_MUL_VR54XX(ctx->opcode); gen_mul_vr54xx(ctx, op1, rd, rs, rt); -} else if (ctx->insn_flags & INSN_R5900) { -gen_mul_txx9(ctx, op1, rd, rs, rt); } else { gen_muldiv(ctx, op1, rd & 3, rs, rt); } @@ -23893,7 +23938,6 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_DDIV: case OPC_DDIVU: check_insn(ctx, ISA_MIPS3); -check_insn_opc_user_only(ctx, INSN_R5900); check_mips_64(ctx); gen_muldiv(ctx, op1, 0, rs, rt); break; @@ -24120,6 +24164,8 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) default: if (ctx->insn_flags & ISA_MIPS32R6) { decode_opc_special_r6(env, ctx); +} else if (ctx->insn_flags & INSN_R5900) { +decode_opc_special_tx79(env, ctx); } else { decode_opc_special_legacy(env, ctx); } -- 2.18.1
[Qemu-devel] [PATCH v2 5/6] target/mips: Guard check_insn_opc_user_only with INSN_R5900 check
Signed-off-by: Fredrik Noring --- target/mips/translate.c | 16 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 45ad70c097..c3ed4c21ce 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28285,7 +28285,9 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_LL: /* Load and stores */ check_insn(ctx, ISA_MIPS2); -check_insn_opc_user_only(ctx, INSN_R5900); +if (ctx->insn_flags & INSN_R5900) { +check_insn_opc_user_only(ctx, INSN_R5900); +} /* Fallthrough */ case OPC_LWL: case OPC_LWR: @@ -28311,7 +28313,9 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SC: check_insn(ctx, ISA_MIPS2); check_insn_opc_removed(ctx, ISA_MIPS32R6); -check_insn_opc_user_only(ctx, INSN_R5900); +if (ctx->insn_flags & INSN_R5900) { +check_insn_opc_user_only(ctx, INSN_R5900); +} gen_st_cond(ctx, op, rt, rs, imm); break; case OPC_CACHE: @@ -28579,7 +28583,9 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) #if defined(TARGET_MIPS64) /* MIPS64 opcodes */ case OPC_LLD: -check_insn_opc_user_only(ctx, INSN_R5900); +if (ctx->insn_flags & INSN_R5900) { +check_insn_opc_user_only(ctx, INSN_R5900); +} /* fall through */ case OPC_LDL: case OPC_LDR: @@ -28603,7 +28609,9 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SCD: check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS3); -check_insn_opc_user_only(ctx, INSN_R5900); +if (ctx->insn_flags & INSN_R5900) { +check_insn_opc_user_only(ctx, INSN_R5900); +} check_mips_64(ctx); gen_st_cond(ctx, op, rt, rs, imm); break; -- 2.18.1
[Qemu-devel] [PATCH v2 6/6] target/mips: Guard check_insn with INSN_R5900 check
Signed-off-by: Fredrik Noring --- target/mips/translate.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index c3ed4c21ce..007dfd2975 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28329,8 +28329,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_PREF: check_insn_opc_removed(ctx, ISA_MIPS32R6); -check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | - INSN_R5900); +if (ctx->insn_flags & INSN_R5900) { +/* The R5900 implements PREF. */ +} else { +check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); +} /* Treat as NOP. */ break; -- 2.18.1
[Qemu-devel] [PATCH 0/2] linux-user/mips: Support the n32 ABI for the R5900
Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI. Test that DMULT is emulated in user mode. This series has been successfully built with the 10 different build configurations {gcc,clang} x -m64 x mips{,64}el-{linux-user,softmmu} {gcc,clang} x -m64 x mipsn32el-linux-user in addition successfully completing the R5900 test suite cd tests/tcg/mips/mipsr5900 && make check cd tests/tcg/mips/mipsn32r5900 && make check Fredrik Noring (2): linux-user/mips: Support the n32 ABI for the R5900 tests/tcg/mips: Test user mode DMULT for the R5900 linux-user/mips64/target_elf.h | 3 +++ tests/tcg/mips/mipsn32r5900/Makefile | 25 + tests/tcg/mips/mipsn32r5900/dmult.c | 40 3 files changed, 68 insertions(+) create mode 100644 tests/tcg/mips/mipsn32r5900/Makefile create mode 100644 tests/tcg/mips/mipsn32r5900/dmult.c -- 2.18.1
[Qemu-devel] [PATCH 1/2] linux-user/mips: Support the n32 ABI for the R5900
Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI. Signed-off-by: Fredrik Noring --- linux-user/mips64/target_elf.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-user/mips64/target_elf.h b/linux-user/mips64/target_elf.h index ec55d8542a..5f2f2df29f 100644 --- a/linux-user/mips64/target_elf.h +++ b/linux-user/mips64/target_elf.h @@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags) if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_64R6) { return "I6400"; } +if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) { +return "R5900"; +} return "5KEf"; } #endif -- 2.18.1
[Qemu-devel] [PATCH 2/2] tests/tcg/mips: Test user mode DMULT for the R5900
The R5900 reports itself as MIPS III but does not implement DMULT. Verify that DMULT is emulated properly in user mode by multiplying two 64-bit numbers to produce a 128-bit number. Signed-off-by: Fredrik Noring --- tests/tcg/mips/mipsn32r5900/Makefile | 25 + tests/tcg/mips/mipsn32r5900/dmult.c | 40 2 files changed, 65 insertions(+) create mode 100644 tests/tcg/mips/mipsn32r5900/Makefile create mode 100644 tests/tcg/mips/mipsn32r5900/dmult.c diff --git a/tests/tcg/mips/mipsn32r5900/Makefile b/tests/tcg/mips/mipsn32r5900/Makefile new file mode 100644 index 00..7dd16723fe --- /dev/null +++ b/tests/tcg/mips/mipsn32r5900/Makefile @@ -0,0 +1,25 @@ +-include ../../config-host.mak + +CROSS=mips64r5900el-unknown-linux-gnu- + +SIM=qemu-mipsn32el +SIM_FLAGS=-cpu R5900 + +CC = $(CROSS)gcc +CFLAGS = -Wall -mabi=n32 -march=r5900 -static + +TESTCASES = dmult.tst + +all: $(TESTCASES) + +%.tst: %.c + $(CC) $(CFLAGS) $< -o $@ + +check: $(TESTCASES) + @for case in $(TESTCASES); do \ +echo $(SIM) $(SIM_FLAGS) ./$$case;\ +$(SIM) $(SIM_FLAGS) ./$$case; \ + done + +clean: + $(RM) -rf $(TESTCASES) diff --git a/tests/tcg/mips/mipsn32r5900/dmult.c b/tests/tcg/mips/mipsn32r5900/dmult.c new file mode 100644 index 00..2827ab5358 --- /dev/null +++ b/tests/tcg/mips/mipsn32r5900/dmult.c @@ -0,0 +1,40 @@ +/* + * Test DMULT. + */ + +#include +#include +#include + +struct hi_lo { int64_t hi; uint64_t lo; }; + +static struct hi_lo dmult(int64_t rs, int64_t rt) +{ +int64_t hi; +uint64_t lo; + +/* + * The R5900 reports itself as MIPS III but does not implement DMULT. + * Verify that DMULT is emulated properly in user mode. + */ +__asm__ __volatile__ ( +".set mips3\n" +"dmult %2, %3\n" +"mfhi %0\n" +"mflo %1\n" +: "=r" (hi), "=r" (lo) +: "r" (rs), "r" (rt)); + +return (struct hi_lo) { .hi = hi, .lo = lo }; +} + +int main() +{ +/* Verify that multiplying two 64-bit numbers yields a 128-bit number. */ +struct hi_lo r = dmult(2760727302517, 5665449960167); + +assert(r.hi == 847887); +assert(r.lo == 7893651516417804947); + +return 0; +} -- 2.18.1
Re: [Qemu-devel] [PATCH v2 4/6] target/mips: Fix decoding mechanism of special R5900 opcodes
Hi Aleksandar, > Fredrik, do you know by any chance if a document exists that would justify > inclusion of non-R5900 DMULT, DMULTU, DDIV, DDIVU in R5900 executables by > gcc for R5900? Is it included by cross-gcc or by native gcc, or by both? > > I think gcc folks must have had a good reason for that, some kind of > design - it can't be 'I really like/miss this instruction, let's include > it...' The R5900 reports itself as MIPS III and DMULT, DMULTU, DDIV and DDIVU are part of the MIPS III ISA. They are emulated in user mode to support generic MIPS III programs. I have now obtained an R5900 n32 ABI toolchain. R5900 n32 ABI emulation support is recognised with http://lists.nongnu.org/archive/html/qemu-devel/2018-11/msg01609.html and a test of DMULT emulation is available with http://lists.nongnu.org/archive/html/qemu-devel/2018-11/msg01610.html Fredrik
Re: [Qemu-devel] [PATCH v2 4/6] target/mips: Fix decoding mechanism of special R5900 opcodes
Hi Aleksandar, > > The R5900 reports itself as MIPS III ... > > This is very unclear. What do you mean by this? How does R5900 do that? I > can't find any trace of such intentions in R5900 docs. In QEMU, we have previously defined the R5900 as MIPS III by #define CPU_R5900 (CPU_MIPS3 | INSN_R5900) by referring to the "Toshiba TX System RISC TX79 Core Architecture" manual https://wiki.qemu.org/File:C790.pdf It says in the introduction, for example, that 3.1 Introduction The C790 supports all MIPS III instructions with the exception of 64-bit multiply, 64-bit divide, Load Linked and Store Conditional instructions. It also supports a limited number of MIPS IV instructions and additional C790-specific instructions, such as Multiply/Add instructions and multimedia instructions. The manual mentions MIPS III in several other places, and appendix A-1 "CPU Instruction Set Details" describes the implemented MIPS III subset. > > ... and DMULT, DMULTU, DDIV and DDIVU > > are part of the MIPS III ISA. They are emulated in user mode to support > > generic MIPS III programs. > > Pure MIPS III executables should not be a concern of the R5900 emulation, > but R5900 executables. Many Linux distributions rely on precompiled packages, and they are often made to work with a broad range of hardware. This is done in part by choosing a common denominator, such as MIPS III. Compatibility with other implementations means that the R5900 more easily can be part of the MIPS Linux ecosystem. In contrast, Gentoo Linux mainly builds its packages locally from source, often optimised for the hardware, such as the R5900. Even so, Gentoo does rely on a small set of precompiled "stage 3" packages for the installation, and so the argument above still applies. > Could you please provide a document that would justify inclusion of these > non-R5900 instruction in an R5900 emulation? Would you accept the TX79 manual mentioned above as such a document? Fredrik
Re: [Qemu-devel] [PATCH v2 4/6] target/mips: Fix decoding mechanism of special R5900 opcodes
Hi Aleksandar, > Tx79 mentions the opposite: that DDIV, DDIVU, DMULT, DMULTU are not > included in R5900 set. > > I think that the best solution that you exclude DDIV, DDIVU, DMULT, DMULTU > in a separate patch - there is no document to support their inclusion. As Maciej noted, the 64-bit MIPS Linux psABI is indivisible, so how could your alternative possibly work? Fredrik
Re: [Qemu-devel] [PATCH] target/mips: Disable R5900 support
Hi Philippe, On Tue, Nov 13, 2018 at 11:51:54PM +0100, Philippe Mathieu-Daudé wrote: > On Tue, Nov 13, 2018 at 8:29 PM Philippe Mathieu-Daudé > wrote: > > On Tue, Nov 13, 2018 at 8:08 PM Aleksandar Markovic > > wrote: > > > > > > From: Aleksandar Markovic > > > > > > Disable R5900 support. There are some outstanding issues related > > > to ABI support and emulation accuracy, that were not understood > > > well during review process. Disable to avoid backward compatibility > > > issues. > > If the issues you mentioned are "the R5900 tcg opcodes are not > implemented correctly", then this patch is OK, because no cpu can use > the R5900 opcodes. The issue is that the Linux kernel emulates certain opcodes (e.g. LL, SC, RDHWR, DMULT, etc.) by psABI requirements. This is a common requirement for many other MIPS implementations, not only the R5900. It is trivial to do this with QEMU user mode, but evidently for whatever reason Aleksandar does not permit this emulation. > At some point while reading your reviews, I understood the R5900 > patches introduced incorrect behaviors for the non-R5900 cpus. In this > case this patch wouldn't suffice. No, that was never the case and I'm not aware of any such problems. However, there is a refactoring series, and we have observed preexisting bugs in the MIPS emulation, unrelated to the R5900. The opcode decoder could also be improved, such as in asserting reserved instructions in more cases where opcodes are invalid, etc. > Hoping I misinterpreted your reviews, then this patch is OK. > With one of the suggested comments: > Reviewed-by: Philippe Mathieu-Daudé > > Then we will fix this for the 4.0 release. What exactly needs to be fixed regarding the psABI? The relevant opcodes would need to stay, and not be prohibited and removed as Aleksandar has suggested, since such opcode removal breaks the psABI requirements. Finally, as Maciej explained in some detail, the document that Aleksandar just recently requested is known to not exist, for any MIPS implementation, so we are not going to make any progress on that either. Fredrik
Re: [Qemu-devel] [PATCH v5 6/8] target/mips: Define the R5900 CPU
Thank you for your reviews, Philippe, > Fredrik: maybe you can simply name the C790 in the comment pointing to > the DS documentation. Sure, I will do that for v6! I am also adding some of Maciej's notes on the differences between the C790 and the R5900, along with PRId 0X2E00 as noted by Jürgen: { /* * The Toshiba TX System RISC TX79 Core Architecture manual * * http://www.lukasz.dk/files/tx79architecture.pdf * * describes the C790 processor which is a follow-up to the R5900. * There are a few notable differences in that the R5900 FPU * * - is not fully IEEE 754-1985 compliant, * - does not implement double format, and * - its machine code is nonstandard. */ .name = "R5900", .CP0_PRid = 0x2E00, > Fredrik, except the linux-user part for kernel FPU emulation that I > don't feel confident to review, the rest of this patch looks OK to me: > Reviewed-by: Philippe Mathieu-Daudé Would you rather have an acked-by as a less formal "looks good to me" tag? I anticipate significant changes to the notes and commit messages in v6, so all previous tags ought to be reset for that reason, I think. Fredrik
Re: [Qemu-devel] [PATCH v5 2/8] target/mips: Support R5900 specific three-operand MULT and MULTU
Hi Philippe, > Can you copy/paste some info regarding those instructions from the ISA > here, to note how they differ? ... Yes. Other corresponding functions typically do not seem to have such ISA notes, but I can certainly write one for it. > Since we have acc = 0 we can directly use cpu_LO[0] and cpu_HI[0], > removing needs for an 'acc' argument. We could, but as Maciej replied there are pipeline 1 versions of these instructions which would have acc = 1. I retained the acc parameter mainly to avoid the error of forgetting to replace 0 with acc when introducing them later on. > > +{ > > +TCGv t0 = tcg_temp_new(); > > +TCGv t1 = tcg_temp_new(); > > + > > +gen_load_gpr(t0, rs); > > +gen_load_gpr(t1, rt); > > + > > +switch (opc) { > > +case OPC_MULT: > > +{ > > +TCGv_i32 t2 = tcg_temp_new_i32(); > > +TCGv_i32 t3 = tcg_temp_new_i32(); > > +tcg_gen_trunc_tl_i32(t2, t0); > > +tcg_gen_trunc_tl_i32(t3, t1); > > +tcg_gen_muls2_i32(t2, t3, t2, t3); > > +if (rd) > > Check QEMU CODING_STYLE "Block structure": > > Every indented statement is braced; even if the block contains > just one statement. The opening brace is on the line that > contains the control flow statement that introduces the new block; > the closing brace is on the same line as the else keyword, or on > a line by itself if there is no else keyword. > > QEMU scripts/checkpatch.pl reports such mistakes. Done. > > +tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); > > I'd use: > >gen_move_low32(cpu_gpr[rd], t2); Are you sure this is correct? The GPR rd must be sign-extended. > > +tcg_gen_ext_i32_tl(cpu_LO[acc], t2); > > So: > >tcg_gen_ext_i32_tl(cpu_LO[0], t2); > > > +tcg_gen_ext_i32_tl(cpu_HI[acc], t3); > > And: > >tcg_gen_ext_i32_tl(cpu_HI[0], t3); Done. > > +tcg_temp_free_i32(t2); > > +tcg_temp_free_i32(t3); > > +} > > +break; > > +case OPC_MULTU: > > +{ > > +TCGv_i32 t2 = tcg_temp_new_i32(); > > +TCGv_i32 t3 = tcg_temp_new_i32(); > > +tcg_gen_trunc_tl_i32(t2, t0); > > +tcg_gen_trunc_tl_i32(t3, t1); > > +tcg_gen_mulu2_i32(t2, t3, t2, t3); > > +if (rd) > > +tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); > > +tcg_gen_ext_i32_tl(cpu_LO[acc], t2); > > +tcg_gen_ext_i32_tl(cpu_HI[acc], t3); > > Same comments from MULT apply here. Done. > > +tcg_temp_free_i32(t2); > > +tcg_temp_free_i32(t3); > > +} > > +break; > > +default: > > +MIPS_INVAL("mul R5900"); > > +generate_exception_end(ctx, EXCP_RI); > > +goto out; > > +} > > + > > + out: > > +tcg_temp_free(t0); > > +tcg_temp_free(t1); > > +} > > + > > static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, > > int rd, int rs, int rt) > > { > > @@ -22378,6 +22429,8 @@ static void decode_opc_special_legacy(CPUMIPSState > > *env, DisasContext *ctx) > > check_insn(ctx, INSN_VR54XX); > > op1 = MASK_MUL_VR54XX(ctx->opcode); > > gen_mul_vr54xx(ctx, op1, rd, rs, rt); > > +} else if (ctx->insn_flags & INSN_R5900) { > > +gen_mul_r5900(ctx, op1, 0, rd, rs, rt); > > Removing 'acc' arg: > >gen_mul_r5900(ctx, op1, rd, rs, rt); Done. > Note, these instructions are also valid on the R3900 (which also has > MADD/MADDU). > > Would gen_mul_toshiba() be a better common name? I don't like it but > can't think of another. I propose gen_mul_3op, since its distinctive feature is the three operands. Fredrik
Re: [Qemu-devel] [PATCH v5 0/8] target/mips: Support R5900 GCC programs in user mode
Hi Philippe, > We could manage to build a docker mips-r5900 cross-compiler image, such: > https://lists.gnu.org/archive/html/qemu-devel/2018-06/msg06908.html > > But we'll need your patches. The attached patches for GAS and GCC are provisional and intended to enable and simplify the use of a modern GCC for the R5900 target. There are two main parts: 1. Libc needs LL and SC instructions which GAS refuses to assemble since they are not part of the R5900 ISA. However, they are required and emulated by the Linux kernel. I have been told that the recommended fix is to implement special architecture overrides in libc which will force GAS to accept LL and SC, and since this involves public headers certain compatibility issues need to be addressed. The attached workaround simply makes GAS and GCC accept LL and SC so that libc can use the instructions as-is. 2. Similarly, GCC emits certain floating point instructions which GAS refuses to assemble since they are not part of the R5900 ISA. Like LL and SC, the kernel is designed to emulate such instructions. The attached workaround forces the use of the single precision floating point format to avoid these problems. Finally, it seems GCC emits MIPS16 instructions which are causing problems for the R5900 target. The attached patches fix these as well. Gentoo can be compiled for the R5900. To do this, the attached patches need to be installed in /etc/portage/patches/cross-mipsr5900el-unknown-linux-gnu/ on a host Gentoo system, in subdirectories such as binutils-2.31.1 gcc-7.3.0 depending on the particular versions that will be used. The Gentoo sys-devel/crossdev package page https://wiki.gentoo.org/wiki/Crossdev and the cross build environment guide https://wiki.gentoo.org/wiki/Cross_build_environment explain the details involving configuring for example a Gentoo profile and an overlay. Once those simple steps have been taken the command # crossdev -s4 -t mipsr5900el-unknown-linux-gnu can be used to obtain an R5900 cross toolchain as well as the basis of an R5900 Gentoo root filesystem in /usr/mipsr5900el-unknown-linux-gnu As the guide explains, the R5900 base system can be built from scratch using the command # mipsr5900el-unknown-linux-gnu-emerge -uva --keep-going @system The root filesystem can then be used for R5900 QEMU user mode emulation (as described in the guide) or directly in Linux on R5900 hardware. Fredrik diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c index 1cbcbc6..0986b0a 100644 --- a/opcodes/mips-opc.c +++ b/opcodes/mips-opc.c @@ -1280,11 +1280,11 @@ const struct mips_opcode mips_builtin_opcodes[] = {"li.s", "t,f", 0,(int) M_LI_S, INSN_MACRO, INSN2_M_FP_S, I1, 0, 0 }, {"li.s", "T,l", 0,(int) M_LI_SS, INSN_MACRO, INSN2_M_FP_S, I1, 0, 0 }, {"ll", "t,+j(b)", 0x7c36, 0xfc7f, WR_1|RD_3|LM, 0, I37, 0, 0 }, -{"ll", "t,o(b)", 0xc000, 0xfc00, WR_1|RD_3|LM, 0, I2, 0, EE|I37 }, -{"ll", "t,A(b)", 0,(int) M_LL_AB, INSN_MACRO, 0, I2, 0, EE }, +{"ll", "t,o(b)", 0xc000, 0xfc00, WR_1|RD_3|LM, 0, I2, 0, I37 }, +{"ll", "t,A(b)", 0,(int) M_LL_AB, INSN_MACRO, 0, I2, 0, 0 }, {"lld", "t,+j(b)", 0x7c37, 0xfc7f, WR_1|RD_3|LM, 0, I69, 0, 0 }, -{"lld", "t,o(b)", 0xd000, 0xfc00, WR_1|RD_3|LM, 0, I3, 0, EE|I69 }, -{"lld", "t,A(b)", 0,(int) M_LLD_AB, INSN_MACRO, 0, I3, 0, EE }, +{"lld", "t,o(b)", 0xd000, 0xfc00, WR_1|RD_3|LM, 0, I3, 0, I69 }, +{"lld", "t,A(b)", 0,(int) M_LLD_AB, INSN_MACRO, 0, I3, 0, 0 }, {"lq", "t,o(b)", 0x7800, 0xfc00, WR_1|RD_3|LM, 0, MMI, 0, 0 }, {"lq", "t,A(b)", 0,(int) M_LQ_AB, INSN_MACRO, 0, MMI, 0, 0 }, {"lqc2", "+7,o(b)", 0xd800, 0xfc00, RD_3|WR_C2|LM, 0, EE, 0, 0 }, @@ -1810,11 +1810,11 @@ const struct mips_opcode mips_builtin_opcodes[] = {"sb", "t,o(b)", 0xa000, 0xfc00, RD_1|RD_3|SM, 0, I1, 0, 0 }, {"sb", "t,A(b)", 0,(int) M_SB_AB, INSN_MACRO, 0, I1, 0, 0 }, {"sc", "t,+j(b)", 0x7c26, 0xfc7f, MOD_1|RD_3|SM, 0, I37, 0, 0 }, -{"sc", "t,o(b)", 0xe000, 0xfc00, MOD_1|RD_3|SM, 0, I2, 0, EE|I37 }, -{"sc", "t,A(b)", 0,(int) M_SC_AB, INSN_MACRO, 0, I2, 0, EE }, +{"sc", "t,o(b)", 0xe000, 0xfc00, MOD_1|RD_3|SM, 0, I2, 0, I37 }, +{"sc", "t,A(b)", 0,(int) M_SC_AB, INSN_MACRO, 0, I2, 0, 0 }, {"scd", "t,+j(b)", 0x7c27, 0xfc7f, MOD_1|RD_3|SM, 0, I69, 0, 0 }, -{"scd", "t,o(b)", 0xf000, 0xfc00, MOD_1|RD_3|SM, 0, I3, 0, EE|I69 }, -{"scd", "t,A(b)", 0,(int) M_SCD_AB, INSN_MACRO, 0, I3, 0, EE }, +{"scd", "t,o(b)", 0xf000, 0xfc00, MOD_1|RD_3|SM, 0, I3, 0, I69 }, +{"scd", "t,A(b)", 0,(int) M_SCD_AB, INSN_MACRO, 0, I3, 0, 0 }, /* The macro has to be first to handle o32 correctly. */ {"sd", "t,A(b)", 0,(int) M_SD_AB, INSN_MACRO, 0, I1, 0, 0 }, {"sd", "t,
[Qemu-devel] [PATCH v6 0/7] target/mips: Limited support for the R5900
900 values - LL/SC and FPU are user only Fredrik Noring (7): target/mips: Define R5900 instructions and CPU preprocessor constants target/mips: Support R5900 specific three-operand MULT and MULTU target/mips: Support R5900 instructions MOVN, MOVZ and PREF from MIPS IV target/mips: R5900 DMULT[U], DDIV[U], LL[D] and SC[D] are user only target/mips: Define the R5900 CPU linux-user/mips: Recognise the R5900 CPU model elf: Toshiba/Sony rather than MIPS are the implementors of the R5900 include/elf.h| 2 +- linux-user/mips/target_elf.h | 3 ++ target/mips/mips-defs.h | 2 + target/mips/translate.c | 101 +-- target/mips/translate_init.inc.c | 59 +++ 5 files changed, 163 insertions(+), 4 deletions(-) -- 2.16.4
[Qemu-devel] [PATCH v6 1/7] target/mips: Define R5900 instructions and CPU preprocessor constants
The R5900 implements the 64-bit MIPS III instruction set except DMULT, DMULTU, DDIV, DDIVU, LL, SC, LLD and SCD. The MIPS IV instructions MOVN, MOVZ and PREF are implemented. It has the R5900 specific three-operand instructions MADD, MADDU, MULT and MULTU as well as pipeline 1 versions MULT1, MULTU1, DIV1, DIVU1, MADD1, MADDU1, MFHI1, MFLO1, MTHI1 and MTLO1. A set of 93 128-bit multimedia instructions specific to the R5900 is also implemented. The Toshiba TX System RISC TX79 Core Architecture manual http://www.lukasz.dk/files/tx79architecture.pdf describes the C790 processor that is a follow-up to the R5900. There are a few notable differences in that the R5900 FPU - is not IEEE 754-1985 compliant, - does not implement double format, and - its machine code is nonstandard. Signed-off-by: Fredrik Noring --- target/mips/mips-defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index c8e99791ad..76550de2da 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -53,6 +53,7 @@ #define ASE_MSA 0x0100 /* Chip specific instructions. */ +#define INSN_R5900 0x1000 #defineINSN_LOONGSON2E 0x2000 #defineINSN_LOONGSON2F 0x4000 #defineINSN_VR54XX 0x8000 @@ -63,6 +64,7 @@ #defineCPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) #defineCPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) #defineCPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) +#define CPU_R5900 (CPU_MIPS3 | INSN_R5900) #defineCPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) #defineCPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) -- 2.16.4
[Qemu-devel] [PATCH v6 2/7] target/mips: Support R5900 specific three-operand MULT and MULTU
The three-operand MULT and MULTU are the only R5900 specific instructions emitted by GCC 7.3. The R5900 also implements the three- operand MADD and MADDU instructions, but they are omitted in QEMU for now since they are absent in programs compiled by current GCC versions. Likewise, the R5900 specific pipeline 1 instruction variants MULT1, MULTU1, DIV1, DIVU1, MADD1, MADDU1, MFHI1, MFLO1, MTHI1 and MTLO1 are omitted here as well. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 73 + 1 file changed, 73 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index ab16cdb911..7e18ec0d03 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -3768,6 +3768,77 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } +/* + * These MULT and MULTU instructions implemented in for example the + * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core + * architectures are special three-operand variants with the syntax + * + * MULT[U] rd, rs, rt + * + * such that + * + * (rd, LO, HI) <- rs * rt + * + * where the low-order 32-bits of the result is placed into both the + * GPR rd and the special register LO. The high-order 32-bits of the + * result is placed into the special register HI. + * + * If the GPR rd is omitted in assembly language, it is taken to be 0, + * which is the zero register that always reads as 0. + */ +static void gen_mul_txxx(DisasContext *ctx, uint32_t opc, + int acc, int rd, int rs, int rt) +{ +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +switch (opc) { +case OPC_MULT: +{ +TCGv_i32 t2 = tcg_temp_new_i32(); +TCGv_i32 t3 = tcg_temp_new_i32(); +tcg_gen_trunc_tl_i32(t2, t0); +tcg_gen_trunc_tl_i32(t3, t1); +tcg_gen_muls2_i32(t2, t3, t2, t3); +if (rd) { +tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); +} +tcg_gen_ext_i32_tl(cpu_LO[acc], t2); +tcg_gen_ext_i32_tl(cpu_HI[acc], t3); +tcg_temp_free_i32(t2); +tcg_temp_free_i32(t3); +} +break; +case OPC_MULTU: +{ +TCGv_i32 t2 = tcg_temp_new_i32(); +TCGv_i32 t3 = tcg_temp_new_i32(); +tcg_gen_trunc_tl_i32(t2, t0); +tcg_gen_trunc_tl_i32(t3, t1); +tcg_gen_mulu2_i32(t2, t3, t2, t3); +if (rd) { +tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); +} +tcg_gen_ext_i32_tl(cpu_LO[acc], t2); +tcg_gen_ext_i32_tl(cpu_HI[acc], t3); +tcg_temp_free_i32(t2); +tcg_temp_free_i32(t3); +} +break; +default: +MIPS_INVAL("mul R5900"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + + out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { @@ -22378,6 +22449,8 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) check_insn(ctx, INSN_VR54XX); op1 = MASK_MUL_VR54XX(ctx->opcode); gen_mul_vr54xx(ctx, op1, rd, rs, rt); +} else if (ctx->insn_flags & INSN_R5900) { +gen_mul_txxx(ctx, op1, 0, rd, rs, rt); } else { gen_muldiv(ctx, op1, rd & 3, rs, rt); } -- 2.16.4
[Qemu-devel] [PATCH v6 5/7] target/mips: Define the R5900 CPU
The primary purpose of this change is to support programs compiled by GCC for the R5900 target and thereby run R5900 Linux distributions, for example Gentoo. GCC in version 7.3, by itself, by inspection of the GCC source code and inspection of the generated machine code, for the R5900 target, only emits two instructions that are specific to the R5900: the three- operand MULT and MULTU. GCC and libc also emit certain MIPS III instructions that are not part of the R5900 ISA. They are normally trapped and emulated by the Linux kernel, and therefore need to be treated accordingly by QEMU. A program compiled by GCC is taken to mean source code compiled by GCC under the restrictions above. One can, with the apparent limitations, with a bit of effort obtain a fully functioning operating system such as R5900 Gentoo. Strictly speaking, programs need not be compiled by GCC to make use of this change. Instructions and other facilities of the R5900 not implemented by this change are intended to signal provisional exceptions. One such example is the FPU that is not compliant with IEEE 754-1985 in system mode. It is therefore provisionally disabled. In user space the FPU is trapped and emulated by IEEE 754-1985 compliant software in the kernel, and this is handled accordingly by QEMU. Another example is the 93 multimedia instructions specific to the R5900 that generate provisional reserved instruction exception signals. One of the benefits of running a Linux distribution under QEMU is that programs can be compiled with a native compiler, where the host and target are the same, as opposed to a cross-compiler, where they are not the same. This is especially important in cases where the target hardware does not have the resources to run a native compiler. Problems with cross-compilation are often related to host and target differences in integer sizes, pointer sizes, endianness, machine code, ABI, etc. Sometimes cross-compilation is not even supported by the build script for a given package. One effective way to avoid those problems is to replace the cross-compiler with a native compiler. This change of compilation methods does not resolve the inherent problems with cross-compilation. The native compiler naturally replaces the cross-compiler, because one typically uses one or the other, and preferably the native compiler when the circumstances admit this. The native compiler is also a good test case for the R5900 QEMU user mode. Additionally, Gentoo is well- known for compiling and installing its packages from sources. This change has been tested with Gentoo compiled for R5900, including native compilation of several packages under QEMU. Signed-off-by: Fredrik Noring --- target/mips/translate_init.inc.c | 59 1 file changed, 59 insertions(+) diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c index b3320b9dc7..b5dacf4ffe 100644 --- a/target/mips/translate_init.inc.c +++ b/target/mips/translate_init.inc.c @@ -410,6 +410,65 @@ const mips_def_t mips_defs[] = .insn_flags = CPU_MIPS32R5 | ASE_MSA, .mmu_type = MMU_TYPE_R4000, }, +{ +/* + * The Toshiba TX System RISC TX79 Core Architecture manual + * + * http://www.lukasz.dk/files/tx79architecture.pdf + * + * describes the C790 processor that is a follow-up to the R5900. + * There are a few notable differences in that the R5900 FPU + * + * - is not IEEE 754-1985 compliant, + * - does not implement double format, and + * - its machine code is nonstandard. + */ +.name = "R5900", +.CP0_PRid = 0x2E00, +/* No L2 cache, icache size 32k, dcache size 32k, uncached coherency. */ +.CP0_Config0 = (0x3 << 9) | (0x3 << 6) | (0x2 << CP0C0_K0), +.CP0_Status_rw_bitmask = 0xF4C79C1F, +#ifdef CONFIG_USER_ONLY +/* + * R5900 hardware traps to the Linux kernel for IEEE 754-1985 and LL/SC + * emulation. For user only, QEMU is the kernel, so we emulate the traps + * by simply emulating the instructions directly. + * + * Note: Config1 is only used internally, the R5900 has only Config0. + */ +.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), +.CP0_LLAddr_rw_bitmask = 0x, +.CP0_LLAddr_shift = 4, +.CP1_fcr0 = (0x38 << FCR0_PRID) | (0x0 << FCR0_REV), +.CP1_fcr31 = 0, +.CP1_fcr31_rw_bitmask = 0x0183, +#else +/* + * The R5900 COP1 FPU implements single-precision floating-point + * operations but is not entirely IEEE 754-1985 compatible. In + * particular, + * + * - NaN (not a number) and +/- infinities are not supported; + * - exception mechanisms are not fully supported; + * - denormalized numbers are not supported; + * -
[Qemu-devel] [PATCH v6 4/7] target/mips: R5900 DMULT[U], DDIV[U], LL[D] and SC[D] are user only
The Linux kernel traps certain reserved instruction exceptions to emulate the corresponding instructions. QEMU is the kernel in user mode, so those traps are emulated by accepting the instructions. This change adds the function check_insn_opc_user_only to signal a reserved instruction exception for flagged CPUs in QEMU system mode. The MIPS III instructions DMULT[U], DDIV[U], LL[D] and SC[D] are not implemented in R5900 hardware. They are trapped and emulated by the Linux kernel and, accordingly, therefore QEMU user only instructions. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 0c445c11c5..5a5021fe36 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1887,6 +1887,21 @@ static inline void check_insn_opc_removed(DisasContext *ctx, int flags) } } +/* + * The Linux kernel traps certain reserved instruction exceptions to + * emulate the corresponding instructions. QEMU is the kernel in user + * mode, so those traps are emulated by accepting the instructions. + * + * A reserved instruction exception is generated for flagged CPUs if + * QEMU runs in system mode. + */ +static inline void check_insn_opc_user_only(DisasContext *ctx, int flags) +{ +#ifndef CONFIG_USER_ONLY +check_insn_opc_removed(ctx, flags); +#endif +} + /* This code generates a "reserved instruction" exception if the CPU does not support 64-bit paired-single (PS) floating point data type */ static inline void check_ps(DisasContext *ctx) @@ -22465,6 +22480,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_DDIV: case OPC_DDIVU: check_insn(ctx, ISA_MIPS3); +check_insn_opc_user_only(ctx, INSN_R5900); check_mips_64(ctx); gen_muldiv(ctx, op1, 0, rs, rt); break; @@ -24968,6 +24984,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_LL: /* Load and stores */ check_insn(ctx, ISA_MIPS2); +check_insn_opc_user_only(ctx, INSN_R5900); /* Fallthrough */ case OPC_LWL: case OPC_LWR: @@ -24993,6 +25010,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SC: check_insn(ctx, ISA_MIPS2); check_insn_opc_removed(ctx, ISA_MIPS32R6); +check_insn_opc_user_only(ctx, INSN_R5900); gen_st_cond(ctx, op, rt, rs, imm); break; case OPC_CACHE: @@ -25259,9 +25277,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) #if defined(TARGET_MIPS64) /* MIPS64 opcodes */ +case OPC_LLD: +check_insn_opc_user_only(ctx, INSN_R5900); +/* fall through */ case OPC_LDL: case OPC_LDR: -case OPC_LLD: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* fall through */ case OPC_LWU: @@ -25282,6 +25302,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SCD: check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS3); +check_insn_opc_user_only(ctx, INSN_R5900); check_mips_64(ctx); gen_st_cond(ctx, op, rt, rs, imm); break; -- 2.16.4
[Qemu-devel] [PATCH v6 3/7] target/mips: Support R5900 instructions MOVN, MOVZ and PREF from MIPS IV
The R5900 is taken to be MIPS III with certain modifications. From MIPS IV it implements the instructions MOVN, MOVZ and PREF. Signed-off-by: Fredrik Noring --- target/mips/translate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 7e18ec0d03..0c445c11c5 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -22422,7 +22422,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_MOVN: /* Conditional move */ case OPC_MOVZ: check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | - INSN_LOONGSON2E | INSN_LOONGSON2F); + INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900); gen_cond_move(ctx, op1, rd, rs, rt); break; case OPC_MFHI: /* Move from HI/LO */ @@ -25006,7 +25006,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_PREF: check_insn_opc_removed(ctx, ISA_MIPS32R6); -check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); +check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | + INSN_R5900); /* Treat as NOP. */ break; -- 2.16.4
[Qemu-devel] [PATCH v6 7/7] elf: Toshiba/Sony rather than MIPS are the implementors of the R5900
Sources [1][2] indicate that the Emotion Engine was designed by Toshiba and licensed to Sony. Others [3][4][5] claim it was a joint effort. It therefore makes sense to refer to the CPU as "Toshiba/Sony R5900". [1] http://cs.nyu.edu/courses/spring02/V22.0480-002/projects/aldrich/emotionengine.ppt [2] http://archive.arstechnica.com/reviews/1q00/playstation2/m-ee-3.html [3] http://docencia.ac.upc.edu/ETSETB/SEGPAR/microprocessors/emotionengine%20(mpr).pdf [4] http://www.eetimes.com/document.asp?doc_id=1144055 [5] https://www.toshiba.co.jp/about/press/2001_09/pr2701.htm Reported-by: Maciej W. Rozycki Signed-off-by: Fredrik Noring --- include/elf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/elf.h b/include/elf.h index 312f68af81..2510fc7be4 100644 --- a/include/elf.h +++ b/include/elf.h @@ -76,7 +76,7 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_MACH_OCTEON2 0x008d /* Cavium Networks Octeon2 */ #define EF_MIPS_MACH_OCTEON3 0x008e /* Cavium Networks Octeon3 */ #define EF_MIPS_MACH_5400 0x0091 /* NEC VR5400 */ -#define EF_MIPS_MACH_5900 0x0092 /* MIPS R5900 */ +#define EF_MIPS_MACH_5900 0x0092 /* Toshiba/Sony R5900 */ #define EF_MIPS_MACH_5500 0x0098 /* NEC VR5500 */ #define EF_MIPS_MACH_9000 0x0099 /* PMC-Sierra's RM9000 */ #define EF_MIPS_MACH_LS2E 0x00a0 /* ST Microelectronics Loongson 2E */ -- 2.16.4
[Qemu-devel] [PATCH v6 6/7] linux-user/mips: Recognise the R5900 CPU model
This kind of ELF for the R5900 relies on an IEEE 754-1985 compliant FPU. The R5900 FPU hardware is noncompliant and it is therefore emulated in software by the Linux kernel. QEMU emulates a compliant FPU accordingly. Signed-off-by: Fredrik Noring --- linux-user/mips/target_elf.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-user/mips/target_elf.h b/linux-user/mips/target_elf.h index fa5d30bf99..a98c9bd6ad 100644 --- a/linux-user/mips/target_elf.h +++ b/linux-user/mips/target_elf.h @@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags) if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) { return "mips32r6-generic"; } +if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) { +return "R5900"; +} return "24Kf"; } #endif -- 2.16.4
[Qemu-devel] [PATCH v7 0/7] target/mips: Limited support for the R5900
nges in v3: - Apply to HEAD - Remove the word "initial" from subject line Changes in v2: - Update mips_defs array with R5900 values - LL/SC and FPU are user only Fredrik Noring (7): target/mips: Define R5900 instructions and CPU preprocessor constants target/mips: Support R5900 specific three-operand MULT and MULTU target/mips: Support R5900 instructions MOVN, MOVZ and PREF from MIPS IV target/mips: R5900 DMULT[U], DDIV[U], LL[D] and SC[D] are user only target/mips: Define the R5900 CPU linux-user/mips: Recognise the R5900 CPU model elf: Toshiba/Sony rather than MIPS are the implementors of the R5900 include/elf.h| 2 +- linux-user/mips/target_elf.h | 3 ++ target/mips/mips-defs.h | 2 + target/mips/translate.c | 101 +-- target/mips/translate_init.inc.c | 59 +++ 5 files changed, 163 insertions(+), 4 deletions(-) -- 2.16.4
[Qemu-devel] [PATCH v7 2/7] target/mips: Support R5900 specific three-operand MULT and MULTU
The three-operand MULT and MULTU are the only R5900 specific instructions emitted by GCC 7.3. The R5900 also implements the three- operand MADD and MADDU instructions, but they are omitted in QEMU for now since they are absent in programs compiled by current GCC versions. Likewise, the R5900 specific pipeline 1 instruction variants MULT1, MULTU1, DIV1, DIVU1, MADD1, MADDU1, MFHI1, MFLO1, MTHI1 and MTLO1 are omitted here as well. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/translate.c | 73 + 1 file changed, 73 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index ab16cdb911..a32e021745 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -3768,6 +3768,77 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } +/* + * These MULT and MULTU instructions implemented in for example the + * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core + * architectures are special three-operand variants with the syntax + * + * MULT[U] rd, rs, rt + * + * such that + * + * (rd, LO, HI) <- rs * rt + * + * where the low-order 32-bits of the result is placed into both the + * GPR rd and the special register LO. The high-order 32-bits of the + * result is placed into the special register HI. + * + * If the GPR rd is omitted in assembly language, it is taken to be 0, + * which is the zero register that always reads as 0. + */ +static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, + int acc, int rd, int rs, int rt) +{ +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +switch (opc) { +case OPC_MULT: +{ +TCGv_i32 t2 = tcg_temp_new_i32(); +TCGv_i32 t3 = tcg_temp_new_i32(); +tcg_gen_trunc_tl_i32(t2, t0); +tcg_gen_trunc_tl_i32(t3, t1); +tcg_gen_muls2_i32(t2, t3, t2, t3); +if (rd) { +tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); +} +tcg_gen_ext_i32_tl(cpu_LO[acc], t2); +tcg_gen_ext_i32_tl(cpu_HI[acc], t3); +tcg_temp_free_i32(t2); +tcg_temp_free_i32(t3); +} +break; +case OPC_MULTU: +{ +TCGv_i32 t2 = tcg_temp_new_i32(); +TCGv_i32 t3 = tcg_temp_new_i32(); +tcg_gen_trunc_tl_i32(t2, t0); +tcg_gen_trunc_tl_i32(t3, t1); +tcg_gen_mulu2_i32(t2, t3, t2, t3); +if (rd) { +tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); +} +tcg_gen_ext_i32_tl(cpu_LO[acc], t2); +tcg_gen_ext_i32_tl(cpu_HI[acc], t3); +tcg_temp_free_i32(t2); +tcg_temp_free_i32(t3); +} +break; +default: +MIPS_INVAL("mul TXx9"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + + out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { @@ -22378,6 +22449,8 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) check_insn(ctx, INSN_VR54XX); op1 = MASK_MUL_VR54XX(ctx->opcode); gen_mul_vr54xx(ctx, op1, rd, rs, rt); +} else if (ctx->insn_flags & INSN_R5900) { +gen_mul_txx9(ctx, op1, 0, rd, rs, rt); } else { gen_muldiv(ctx, op1, rd & 3, rs, rt); } -- 2.16.4
[Qemu-devel] [PATCH v7 1/7] target/mips: Define R5900 instructions and CPU preprocessor constants
The R5900 implements the 64-bit MIPS III instruction set except DMULT, DMULTU, DDIV, DDIVU, LL, SC, LLD and SCD. The MIPS IV instructions MOVN, MOVZ and PREF are implemented. It has the R5900 specific three-operand instructions MADD, MADDU, MULT and MULTU as well as pipeline 1 versions MULT1, MULTU1, DIV1, DIVU1, MADD1, MADDU1, MFHI1, MFLO1, MTHI1 and MTLO1. A set of 93 128-bit multimedia instructions specific to the R5900 is also implemented. The Toshiba TX System RISC TX79 Core Architecture manual http://www.lukasz.dk/files/tx79architecture.pdf describes the C790 processor that is a follow-up to the R5900. There are a few notable differences in that the R5900 FPU - is not IEEE 754-1985 compliant, - does not implement double format, and - its machine code is nonstandard. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/mips-defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index c8e99791ad..76550de2da 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -53,6 +53,7 @@ #define ASE_MSA 0x0100 /* Chip specific instructions. */ +#define INSN_R5900 0x1000 #defineINSN_LOONGSON2E 0x2000 #defineINSN_LOONGSON2F 0x4000 #defineINSN_VR54XX 0x8000 @@ -63,6 +64,7 @@ #defineCPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) #defineCPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) #defineCPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) +#define CPU_R5900 (CPU_MIPS3 | INSN_R5900) #defineCPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) #defineCPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) -- 2.16.4
[Qemu-devel] [PATCH v7 5/7] target/mips: Define the R5900 CPU
The primary purpose of this change is to support programs compiled by GCC for the R5900 target and thereby run R5900 Linux distributions, for example Gentoo. GCC in version 7.3, by itself, by inspection of the GCC source code and inspection of the generated machine code, for the R5900 target, only emits two instructions that are specific to the R5900: the three- operand MULT and MULTU. GCC and libc also emit certain MIPS III instructions that are not part of the R5900 ISA. They are normally trapped and emulated by the Linux kernel, and therefore need to be treated accordingly by QEMU. A program compiled by GCC is taken to mean source code compiled by GCC under the restrictions above. One can, with the apparent limitations, with a bit of effort obtain a fully functioning operating system such as R5900 Gentoo. Strictly speaking, programs need not be compiled by GCC to make use of this change. Instructions and other facilities of the R5900 not implemented by this change are intended to signal provisional exceptions. One such example is the FPU that is not compliant with IEEE 754-1985 in system mode. It is therefore provisionally disabled. In user space the FPU is trapped and emulated by IEEE 754-1985 compliant software in the kernel, and this is handled accordingly by QEMU. Another example is the 93 multimedia instructions specific to the R5900 that generate provisional reserved instruction exception signals. One of the benefits of running a Linux distribution under QEMU is that programs can be compiled with a native compiler, where the host and target are the same, as opposed to a cross-compiler, where they are not the same. This is especially important in cases where the target hardware does not have the resources to run a native compiler. Problems with cross-compilation are often related to host and target differences in integer sizes, pointer sizes, endianness, machine code, ABI, etc. Sometimes cross-compilation is not even supported by the build script for a given package. One effective way to avoid those problems is to replace the cross-compiler with a native compiler. This change of compilation methods does not resolve the inherent problems with cross-compilation. The native compiler naturally replaces the cross-compiler, because one typically uses one or the other, and preferably the native compiler when the circumstances admit this. The native compiler is also a good test case for the R5900 QEMU user mode. Additionally, Gentoo is well- known for compiling and installing its packages from sources. This change has been tested with Gentoo compiled for R5900, including native compilation of several packages under QEMU. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/translate_init.inc.c | 59 1 file changed, 59 insertions(+) diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c index b3320b9dc7..b5dacf4ffe 100644 --- a/target/mips/translate_init.inc.c +++ b/target/mips/translate_init.inc.c @@ -410,6 +410,65 @@ const mips_def_t mips_defs[] = .insn_flags = CPU_MIPS32R5 | ASE_MSA, .mmu_type = MMU_TYPE_R4000, }, +{ +/* + * The Toshiba TX System RISC TX79 Core Architecture manual + * + * http://www.lukasz.dk/files/tx79architecture.pdf + * + * describes the C790 processor that is a follow-up to the R5900. + * There are a few notable differences in that the R5900 FPU + * + * - is not IEEE 754-1985 compliant, + * - does not implement double format, and + * - its machine code is nonstandard. + */ +.name = "R5900", +.CP0_PRid = 0x2E00, +/* No L2 cache, icache size 32k, dcache size 32k, uncached coherency. */ +.CP0_Config0 = (0x3 << 9) | (0x3 << 6) | (0x2 << CP0C0_K0), +.CP0_Status_rw_bitmask = 0xF4C79C1F, +#ifdef CONFIG_USER_ONLY +/* + * R5900 hardware traps to the Linux kernel for IEEE 754-1985 and LL/SC + * emulation. For user only, QEMU is the kernel, so we emulate the traps + * by simply emulating the instructions directly. + * + * Note: Config1 is only used internally, the R5900 has only Config0. + */ +.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), +.CP0_LLAddr_rw_bitmask = 0x, +.CP0_LLAddr_shift = 4, +.CP1_fcr0 = (0x38 << FCR0_PRID) | (0x0 << FCR0_REV), +.CP1_fcr31 = 0, +.CP1_fcr31_rw_bitmask = 0x0183, +#else +/* + * The R5900 COP1 FPU implements single-precision floating-point + * operations but is not entirely IEEE 754-1985 compatible. In + * particular, + * + * - NaN (not a number) and +/- infinities are not supported; + * - exception mechanisms are not fully supported; + * - denormalized numbe
[Qemu-devel] [PATCH v7 6/7] linux-user/mips: Recognise the R5900 CPU model
This kind of ELF for the R5900 relies on an IEEE 754-1985 compliant FPU. The R5900 FPU hardware is noncompliant and it is therefore emulated in software by the Linux kernel. QEMU emulates a compliant FPU accordingly. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- linux-user/mips/target_elf.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-user/mips/target_elf.h b/linux-user/mips/target_elf.h index fa5d30bf99..a98c9bd6ad 100644 --- a/linux-user/mips/target_elf.h +++ b/linux-user/mips/target_elf.h @@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags) if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) { return "mips32r6-generic"; } +if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) { +return "R5900"; +} return "24Kf"; } #endif -- 2.16.4
[Qemu-devel] [PATCH v7 4/7] target/mips: R5900 DMULT[U], DDIV[U], LL[D] and SC[D] are user only
The Linux kernel traps certain reserved instruction exceptions to emulate the corresponding instructions. QEMU is the kernel in user mode, so those traps are emulated by accepting the instructions. This change adds the function check_insn_opc_user_only to signal a reserved instruction exception for flagged CPUs in QEMU system mode. The MIPS III instructions DMULT[U], DDIV[U], LL[D] and SC[D] are not implemented in R5900 hardware. They are trapped and emulated by the Linux kernel and, accordingly, therefore QEMU user only instructions. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/translate.c | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 9d9be199e4..2d5c0a8173 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1887,6 +1887,21 @@ static inline void check_insn_opc_removed(DisasContext *ctx, int flags) } } +/* + * The Linux kernel traps certain reserved instruction exceptions to + * emulate the corresponding instructions. QEMU is the kernel in user + * mode, so those traps are emulated by accepting the instructions. + * + * A reserved instruction exception is generated for flagged CPUs if + * QEMU runs in system mode. + */ +static inline void check_insn_opc_user_only(DisasContext *ctx, int flags) +{ +#ifndef CONFIG_USER_ONLY +check_insn_opc_removed(ctx, flags); +#endif +} + /* This code generates a "reserved instruction" exception if the CPU does not support 64-bit paired-single (PS) floating point data type */ static inline void check_ps(DisasContext *ctx) @@ -22465,6 +22480,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_DDIV: case OPC_DDIVU: check_insn(ctx, ISA_MIPS3); +check_insn_opc_user_only(ctx, INSN_R5900); check_mips_64(ctx); gen_muldiv(ctx, op1, 0, rs, rt); break; @@ -24968,6 +24984,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_LL: /* Load and stores */ check_insn(ctx, ISA_MIPS2); +check_insn_opc_user_only(ctx, INSN_R5900); /* Fallthrough */ case OPC_LWL: case OPC_LWR: @@ -24993,6 +25010,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SC: check_insn(ctx, ISA_MIPS2); check_insn_opc_removed(ctx, ISA_MIPS32R6); +check_insn_opc_user_only(ctx, INSN_R5900); gen_st_cond(ctx, op, rt, rs, imm); break; case OPC_CACHE: @@ -25259,9 +25277,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) #if defined(TARGET_MIPS64) /* MIPS64 opcodes */ +case OPC_LLD: +check_insn_opc_user_only(ctx, INSN_R5900); +/* fall through */ case OPC_LDL: case OPC_LDR: -case OPC_LLD: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* fall through */ case OPC_LWU: @@ -25282,6 +25302,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SCD: check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS3); +check_insn_opc_user_only(ctx, INSN_R5900); check_mips_64(ctx); gen_st_cond(ctx, op, rt, rs, imm); break; -- 2.16.4
[Qemu-devel] [PATCH v7 3/7] target/mips: Support R5900 instructions MOVN, MOVZ and PREF from MIPS IV
The R5900 is taken to be MIPS III with certain modifications. From MIPS IV it implements the instructions MOVN, MOVZ and PREF. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/translate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index a32e021745..9d9be199e4 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -22422,7 +22422,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_MOVN: /* Conditional move */ case OPC_MOVZ: check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | - INSN_LOONGSON2E | INSN_LOONGSON2F); + INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900); gen_cond_move(ctx, op1, rd, rs, rt); break; case OPC_MFHI: /* Move from HI/LO */ @@ -25006,7 +25006,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_PREF: check_insn_opc_removed(ctx, ISA_MIPS32R6); -check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); +check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | + INSN_R5900); /* Treat as NOP. */ break; -- 2.16.4
[Qemu-devel] [PATCH v7 7/7] elf: Toshiba/Sony rather than MIPS are the implementors of the R5900
Sources [1][2] indicate that the Emotion Engine was designed by Toshiba and licensed to Sony. Others [3][4][5] claim it was a joint effort. It therefore makes sense to refer to the CPU as "Toshiba/Sony R5900". [1] http://cs.nyu.edu/courses/spring02/V22.0480-002/projects/aldrich/emotionengine.ppt [2] http://archive.arstechnica.com/reviews/1q00/playstation2/m-ee-3.html [3] http://docencia.ac.upc.edu/ETSETB/SEGPAR/microprocessors/emotionengine%20(mpr).pdf [4] http://www.eetimes.com/document.asp?doc_id=1144055 [5] https://www.toshiba.co.jp/about/press/2001_09/pr2701.htm Reported-by: Maciej W. Rozycki Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- include/elf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/elf.h b/include/elf.h index 312f68af81..2510fc7be4 100644 --- a/include/elf.h +++ b/include/elf.h @@ -76,7 +76,7 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_MACH_OCTEON2 0x008d /* Cavium Networks Octeon2 */ #define EF_MIPS_MACH_OCTEON3 0x008e /* Cavium Networks Octeon3 */ #define EF_MIPS_MACH_5400 0x0091 /* NEC VR5400 */ -#define EF_MIPS_MACH_5900 0x0092 /* MIPS R5900 */ +#define EF_MIPS_MACH_5900 0x0092 /* Toshiba/Sony R5900 */ #define EF_MIPS_MACH_5500 0x0098 /* NEC VR5500 */ #define EF_MIPS_MACH_9000 0x0099 /* PMC-Sierra's RM9000 */ #define EF_MIPS_MACH_LS2E 0x00a0 /* ST Microelectronics Loongson 2E */ -- 2.16.4
Re: [Qemu-devel] [PATCH] target/mips: Support Toshiba specific three-operand MADD and MADDU
Hi Philippe, > --- a/target/mips/translate.c > +++ b/target/mips/translate.c > @@ -3843,6 +3843,46 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t > opc, What about documenting MADD and MADDU along with MULT and MULTU in the note above? > +case OPC_MADD: This case is unreachable, because gen_mul_txx9 will never be called for OPC_MADD. > +TCGv_i64 t2 = tcg_temp_new_i64(); > +TCGv_i64 t3 = tcg_temp_new_i64(); The MADD (and MADDU) instructions are defined to multiply 32-bit integers in the C790 manual. Are 64-bit integers required to perform this with QEMU? > +gen_move_low32(cpu_LO[acc], t2); > +gen_move_high32(cpu_HI[acc], t2); > +if (rd) { > +gen_move_low32(cpu_gpr[rd], t2); Are LO, HI and GPR[rd] sign-extended to 64 bits when required? > +case OPC_MADDU: As above, this case is unreachable, because gen_mul_txx9 will never be called for OPC_MADDU. > +gen_move_low32(cpu_LO[acc], t2); > +gen_move_high32(cpu_HI[acc], t2); > +if (rd) { > +gen_move_low32(cpu_gpr[rd], t2); As above, are LO, HI and GPR[rd] sign-extended to 64 bits when required? Fredrik
Re: [Qemu-devel] [PATCH] target/mips: Support Toshiba specific three-operand MADD and MADDU
Hi Philippe, > That's true it is not reachable, it lacks the INSN_R3900 definition, > used by the R3900 mips_def_t. > > I'll stop bothering with this until the code is reachable (my branch posted). I would be happy if your patch could be merged soon. Adding the following five lines to it would make both MADD and MADDU immediately reachable and testable, at least for the R5900 to begin with: --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -22768,6 +22768,11 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) switch (op1) { case OPC_MADD: /* Multiply and add/sub */ case OPC_MADDU: +if (ctx->insn_flags & INSN_R5900) { +gen_mul_txx9(ctx, op1, 0, rd, rs, rt); +break; +} +/* Fallthrough */ case OPC_MSUB: case OPC_MSUBU: check_insn(ctx, ISA_MIPS32); > To be able to use the 64-bit result we need to use tcg_gen_mul_i64(). tcg_gen_muls2_i32 produces a 64-bit result in two 32-bit registers, and tcg_gen_add2_i32 seems to correspond to adding such registers. And then tcg_gen_ext_i32_tl could be used to extend the results to 64 bits. Look at the cases for MULT and MULTU, since they are very similar. Fredrik
Re: [Qemu-devel] [PATCH] target/mips: Support Toshiba specific three-operand MADD and MADDU
Hi Maciej, Philippe, > So results of individual operations are as in the comments with this > code: > > mthi$0 # HI <- 0 > mtlo$0 # LO <- 0 > addiu $2, $0, 1 # $2 <- 1 > lui $3, 0x4000 # $3 <- 0x4000 > maddu $4, $3, $2 # HI <- 0 > # LO <- 0x4000 > # $4 <- 0x4000 > maddu $5, $4, $2 # HI <- 0 > # LO <- 0x8000 > # $5 <- 0x8000 > maddu $6, $4, $2 # HI <- 1 > # LO <- 0 > # $6 <- 0 Adding tests such as the one above to for example tests/tcg/mips/txx9/ would be useful, I think. As previously noted, GCC can produce 32-bit R5900 programs but 64-bit compilations fail, so full test coverage may not be easily obtainable at the moment. Fredrik
Re: [Qemu-devel] [RFC] target/mips: Initial support for MIPS R5900
Thank you for your review, Maciej, > > The MIPS R5900 is normally taken to be MIPS3, but it has MOVN, MOVZ and PREF > > defined in MIPS4 which is why ISA_MIPS4 is chosen for this patch. > > It also has several instructions removed, so I don't think you can really > just mark it MIPS IV without special-casing those instructions, or the > emulation won't be accurate (and consequently programs that use them won't > trigger exceptions that they are supposed to). Agreed. However, complete and perfect emulation of the R5900 will require a substantial amount of work. What level is suitable for an initial patch? > > Some flags in the mips_defs array are marked FIXME as I don't know the > > proper values. > > Well, the FPU is non-standard so until you implement it I'd rather kept > it disabled and then all the FPU-related settings can go for now. For the > rest see below. The kernel traps FPU instructions to emulate them accurately, and unless the FPU is enabled here the QEMU Linux user space emulator crashes with "illegal hardware instruction" on valid programs. Can QEMU be instructed to emulate the FPU only for Linux user space programs as opposed to hardware emulation? > > --- a/target/mips/translate_init.inc.c > > +++ b/target/mips/translate_init.inc.c > > @@ -411,6 +411,26 @@ const mips_def_t mips_defs[] = > > .mmu_type = MMU_TYPE_R4000, > > }, > > { > > +.name = "R5900", > > +.CP0_PRid = 0x3800, > > +/* No L2 cache, icache size 32k, dcache size 32k, uncached > > coherency. */ > > +.CP0_Config0 = (1 << 17) | (0x3 << 9) | (0x3 << 6) | (0x2 << > > CP0C0_K0), > > +/* Note: Config1 is only used internally, the R5900 has only > > Config0. */ > > +.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), > > So I'd clear CP0C1_FP then; also make sure accessing CP0.Config1 from > emulated code does what it does on actual hardware. > > > +.CP0_LLAddr_rw_bitmask = 0x, /* FIXME */ > > +.CP0_LLAddr_shift = 4, /* FIXME */ > > No LL/SC in the R5900, so the LLAddr settings can go. Again, the kernel emulates LL/SC so I suppose some kind indication is needed for that in the QEMU Linux user space emulator? > > +.SYNCI_Step = 16, /* FIXME */ > > SYNCI is MIPS32r2+, so this can go. > > > +.CCRes = 2,/* FIXME */ > > Likewise, CCRes is MIPS32r2+, so this can go. Sure! > > +.CP0_Status_rw_bitmask = 0x3678, /* FIXME */ > > This has to indicate which bits in CP0.Status are writable. Check with > the manual and/or actual hardware. The TX79 manual describes the writable bits on pages 4.16-4.18, and it seems 0xF4C79C1F would be those. > > +.CP1_fcr0 = (0x38 << FCR0_PRID) | (0x0 << FCR0_REV), > > +.CP1_fcr31 = 0, > > +.CP1_fcr31_rw_bitmask = 0x0183,/* FIXME */ > > This is all FPU stuff and it can go. > > > +.SEGBITS = 40, /* FIXME */ > > This is the number of virtual address bits. Determined by the highest > writable CP0.EntryHi.VPN2 bit. VPN2 is bits 31:13 and so it is 19 bits wide, according to page 4.14 of the TX79 manual. > > +.PABITS = 36, /* FIXME */ > > Likewise physical address bits. Determined by the highest writable > CP0.EntryLo0.PFN and CP0.EntryLo1.PFN bit. PFN is bits 25:6 and so it is 20 bits wide, according to page 4.8 of the TX79 manual. > > +.insn_flags = CPU_R5900, > > +.mmu_type = MMU_TYPE_R4000,/* FIXME */ > > This looks right to me. Good. :) > FWIW; I don't have any authority for QEMU maintenance. The MAINTAINERS file indicates that Aurelien Jarno and Aleksandar Markovic have authority over the MIPS emulation (CCed to this post). Fredrik
[Qemu-devel] [RFC] target/mips: Initial support for MIPS R5900
Hi, This patch implements initial QEMU support for the MIPS R5900. Primarily code generated by GCC. The only special instruction needed for this, as far as I can tell, is the three-operand multiply. The MIPS R5900 is normally taken to be MIPS3, but it has MOVN, MOVZ and PREF defined in MIPS4 which is why ISA_MIPS4 is chosen for this patch. I have tested the patch with Linux user mode emulation on a root filesystem compiled for R5900 and it worked without apparent issues, apart from: qemu: Unsupported syscall: 4352 (seccomp) Some flags in the mips_defs array are marked FIXME as I don't know the proper values. Would this patch be an acceptable initial submission for the MIPS R5900? Fredrik --- include/elf.h| 3 +++ linux-user/mips/target_elf.h | 3 +++ target/mips/mips-defs.h | 2 ++ target/mips/translate.c | 31 ++- target/mips/translate_init.inc.c | 20 5 files changed, 58 insertions(+), 1 deletion(-) --- a/include/elf.h +++ b/include/elf.h @@ -48,6 +48,8 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_ARCH_32R6 0x9000 /* MIPS32r6 code. */ #define EF_MIPS_ARCH_64R6 0xa000 /* MIPS64r6 code. */ +#define EF_MIPS_MACH_5900 0x0092 + /* The ABI of a file. */ #define EF_MIPS_ABI_O320x1000 /* O32 ABI. */ #define EF_MIPS_ABI_O640x2000 /* O32 extended for 64 bit. */ @@ -62,6 +64,7 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_FP64 0x0200 #define EF_MIPS_NAN2008 0x0400 #define EF_MIPS_ARCH 0xf000 +#define EF_MIPS_MACH 0x00ff /* These constants define the different elf file types */ #define ET_NONE 0 --- a/linux-user/mips/target_elf.h +++ b/linux-user/mips/target_elf.h @@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags) if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) { return "mips32r6-generic"; } +if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) { +return "R5900"; +} return "24Kf"; } #endif --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -52,6 +52,7 @@ #define ASE_MSA 0x0100 /* Chip specific instructions. */ +#defineINSN_R5900 0x1000 #defineINSN_LOONGSON2E 0x2000 #defineINSN_LOONGSON2F 0x4000 #defineINSN_VR54XX 0x8000 @@ -62,6 +63,7 @@ #defineCPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) #defineCPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) #defineCPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) +#defineCPU_R5900 (CPU_MIPS4 | INSN_R5900) #defineCPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) #defineCPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -3618,6 +3618,31 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } +static void gen_mul_r5900 (DisasContext *ctx, uint32_t opc, +int rd, int rs, int rt) +{ +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +switch (opc) { +case OPC_MULT: +case OPC_MULTU: +tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); +break; +default: +MIPS_INVAL("mul R5900"); +generate_exception_end(ctx, EXCP_RI); +goto out; +} + + out: +tcg_temp_free(t0); +tcg_temp_free(t1); +} + static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { @@ -17357,7 +17382,11 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) break; case OPC_MULT: case OPC_MULTU: -if (sa) { +if (ctx->insn_flags & INSN_R5900) { +gen_muldiv(ctx, op1, 0, rs, rt); +if (rd != 0) +gen_mul_r5900(ctx, op1, rd, rs, rt); +} else if (sa) { check_insn(ctx, INSN_VR54XX); op1 = MASK_MUL_VR54XX(ctx->opcode); gen_mul_vr54xx(ctx, op1, rd, rs, rt); --- a/target/mips/translate_init.inc.c +++ b/target/mips/translate_init.inc.c @@ -411,6 +411,26 @@ const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { +.name = "R5900", +.CP0_PRid = 0x3800, +/* No L2 cache, icache size 32k, dcache size 32k, uncached coherency. */ +.CP0_Config0 = (1 << 17) | (0x3 << 9) | (0x3 << 6) | (0x2 << CP0C0_K0), +/* Note: Config1 is only used internally, the R5900 has only Config0. */ +.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), +.CP0_LLAddr_rw_bitmask = 0x, /* FIXME */ +.CP0_LLAddr_shift = 4, /* FIXME */ +.SYNCI_Step = 16, /* FIXME */ +
Re: [Qemu-devel] [RFC] target/mips: Initial support for MIPS R5900
> I have tested the patch with Linux user mode emulation on a root filesystem > compiled for R5900 and it worked without apparent issues, apart from: > > qemu: Unsupported syscall: 4352 (seccomp) I have also observed the following QEMU crash: qemu-mipsel: qemu/accel/tcg/cpu-exec.c:634: cpu_loop_exec_tb: Assertion `use_icount' failed. qemu: uncaught target signal 11 (Segmentation fault) - core dumped It occurred when compiling Perl, and it seems to be identical to this bug reported by John Paul Adrian Glaubitz for SH4: https://bugs.launchpad.net/qemu/+bug/1768246 Fredrik
Re: [Qemu-devel] [RFC PATCH 0/2] docker: Add gentoo-mipsr5900el-cross image
Many thanks, Philippe! > The first patch adds a cross toolchain for the R5900 MIPS. > It is working correctly but the patches provided by Fredrik in [1] don't > have proper S-o-b, thus it is tagged RFC. > Fredrik: any update on the status of those patches upstream? With GCC 8.2.0 and a current Gentoo this is even simpler. You should only need commit d728eb9085d8 ("MIPS: Default to --with-llsc for the R5900 Linux target as well"): https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=d728eb9085d8 For the o32 ABI with Glibc, only commit 8e3c00db16fc ("MIPS: Use `.set mips2' to emulate LL/SC for the R5900 too") is needed: https://sourceware.org/git/?p=glibc.git;a=commit;h=8e3c00db16fc Eventually, with a future GCC/Glibc release, no patches will be needed. [ I recommend removing the changelog part of the commits above, since they might conflict with other GCC/Glibc versions; I've attached them to this email for easy reference. ] > I setup this image to try Fredrik's TCG tests in [2]. Nice! Would you like to test the n32 ABI in addition to the o32 ABI? It's very easy to set that up as well. > I don't think there is > interest in running cross-compiled QEMU on a PS2... But we never know ;) I wouldn't rule that out. ;) > The failure I have is pkg-config using an incorrect path. I suppose I > am not using the CROSSDEV_OVERLAY path correctly. > Help from Gentoo developers would be appreciated! Hmm... Did you follow the guide on how to configure the overlay? Fredrik >From d728eb9085d80b6c5ce1bc8b6f99859fe0f0aaa5 Mon Sep 17 00:00:00 2001 From: macro Date: Mon, 12 Nov 2018 23:16:40 + Subject: [PATCH] MIPS: Default to --with-llsc for the R5900 Linux target as well The Linux kernel requires and emulates LL and SC for the R5900 too. The special --without-llsc default for the R5900 is therefore not applicable in that case. Reviewed-by: Maciej W. Rozycki 2018-11-12 Fredrik Noring gcc/ * config.gcc: Update with-llsc defaults for MIPS r5900. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@266038 138bc75d-0d04-0410-961f-82ee72b054a4 diff --git a/gcc/config.gcc b/gcc/config.gcc index e2b9946..8525cb5 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -3795,14 +3795,14 @@ fi # Infer a default setting for --with-llsc. if test x$with_llsc = x; then case ${target} in -mips64r5900-*-* | mips64r5900el-*-* | mipsr5900-*-* | mipsr5900el-*-*) - # The R5900 doesn't support LL(D) and SC(D). - with_llsc=no - ;; mips*-*-linux*) # The kernel emulates LL and SC where necessary. with_llsc=yes ;; +mips64r5900-*-* | mips64r5900el-*-* | mipsr5900-*-* | mipsr5900el-*-*) + # The R5900 doesn't support LL(D) and SC(D). + with_llsc=no + ;; esac fi -- 2.9.3 >From 8e3c00db16fcedea0ea47d93c2acb6d7d5ba9164 Mon Sep 17 00:00:00 2001 From: Fredrik Noring Date: Thu, 1 Nov 2018 14:36:48 + Subject: [PATCH] MIPS: Use `.set mips2' to emulate LL/SC for the R5900 too GAS treats the R5900 as MIPS III, with some modifications. The MIPS III designation means that the GNU C Library will try to assemble the LL and SC instructions, even though they are not implemented in the R5900. GAS will therefore produce the following errors: Error: opcode not supported on this processor: r5900 (mips3) `ll $2,0($4)' Error: opcode not supported on this processor: r5900 (mips3) `sc $6,0($4)' The MIPS II ISA override as used here enables the kernel to trap and emulate the LL and SC instructions, as required. This change has been tested by compiling the GNU C Library 2.27 with a GCC 8.2.0 cross-compiler for mipsr5900el-unknown-linux-gnu under Gentoo. * sysdeps/mips/sys/tas.h (_test_and_set): Handle the R5900 CPU with the ISA override. diff --git a/sysdeps/mips/sys/tas.h b/sysdeps/mips/sys/tas.h index d5ed013..22cee94 100644 --- a/sysdeps/mips/sys/tas.h +++ b/sysdeps/mips/sys/tas.h @@ -38,10 +38,11 @@ __NTH (_test_and_set (int *__p, int __v)) { int __r, __t; + /* The R5900 reports itself as MIPS III but it does not have LL/SC. */ __asm__ __volatile__ ("/* Inline test and set */\n" ".set push\n\t" -#if _MIPS_SIM == _ABIO32 && __mips < 2 +#if _MIPS_SIM == _ABIO32 && (__mips < 2 || defined (_MIPS_ARCH_R5900)) ".set mips2\n\t" #endif "sync\n\t" -- 2.9.3
Re: [Qemu-devel] [RFC PATCH 1/2] docker: Add gentoo-mipsr5900el-cross image
Hi Alex, > This fails to build glibc, but doesn't exactly give much info: > >* Log: /var/log/portage/cross-mipsr5900el-unknown-linux-gnu-binutils.log >* Emerging cross-binutils ...[ > ok ] >* Log: > /var/log/portage/cross-mipsr5900el-unknown-linux-gnu-linux-headers-quick.log >* Emerging cross-linux-headers-quick ... [ > ok ] >* Log: > /var/log/portage/cross-mipsr5900el-unknown-linux-gnu-glibc-headers.log >* Emerging cross-glibc-headers ... > >* error: glibc failed :( >* >* If you file a bug, please attach the following logfiles: >* /var/log/portage/cross-mipsr5900el-unknown-linux-gnu-info.log >* /var/log/portage/cross-mipsr5900el-unknown-linux-gnu-glibc-headers.log.xz >* > /var/tmp/portage/cross-mipsr5900el-unknown-linux-gnu/glibc*/temp/glibc-config.logs.tar.xz > The command '/bin/sh -c crossdev -s3 -t mipsr5900el-unknown-linux-gnu > --binutils ">=2.30" --gcc ">=7.2.0"' returned a non-zero code: 1 I would recommend using GCC 8.2.0, by omitting the --binutils and --gcc options to crossdev, unless you would like to debug this particular combination of GCC and Glibc (which I can confirm seems broke). Updated and much simplified R5900 patches are available in my previous email: http://lists.nongnu.org/archive/html/qemu-devel/2018-11/msg03649.html Hopefully soon, with upcoming GCC and Gblic releases, no R5900 patches are needed at all. Also, a new -mfix-r5900 option has been proposed to both GAS and GCC: http://www.sourceware.org/ml/binutils/2018-10/msg00301.html https://gcc.gnu.org/ml/gcc-patches/2018-11/msg00773.html With that option one can compile e.g. MIPS II or MIPS III that also work with the R5900. The R3900 and the R5900 could for example run the same programs then, and I do hope that Philippe will be able to merge his R3900 series eventually. Fredrik
Re: [Qemu-devel] [RFC PATCH 0/2] docker: Add gentoo-mipsr5900el-cross image
Hi Maciej, > Of course you can instead just set the default manually by using > `--with-llsc' when configuring GCC or specify `-mllsc' explicitly in > CFLAGS with a compiler that has been already built without that set by > default. There are ways to pass such flags to the crossdev command, but I found that method somewhat fiddly, perhaps because I was just about to learn crossdev but also because there are multiple compiler stages involved that sometimes need different options (floating point support and other things were broken back then too). So patches seemed simpler and more reliable to me. :) Fredrik
Re: [Qemu-devel] [PATCH] target/mips: Support Toshiba specific three-operand MADD and MADDU
Hi Aleksandar, > A peculiar case of DMULTU would be interesting. Agreed, DMULTU would be good to test as well. (DMULTU isn't part of the R5900 ISA, though.) > It would be nice to implement just a single instruction from MMI, let's > say PAND, and have a test for it. Most if not all multimedia instructions operate on 128-bit GPRs, which means all GPRs need to be extended. I suppose there are several ways to implement this. The definitions in target/mips/translate.c are: /* global register indices */ static TCGv cpu_gpr[32], cpu_PC; static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; One option is to create a new array such as static TCGv_i64 mmi_gpr[32]; that represents the upper 64 bits of each GPR. Then cpu_gpr must be of a 64-bit type too, even when QEMU runs in 32-bit user mode. The R5900 does not implement CP0.Status.UX in hardware, though, so system mode is 64 bits, regardless. Interestingly, LO and HI are also extended to 128 bits, where the upper 64 bits are used for the I1 pipeline instructions MULT1, etc. Additionally, a special SA register contains the shift amount used by the 256-bit funnel shift multimedia instruction QFSRV. What are your thoughts on making these register extensions in QEMU? Fredrik
Re: [Qemu-devel] [PATCH] target/mips: Support Toshiba specific three-operand MADD and MADDU
Hi Richard, > > /* global register indices */ > > static TCGv cpu_gpr[32], cpu_PC; > > static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; > > > > One option is to create a new array such as > > > > static TCGv_i64 mmi_gpr[32]; > > > > that represents the upper 64 bits of each GPR. Then cpu_gpr must be of > > a 64-bit type too, even when QEMU runs in 32-bit user mode. The R5900 > > does not implement CP0.Status.UX in hardware, though, so system mode is > > 64 bits, regardless. > > I would not implement r5900 for mips32 in that case, > I would implement it only for TARGET_MIPS64. R5900 Linux implements the O32 ABI, which is why 32-bit QEMU user-mode is very useful. Perhaps a better alternative is to define the MMI registers as 128-bit, similar to static TCGv_u128 mmi_gpr[32]; and then copy cpu_gpr to/from mmi_gpr as needed when running the MMIs? Fredrik
Re: [Qemu-devel] [PATCH v5 6/8] target/mips: Define the R5900 CPU
Hi Maciej, > The C790 is a follow-up to the R5900. The R5900 has an FPU that is not > compliant to the IEEE 754 standard for floating-point arithmetic. It > doesn't implement exceptions, infinities, NaNs or denormals. It doesn't > implement the the double format either, but that is really tangential, > because the same was the case with the IDT R4650, which had a standard > IEEE 754 FPU, but no double format either. Finally it has some anomalies > in the FP instruction set; not all opcode encodings are standard. Do you know where one might find a list of the nonstandard FP instructions? The command % grep 'FP_.*EE' binutils/opcodes/mips-opc.c gives a list of candidates, I suppose? Fredrik
Re: [Qemu-devel] [PATCH v7 0/7] target/mips: Limited support for the R5900
Hi Aleksandar, > Your series is getting better and better with each version, which is very > good. For a change, I don't have any objection about the title. :) Good! > Patch 7 will be integrated shortly in the MIPS queue, you don't need to > worry about it. Thanks! > With this series you are not only supporting your prime use case, but you > are introducing a new instruction set to QEMU. Try to step back and get > wider perspective. No matter how limited the support for the new ISA is, > its introduction to QEMU must have following elements: > > (1) Definition of basic preprocessor constants for the new ISA. > (2) All opcodes for the ISA. > (3) Basic decoding engine for new instructions. > > Your patch 1 adresses 1). However, there are no patches for (2) and (3) in > this series. Let me walk though the details on how to implement (2) and (3). Thank you for your detailed description, it was helpful. > (2) All opcodes for the ISA. > > Only if an R5900 instruction has the same name, opcode, and functionality, > corresponding MIPS III/IV opcode can and must be reused for R5900. For all > other cases, R5900-specific opcode must be supplied. I'll limit further > consideration to MMI instructions, but you should consider the whole R5900 > instruction set. I'm preparing v8 with (2) and (3) and other changes, to be posted shortly. > Of course, you need to specify functions decode_ee_mmi0(), > decode_ee_mmi1(), decode_ee_mmi2(), and decode_ee_mmi3() too. Done. > You can change format and naming in the code above, but I insist that each > unimplemeted instuction has its own "TODO" and "generate_exception()". They have TODOs, but it turns out that having individual generate_exception calls is somewhat impractical, because instructions are typically grouped and folded into other functions in various ways. I think this is reasonable evident when looking at how the v8 patch series develops. > FPU opcodes need such treatment too. This will affect your overall > solution, hopefully it will be better after the reorganization. I'm not sure whether the R5900 FPU opcode anomalies are documented. I will have to investigate this. Fredrik
[Qemu-devel] [PATCH v8 00/38] target/mips: Limited support for the R5900
removed in check_insn_opc_user_only Changes in v4: - Split into a patch series consisting of eight changes - Expand commit messages and notes - Introduce check_insn_opc_user_only - Base R5900 on MIPS III, with MOVN, MOVZ and PREF from MIPS IV - DMULT, DMULTU, DDIV, DDIVU, LL, SC, LLD and SCD are user only - Note Toshiba/Sony R5900 for EF_MIPS_MACH_R5900 definition - Rework gen_mul_r5900 - Fix ICE and DCE - Fix SEGBITS and PABITS - Fix indentation Changes in v3: - Apply to HEAD - Remove the word "initial" from subject line Changes in v2: - Update mips_defs array with R5900 values - LL/SC and FPU are user only Fredrik Noring (38): target/mips: Define R5900 instructions and CPU preprocessor constants disas/mips: Define R5900 disassembly constants target/mips: R5900 Multimedia Instruction overview note target/mips: Define R5900 MMI class, and LQ and SQ opcode constants target/mips: Define R5900 MMI{0,1,2,3} subclasses and MMI opcode constants target/mips: Define R5900 MMI0 opcode constants target/mips: Define R5900 MMI1 opcode constants target/mips: Define R5900 MMI2 opcode constants target/mips: Define R5900 MMI3 opcode constants target/mips: Placeholder for R5900 MMI SQ, handle user mode RDHWR target/mips: Placeholder for R5900 MMI LQ target/mips: Placeholder for R5900 MMI instruction class target/mips: Placeholder for R5900 MMI0 instruction subclass target/mips: Placeholder for R5900 MMI1 instruction subclass target/mips: Placeholder for R5900 MMI2 instruction subclass target/mips: Placeholder for R5900 MMI3 instruction subclass target/mips: Support R5900 three-operand MULT and MULTU target/mips: Support R5900 three-operand MULT1 and MULTU1 target/mips: Support R5900 MFLO1, MTLO1, MFHI1 and MTHI1 target/mips: Support R5900 DIV1 and DIVU1 target/mips: Support R5900 MOVN, MOVZ and PREF from MIPS IV target/mips: Support R5900 three-operand MADD and MADD1 target/mips: Support R5900 three-operand MADDU and MADDU1 target/mips: R5900 DMULT[U], DDIV[U], LL[D] and SC[D] are user only tests/tcg/mips: Test R5900 three-operand MULT tests/tcg/mips: Test R5900 three-operand MULTU tests/tcg/mips: Test R5900 three-operand MULT1 tests/tcg/mips: Test R5900 three-operand MULTU1 tests/tcg/mips: Test R5900 MFLO1 and MFHI1 tests/tcg/mips: Test R5900 MTLO1 and MTHI1 tests/tcg/mips: Test R5900 DIV1 tests/tcg/mips: Test R5900 DIVU1 tests/tcg/mips: Test R5900 three-operand MADD tests/tcg/mips: Test R5900 three-operand MADD1 tests/tcg/mips: Test R5900 three-operand MADDU tests/tcg/mips: Test R5900 three-operand MADDU1 target/mips: Define the R5900 CPU linux-user/mips: Recognise the R5900 CPU model disas/mips.c | 20 + linux-user/mips/target_elf.h | 3 + target/mips/mips-defs.h| 2 + target/mips/translate.c| 871 - target/mips/translate_init.inc.c | 59 ++ tests/tcg/mips/mipsr5900/Makefile | 32 ++ tests/tcg/mips/mipsr5900/div1.c| 73 +++ tests/tcg/mips/mipsr5900/divu1.c | 48 ++ tests/tcg/mips/mipsr5900/madd.c| 78 +++ tests/tcg/mips/mipsr5900/maddu.c | 70 +++ tests/tcg/mips/mipsr5900/mflohi1.c | 35 ++ tests/tcg/mips/mipsr5900/mtlohi1.c | 40 ++ tests/tcg/mips/mipsr5900/mult.c| 76 +++ tests/tcg/mips/mipsr5900/multu.c | 68 +++ 14 files changed, 1465 insertions(+), 10 deletions(-) create mode 100644 tests/tcg/mips/mipsr5900/Makefile create mode 100644 tests/tcg/mips/mipsr5900/div1.c create mode 100644 tests/tcg/mips/mipsr5900/divu1.c create mode 100644 tests/tcg/mips/mipsr5900/madd.c create mode 100644 tests/tcg/mips/mipsr5900/maddu.c create mode 100644 tests/tcg/mips/mipsr5900/mflohi1.c create mode 100644 tests/tcg/mips/mipsr5900/mtlohi1.c create mode 100644 tests/tcg/mips/mipsr5900/mult.c create mode 100644 tests/tcg/mips/mipsr5900/multu.c -- 2.18.1
[Qemu-devel] [PATCH v8 01/38] target/mips: Define R5900 instructions and CPU preprocessor constants
The R5900 implements the 64-bit MIPS III instruction set except DMULT, DMULTU, DDIV, DDIVU, LL, SC, LLD and SCD. The MIPS IV instructions MOVN, MOVZ and PREF are implemented. It has the R5900-specific three-operand instructions MADD, MADDU, MULT and MULTU as well as pipeline 1 versions MULT1, MULTU1, DIV1, DIVU1, MADD1, MADDU1, MFHI1, MFLO1, MTHI1 and MTLO1. A set of 93 128-bit multimedia instructions specific to the R5900 is also implemented. The Toshiba TX System RISC TX79 Core Architecture manual https://wiki.qemu.org/File:C790.pdf describes the C790 processor that is a follow-up to the R5900. There are a few notable differences in that the R5900 FPU - is not IEEE 754-1985 compliant, - does not implement double format, and - its machine code is nonstandard. Signed-off-by: Fredrik Noring Reviewed-by: Philippe Mathieu-Daudé --- target/mips/mips-defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index 71ea4ef892..f017551e15 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -64,6 +64,7 @@ #define INSN_LOONGSON2E 0x0001ULL #define INSN_LOONGSON2F 0x0002ULL #define INSN_VR54XX 0x0004ULL +#define INSN_R59000x0008ULL /* * bits 56-63: vendor-specific ASEs */ @@ -74,6 +75,7 @@ #defineCPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) #defineCPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) #defineCPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) +#define CPU_R5900 (CPU_MIPS3 | INSN_R5900) #defineCPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) #defineCPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) -- 2.18.1
[Qemu-devel] [PATCH v8 05/38] target/mips: Define R5900 MMI{0, 1, 2, 3} subclasses and MMI opcode constants
Signed-off-by: Fredrik Noring --- target/mips/translate.c | 51 + 1 file changed, 51 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index e205c3eaef..ae988177a1 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2129,6 +2129,57 @@ enum { TX79_SQ= 0x1F << 26,/* Same as OPC_SPECIAL3 */ }; +/* + * TX79 Multimedia Instructions with opcode field = MMI: + * + * 3126 5 0 + * ++---++ + * | MMI | |function| + * ++---++ + * + * function bits 2..0 + * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 + * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 + * ---+---+---+---+---+---+---+---+--- + *0 000 | MADD | MADDU | * | * | PLZCW | * | * | * + *1 001 | MMI0% | MMI2% | * | * | * | * | * | * + *2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * + *3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * + *4 100 | MADD1 | MADDU1| * | * | * | * | * | * + *5 101 | MMI1% | MMI3% | * | * | * | * | * | * + *6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH + *7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW + */ + +#define MASK_TX79_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) +enum { +TX79_MMI_MADD = 0x00 | TX79_CLASS_MMI, /* Same as OPC_MADD */ +TX79_MMI_MADDU = 0x01 | TX79_CLASS_MMI, /* Same as OPC_MADDU */ +TX79_MMI_PLZCW = 0x04 | TX79_CLASS_MMI, +TX79_MMI_CLASS_MMI0 = 0x08 | TX79_CLASS_MMI, +TX79_MMI_CLASS_MMI2 = 0x09 | TX79_CLASS_MMI, +TX79_MMI_MFHI1 = 0x10 | TX79_CLASS_MMI, /* Same minor as OPC_MFHI */ +TX79_MMI_MTHI1 = 0x11 | TX79_CLASS_MMI, /* Same minor as OPC_MTHI */ +TX79_MMI_MFLO1 = 0x12 | TX79_CLASS_MMI, /* Same minor as OPC_MFLO */ +TX79_MMI_MTLO1 = 0x13 | TX79_CLASS_MMI, /* Same minor as OPC_MTLO */ +TX79_MMI_MULT1 = 0x18 | TX79_CLASS_MMI, /* Same minor as OPC_MULT */ +TX79_MMI_MULTU1 = 0x19 | TX79_CLASS_MMI, /* Same minor as OPC_MULTU */ +TX79_MMI_DIV1 = 0x1A | TX79_CLASS_MMI, /* Same minor as OPC_DIV */ +TX79_MMI_DIVU1 = 0x1B | TX79_CLASS_MMI, /* Same minor as OPC_DIVU */ +TX79_MMI_MADD1 = 0x20 | TX79_CLASS_MMI, +TX79_MMI_MADDU1 = 0x21 | TX79_CLASS_MMI, +TX79_MMI_CLASS_MMI1 = 0x28 | TX79_CLASS_MMI, +TX79_MMI_CLASS_MMI3 = 0x29 | TX79_CLASS_MMI, +TX79_MMI_PMFHL = 0x30 | TX79_CLASS_MMI, +TX79_MMI_PMTHL = 0x31 | TX79_CLASS_MMI, +TX79_MMI_PSLLH = 0x34 | TX79_CLASS_MMI, +TX79_MMI_PSRLH = 0x36 | TX79_CLASS_MMI, +TX79_MMI_PSRAH = 0x37 | TX79_CLASS_MMI, +TX79_MMI_PSLLW = 0x3C | TX79_CLASS_MMI, +TX79_MMI_PSRLW = 0x3E | TX79_CLASS_MMI, +TX79_MMI_PSRAW = 0x3F | TX79_CLASS_MMI, +}; + /* global register indices */ static TCGv cpu_gpr[32], cpu_PC; static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; -- 2.18.1
[Qemu-devel] [PATCH v8 02/38] disas/mips: Define R5900 disassembly constants
Signed-off-by: Fredrik Noring --- disas/mips.c | 8 1 file changed, 8 insertions(+) diff --git a/disas/mips.c b/disas/mips.c index 97f661a37e..ae72059c46 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -611,6 +611,9 @@ struct mips_opcode /* ST Microelectronics Loongson 2F. */ #define INSN_LOONGSON_2F 0x8000 +/* Sony/Toshiba R5900 */ +#define INSN_5900 0x1 + /* MIPS ISA defines, use instead of hardcoding ISA level. */ #define ISA_UNKNOWN 0 /* Gas internal use. */ @@ -646,6 +649,7 @@ struct mips_opcode #define CPU_R5000 5000 #define CPU_VR5400 5400 #define CPU_VR5500 5500 +#define CPU_R5900 5900 #define CPU_R6000 6000 #define CPU_RM7000 7000 #define CPU_R8000 8000 @@ -1193,6 +1197,7 @@ extern const int bfd_mips16_num_opcodes; #define N5 (INSN_5400 | INSN_5500) #define N54INSN_5400 #define N55INSN_5500 +#define EE INSN_5900/* Emotion Engine */ #define G1 (T3 \ ) @@ -3861,6 +3866,7 @@ struct mips_arch_choice #define bfd_mach_mips5000 5000 #define bfd_mach_mips5400 5400 #define bfd_mach_mips5500 5500 +#define bfd_mach_mips5900 5900 #define bfd_mach_mips6000 6000 #define bfd_mach_mips7000 7000 #define bfd_mach_mips8000 8000 @@ -3908,6 +3914,8 @@ static const struct mips_arch_choice mips_arch_choices[] = mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, + { "r5900",1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, +mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, -- 2.18.1
[Qemu-devel] [PATCH v8 04/38] target/mips: Define R5900 MMI class, and LQ and SQ opcode constants
Signed-off-by: Fredrik Noring --- target/mips/translate.c | 40 1 file changed, 40 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 32d1d2d83f..e205c3eaef 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2087,8 +2087,48 @@ enum { * MTSAB rs, immediate Move Byte Count to Shift Amount Register * MTSAH rs, immediate Move Halfword Count to Shift Amount Register * PROT3W rd, rtParallel Rotate 3 Words + * + * The TX79-specific Multimedia Instruction encodings + * == + * + * TX79 Multimedia Instruction encoding table keys: + * + * * This code is reserved for future use. An attempt to execute it + * causes a Reserved Instruction exception. + * % This code indicates an instruction class. The instruction word + * must be further decoded by examining additional tables that show + * the values for other instruction fields. + * # This code is reserved for the unsupported instructions DMULT, + * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt + * to execute it causes a Reserved Instruction exception. + * + * TX79 Multimedia Instructions encoded by opcode field (MMI, LQ, SQ): + * + * 31260 + * +++ + * | opcode || + * +++ + * + * opcode bits 28..26 + * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 + * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 + * ---+---+---+---+---+---+---+---+--- + *0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ + *1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI + *2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL + *3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ + *4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU + *5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE + *6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD + *7 111 | # | SWC1 | # | * | # | SDC1 | # | SD */ +enum { +TX79_CLASS_MMI = 0x1C << 26,/* Same as OPC_SPECIAL2 */ +TX79_LQ= 0x1E << 26,/* Same as OPC_MSA */ +TX79_SQ= 0x1F << 26,/* Same as OPC_SPECIAL3 */ +}; + /* global register indices */ static TCGv cpu_gpr[32], cpu_PC; static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; -- 2.18.1