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