linux-user/mips: Support the n32 ABI for the R5900
cover 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 checkFredrik 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
Signature · 1 line
2.18.1
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.
--- linux-user/mips64/target_elf.h | 3 +++ 1 file changed, 3 insertions(+)
linux-user/mips64/target_elf.h +3 -0
@@ -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
Signature · 1 line
2.18.1
Quoted 14 lines · Fredrik Noring
Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI.
Signed-off-by Fredrik Noring <[email protected]>--- linux-user/mips64/target_elf.h | 3 +++ 1 file changed, 3 insertions(+)linux-user/mips64/target_elf.h +0
-0
linux-user/mips64/target_elf.h static inline const char *cpu_get_model(uint32_t eflags) · line 20
Quoted 9 lines
linux-user/mips64/target_elf.h +3
-0@@ -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
Quoted 8 lines · Fredrik Noring
Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI.
Signed-off-by Fredrik Noring <[email protected]>--- linux-user/mips64/target_elf.h | 3 +++ 1 file changed, 3 insertions(+)
Quoted 2 lines · Philippe Mathieu-Daudé
On Thu, Nov 8, 2018 at 7:45 PM Fredrik Noring <[email protected]> wrote:
Oops, an old patch from 2018 and was never applied?
Quoted 11 lines
Quoted 8 lines
Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI.
Signed-off-by Fredrik Noring <[email protected]>--- linux-user/mips64/target_elf.h | 3 +++ 1 file changed, 3 insertions(+)Reviewed-by Philippe Mathieu-Daudé <[email protected]>
Regards,
Bin
Laurent Vivier
AppliedLe 14/02/2021 à 16:17, Philippe Mathieu-Daudé a écrit :
Quoted 5 lines · Fredrik Noring
Quoted 4 lines
Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI.
Quoted 8 lines
Quoted 4 lines
Signed-off-by Fredrik Noring <[email protected]>--- linux-user/mips64/target_elf.h | 3 +++ 1 file changed, 3 insertions(+)Reviewed-by Philippe Mathieu-Daudé <[email protected]>
Applied to my linux-user-for-6.0 branch.
Thanks,
Laurent
PATCH 2/2 tests/tcg/mips: Test user mode DMULT for the R5900
In reply to Fredrik NoringThe 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.
--- 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
tests/tcg/mips/mipsn32r5900/Makefile new file +25 -0
@@ -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)
tests/tcg/mips/mipsn32r5900/dmult.c new file +40 -0
@@ -0,0 +1,40 @@ +/* +* Test DMULT. +*/ + +#include <stdio.h> +#include <inttypes.h> +#include <assert.h> + +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 ; +}
Signature · 1 line
2.18.1
Quoted 2 lines · Fredrik Noring
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.
if you have time, o32 & n32 support needs to be reworked.
We have two binaries qemu-mips and qemu-mipsn32 sharing the same ELF mask/magic.
As n32 identifies a kernel ABI version, we should have only one binary for qemu-mips and qemu-mipsn32 and the ABI version should be identified at runtime as it is done for ARM:
ce4defa062 Arm Linux EABI syscall support.
[I think we can use e_flags for that]
I never did the change because I don't know where to find mipsn32 binaries to test my changes.
Thanks,
Laurent
Quoted 10 lines · Laurent Vivier
if you have time, o32 & n32 support needs to be reworked.
We have two binaries qemu-mips and qemu-mipsn32 sharing the same ELF mask/magic.
As n32 identifies a kernel ABI version, we should have only one binary for qemu-mips and qemu-mipsn32 and the ABI version should be identified at runtime as it is done for ARM:
ce4defa062Arm Linux EABI syscall support.
Are you sure? So is the ARM ABI handled with ce4defa062 64-bit?
The o32 ABI is 32-bit (32-bit GPR width) while n32 is 64-bit (64-bit GPR
width). The correspondence between the i386 ABI and the x86-64 x32 ABI is analogous to these two ABIs.
How are these x86 ABIs handled WRT the user emulation mode; are they
analogous to the ARM ABIs you've mentioned?
Quoted 1 line
[I think we can use
e_flagsfor that]
The EF_MIPS_ABI2 `e_flags' bit denotes the n32 ABI. The container format
is ELF32 obviously, because addressing is 32-bit with n32.
Quoted 2 lines
I never did the change because I don't know where to find mipsn32 binaries to test my changes.
I believe MIPS64 Debian is all n32.
Maciej
Quoted 7 lines · Maciej W. Rozycki
Quoted 5 lines · Laurent Vivier
if you have time, o32 & n32 support needs to be reworked.
We have two binaries qemu-mips and qemu-mipsn32 sharing the same ELF mask/magic.
Quoted 7 lines
Quoted 5 lines
As n32 identifies a kernel ABI version, we should have only one binary for qemu-mips and qemu-mipsn32 and the ABI version should be identified at runtime as it is done for ARM:
ce4defa062Arm Linux EABI syscall support.Are you sure? So is the ARM ABI handled with
ce4defa06264-bit?
I'm sure of nothing. It's why it's better if someone involved in mips development has an opinion on it :)
Quoted 10 lines
The o32 ABI is 32-bit (32-bit GPR width) while n32 is 64-bit (64-bit GPR
width). The correspondence between the i386 ABI and the x86-64 x32 ABI is analogous to these two ABIs.
How are these x86 ABIs handled WRT the user emulation mode; are they
analogous to the ARM ABIs you've mentioned?Quoted 1 line
[I think we can use
e_flagsfor that]The
EF_MIPS_ABI2`e_flags' bit denotes the n32 ABI. The container format
is ELF32 obviously, because addressing is 32-bit with n32.
OK, I understand better. It looks like qemu-sparc32plus or qemu-ppc64abi32. If this is the case, you're right we need different binaries.
Quoted 4 lines
Quoted 2 lines
I never did the change because I don't know where to find mipsn32 binaries to test my changes.
I believe MIPS64 Debian is all n32.
Some readelf results:
mips64el/stretch
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Flags: 0x80000007, noreorder, pic, cpic, mips64r2
mipsel/stretch
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Flags: 0x70001007, noreorder, pic, cpic, o32, mips32r2
mips/stretch/bin
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Flags: 0x70001007, noreorder, pic, cpic, o32, mips32r2
So 32bit mips are all o32, 64bit is n32.
Are there any distros that are 32bit but n32? Any binaries that need qemu-mipsn32 or qemu-mipsn32el?
Thanks,
Laurent
Quoted 9 lines · Laurent Vivier
Quoted 1 line
I believe MIPS64 Debian is all n32.
Some readelf results:
mips64el/stretch
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Flags: 0x80000007, noreorder, pic, cpic, mips64r2
Hmm, that's weird -- what executable did you check? There may be some
that are n64, or maybe they've switched (which I would applaud, FWIW). I remember seeing mostly n32, with minimal support for n64, but that was a while ago -- jessie or suchlike, I believe. Using MIPS64r2 as the base ISA also looks new to me, that used to be plain MIPS III, and some of Debian's MIPS build systems used to be either MIPS III (Lemote Loongson) or MIPS64r1 (Broadcom SiByte).
Quoted 1 line
Are there any distros that are 32bit but n32?
You need 64-bit hardware for n32, so you can't do a 32-bit distribution
with n32. FAOD n32 is ILP32 with 64-bit `long long' and 64-bit stack slots both using the native 64-bit register width.
Quoted 1 line
Any binaries that need qemu-mipsn32 or qemu-mipsn32el?
I'd expect at least the n32 dynamic loader (along with libc and some
other essential DSOs) to be present with MIPS64 Debian. Traditionally, under the FHS rules, it would be installed as /lib32/ld.so.1 (with the o32 one as /lib/ld.so.1 and the n64 as /lib64/ld.so.1), but Debian uses their own multiarch filesystem layout standard, and offhand I don't remember what the paths are defined to there.
Anyway, once you have tracked down the `ld.so.1' binary you can invoke it
directly for some output, and it should be good enough for your smoke test purposes IIUC.
I am away travelling through the end of this week and I have limited
access to resources. I can help more once I am back next week.
Maciej
Quoted 8 lines · Maciej W. Rozycki
Quoted 7 lines
Some readelf results:
mips64el/stretch
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Flags: 0x80000007, noreorder, pic, cpic, mips64r2
Quoted 7 lines
Hmm, that's weird -- what executable did you check? There may be some
that are n64, or maybe they've switched (which I would applaud, FWIW). I remember seeing mostly n32, with minimal support for n64, but that was a while ago -- jessie or suchlike, I believe. Using MIPS64r2 as the base ISA also looks new to me, that used to be plain MIPS III, and some of Debian's MIPS build systems used to be either MIPS III (Lemote Loongson) or MIPS64r1 (Broadcom SiByte).
OK, I definitely got this confused. I did some checking and jessie
didn't even have a 64-bit MIPS port. I got their build systems right though, and the kernel is 64-bit for systems that support it.
Quoted 8 lines
Quoted 1 line
Any binaries that need qemu-mipsn32 or qemu-mipsn32el?
I'd expect at least the n32 dynamic loader (along with libc and some
other essential DSOs) to be present with MIPS64 Debian. Traditionally, under the FHS rules, it would be installed as /lib32/ld.so.1 (with the o32 one as/lib/ld.so.1and the n64 as/lib64/ld.so.1), but Debian uses their own multiarch filesystem layout standard, and offhand I don't remember what the paths are defined to there.
So with jessie you can install the `libc6-dev-mipsn32' package, which
will get you n32 glibc development libraries and will pull the complementing n32 dynamic loader (at /lib32/ld.so.1 actually) and n32 glibc shared libraries as well.
Unfortunately multilib support files, such as the CRT files, seem to be
missing from GCC for n32 or I cannot find them. Otherwise you would be able to compile and link n32 binaries just by calling `gcc -mabi=n32'. Still the dynamic loader is directly runnable, as I noted above.
HTH,
Maciej