xref: /aosp_15_r20/external/XNNPACK/src/f32-f16-vcvt/gen/vcvt-scalar-fabsf-x4.c (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1 // Auto-generated file. Do not edit!
2 //   Template: src/f32-f16-vcvt/scalar-fabsf.c.in
3 //   Generator: tools/xngen
4 //
5 // Copyright 2021 Google LLC
6 //
7 // This source code is licensed under the BSD-style license found in the
8 // LICENSE file in the root directory of this source tree.
9 
10 #include <assert.h>
11 #include <math.h>
12 
13 #include <xnnpack/common.h>
14 #include <xnnpack/math.h>
15 #include <xnnpack/vcvt.h>
16 
17 
xnn_f32_f16_vcvt_ukernel__scalar_fabsf_x4(size_t n,const float * input,void * output,const union xnn_f32_f16_cvt_params params[restrict XNN_MIN_ELEMENTS (1)])18 void xnn_f32_f16_vcvt_ukernel__scalar_fabsf_x4(
19     size_t n,
20     const float* input,
21     void* output,
22     const union xnn_f32_f16_cvt_params params[restrict XNN_MIN_ELEMENTS(1)])
23 {
24   assert(n != 0);
25   assert(n % sizeof(float) == 0);
26   assert(input != NULL);
27   assert(output != NULL);
28 
29   const float vscale_to_inf = params->scalar_fabsf.scale_to_inf;
30   const uint32_t vexp_bias = params->scalar_fabsf.exp_bias;
31   const float vscale_to_zero = params->scalar_fabsf.scale_to_zero;
32   const uint32_t vexpw_max = params->scalar_fabsf.expw_max;
33   const uint32_t vbias_min = params->scalar_fabsf.bias_min;
34   const uint16_t vexph_mask = params->scalar_fabsf.exph_mask;
35   const uint16_t vmanth_mask = params->scalar_fabsf.manth_mask;
36   const uint16_t vnanh = params->scalar_fabsf.nanh;
37 
38   uint16_t* o = (uint16_t*) output;
39   for (; n >= 4 * sizeof(float); n -= 4 * sizeof(float)) {
40     const float vx0 = input[0];
41     const float vx1 = input[1];
42     const float vx2 = input[2];
43     const float vx3 = input[3];
44     input += 4;
45 
46     const float vabsx0 = fabsf(vx0);
47     const float vabsx1 = fabsf(vx1);
48     const float vabsx2 = fabsf(vx2);
49     const float vabsx3 = fabsf(vx3);
50     uint32_t vsignw0 = float_as_uint32(vx0);
51     uint32_t vsignw1 = float_as_uint32(vx1);
52     uint32_t vsignw2 = float_as_uint32(vx2);
53     uint32_t vsignw3 = float_as_uint32(vx3);
54 
55     const uint32_t vnonsignw0 = float_as_uint32(vabsx0);
56     const uint32_t vnonsignw1 = float_as_uint32(vabsx1);
57     const uint32_t vnonsignw2 = float_as_uint32(vabsx2);
58     const uint32_t vnonsignw3 = float_as_uint32(vabsx3);
59     float vf0 = vabsx0 * vscale_to_inf;
60     float vf1 = vabsx1 * vscale_to_inf;
61     float vf2 = vabsx2 * vscale_to_inf;
62     float vf3 = vabsx3 * vscale_to_inf;
63 
64     uint32_t vbias0 = vnonsignw0 + vexp_bias;
65     uint32_t vbias1 = vnonsignw1 + vexp_bias;
66     uint32_t vbias2 = vnonsignw2 + vexp_bias;
67     uint32_t vbias3 = vnonsignw3 + vexp_bias;
68     vsignw0 ^= vnonsignw0;
69     vsignw1 ^= vnonsignw1;
70     vsignw2 ^= vnonsignw2;
71     vsignw3 ^= vnonsignw3;
72 
73     vf0 *= vscale_to_zero;
74     vf1 *= vscale_to_zero;
75     vf2 *= vscale_to_zero;
76     vf3 *= vscale_to_zero;
77     vbias0 &= vexpw_max;
78     vbias1 &= vexpw_max;
79     vbias2 &= vexpw_max;
80     vbias3 &= vexpw_max;
81 
82     vbias0 = math_max_u32(vbias0, vbias_min);
83     vbias1 = math_max_u32(vbias1, vbias_min);
84     vbias2 = math_max_u32(vbias2, vbias_min);
85     vbias3 = math_max_u32(vbias3, vbias_min);
86 
87     vf0 += uint32_as_float(vbias0);
88     vf1 += uint32_as_float(vbias1);
89     vf2 += uint32_as_float(vbias2);
90     vf3 += uint32_as_float(vbias3);
91 
92     const uint32_t vbits0 = float_as_uint32(vf0);
93     const uint32_t vbits1 = float_as_uint32(vf1);
94     const uint32_t vbits2 = float_as_uint32(vf2);
95     const uint32_t vbits3 = float_as_uint32(vf3);
96 
97     const uint16_t vexph0 = (uint16_t) (vbits0 >> 13) & vexph_mask;
98     const uint16_t vexph1 = (uint16_t) (vbits1 >> 13) & vexph_mask;
99     const uint16_t vexph2 = (uint16_t) (vbits2 >> 13) & vexph_mask;
100     const uint16_t vexph3 = (uint16_t) (vbits3 >> 13) & vexph_mask;
101     const uint16_t vmanth0 = (uint16_t) vbits0 & vmanth_mask;
102     const uint16_t vmanth1 = (uint16_t) vbits1 & vmanth_mask;
103     const uint16_t vmanth2 = (uint16_t) vbits2 & vmanth_mask;
104     const uint16_t vmanth3 = (uint16_t) vbits3 & vmanth_mask;
105     const uint16_t vsignh0 = (uint16_t) (vsignw0 >> 16);
106     const uint16_t vsignh1 = (uint16_t) (vsignw1 >> 16);
107     const uint16_t vsignh2 = (uint16_t) (vsignw2 >> 16);
108     const uint16_t vsignh3 = (uint16_t) (vsignw3 >> 16);
109 
110     uint16_t vh0 = vexph0 + vmanth0;
111     uint16_t vh1 = vexph1 + vmanth1;
112     uint16_t vh2 = vexph2 + vmanth2;
113     uint16_t vh3 = vexph3 + vmanth3;
114     if XNN_UNPREDICTABLE(vnonsignw0 > vexpw_max) {
115       vh0 = vnanh;
116     }
117     if XNN_UNPREDICTABLE(vnonsignw1 > vexpw_max) {
118       vh1 = vnanh;
119     }
120     if XNN_UNPREDICTABLE(vnonsignw2 > vexpw_max) {
121       vh2 = vnanh;
122     }
123     if XNN_UNPREDICTABLE(vnonsignw3 > vexpw_max) {
124       vh3 = vnanh;
125     }
126     vh0 |= vsignh0;
127     vh1 |= vsignh1;
128     vh2 |= vsignh2;
129     vh3 |= vsignh3;
130 
131     o[0] = vh0;
132     o[1] = vh1;
133     o[2] = vh2;
134     o[3] = vh3;
135     o += 4;
136   }
137   if XNN_UNLIKELY(n != 0) {
138     do {
139       const float vx = *input++;
140 
141       const float vabsx = fabsf(vx);
142       uint32_t vsignw = float_as_uint32(vx);
143 
144       const uint32_t vnonsignw = float_as_uint32(vabsx);
145       float vf = vabsx * vscale_to_inf;
146 
147       uint32_t vbias = vnonsignw + vexp_bias;
148       vsignw ^= vnonsignw;
149 
150       vf *= vscale_to_zero;
151       vbias &= vexpw_max;
152 
153       vbias = math_max_u32(vbias, vbias_min);
154 
155       vf += uint32_as_float(vbias);
156 
157       const uint32_t vbits = float_as_uint32(vf);
158 
159       const uint16_t vexph = (uint16_t) (vbits >> 13) & vexph_mask;
160       const uint16_t vmanth = (uint16_t) vbits & vmanth_mask;
161       const uint16_t vsignh = (uint16_t) (vsignw >> 16);
162 
163       uint16_t vh = vexph + vmanth;
164       if XNN_UNPREDICTABLE(vnonsignw > vexpw_max) {
165         vh = vnanh;
166       }
167       vh |= vsignh;
168 
169       *o++ = vh;
170 
171       n -= sizeof(float);
172     } while (n != 0);
173   }
174 }
175