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