(root)/
glibc-2.38/
sysdeps/
i386/
fpu/
i386-math-asm.h
       1  /* Helper macros for x86 libm functions.
       2     Copyright (C) 2015-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #ifndef _I386_MATH_ASM_H
      20  #define _I386_MATH_ASM_H 1
      21  
      22  /* Remove excess range and precision by storing a value on the stack
      23     and loading it back.  */
      24  #define FLT_NARROW_EVAL				\
      25  	subl	$4, %esp;			\
      26  	cfi_adjust_cfa_offset (4);		\
      27  	fstps	(%esp);				\
      28  	flds	(%esp);				\
      29  	addl	$4, %esp;			\
      30  	cfi_adjust_cfa_offset (-4);
      31  #define DBL_NARROW_EVAL				\
      32  	subl	$8, %esp;			\
      33  	cfi_adjust_cfa_offset (8);		\
      34  	fstpl	(%esp);				\
      35  	fldl	(%esp);				\
      36  	addl	$8, %esp;			\
      37  	cfi_adjust_cfa_offset (-8);
      38  
      39  /* Define constants for the minimum value of a floating-point
      40     type.  */
      41  #define DEFINE_FLT_MIN				\
      42  	.section .rodata.cst4,"aM",@progbits,4;	\
      43  	.p2align 2;				\
      44  	.type flt_min,@object;			\
      45  flt_min:					\
      46  	.byte 0, 0, 0x80, 0;			\
      47  	.size flt_min, .-flt_min;
      48  #define DEFINE_DBL_MIN				\
      49  	.section .rodata.cst8,"aM",@progbits,8;	\
      50  	.p2align 3;				\
      51  	.type dbl_min,@object;			\
      52  dbl_min:					\
      53  	.byte 0, 0, 0, 0, 0, 0, 0x10, 0;	\
      54  	.size dbl_min, .-dbl_min;
      55  #define DEFINE_LDBL_MIN					\
      56  	.section .rodata.cst16,"aM",@progbits,16;	\
      57  	.p2align 4;					\
      58  	.type ldbl_min,@object;				\
      59  ldbl_min:						\
      60  	.byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x1, 0;	\
      61  	.byte 0, 0, 0, 0, 0, 0;				\
      62  	.size ldbl_min, .-ldbl_min;
      63  
      64  /* Remove excess range and precision by storing a value on the stack
      65     and loading it back.  The value is given to be nonnegative or NaN;
      66     if it is subnormal, also force an underflow exception.  The
      67     relevant constant for the minimum of the type must have been
      68     defined, the MO macro must have been defined for access to memory
      69     operands, and, if PIC, the PIC register must have been loaded.  */
      70  #define FLT_NARROW_EVAL_UFLOW_NONNEG_NAN	\
      71  	subl	$4, %esp;			\
      72  	cfi_adjust_cfa_offset (4);		\
      73  	flds	MO(flt_min);			\
      74  	fld	%st(1);				\
      75  	fucompp;				\
      76  	fnstsw;					\
      77  	sahf;					\
      78  	jnc 6424f;				\
      79  	fld	%st(0);				\
      80  	fmul	%st(0);				\
      81  	fstps	(%esp);				\
      82  6424:	fstps	(%esp);				\
      83  	flds	(%esp);				\
      84  	addl	$4, %esp;			\
      85  	cfi_adjust_cfa_offset (-4);
      86  #define DBL_NARROW_EVAL_UFLOW_NONNEG_NAN	\
      87  	subl	$8, %esp;			\
      88  	cfi_adjust_cfa_offset (8);		\
      89  	fldl	MO(dbl_min);			\
      90  	fld	%st(1);				\
      91  	fucompp;				\
      92  	fnstsw;					\
      93  	sahf;					\
      94  	jnc 6453f;				\
      95  	fld	%st(0);				\
      96  	fmul	%st(0);				\
      97  	fstpl	(%esp);				\
      98  6453:	fstpl	(%esp);				\
      99  	fldl	(%esp);				\
     100  	addl	$8, %esp;			\
     101  	cfi_adjust_cfa_offset (-8);
     102  
     103  /* Likewise, but the argument is not a NaN (so fcom instructions,
     104     which support memory operands, can be used).  */
     105  #define FLT_NARROW_EVAL_UFLOW_NONNEG		\
     106  	subl	$4, %esp;			\
     107  	cfi_adjust_cfa_offset (4);		\
     108  	fcoms	MO(flt_min);			\
     109  	fnstsw;					\
     110  	sahf;					\
     111  	jnc 6424f;				\
     112  	fld	%st(0);				\
     113  	fmul	%st(0);				\
     114  	fstps	(%esp);				\
     115  6424:	fstps	(%esp);				\
     116  	flds	(%esp);				\
     117  	addl	$4, %esp;			\
     118  	cfi_adjust_cfa_offset (-4);
     119  #define DBL_NARROW_EVAL_UFLOW_NONNEG		\
     120  	subl	$8, %esp;			\
     121  	cfi_adjust_cfa_offset (8);		\
     122  	fcoml	MO(dbl_min);			\
     123  	fnstsw;					\
     124  	sahf;					\
     125  	jnc 6453f;				\
     126  	fld	%st(0);				\
     127  	fmul	%st(0);				\
     128  	fstpl	(%esp);				\
     129  6453:	fstpl	(%esp);				\
     130  	fldl	(%esp);				\
     131  	addl	$8, %esp;			\
     132  	cfi_adjust_cfa_offset (-8);
     133  
     134  /* Likewise, but the non-NaN argument may be negative.  */
     135  #define FLT_NARROW_EVAL_UFLOW_NONNAN		\
     136  	subl	$4, %esp;			\
     137  	cfi_adjust_cfa_offset (4);		\
     138  	fld	%st(0);				\
     139  	fabs;					\
     140  	fcomps	MO(flt_min);			\
     141  	fnstsw;					\
     142  	sahf;					\
     143  	jnc 6424f;				\
     144  	fld	%st(0);				\
     145  	fmul	%st(0);				\
     146  	fstps	(%esp);				\
     147  6424:	fstps	(%esp);				\
     148  	flds	(%esp);				\
     149  	addl	$4, %esp;			\
     150  	cfi_adjust_cfa_offset (-4);
     151  #define DBL_NARROW_EVAL_UFLOW_NONNAN		\
     152  	subl	$8, %esp;			\
     153  	cfi_adjust_cfa_offset (8);		\
     154  	fld	%st(0);				\
     155  	fabs;					\
     156  	fcompl	MO(dbl_min);			\
     157  	fnstsw;					\
     158  	sahf;					\
     159  	jnc 6453f;				\
     160  	fld	%st(0);				\
     161  	fmul	%st(0);				\
     162  	fstpl	(%esp);				\
     163  6453:	fstpl	(%esp);				\
     164  	fldl	(%esp);				\
     165  	addl	$8, %esp;			\
     166  	cfi_adjust_cfa_offset (-8);
     167  
     168  /* Force an underflow exception if the given value is subnormal.  The
     169     relevant constant for the minimum of the type must have been
     170     defined, the MO macro must have been defined for access to memory
     171     operands, and, if PIC, the PIC register must have been loaded.  */
     172  #define FLT_CHECK_FORCE_UFLOW			\
     173  	flds	MO(flt_min);			\
     174  	fld	%st(1);				\
     175  	fabs;					\
     176  	fucompp;				\
     177  	fnstsw;					\
     178  	sahf;					\
     179  	jnc 6424f;				\
     180  	subl	$4, %esp;			\
     181  	cfi_adjust_cfa_offset (4);		\
     182  	fld	%st(0);				\
     183  	fmul	%st(0);				\
     184  	fstps	(%esp);				\
     185  	addl	$4, %esp;			\
     186  	cfi_adjust_cfa_offset (-4);		\
     187  6424:
     188  #define DBL_CHECK_FORCE_UFLOW			\
     189  	fldl	MO(dbl_min);			\
     190  	fld	%st(1);				\
     191  	fabs;					\
     192  	fucompp;				\
     193  	fnstsw;					\
     194  	sahf;					\
     195  	jnc 6453f;				\
     196  	subl	$8, %esp;			\
     197  	cfi_adjust_cfa_offset (8);		\
     198  	fld	%st(0);				\
     199  	fmul	%st(0);				\
     200  	fstpl	(%esp);				\
     201  	addl	$8, %esp;			\
     202  	cfi_adjust_cfa_offset (-8);		\
     203  6453:
     204  
     205  /* Likewise, but also remove excess range and precision if the value
     206     is subnormal.  */
     207  #define FLT_CHECK_FORCE_UFLOW_NARROW		\
     208  	flds	MO(flt_min);			\
     209  	fld	%st(1);				\
     210  	fabs;					\
     211  	fucompp;				\
     212  	fnstsw;					\
     213  	sahf;					\
     214  	jnc 6424f;				\
     215  	subl	$4, %esp;			\
     216  	cfi_adjust_cfa_offset (4);		\
     217  	fld	%st(0);				\
     218  	fmul	%st(0);				\
     219  	fstps	(%esp);				\
     220  	fstps	(%esp);				\
     221  	flds	(%esp);				\
     222  	addl	$4, %esp;			\
     223  	cfi_adjust_cfa_offset (-4);		\
     224  6424:
     225  #define DBL_CHECK_FORCE_UFLOW_NARROW		\
     226  	fldl	MO(dbl_min);			\
     227  	fld	%st(1);				\
     228  	fabs;					\
     229  	fucompp;				\
     230  	fnstsw;					\
     231  	sahf;					\
     232  	jnc 6453f;				\
     233  	subl	$8, %esp;			\
     234  	cfi_adjust_cfa_offset (8);		\
     235  	fld	%st(0);				\
     236  	fmul	%st(0);				\
     237  	fstpl	(%esp);				\
     238  	fstpl	(%esp);				\
     239  	fldl	(%esp);				\
     240  	addl	$8, %esp;			\
     241  	cfi_adjust_cfa_offset (-8);		\
     242  6453:
     243  
     244  /* Likewise, but the argument is nonnegative or NaN.  */
     245  #define LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN	\
     246  	fldt	MO(ldbl_min);			\
     247  	fld	%st(1);				\
     248  	fucompp;				\
     249  	fnstsw;					\
     250  	sahf;					\
     251  	jnc 6464f;				\
     252  	fld	%st(0);				\
     253  	fmul	%st(0);				\
     254  	fstp	%st(0);				\
     255  6464:
     256  
     257  /* Likewise, but the argument is not a NaN.  */
     258  #define FLT_CHECK_FORCE_UFLOW_NONNAN		\
     259  	fld %st(0);				\
     260  	fabs;					\
     261  	fcomps	MO(flt_min);			\
     262  	fnstsw;					\
     263  	sahf;					\
     264  	jnc 6424f;				\
     265  	subl	$4, %esp;			\
     266  	cfi_adjust_cfa_offset (4);		\
     267  	fld	%st(0);				\
     268  	fmul	%st(0);				\
     269  	fstps	(%esp);				\
     270  	addl	$4, %esp;			\
     271  	cfi_adjust_cfa_offset (-4);		\
     272  6424:
     273  #define DBL_CHECK_FORCE_UFLOW_NONNAN		\
     274  	fld %st(0);				\
     275  	fabs;					\
     276  	fcompl	MO(dbl_min);			\
     277  	fnstsw;					\
     278  	sahf;					\
     279  	jnc 6453f;				\
     280  	subl	$8, %esp;			\
     281  	cfi_adjust_cfa_offset (8);		\
     282  	fld	%st(0);				\
     283  	fmul	%st(0);				\
     284  	fstpl	(%esp);				\
     285  	addl	$8, %esp;			\
     286  	cfi_adjust_cfa_offset (-8);		\
     287  6453:
     288  #define LDBL_CHECK_FORCE_UFLOW_NONNAN		\
     289  	fldt	MO(ldbl_min);			\
     290  	fld	%st(1);				\
     291  	fabs;					\
     292  	fcompp;					\
     293  	fnstsw;					\
     294  	sahf;					\
     295  	jnc 6464f;				\
     296  	fld	%st(0);				\
     297  	fmul	%st(0);				\
     298  	fstp	%st(0);				\
     299  6464:
     300  
     301  /* Likewise, but the argument is nonnegative and not a NaN.  */
     302  #define FLT_CHECK_FORCE_UFLOW_NONNEG		\
     303  	fcoms	MO(flt_min);			\
     304  	fnstsw;					\
     305  	sahf;					\
     306  	jnc 6424f;				\
     307  	subl	$4, %esp;			\
     308  	cfi_adjust_cfa_offset (4);		\
     309  	fld	%st(0);				\
     310  	fmul	%st(0);				\
     311  	fstps	(%esp);				\
     312  	addl	$4, %esp;			\
     313  	cfi_adjust_cfa_offset (-4);		\
     314  6424:
     315  #define DBL_CHECK_FORCE_UFLOW_NONNEG		\
     316  	fcoml	MO(dbl_min);			\
     317  	fnstsw;					\
     318  	sahf;					\
     319  	jnc 6453f;				\
     320  	subl	$8, %esp;			\
     321  	cfi_adjust_cfa_offset (8);		\
     322  	fld	%st(0);				\
     323  	fmul	%st(0);				\
     324  	fstpl	(%esp);				\
     325  	addl	$8, %esp;			\
     326  	cfi_adjust_cfa_offset (-8);		\
     327  6453:
     328  #define LDBL_CHECK_FORCE_UFLOW_NONNEG		\
     329  	fldt	MO(ldbl_min);			\
     330  	fld	%st(1);				\
     331  	fcompp;					\
     332  	fnstsw;					\
     333  	sahf;					\
     334  	jnc 6464f;				\
     335  	fld	%st(0);				\
     336  	fmul	%st(0);				\
     337  	fstp	%st(0);				\
     338  6464:
     339  
     340  #endif /* i386-math-asm.h.  */