Fix powerpc fmax, fmin sNaN handling (bug 20947).
[glibc.git] / sysdeps / powerpc / fpu / s_fmax.S
blobe6405c02dd6b9f3e630ea8c970b48be2db2a9d32
1 /* Floating-point maximum.  PowerPC version.
2    Copyright (C) 1997-2016 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
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.
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.
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    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
21 ENTRY(__fmax)
22 /* double [f1] fmax (double [f1] x, double [f2] y); */
23         fcmpu   cr0,fp1,fp2
24         blt     cr0,0f          /* if x < y, neither x nor y can be NaN... */
25         bnulr+  cr0
26 /* x and y are unordered, so one of x or y must be a NaN... */
27         fcmpu   cr1,fp2,fp2
28         bun     cr1,1f
29 /* x is a NaN; y is not.  Test if x is signaling.  */
30 #ifdef __powerpc64__
31         stfd    fp1,-8(r1)
32         lwz     r3,-8+HIWORD(r1)
33 #else
34         stwu    r1,-16(r1)
35         cfi_adjust_cfa_offset (16)
36         stfd    fp1,8(r1)
37         lwz     r3,8+HIWORD(r1)
38         addi    r1,r1,16
39         cfi_adjust_cfa_offset (-16)
40 #endif
41         andis.  r3,r3,8
42         bne     cr0,0f
43         b       2f
44 1:      /* y is a NaN; x may or may not be.  */
45         fcmpu   cr1,fp1,fp1
46         bun     cr1,2f
47 /* y is a NaN; x is not.  Test if y is signaling.  */
48 #ifdef __powerpc64__
49         stfd    fp2,-8(r1)
50         lwz     r3,-8+HIWORD(r1)
51 #else
52         stwu    r1,-16(r1)
53         cfi_adjust_cfa_offset (16)
54         stfd    fp2,8(r1)
55         lwz     r3,8+HIWORD(r1)
56         addi    r1,r1,16
57         cfi_adjust_cfa_offset (-16)
58 #endif
59         andis.  r3,r3,8
60         bnelr   cr0
61 2:      /* x and y are NaNs, or one is a signaling NaN.  */
62         fadd    fp1,fp1,fp2
63         blr
64 0:      fmr     fp1,fp2
65         blr
66 END(__fmax)
68 weak_alias (__fmax,fmax)
70 /* It turns out that it's safe to use this code even for single-precision.  */
71 strong_alias(__fmax,__fmaxf)
72 weak_alias (__fmax,fmaxf)
74 #ifdef NO_LONG_DOUBLE
75 weak_alias (__fmax,__fmaxl)
76 weak_alias (__fmax,fmaxl)
77 #endif