From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 6D5C43948A5B; Wed, 23 Feb 2022 11:57:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6D5C43948A5B From: "adhemerval.zanella at linaro dot org" To: glibc-bugs@sourceware.org Subject: [Bug ports/28872] Building glibc for MIPSel single float targets Date: Wed, 23 Feb 2022 11:57:00 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: ports X-Bugzilla-Version: 2.30 X-Bugzilla-Keywords: X-Bugzilla-Severity: critical X-Bugzilla-Who: adhemerval.zanella at linaro dot org X-Bugzilla-Status: RESOLVED X-Bugzilla-Resolution: INVALID X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: glibc-bugs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-bugs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Feb 2022 11:57:01 -0000 https://sourceware.org/bugzilla/show_bug.cgi?id=3D28872 --- Comment #18 from Adhemerval Zanella --- (In reply to Den from comment #17) > (In reply to Adhemerval Zanella from comment #16) > > I am confused because in some places you refers to r5900 and other r600= 0. > I am assuming that r6000 is supported the best and stable way from each g= cc > revision rather than r5900 which was accepted in relatively nearest years > (2013?..). r5900 has some opcodes from ISA MIPS-III, but only SOME of the= m, > so we decided to choose r6000 for fp tests purposes because of it's ISA > MIPS-II, so it will be not generating the unsupported for r5900 opcodes. = The > only stable fp generating logic toolchain for linux mipsr5900el target kn= own > by me consists from binutils-2.23.1 and gcc-svn-20130804 . binutils was > processing l.d/s.d opcodes, as I assume, before v2.25. Then something > changed since v2.25 and those opcodes becomes unsupported for single-float > targets > Maybe it is possible in gcc to selectively choose 64bit operations being > processed emulately, with softfp? And rely 32bit single float operation > being processed hardwarely, with hard- single-float fp. You will need to check on gcc, mips ABI is a complete mess. But from an ABI perpective, using different code sequence for double precision is an different ABI. >=20 > > AFAIK r6000 was never supported on Linux [1], and it seems that gcc also > > does not fully support the r6010 floating point controller: > >=20 > > $ cat test.c > > void foo (double *m, double v) > > { > > *m =3D v; > > } > > $ mips64el-glibc-linux-gnu-gcc -O2 -mabi=3D32 -march=3Dr6000 -mfp32 > > -msingle-float -mhard-float test.c -S -o - > > > > [...] > >=20=20 > > So gcc does not transform double stores to 'swc1', it seems to be using > > softfp in this case. > If to not use -O2 flag then the output changes... Yes, but it should not change ABI whether you use optimizations flags or no= t. > Yes, I actually could not obtain whenever double is transformed from some= C > code into swc1 too. > $ cat asmtest.c > int main(){ > asm volatile ( "s.d $f0,($0)" );} > $ mipsr5900el-unknown-linux-uclibc-gcc asmtest.c -o asmtest.o > $ mipsr5900el-unknown-linux-uclibc-objdump -d asmtest.o > - I noticed sdc1 only among the output. > (mipsr5900el-unknown-linux-uclibc is the target of that stable toolchain > with gcc-svn I described above) I still learning the peculiarities os MIPS ABI and it seems that my initial example does not exercices what I was trying find out. It seems that o32 ABI always pass floaring point register in $a0-$a3. Using another example to force a floating-point store: $ cat test.c=20 float foo_float (float *m, float x, float y) { *m =3D x + y; return *m; } double foo_double (double *m, double x, double y) { *m =3D x + y; return *m; } $ mips64el-linux-gnu/bin/mips64el-glibc-linux-gnu-gcc -O2 -mabi=3D32 -mfp32 -msingle-float -mhard-float test.c -S -o - [...] foo_float: [...] mtc1 $5,$f0 mtc1 $6,$f1 nop add.s $f0,$f0,$f1 jr $31 swc1 $f0,0($4) [...] foo_double: .frame $sp,32,$31 # vars=3D 0, regs=3D 2/0, args=3D 1= 6, gp=3D 8 .mask 0x80010000,-4 .fmask 0x00000000,0 .set noreorder .set nomacro addiu $sp,$sp,-32 move $2,$6 move $3,$7 lw $6,48($sp) lw $7,52($sp) sw $16,24($sp) move $5,$3 move $16,$4 sw $31,28($sp) jal __adddf3 move $4,$2 lw $31,28($sp) sw $2,0($16) sw $3,4($16) lw $16,24($sp) jr $31 addiu $sp,$sp,32 [...] So it confirms that for -mfp32 softfp is used. >=20 > > In an case, I think you can try replace LDFPR and STFPR on my patch to = the > > with 'lwc1' and 'swc1' if __mips_fpr is 32. Something like: > >=20 > > #if __mips_fpr =3D=3D 0 || __mips_fpr =3D=3D 64 > > # define STFPR sdc1 > > #else if __mips_fpr =3D=3D 32 > > # define STFPR swc1 > > #else > > # define STFPR s.d > > #endif > >=20 > > Assuming that the mips machine ou are targetting have the same set of > > floating -point registers. > >=20 > > [1] https://www.linux-mips.org/wiki/R6000 > That will result to the changes I began in this thread from. Which are > supposedly wrong. I think you misunderstand what I pointed as wrong, the issue was changing t= he jmp_buf size and not making the use of lwc1/swc1 conditionally on the __mips_fpr begin used by the compiler.=20=20 The glibc does not use a opaque type but rather a struct with expected inte= rnal types to certify that internal field alignement is the expected one (as you noted newlib had to resort on a hack to make it work since it defines jmp_buf as = an=20 array of 'int').=20 >=20 > So, for the single-float targets, the task comes down to a someway method= of > storing/loading doubles into/from 32bit floating point registers. Can you > imagine the practice realization of the next test: > -] x is double,=20 > -] y is might double too, > -] let x=3Dmaximum value of double (which is surely beyond the float maxi= mum > value), > -]some (math?) operation which result to the output which is storable in = fp > regs, > -]word store opcode use to fp register with x, > -] --word load opcode use from fp register with y-- instead of it - some > (math?) operation to use the previously stored data in fp regs to retreive > the original value of x and return it to the y > -] printf value of y. > -] y=3Dx then hooray! - I found a way to implement that in libc without > current abi logic thinking-out! > -] y!=3Dx then damn it, searching for the workaround... >=20 >=20 > I was thinking about getting the hex value of the x (how it is stored in > RAM), "slice" it, return the "sliced" pieces to float variables (maybe wi= th > a conversion to the decimal back again, the acceptable for float variable > data), then store those variables into 32bit fp regs, and the reverse hex > data uniting into an original for the x hex/decimal value. I think you also misunderstanding what need to done here: jmp_buf is essentially a opaque type with enough size to store the machine *state* which would be = save and restored. If the machine register state does not contain double precis= ion floating point state there is no sense in trying to save and restore it, yo= u=20 just need to save and restore the single-precision (the ABI expectations wi= ll be fullfilled).=20=20 I attached a patch which should be a fix, at least stdlib setcontext/makecontext tests do not trigger any regression with qemu-user (although I don't think= =20 qemu-user has an option to select a CPU with single precision only). The do= uble precision tests uses softfp, which should be handled by save/restore the general registers. --=20 You are receiving this mail because: You are on the CC list for the bug.=