xref: /aosp_15_r20/external/deqp/framework/delibs/debase/deInt32.c (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Base Portability Library
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief 32-bit integer math.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker DE_BEGIN_EXTERN_C
27*35238bceSAndroid Build Coastguard Worker 
28*35238bceSAndroid Build Coastguard Worker const int8_t g_clzLUT[256] = {
29*35238bceSAndroid Build Coastguard Worker     8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2,
30*35238bceSAndroid Build Coastguard Worker     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
31*35238bceSAndroid Build Coastguard Worker     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
32*35238bceSAndroid Build Coastguard Worker     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33*35238bceSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34*35238bceSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35*35238bceSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker const int8_t g_ctzLUT[256] = {
38*35238bceSAndroid Build Coastguard Worker     8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2,
39*35238bceSAndroid Build Coastguard Worker     0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0,
40*35238bceSAndroid Build Coastguard Worker     1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1,
41*35238bceSAndroid Build Coastguard Worker     0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0,
42*35238bceSAndroid Build Coastguard Worker     2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3,
43*35238bceSAndroid Build Coastguard Worker     0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0,
44*35238bceSAndroid Build Coastguard Worker     1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
45*35238bceSAndroid Build Coastguard Worker 
46*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
47*35238bceSAndroid Build Coastguard Worker  * \brief Compute the reciprocal of an integer.
48*35238bceSAndroid Build Coastguard Worker  * \param a        Input value.
49*35238bceSAndroid Build Coastguard Worker  * \param rcp    Pointer to resulting reciprocal "mantissa" value.
50*35238bceSAndroid Build Coastguard Worker  * \param exp    Pointer to resulting exponent value.
51*35238bceSAndroid Build Coastguard Worker  *
52*35238bceSAndroid Build Coastguard Worker  * The returned value is split into an exponent part and a mantissa part for
53*35238bceSAndroid Build Coastguard Worker  * practical reasons. The actual reciprocal can be computed with the formula:
54*35238bceSAndroid Build Coastguard Worker  * result = exp2(exp) * rcp / (1<<DE_RCP_FRAC_BITS).
55*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
deRcp32(uint32_t a,uint32_t * rcp,int * exp)56*35238bceSAndroid Build Coastguard Worker void deRcp32(uint32_t a, uint32_t *rcp, int *exp)
57*35238bceSAndroid Build Coastguard Worker {
58*35238bceSAndroid Build Coastguard Worker     enum
59*35238bceSAndroid Build Coastguard Worker     {
60*35238bceSAndroid Build Coastguard Worker         RCP_LUT_BITS = 8
61*35238bceSAndroid Build Coastguard Worker     };
62*35238bceSAndroid Build Coastguard Worker     static const uint32_t s_rcpLUT[1 << RCP_LUT_BITS] = {
63*35238bceSAndroid Build Coastguard Worker         0x40000000, 0x3fc03fc0, 0x3f80fe03, 0x3f423954, 0x3f03f03f, 0x3ec62159, 0x3e88cb3c, 0x3e4bec88, 0x3e0f83e0,
64*35238bceSAndroid Build Coastguard Worker         0x3dd38ff0, 0x3d980f66, 0x3d5d00f5, 0x3d226357, 0x3ce8354b, 0x3cae7592, 0x3c7522f3, 0x3c3c3c3c, 0x3c03c03c,
65*35238bceSAndroid Build Coastguard Worker         0x3bcbadc7, 0x3b9403b9, 0x3b5cc0ed, 0x3b25e446, 0x3aef6ca9, 0x3ab95900, 0x3a83a83a, 0x3a4e5947, 0x3a196b1e,
66*35238bceSAndroid Build Coastguard Worker         0x39e4dcb8, 0x39b0ad12, 0x397cdb2c, 0x3949660a, 0x39164cb5, 0x38e38e38, 0x38b129a2, 0x387f1e03, 0x384d6a72,
67*35238bceSAndroid Build Coastguard Worker         0x381c0e07, 0x37eb07dd, 0x37ba5713, 0x3789facb, 0x3759f229, 0x372a3c56, 0x36fad87b, 0x36cbc5c7, 0x369d0369,
68*35238bceSAndroid Build Coastguard Worker         0x366e9095, 0x36406c80, 0x36129663, 0x35e50d79, 0x35b7d0ff, 0x358ae035, 0x355e3a5f, 0x3531dec0, 0x3505cca2,
69*35238bceSAndroid Build Coastguard Worker         0x34da034d, 0x34ae820e, 0x34834834, 0x3458550f, 0x342da7f2, 0x34034034, 0x33d91d2a, 0x33af3e2e, 0x3385a29d,
70*35238bceSAndroid Build Coastguard Worker         0x335c49d4, 0x33333333, 0x330a5e1b, 0x32e1c9f0, 0x32b97617, 0x329161f9, 0x32698cff, 0x3241f693, 0x321a9e24,
71*35238bceSAndroid Build Coastguard Worker         0x31f3831f, 0x31cca4f5, 0x31a6031a, 0x317f9d00, 0x3159721e, 0x313381ec, 0x310dcbe1, 0x30e84f79, 0x30c30c30,
72*35238bceSAndroid Build Coastguard Worker         0x309e0184, 0x30792ef5, 0x30549403, 0x30303030, 0x300c0300, 0x2fe80bfa, 0x2fc44aa2, 0x2fa0be82, 0x2f7d6724,
73*35238bceSAndroid Build Coastguard Worker         0x2f5a4411, 0x2f3754d7, 0x2f149902, 0x2ef21023, 0x2ecfb9c8, 0x2ead9584, 0x2e8ba2e8, 0x2e69e18a, 0x2e4850fe,
74*35238bceSAndroid Build Coastguard Worker         0x2e26f0db, 0x2e05c0b8, 0x2de4c02d, 0x2dc3eed6, 0x2da34c4d, 0x2d82d82d, 0x2d629215, 0x2d4279a2, 0x2d228e75,
75*35238bceSAndroid Build Coastguard Worker         0x2d02d02d, 0x2ce33e6c, 0x2cc3d8d4, 0x2ca49f0a, 0x2c8590b2, 0x2c66ad71, 0x2c47f4ee, 0x2c2966d0, 0x2c0b02c0,
76*35238bceSAndroid Build Coastguard Worker         0x2becc868, 0x2bceb771, 0x2bb0cf87, 0x2b931057, 0x2b75798c, 0x2b580ad6, 0x2b3ac3e2, 0x2b1da461, 0x2b00ac02,
77*35238bceSAndroid Build Coastguard Worker         0x2ae3da78, 0x2ac72f74, 0x2aaaaaaa, 0x2a8e4bcd, 0x2a721291, 0x2a55fead, 0x2a3a0fd5, 0x2a1e45c2, 0x2a02a02a,
78*35238bceSAndroid Build Coastguard Worker         0x29e71ec5, 0x29cbc14e, 0x29b0877d, 0x2995710e, 0x297a7dbb, 0x295fad40, 0x2944ff5a, 0x292a73c7, 0x29100a44,
79*35238bceSAndroid Build Coastguard Worker         0x28f5c28f, 0x28db9c68, 0x28c1978f, 0x28a7b3c5, 0x288df0ca, 0x28744e61, 0x285acc4b, 0x28416a4c, 0x28282828,
80*35238bceSAndroid Build Coastguard Worker         0x280f05a2, 0x27f6027f, 0x27dd1e85, 0x27c45979, 0x27abb323, 0x27932b48, 0x277ac1b2, 0x27627627, 0x274a4870,
81*35238bceSAndroid Build Coastguard Worker         0x27323858, 0x271a45a6, 0x27027027, 0x26eab7a3, 0x26d31be7, 0x26bb9cbf, 0x26a439f6, 0x268cf359, 0x2675c8b6,
82*35238bceSAndroid Build Coastguard Worker         0x265eb9da, 0x2647c694, 0x2630eeb1, 0x261a3202, 0x26039055, 0x25ed097b, 0x25d69d43, 0x25c04b80, 0x25aa1402,
83*35238bceSAndroid Build Coastguard Worker         0x2593f69b, 0x257df31c, 0x2568095a, 0x25523925, 0x253c8253, 0x2526e4b7, 0x25116025, 0x24fbf471, 0x24e6a171,
84*35238bceSAndroid Build Coastguard Worker         0x24d166f9, 0x24bc44e1, 0x24a73afd, 0x24924924, 0x247d6f2e, 0x2468acf1, 0x24540245, 0x243f6f02, 0x242af300,
85*35238bceSAndroid Build Coastguard Worker         0x24168e18, 0x24024024, 0x23ee08fb, 0x23d9e878, 0x23c5de76, 0x23b1eace, 0x239e0d5b, 0x238a45f8, 0x23769480,
86*35238bceSAndroid Build Coastguard Worker         0x2362f8cf, 0x234f72c2, 0x233c0233, 0x2328a701, 0x23156107, 0x23023023, 0x22ef1432, 0x22dc0d12, 0x22c91aa1,
87*35238bceSAndroid Build Coastguard Worker         0x22b63cbe, 0x22a37347, 0x2290be1c, 0x227e1d1a, 0x226b9022, 0x22591713, 0x2246b1ce, 0x22346033, 0x22222222,
88*35238bceSAndroid Build Coastguard Worker         0x220ff77c, 0x21fde021, 0x21ebdbf5, 0x21d9ead7, 0x21c80cab, 0x21b64151, 0x21a488ac, 0x2192e29f, 0x21814f0d,
89*35238bceSAndroid Build Coastguard Worker         0x216fcdd8, 0x215e5ee4, 0x214d0214, 0x213bb74d, 0x212a7e72, 0x21195766, 0x21084210, 0x20f73e53, 0x20e64c14,
90*35238bceSAndroid Build Coastguard Worker         0x20d56b38, 0x20c49ba5, 0x20b3dd40, 0x20a32fef, 0x20929398, 0x20820820, 0x20718d6f, 0x2061236a, 0x2050c9f8,
91*35238bceSAndroid Build Coastguard Worker         0x20408102, 0x2030486c, 0x20202020, 0x20100804};
92*35238bceSAndroid Build Coastguard Worker 
93*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_rcpLUT) == (1 << RCP_LUT_BITS));
94*35238bceSAndroid Build Coastguard Worker 
95*35238bceSAndroid Build Coastguard Worker     int shift           = deClz32(a);
96*35238bceSAndroid Build Coastguard Worker     uint32_t normalized = (uint32_t)a << shift; /* Highest bit is always 1. */
97*35238bceSAndroid Build Coastguard Worker     int lookupNdx =
98*35238bceSAndroid Build Coastguard Worker         (normalized >> (31 - RCP_LUT_BITS)) &
99*35238bceSAndroid Build Coastguard Worker         ((1 << RCP_LUT_BITS) - 1); /* Discard high bit, leave 8 next highest bits to lowest bits of normalized. */
100*35238bceSAndroid Build Coastguard Worker     uint32_t result;
101*35238bceSAndroid Build Coastguard Worker     uint32_t tmp;
102*35238bceSAndroid Build Coastguard Worker 
103*35238bceSAndroid Build Coastguard Worker     /* Must be non-negative. */
104*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(a > 0);
105*35238bceSAndroid Build Coastguard Worker 
106*35238bceSAndroid Build Coastguard Worker     /* First approximation from lookup table. */
107*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(lookupNdx >= 0 && lookupNdx < (1 << RCP_LUT_BITS));
108*35238bceSAndroid Build Coastguard Worker     result = s_rcpLUT[lookupNdx];
109*35238bceSAndroid Build Coastguard Worker 
110*35238bceSAndroid Build Coastguard Worker     /* Newton-Raphson iteration for improved accuracy (has 16 bits of accuracy afterwards). */
111*35238bceSAndroid Build Coastguard Worker     tmp    = deSafeMuluAsr32(result, normalized, 31);
112*35238bceSAndroid Build Coastguard Worker     result = deSafeMuluAsr32(result, (2u << DE_RCP_FRAC_BITS) - tmp, DE_RCP_FRAC_BITS);
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker     /* Second Newton-Raphson iteration (now has full accuracy). */
115*35238bceSAndroid Build Coastguard Worker     tmp    = deSafeMuluAsr32(result, normalized, 31);
116*35238bceSAndroid Build Coastguard Worker     result = deSafeMuluAsr32(result, (2u << DE_RCP_FRAC_BITS) - tmp, DE_RCP_FRAC_BITS);
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker     /* Return results. */
119*35238bceSAndroid Build Coastguard Worker     *rcp = result;
120*35238bceSAndroid Build Coastguard Worker     *exp = 31 - shift;
121*35238bceSAndroid Build Coastguard Worker }
122*35238bceSAndroid Build Coastguard Worker 
123*35238bceSAndroid Build Coastguard Worker DE_END_EXTERN_C
124