From: Adhemerval Zanella Date: Fri, 23 Jan 2026 13:02:19 +0000 (-0300) Subject: i386: Remove f{max,min} assembly implementations X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d8658e02d55d563b5a064efce868b1a2cd2b44be;p=thirdparty%2Fglibc.git i386: Remove f{max,min} assembly implementations The sNaN handling on i386 was not properly implemented or tested due to ABI and compiler constraints [1] [2], and although GCC has an open bug to try to fix at least the sNaN in the function call arguments [3], it will most likely never be fixed. To simplify the fix or the order signed zeros and make f{fmin,fmax} behave semantically equal to the rest of the f{min,max}* function, this patch removes all i386 assembly optimizations. The f{min,max} functions should not be hotspots in any meaningful code people are running on i386 nowadays. Checked on i686-linux-gnu. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57484#c11 [2] https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=5aa4a1a1fd742479818a668d42d91ca9ec4a6318 [3] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56831 Reviewed-by: Wilco Dijkstra --- diff --git a/sysdeps/i386/fpu/s_fmax.S b/sysdeps/i386/fpu/s_fmax.S deleted file mode 100644 index e0e8bf9807..0000000000 --- a/sysdeps/i386/fpu/s_fmax.S +++ /dev/null @@ -1,43 +0,0 @@ -/* Compute maximum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fmax) - fldl 12(%esp) // y - fxam - fnstsw - fldl 4(%esp) // y : x - - andb $0x45, %ah - cmpb $0x01, %ah - je 1f // y == NaN - - fucom %st(1) - fnstsw - sahf - jnc 1f - - fxch %st(1) -1: fstp %st(1) - - ret -END(__fmax) -libm_alias_double (__fmax, fmax) diff --git a/sysdeps/i386/fpu/s_fmaxf.S b/sysdeps/i386/fpu/s_fmaxf.S deleted file mode 100644 index 2d4b708c54..0000000000 --- a/sysdeps/i386/fpu/s_fmaxf.S +++ /dev/null @@ -1,43 +0,0 @@ -/* Compute maximum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fmaxf) - flds 8(%esp) // y - fxam - fnstsw - flds 4(%esp) // y : x - - andb $0x45, %ah - cmpb $0x01, %ah - je 1f // y == NaN - - fucom %st(1) - fnstsw - sahf - jnc 1f - - fxch %st(1) -1: fstp %st(1) - - ret -END(__fmaxf) -libm_alias_float (__fmax, fmax) diff --git a/sysdeps/i386/fpu/s_fmaxl.S b/sysdeps/i386/fpu/s_fmaxl.S deleted file mode 100644 index adfafdb50d..0000000000 --- a/sysdeps/i386/fpu/s_fmaxl.S +++ /dev/null @@ -1,71 +0,0 @@ -/* Compute maximum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fmaxl) - fldt 16(%esp) // y - fxam - fnstsw - fldt 4(%esp) // y : x - - andb $0x45, %ah - cmpb $0x01, %ah - je 2f // y == NaN - - fxam - fnstsw - andb $0x45, %ah - cmpb $0x01, %ah - je 3f // x == NaN - - fucom %st(1) - fnstsw - sahf - jnc 1f - - fxch %st(1) -1: fstp %st(1) - - ret - -2: // st(1) is a NaN; st(0) may or may not be. - fxam - fnstsw - andb $0x45, %ah - cmpb $0x01, %ah - je 4f - // st(1) is a NaN; st(0) is not. Test if st(1) is signaling. - testb $0x40, 23(%esp) - jz 4f - fstp %st(1) - ret - -3: // st(0) is a NaN; st(1) is not. Test if st(0) is signaling. - testb $0x40, 11(%esp) - jz 4f - fstp %st(0) - ret - -4: // Both arguments are NaNs, or one is a signaling NaN. - faddp - ret -END(__fmaxl) -libm_alias_ldouble (__fmax, fmax) diff --git a/sysdeps/i386/fpu/s_fmin.S b/sysdeps/i386/fpu/s_fmin.S deleted file mode 100644 index cd1e2ca1e5..0000000000 --- a/sysdeps/i386/fpu/s_fmin.S +++ /dev/null @@ -1,43 +0,0 @@ -/* Compute minimum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fmin) - fldl 4(%esp) // x - fldl 12(%esp) // x : y - - fxam - fnstsw - andb $0x45, %ah - cmpb $0x01, %ah - je 1f // y == NaN - - fucom %st(1) - fnstsw - sahf - jc 2f - -1: fxch %st(1) -2: fstp %st(1) - - ret -END(__fmin) -libm_alias_double (__fmin, fmin) diff --git a/sysdeps/i386/fpu/s_fminf.S b/sysdeps/i386/fpu/s_fminf.S deleted file mode 100644 index d2a6c8f3d6..0000000000 --- a/sysdeps/i386/fpu/s_fminf.S +++ /dev/null @@ -1,43 +0,0 @@ -/* Compute minimum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fminf) - flds 4(%esp) // x - flds 8(%esp) // x : y - - fxam - fnstsw - andb $0x45, %ah - cmpb $0x01, %ah - je 1f // y == NaN - - fucom %st(1) - fnstsw - sahf - jc 2f - -1: fxch %st(1) -2: fstp %st(1) - - ret -END(__fminf) -libm_alias_float (__fmin, fmin) diff --git a/sysdeps/i386/fpu/s_fminl.S b/sysdeps/i386/fpu/s_fminl.S deleted file mode 100644 index 7eaad28abf..0000000000 --- a/sysdeps/i386/fpu/s_fminl.S +++ /dev/null @@ -1,71 +0,0 @@ -/* Compute minimum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fminl) - fldt 16(%esp) // y - fxam - fnstsw - fldt 4(%esp) // y : x - - andb $0x45, %ah - cmpb $0x01, %ah - je 2f // y == NaN - - fxam - fnstsw - andb $0x45, %ah - cmpb $0x01, %ah - je 3f // x == NaN - - fucom %st(1) - fnstsw - sahf - jc 1f - - fxch %st(1) -1: fstp %st(1) - - ret - -2: // st(1) is a NaN; st(0) may or may not be. - fxam - fnstsw - andb $0x45, %ah - cmpb $0x01, %ah - je 4f - // st(1) is a NaN; st(0) is not. Test if st(1) is signaling. - testb $0x40, 23(%esp) - jz 4f - fstp %st(1) - ret - -3: // st(0) is a NaN; st(1) is not. Test if st(0) is signaling. - testb $0x40, 11(%esp) - jz 4f - fstp %st(0) - ret - -4: // Both arguments are NaNs, or one is a signaling NaN. - faddp - ret -END(__fminl) -libm_alias_ldouble (__fmin, fmin) diff --git a/sysdeps/i386/i686/fpu/s_fmax.S b/sysdeps/i386/i686/fpu/s_fmax.S deleted file mode 100644 index 0e36a60df8..0000000000 --- a/sysdeps/i386/i686/fpu/s_fmax.S +++ /dev/null @@ -1,39 +0,0 @@ -/* Compute maximum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fmax) - fldl 4(%esp) // x - fldl 12(%esp) // x : y - - fucomi %st(0), %st - fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise - - fxch - - fucomi %st(1), %st - fcmovb %st(1), %st - - fstp %st(1) - - ret -END(__fmax) -libm_alias_double (__fmax, fmax) diff --git a/sysdeps/i386/i686/fpu/s_fmaxf.S b/sysdeps/i386/i686/fpu/s_fmaxf.S deleted file mode 100644 index 33a1aa69eb..0000000000 --- a/sysdeps/i386/i686/fpu/s_fmaxf.S +++ /dev/null @@ -1,39 +0,0 @@ -/* Compute maximum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fmaxf) - flds 4(%esp) // x - flds 8(%esp) // x : y - - fucomi %st(0), %st - fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise - - fxch - - fucomi %st(1), %st - fcmovb %st(1), %st - - fstp %st(1) - - ret -END(__fmaxf) -libm_alias_float (__fmax, fmax) diff --git a/sysdeps/i386/i686/fpu/s_fmaxl.S b/sysdeps/i386/i686/fpu/s_fmaxl.S deleted file mode 100644 index c1b191b296..0000000000 --- a/sysdeps/i386/i686/fpu/s_fmaxl.S +++ /dev/null @@ -1,58 +0,0 @@ -/* Compute maximum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fmaxl) - fldt 4(%esp) // x - fldt 16(%esp) // x : y - - fucomi %st(1), %st - jp 2f - fcmovb %st(1), %st - - fstp %st(1) - - ret - -2: // Unordered. - fucomi %st(0), %st - jp 3f - // st(1) is a NaN; st(0) is not. Test if st(1) is signaling. - testb $0x40, 11(%esp) - jz 4f - fstp %st(1) - ret - -3: // st(0) is a NaN; st(1) may or may not be. - fxch - fucomi %st(0), %st - jp 4f - // st(1) is a NaN; st(0) is not. Test if st(1) is signaling. - testb $0x40, 23(%esp) - jz 4f - fstp %st(1) - ret - -4: // Both arguments are NaNs, or one is a signaling NaN. - faddp - ret -END(__fmaxl) -libm_alias_ldouble (__fmax, fmax) diff --git a/sysdeps/i386/i686/fpu/s_fmin.S b/sysdeps/i386/i686/fpu/s_fmin.S deleted file mode 100644 index ef4e54de2f..0000000000 --- a/sysdeps/i386/i686/fpu/s_fmin.S +++ /dev/null @@ -1,37 +0,0 @@ -/* Compute minimum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fmin) - fldl 4(%esp) // x - fldl 12(%esp) // x : y - - fucomi %st(0), %st - fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise - - fucomi %st(1), %st - fcmovnb %st(1), %st - - fstp %st(1) - - ret -END(__fmin) -libm_alias_double (__fmin, fmin) diff --git a/sysdeps/i386/i686/fpu/s_fminf.S b/sysdeps/i386/i686/fpu/s_fminf.S deleted file mode 100644 index eaa680e412..0000000000 --- a/sysdeps/i386/i686/fpu/s_fminf.S +++ /dev/null @@ -1,37 +0,0 @@ -/* Compute minimum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fminf) - flds 4(%esp) // x - flds 8(%esp) // x : y - - fucomi %st(0), %st - fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise - - fucomi %st(1), %st - fcmovnb %st(1), %st - - fstp %st(1) - - ret -END(__fminf) -libm_alias_float (__fmin, fmin) diff --git a/sysdeps/i386/i686/fpu/s_fminl.S b/sysdeps/i386/i686/fpu/s_fminl.S deleted file mode 100644 index a6cc6ca80e..0000000000 --- a/sysdeps/i386/i686/fpu/s_fminl.S +++ /dev/null @@ -1,58 +0,0 @@ -/* Compute minimum of two numbers, regarding NaN as missing argument. - Copyright (C) 1997-2026 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include - - .text -ENTRY(__fminl) - fldt 4(%esp) // x - fldt 16(%esp) // x : y - - fucomi %st(1), %st - jp 2f - fcmovnb %st(1), %st - - fstp %st(1) - - ret - -2: // Unordered. - fucomi %st(0), %st - jp 3f - // st(1) is a NaN; st(0) is not. Test if st(1) is signaling. - testb $0x40, 11(%esp) - jz 4f - fstp %st(1) - ret - -3: // st(0) is a NaN; st(1) may or may not be. - fxch - fucomi %st(0), %st - jp 4f - // st(1) is a NaN; st(0) is not. Test if st(1) is signaling. - testb $0x40, 23(%esp) - jz 4f - fstp %st(1) - ret - -4: // Both arguments are NaNs, or one is a signaling NaN. - faddp - ret -END(__fminl) -libm_alias_ldouble (__fmin, fmin)