xref: /aosp_15_r20/external/XNNPACK/src/u8-lut32norm/scalar.c (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1*4bdc9457SAndroid Build Coastguard Worker // Copyright (c) Facebook, Inc. and its affiliates.
2*4bdc9457SAndroid Build Coastguard Worker // All rights reserved.
3*4bdc9457SAndroid Build Coastguard Worker //
4*4bdc9457SAndroid Build Coastguard Worker // Copyright 2019 Google LLC
5*4bdc9457SAndroid Build Coastguard Worker //
6*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the
7*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree.
8*4bdc9457SAndroid Build Coastguard Worker 
9*4bdc9457SAndroid Build Coastguard Worker #include <assert.h>
10*4bdc9457SAndroid Build Coastguard Worker 
11*4bdc9457SAndroid Build Coastguard Worker #include <fxdiv.h>
12*4bdc9457SAndroid Build Coastguard Worker 
13*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/lut.h>
14*4bdc9457SAndroid Build Coastguard Worker 
15*4bdc9457SAndroid Build Coastguard Worker 
compute_sum(size_t n,const uint8_t * x,const uint32_t * t)16*4bdc9457SAndroid Build Coastguard Worker static inline uint32_t compute_sum(
17*4bdc9457SAndroid Build Coastguard Worker     size_t n,
18*4bdc9457SAndroid Build Coastguard Worker     const uint8_t* x,
19*4bdc9457SAndroid Build Coastguard Worker     const uint32_t* t)
20*4bdc9457SAndroid Build Coastguard Worker {
21*4bdc9457SAndroid Build Coastguard Worker   assert(n != 0);
22*4bdc9457SAndroid Build Coastguard Worker 
23*4bdc9457SAndroid Build Coastguard Worker   uint32_t vsum = 0;
24*4bdc9457SAndroid Build Coastguard Worker   do {
25*4bdc9457SAndroid Build Coastguard Worker     const size_t vx = *x++;
26*4bdc9457SAndroid Build Coastguard Worker     vsum += t[vx];
27*4bdc9457SAndroid Build Coastguard Worker   } while (--n != 0);
28*4bdc9457SAndroid Build Coastguard Worker   return vsum;
29*4bdc9457SAndroid Build Coastguard Worker }
30*4bdc9457SAndroid Build Coastguard Worker 
xnn_u8_lut32norm_ukernel__scalar(size_t n,const uint8_t * x,const uint32_t * t,uint8_t * y)31*4bdc9457SAndroid Build Coastguard Worker void xnn_u8_lut32norm_ukernel__scalar(
32*4bdc9457SAndroid Build Coastguard Worker     size_t n,
33*4bdc9457SAndroid Build Coastguard Worker     const uint8_t* x,
34*4bdc9457SAndroid Build Coastguard Worker     const uint32_t* t,
35*4bdc9457SAndroid Build Coastguard Worker     uint8_t* y)
36*4bdc9457SAndroid Build Coastguard Worker {
37*4bdc9457SAndroid Build Coastguard Worker   assert(n != 0);
38*4bdc9457SAndroid Build Coastguard Worker 
39*4bdc9457SAndroid Build Coastguard Worker   const uint32_t vsum = compute_sum(n, x, t);
40*4bdc9457SAndroid Build Coastguard Worker   assert(vsum != 0);
41*4bdc9457SAndroid Build Coastguard Worker 
42*4bdc9457SAndroid Build Coastguard Worker   struct fxdiv_divisor_uint32_t vsum_divisor = fxdiv_init_uint32_t(vsum);
43*4bdc9457SAndroid Build Coastguard Worker   const uint32_t vrounding = (vsum >> 1);
44*4bdc9457SAndroid Build Coastguard Worker   do {
45*4bdc9457SAndroid Build Coastguard Worker     const size_t vx = *x++;
46*4bdc9457SAndroid Build Coastguard Worker     const uint32_t vt = t[vx];
47*4bdc9457SAndroid Build Coastguard Worker     const uint32_t vq = fxdiv_quotient_uint32_t((vt << 8) + vrounding, vsum_divisor);
48*4bdc9457SAndroid Build Coastguard Worker     const uint8_t vy = vq > 255 ? UINT8_C(255) : (uint8_t) vq;
49*4bdc9457SAndroid Build Coastguard Worker     *y++ = vy;
50*4bdc9457SAndroid Build Coastguard Worker   } while (--n != 0);
51*4bdc9457SAndroid Build Coastguard Worker }
52