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