frno7 / linux

Linux 2.2, 2.6, 3.x, 4.x and 5.x kernels for the PlayStation 2.
Other
86 stars 5 forks source link

Linux from scratch patches #42

Closed Arch91 closed 2 years ago

Arch91 commented 2 years ago

A patch for building ncurses-5.9

frno7 commented 2 years ago

uClibc-ng-1.0.40 patched with those edits suggested by Zanella girl

I believe Adhemerval Zanella is https://github.com/zatrazz

#elif defined (OP_div3)
TYPE FUNC (TYPE x, TYPE y) { return x / y; }

frno7, what'll do you say?

I’d say that it might be worthwhile to inspect the machine code for this piece, no?

I recompiled the target-system from scratch, everything seems alright, quite stable.

Oh!

frno7, if you'll be minding about fixing the issue about using hard-fp for libgcc floating-point routines, I think you should take a look into a gcc files libgcc/config/t-hardfp, libgcc/config/t-hardfp-sfdf and libgcc/config/hardfp.c

Right. I’m contemplating moving the kernel from o32 to n32 first. The main reason is to support the 128-bit multimedia instructions, which most likely never will work properly with an o32 kernel. An n32 kernel would still be able to run o32 applications.

Arch91 commented 2 years ago

oops) Heh) Zanella girl is not a girl at all) Well... mistake here, mistake there... Anyway, the patch seems do it's work regardless the gender :D Was not mind to check the person personally...

I’d say that it might be worthwhile to inspect the machine code for this piece, no?

Well, yes, but I suppose what if I'll see the unsupported opcode in the end?.. divide double float... I think it is better to rely the "problematic" libgcc functions to be operated using soft-float while using the compatible ones using the hardware's. Again, I found out the quick solution; however, likewisely, I reported an issue, now to gcc bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104984 Let's see how many of the enthusiasts there, who are ready to give a hand.

Besides, that line: #elif defined (OP_div3) I did not find where are those OP_ definitions (OP_div3 in this case) written, either in gcc or binutils. Where else?.. The way I searched is the command while "commander" is located inside the gcc/binutils source main folder `grep -iRI OP_div3 `

to support the 128-bit multimedia instructions, which most likely never will work properly with an o32 kernel

Do you think so? Is it really necessary? Just because of the "natural" n32's TImode support? (by the way, I saw some r5900 mate was writting about that the old ps2linux's TImode is true 128bit comparing to N32's Timode which is not exactly 128bit... something like that) I'll try to explain what I think/mean. The current newest binutils has the vector unit opcodes included in it's source (with some differences comparing to the originals from ps2linux). The programs written for VUs use are including the 128bit variable types, and they could be compiled in the old ps2linux times (binutils-2.9EE)... If to successfully compile such program using the currently newest cross-compiler for mipsr5900el target, it still stays abi o32... I think I failed in explanations) ...or... you mean that you are thinking to change the kernel only, from o32 to n32? To include some 128bit stuff in the kernel source only, so abi n32 programs still will be unsupported? I'm just interesting the opinion, not arguing. I will be glad to see the kernel's "32n32" addition back and working again)

The only ONLY place where I saw a "practical" use of the TImode among the ps2linux C sources is in XFree86-3.3.6, Xgsx driver.

frno7 commented 2 years ago

Let's see how many of the enthusiasts there, who are ready to give a hand.

Yes, let’s see what happens. :-)

Do you think so? Is it really necessary?

The 128-bit multimedia instructions (MMIs) can’t be turned off in hardware, unfortunately. So if someone starts exploring the MMIs, they would appear to work except that an o32 kernel would “randomly” clobber the registers (during context switches, interrupts, etc.), because an o32 kernel only handles 32-bit registers and not 128-bit registers. So people would have randomly crashing MMI programs and register corruption, which most likely would make them frustrated and unhappy, which is why I think we should avoid that scenario.

...or... you mean that you are thinking to change the kernel only, from o32 to n32?

Yes, precisely. A proper n32 kernel is, in principle, able to run both o32 and n32 user programs.

To include some 128bit stuff in the kernel source only, so abi n32 programs still will be unsupported?

Yes, it’s probably easier to only support o32 user programs, to begin with. The kernel would, for the most part, be prepared for n32 user programs later on. The important point is that MMIs would work in all configurations, without clobbering MMI registers.

Arch91 commented 2 years ago

I'm about FPU issue again. The first moment - ld/sd . I figured out that Juergen had the same issue with those opcodes. But he just made them available for o32 abi : https://sourceforge.net/projects/ps2toolchain/ file r5900-binutils-2.23.1.patch from r5900-binutils-2.23.1.tar.gz But I do not understand... r5900 has no 64bit fp registers... So how it is possible that those opcodes will be storing_to/loading_from the 64bit variables ? To/from where?..

The second moment. A person answered me that it IS possible to build libgcc in the form it will be processing single precisions hardwarely and double ones softwarely.

I dare to consider that the FPU issue is solved completely IF to use libgcc soft. While we are compiling the C coded stuff we are alright. At the same time we always must be watching out for the assembler object codes (some "atomics") and a possible assembler inlines in those stuff.

Hardwarely operating is speeding up the things, I'm totally sure in that practically and it is noticeable. To use libgcc hard, it have to be thought-out, and there will be no "other hands/minds" to handle that. There those issueses matters. They have to be traced. We need to know which libgcc functions are problematic. To obtain them, I assume we have to build libgcc using this t-file: a new file libgcc/config/t-hardsf-softdf :

hardfp_float_modes := sf
hardfp_int_modes := si di
hardfp_extensions :=
hardfp_truncations :=
hardfp_exclusions := xxx
softfp_float_modes := df
softfp_int_modes :=
softfp_extensions := sfdf
softfp_truncations := dfsf
softfp_extras := xxx

And after that we have single precisions operated hardwarely and double ones emulated softwarely. Using it, we can step on the battlefield and make tests to find out which hardwarely operated libgcc functions are working non-standard and why. When that kind of function is found - fix it if possible OR exclude it from hardfp list and include it in softfp extras instead. However... I don't get the problem of NaN, inf-/+ unsupports... These are not a functions, they are variables...

frno7 commented 2 years ago

But I do not understand... r5900 has no 64bit fp registers... So how it is possible that those opcodes will be storing_to/loading_from the 64bit variables ? To/from where?..

Well, review the Wikipedia MIPS architecture article: MIPS has 32 floating-point registers. Two registers are paired for double precision numbers. Odd numbered registers cannot be used for arithmetic or branching, just as part of a double precision register pair, resulting in 16 usable registers for most instructions (moves/copies and loads/stores were not affected).

The second moment. A person answered me that it IS possible to build libgcc in the form it will be processing single precisions hardwarely and double ones softwarely.

That seems promising!

When that kind of function is found - fix it if possible OR exclude it from hardfp list and include it in softfp extras instead. However... I don't get the problem of NaN, inf-/+ unsupports... These are not a functions, they are variables...

I think the problem is that most if not all R5900 FPU instructions don’t conform to IEEE 754, which is why I don’t think we can run some in hardware and emulate others, in a reliable way. I believe the best approach is to either emulate the whole FPU, perfectly according to IEEE 754, or run all FPU hardware instructions specific to the R5900, using the previously mentioned special ABI mode.

Arch91 commented 2 years ago

Two registers are paired for double precision numbers.

frno7, can I ask you to write a test program for me? I would like to have it doing these: double x double y let x = 9223372036854775807 (a maximum value for the double type variable, which certainly can not be set to the float type variable) asm volatile ( s.d "$f20, ?" ????? ) (please, use the FPU register number 20) let y = some_way_asm_volatile ( ?l.d? "$20, ?" ????? ) (means make y be taking the variable from the 20th FPU register) printf "20th FPU register currently keeps the %? value", y

I'll test it in qemu's debian (where supposely we certainly have those registers 64bit) and also will make a real test on PS2.

most if not all R5900 FPU instructions don’t conform to IEEE 754

Can you present a list of the all FPU instructions? All of them - both IEEE754 conformable and inconformable (by the way, didn't Juergen obtained them already?..). Maybe I will be searching for the test-programs, so I will be comparing whenever qemu and a real PS2 has a different outputs. And... a silly question... The all instructions known by the main MIPS processor and the FPU instructions known by the main MIPS processor - those are not equal, right?.. And all the existing instructions includes these FPU instructions, so there are some non-FPU instructions, am I correct?

The second moment. A person answered me that it IS possible to build libgcc in the form it will be processing single precisions hardwarely and double ones softwarely.

hardfp_float_modes := sf hardfp_int_modes := si di hardfp_extensions := hardfp_truncations := hardfp_exclusions := xxx softfp_float_modes := df softfp_int_modes := softfp_extensions := sfdf softfp_truncations := dfsf softfp_extras := xxx

That seems promising!

But, again, this case we/someone have to investigate which libgcc functions are alright and can be included to be processed hardwarely and which libgcc functions are problematic as providing a different (from the IEEE754) result or not working at all. The decision - rewrite those "problematic" libgcc functions with a (maybe specific) r5900 FPU insturctions OR to have that kind of them being processed softwarely - is another question. I'd choose the second variant, however, in both variants it is needed to be known WHICH libgcc functions are "problematic"...

At least it is possible to build cross-compiler in the state form in which Juergen left/abandoned/completed/resolved it (with his accepted work and with hard-float while libgcc is operating fp precisions softwarely (which also was like that on the state of gcc-4.3.4, his patches work acception)), with the newest gcc, binutils and almost newest libc. That's a big fortune. By the way, I added the alternative/additional scripts and patches in my repo, so anyone who is interested in can build the cross-compiler with hard-float. I did not note it in your wiki, though... Well, I saw that the Greatest PS2/Linux 'survived' developers were leaving a comments in your issueses here and there... but (almost) no one did any practics for possible merge, only the theories... Other words I wanted to mean is that if someone is really interested in the project, that person will be surely contacting with you and asking the certain questions. Also I did not even note about a way of how to build libgcc in the form it will be processing single precisions hardwarely and double ones softwarely. For the experiments.

frno7 commented 2 years ago

frno7, can I ask you to write a test program for me? I would like to have it doing these: double x double y let x = 9223372036854775807 (a maximum value for the double type variable, which certainly can not be set to the float type variable) asm volatile ( s.d "$f20, ?" ????? ) (please, use the FPU register number 20) let y = some_way_asm_volatile ( ?l.d? "$20, ?" ????? ) (means make y be taking the variable from the 20th FPU register) printf "20th FPU register currently keeps the %? value", y

I'll test it in qemu's debian (where supposely we certainly have those registers 64bit) and ...

It’s probably simplest to let GCC generate this code for you, at least as starting point. Something like a file f.c having

double f(double y)
{
    const double x = 9223372036854775807.0;

    return x + y;
}

and compile it with appropriate options, such as -march=mips3 and -mabi=n32, and suchlike, and study the generated machine code. GCC has several MIPS options. The gcc-help mailing list is likely the best place to ask about which options to use, because I don’t know for sure.

... also will make a real test on PS2.

PlayStation 2 Linux only supports the o32 ABI at this time, so 64-bit registers won’t work now.

Can you present a list of the all FPU instructions? All of them - both IEEE754 conformable and inconformable (by the way, didn't Juergen obtained them already?..).

Variants of the grep command on binutils/opcodes/mips-opc.c described in https://github.com/frno7/linux/issues/3#issue-416361610 should give you want you want. I think it’s fair to assume that none of them are conformant.

And... a silly question... The all instructions known by the main MIPS processor and the FPU instructions known by the main MIPS processor - those are not equal, right?.. And all the existing instructions includes these FPU instructions, so there are some non-FPU instructions, am I correct?

I’m not entirely sure what you mean, but it’s common practice for the Linux MIPS kernel to emulate missing hardware instructions in software.

But, again, this case we/someone have to investigate which libgcc functions are alright and can be included to be processed hardwarely and which libgcc functions are problematic as providing a different (from the IEEE754) result or not working at all. The decision - rewrite those "problematic" libgcc functions with a (maybe specific) r5900 FPU insturctions OR to have that kind of them being processed softwarely - is another question. I'd choose the second variant, however, in both variants it is needed to be known WHICH libgcc functions are "problematic"...

I haven’t looked at what libgcc supplies so I don’t know at this time. It’s a thing for advanced stages of issue #3. :-)