xref: /reactos/sdk/lib/crt/math/libm_sse2/log_special.c (revision 4afb647c)
1*4afb647cSTimo Kreuzer 
2*4afb647cSTimo Kreuzer /*******************************************************************************
3*4afb647cSTimo Kreuzer MIT License
4*4afb647cSTimo Kreuzer -----------
5*4afb647cSTimo Kreuzer 
6*4afb647cSTimo Kreuzer Copyright (c) 2002-2019 Advanced Micro Devices, Inc.
7*4afb647cSTimo Kreuzer 
8*4afb647cSTimo Kreuzer Permission is hereby granted, free of charge, to any person obtaining a copy
9*4afb647cSTimo Kreuzer of this Software and associated documentaon files (the "Software"), to deal
10*4afb647cSTimo Kreuzer in the Software without restriction, including without limitation the rights
11*4afb647cSTimo Kreuzer to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12*4afb647cSTimo Kreuzer copies of the Software, and to permit persons to whom the Software is
13*4afb647cSTimo Kreuzer furnished to do so, subject to the following conditions:
14*4afb647cSTimo Kreuzer 
15*4afb647cSTimo Kreuzer The above copyright notice and this permission notice shall be included in
16*4afb647cSTimo Kreuzer all copies or substantial portions of the Software.
17*4afb647cSTimo Kreuzer 
18*4afb647cSTimo Kreuzer THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19*4afb647cSTimo Kreuzer IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20*4afb647cSTimo Kreuzer FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21*4afb647cSTimo Kreuzer AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22*4afb647cSTimo Kreuzer LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23*4afb647cSTimo Kreuzer OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24*4afb647cSTimo Kreuzer THE SOFTWARE.
25*4afb647cSTimo Kreuzer *******************************************************************************/
26*4afb647cSTimo Kreuzer 
27*4afb647cSTimo Kreuzer #include <fpieee.h>
28*4afb647cSTimo Kreuzer #include <excpt.h>
29*4afb647cSTimo Kreuzer #include <float.h>
30*4afb647cSTimo Kreuzer #include <math.h>
31*4afb647cSTimo Kreuzer #include <errno.h>
32*4afb647cSTimo Kreuzer 
33*4afb647cSTimo Kreuzer #include "libm_new.h"
34*4afb647cSTimo Kreuzer 
35*4afb647cSTimo Kreuzer // y = log10f(x)
36*4afb647cSTimo Kreuzer // y = log10(x)
37*4afb647cSTimo Kreuzer // y = logf(x)
38*4afb647cSTimo Kreuzer // y = log(x)
39*4afb647cSTimo Kreuzer 
40*4afb647cSTimo Kreuzer // these codes and the ones in the related .asm files have to match
41*4afb647cSTimo Kreuzer #define LOG_X_ZERO      1
42*4afb647cSTimo Kreuzer #define LOG_X_NEG       2
43*4afb647cSTimo Kreuzer #define LOG_X_NAN       3
44*4afb647cSTimo Kreuzer 
_logf_special_common(float x,float y,U32 code,unsigned int op,char * name)45*4afb647cSTimo Kreuzer static float _logf_special_common(float x, float y, U32 code, unsigned int op, char *name)
46*4afb647cSTimo Kreuzer {
47*4afb647cSTimo Kreuzer     switch(code)
48*4afb647cSTimo Kreuzer     {
49*4afb647cSTimo Kreuzer     case LOG_X_ZERO:
50*4afb647cSTimo Kreuzer         {
51*4afb647cSTimo Kreuzer             UT64 ym; ym.u64 = 0; ym.f32[0] = y;
52*4afb647cSTimo Kreuzer             _handle_errorf(name, op, ym.u64, _SING, AMD_F_DIVBYZERO, ERANGE, x, 0.0, 1);
53*4afb647cSTimo Kreuzer         }
54*4afb647cSTimo Kreuzer         break;
55*4afb647cSTimo Kreuzer 
56*4afb647cSTimo Kreuzer     case LOG_X_NEG:
57*4afb647cSTimo Kreuzer         {
58*4afb647cSTimo Kreuzer             UT64 ym; ym.u64 = 0; ym.f32[0] = y;
59*4afb647cSTimo Kreuzer             _handle_errorf(name, op, ym.u64, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1);
60*4afb647cSTimo Kreuzer         }
61*4afb647cSTimo Kreuzer         break;
62*4afb647cSTimo Kreuzer 
63*4afb647cSTimo Kreuzer     case LOG_X_NAN:
64*4afb647cSTimo Kreuzer         {
65*4afb647cSTimo Kreuzer             unsigned int is_snan;
66*4afb647cSTimo Kreuzer             UT32 xm; UT64 ym;
67*4afb647cSTimo Kreuzer             xm.f32 = x;
68*4afb647cSTimo Kreuzer             is_snan = (((xm.u32 & QNAN_MASK_32) == QNAN_SET_32) ? 0 : 1);
69*4afb647cSTimo Kreuzer             ym.u64 = 0; ym.f32[0] = y;
70*4afb647cSTimo Kreuzer 
71*4afb647cSTimo Kreuzer             if(is_snan)
72*4afb647cSTimo Kreuzer             {
73*4afb647cSTimo Kreuzer                 _handle_errorf(name, op, ym.u64, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1);
74*4afb647cSTimo Kreuzer             }
75*4afb647cSTimo Kreuzer             else
76*4afb647cSTimo Kreuzer             {
77*4afb647cSTimo Kreuzer                 _handle_errorf(name, op, ym.u64, _DOMAIN, 0, EDOM, x, 0.0, 1);
78*4afb647cSTimo Kreuzer             }
79*4afb647cSTimo Kreuzer         }
80*4afb647cSTimo Kreuzer         break;
81*4afb647cSTimo Kreuzer     }
82*4afb647cSTimo Kreuzer 
83*4afb647cSTimo Kreuzer     return y;
84*4afb647cSTimo Kreuzer }
85*4afb647cSTimo Kreuzer 
_logf_special(float x,float y,U32 code)86*4afb647cSTimo Kreuzer float _logf_special(float x, float y, U32 code)
87*4afb647cSTimo Kreuzer {
88*4afb647cSTimo Kreuzer     return _logf_special_common(x, y, code, _FpCodeLog, "logf");
89*4afb647cSTimo Kreuzer }
90*4afb647cSTimo Kreuzer 
_log10f_special(float x,float y,U32 code)91*4afb647cSTimo Kreuzer float _log10f_special(float x, float y, U32 code)
92*4afb647cSTimo Kreuzer {
93*4afb647cSTimo Kreuzer     return _logf_special_common(x, y, code, _FpCodeLog10, "log10f");
94*4afb647cSTimo Kreuzer }
95*4afb647cSTimo Kreuzer 
_log_special_common(double x,double y,U32 code,unsigned int op,char * name)96*4afb647cSTimo Kreuzer static double _log_special_common(double x, double y, U32 code, unsigned int op, char *name)
97*4afb647cSTimo Kreuzer {
98*4afb647cSTimo Kreuzer     switch(code)
99*4afb647cSTimo Kreuzer     {
100*4afb647cSTimo Kreuzer     case LOG_X_ZERO:
101*4afb647cSTimo Kreuzer         {
102*4afb647cSTimo Kreuzer             UT64 ym; ym.f64 = y;
103*4afb647cSTimo Kreuzer             _handle_error(name, op, ym.u64, _SING, AMD_F_DIVBYZERO, ERANGE, x, 0.0, 1);
104*4afb647cSTimo Kreuzer         }
105*4afb647cSTimo Kreuzer         break;
106*4afb647cSTimo Kreuzer 
107*4afb647cSTimo Kreuzer     case LOG_X_NEG:
108*4afb647cSTimo Kreuzer         {
109*4afb647cSTimo Kreuzer             UT64 ym; ym.f64 = y;
110*4afb647cSTimo Kreuzer             _handle_error(name, op, ym.u64, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1);
111*4afb647cSTimo Kreuzer         }
112*4afb647cSTimo Kreuzer         break;
113*4afb647cSTimo Kreuzer 
114*4afb647cSTimo Kreuzer     case LOG_X_NAN:
115*4afb647cSTimo Kreuzer         {
116*4afb647cSTimo Kreuzer             UT64 ym; ym.f64 = y;
117*4afb647cSTimo Kreuzer             _handle_error(name, op, ym.u64, _DOMAIN, 0, EDOM, x, 0.0, 1);
118*4afb647cSTimo Kreuzer         }
119*4afb647cSTimo Kreuzer         break;
120*4afb647cSTimo Kreuzer     }
121*4afb647cSTimo Kreuzer 
122*4afb647cSTimo Kreuzer     return y;
123*4afb647cSTimo Kreuzer }
124*4afb647cSTimo Kreuzer 
_log_special(double x,double y,U32 code)125*4afb647cSTimo Kreuzer double _log_special(double x, double y, U32 code)
126*4afb647cSTimo Kreuzer {
127*4afb647cSTimo Kreuzer     return _log_special_common(x, y, code, _FpCodeLog, "log");
128*4afb647cSTimo Kreuzer }
129*4afb647cSTimo Kreuzer 
_log10_special(double x,double y,U32 code)130*4afb647cSTimo Kreuzer double _log10_special(double x, double y, U32 code)
131*4afb647cSTimo Kreuzer {
132*4afb647cSTimo Kreuzer     return _log_special_common(x, y, code, _FpCodeLog10, "log10");
133*4afb647cSTimo Kreuzer }
134