1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2022 Imagination Technologies Ltd.
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
5*61046927SAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to deal
6*61046927SAndroid Build Coastguard Worker * in the Software without restriction, including without limitation the rights
7*61046927SAndroid Build Coastguard Worker * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8*61046927SAndroid Build Coastguard Worker * copies of the Software, and to permit persons to whom the Software is
9*61046927SAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18*61046927SAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*61046927SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*61046927SAndroid Build Coastguard Worker * SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include <stddef.h>
25*61046927SAndroid Build Coastguard Worker #include <stdint.h>
26*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker #include "rogue.h"
29*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker /**
32*61046927SAndroid Build Coastguard Worker * \file rogue_constreg.c
33*61046927SAndroid Build Coastguard Worker *
34*61046927SAndroid Build Coastguard Worker * \brief Contains functions to find and allocate constant register values.
35*61046927SAndroid Build Coastguard Worker */
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker /**
38*61046927SAndroid Build Coastguard Worker * \brief Mapping of constant register values and their indices.
39*61046927SAndroid Build Coastguard Worker */
40*61046927SAndroid Build Coastguard Worker typedef struct rogue_constreg_map {
41*61046927SAndroid Build Coastguard Worker uint32_t value;
42*61046927SAndroid Build Coastguard Worker unsigned index;
43*61046927SAndroid Build Coastguard Worker } rogue_constreg_map;
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker #define CONSTREG(VALUE, INDEX) \
46*61046927SAndroid Build Coastguard Worker { \
47*61046927SAndroid Build Coastguard Worker .value = (VALUE), .index = (INDEX), \
48*61046927SAndroid Build Coastguard Worker }
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker /**
51*61046927SAndroid Build Coastguard Worker * \brief Constant register values (sorted for bsearch).
52*61046927SAndroid Build Coastguard Worker */
53*61046927SAndroid Build Coastguard Worker static const rogue_constreg_map const_regs[] = {
54*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000000U, 0U), /* 0 (INT32) / 0.0 (Float) */
55*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000001U, 1U), /* 1 (INT32) */
56*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000002U, 2U), /* 2 (INT32) */
57*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000003U, 3U), /* 3 (INT32) */
58*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000004U, 4U), /* 4 (INT32) */
59*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000005U, 5U), /* 5 (INT32) */
60*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000006U, 6U), /* 6 (INT32) */
61*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000007U, 7U), /* 7 (INT32) */
62*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000008U, 8U), /* 8 (INT32) */
63*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000009U, 9U), /* 9 (INT32) */
64*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000000aU, 10U), /* 10 (INT32) */
65*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000000bU, 11U), /* 11 (INT32) */
66*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000000cU, 12U), /* 12 (INT32) */
67*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000000dU, 13U), /* 13 (INT32) */
68*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000000eU, 14U), /* 14 (INT32) */
69*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000000fU, 15U), /* 15 (INT32) */
70*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000010U, 16U), /* 16 (INT32) */
71*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000011U, 17U), /* 17 (INT32) */
72*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000012U, 18U), /* 18 (INT32) */
73*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000013U, 19U), /* 19 (INT32) */
74*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000014U, 20U), /* 20 (INT32) */
75*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000015U, 21U), /* 21 (INT32) */
76*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000016U, 22U), /* 22 (INT32) */
77*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000017U, 23U), /* 23 (INT32) */
78*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000018U, 24U), /* 24 (INT32) */
79*61046927SAndroid Build Coastguard Worker CONSTREG(0x00000019U, 25U), /* 25 (INT32) */
80*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000001aU, 26U), /* 26 (INT32) */
81*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000001bU, 27U), /* 27 (INT32) */
82*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000001cU, 28U), /* 28 (INT32) */
83*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000001dU, 29U), /* 29 (INT32) */
84*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000001eU, 30U), /* 30 (INT32) */
85*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000001fU, 31U), /* 31 (INT32) */
86*61046927SAndroid Build Coastguard Worker CONSTREG(0x0000007fU, 147U), /* 127 (INT32) */
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker CONSTREG(0x37800000U, 134U), /* 1.0f/65536f */
89*61046927SAndroid Build Coastguard Worker CONSTREG(0x38000000U, 135U), /* 1.0f/32768f */
90*61046927SAndroid Build Coastguard Worker CONSTREG(0x38800000U, 88U), /* float(2^-14) */
91*61046927SAndroid Build Coastguard Worker CONSTREG(0x39000000U, 87U), /* float(2^-13) */
92*61046927SAndroid Build Coastguard Worker CONSTREG(0x39800000U, 86U), /* float(2^-12) */
93*61046927SAndroid Build Coastguard Worker CONSTREG(0x3a000000U, 85U), /* float(2^-11) */
94*61046927SAndroid Build Coastguard Worker CONSTREG(0x3a800000U, 84U), /* float(2^-10) */
95*61046927SAndroid Build Coastguard Worker CONSTREG(0x3b000000U, 83U), /* float(2^-9) */
96*61046927SAndroid Build Coastguard Worker CONSTREG(0x3b4d2e1cU, 136U), /* 0.0031308f */
97*61046927SAndroid Build Coastguard Worker CONSTREG(0x3b800000U, 82U), /* float(2^-8) */
98*61046927SAndroid Build Coastguard Worker CONSTREG(0x3c000000U, 81U), /* float(2^-7) */
99*61046927SAndroid Build Coastguard Worker CONSTREG(0x3c800000U, 80U), /* float(2^-6) */
100*61046927SAndroid Build Coastguard Worker CONSTREG(0x3d000000U, 79U), /* float(2^-5) */
101*61046927SAndroid Build Coastguard Worker CONSTREG(0x3d25aee6U, 156U), /* 0.04045f */
102*61046927SAndroid Build Coastguard Worker CONSTREG(0x3d6147aeU, 140U), /* 0.055f */
103*61046927SAndroid Build Coastguard Worker CONSTREG(0x3d800000U, 78U), /* float(2^-4) */
104*61046927SAndroid Build Coastguard Worker CONSTREG(0x3d9e8391U, 157U), /* 1.0f/12.92f */
105*61046927SAndroid Build Coastguard Worker CONSTREG(0x3e000000U, 77U), /* float(2^-3) */
106*61046927SAndroid Build Coastguard Worker CONSTREG(0x3e2aaaabU, 153U), /* 1/6 */
107*61046927SAndroid Build Coastguard Worker CONSTREG(0x3e800000U, 76U), /* float(2^-2) */
108*61046927SAndroid Build Coastguard Worker CONSTREG(0x3e9a209bU, 145U), /* Log_10(2) */
109*61046927SAndroid Build Coastguard Worker CONSTREG(0x3ea2f983U, 128U), /* Float 1/PI */
110*61046927SAndroid Build Coastguard Worker CONSTREG(0x3eaaaaabU, 152U), /* 1/3 */
111*61046927SAndroid Build Coastguard Worker CONSTREG(0x3ebc5ab2U, 90U), /* 1/e */
112*61046927SAndroid Build Coastguard Worker CONSTREG(0x3ed55555U, 138U), /* 1.0f/2.4f */
113*61046927SAndroid Build Coastguard Worker CONSTREG(0x3f000000U, 75U), /* float(2^-1) */
114*61046927SAndroid Build Coastguard Worker CONSTREG(0x3f22f983U, 129U), /* Float 2/PI */
115*61046927SAndroid Build Coastguard Worker CONSTREG(0x3f317218U, 146U), /* Log_e(2) */
116*61046927SAndroid Build Coastguard Worker CONSTREG(0x3f3504f3U, 92U), /* Float 1/SQRT(2) */
117*61046927SAndroid Build Coastguard Worker CONSTREG(0x3f490fdbU, 93U), /* Float PI/4 */
118*61046927SAndroid Build Coastguard Worker CONSTREG(0x3f72a76fU, 158U), /* 1.0f/1.055f */
119*61046927SAndroid Build Coastguard Worker CONSTREG(0x3f800000U, 64U), /* 1.0f */
120*61046927SAndroid Build Coastguard Worker CONSTREG(0x3f860a92U, 151U), /* Pi/3 */
121*61046927SAndroid Build Coastguard Worker CONSTREG(0x3f870a3dU, 139U), /* 1.055f */
122*61046927SAndroid Build Coastguard Worker CONSTREG(0x3fa2f983U, 130U), /* Float 4/PI */
123*61046927SAndroid Build Coastguard Worker CONSTREG(0x3fb504f3U, 91U), /* Float SQRT(2) */
124*61046927SAndroid Build Coastguard Worker CONSTREG(0x3fb8aa3bU, 155U), /* Log_2(e) */
125*61046927SAndroid Build Coastguard Worker CONSTREG(0x3fc90fdbU, 94U), /* Float PI/2 */
126*61046927SAndroid Build Coastguard Worker CONSTREG(0x40000000U, 65U), /* float(2^1) */
127*61046927SAndroid Build Coastguard Worker CONSTREG(0x4019999aU, 159U), /* 2.4f */
128*61046927SAndroid Build Coastguard Worker CONSTREG(0x402df854U, 89U), /* e */
129*61046927SAndroid Build Coastguard Worker CONSTREG(0x40490fdbU, 95U), /* Float PI */
130*61046927SAndroid Build Coastguard Worker CONSTREG(0x40549a78U, 154U), /* Log_2(10) */
131*61046927SAndroid Build Coastguard Worker CONSTREG(0x40800000U, 66U), /* float(2^2) */
132*61046927SAndroid Build Coastguard Worker CONSTREG(0x40c90fdbU, 131U), /* Float 2*PI */
133*61046927SAndroid Build Coastguard Worker CONSTREG(0x41000000U, 67U), /* float(2^3) */
134*61046927SAndroid Build Coastguard Worker CONSTREG(0x41490fdbU, 132U), /* Float 4*PI */
135*61046927SAndroid Build Coastguard Worker CONSTREG(0x414eb852U, 137U), /* 12.92f */
136*61046927SAndroid Build Coastguard Worker CONSTREG(0x41800000U, 68U), /* float(2^4) */
137*61046927SAndroid Build Coastguard Worker CONSTREG(0x41c90fdbU, 133U), /* Float 8*PI */
138*61046927SAndroid Build Coastguard Worker CONSTREG(0x42000000U, 69U), /* float(2^5) */
139*61046927SAndroid Build Coastguard Worker CONSTREG(0x42800000U, 70U), /* float(2^6) */
140*61046927SAndroid Build Coastguard Worker CONSTREG(0x43000000U, 71U), /* float(2^7) */
141*61046927SAndroid Build Coastguard Worker CONSTREG(0x43800000U, 72U), /* float(2^8) */
142*61046927SAndroid Build Coastguard Worker CONSTREG(0x44000000U, 73U), /* float(2^9) */
143*61046927SAndroid Build Coastguard Worker CONSTREG(0x44800000U, 74U), /* float(2^10) */
144*61046927SAndroid Build Coastguard Worker CONSTREG(0x4b000000U, 149U), /* 2^23 */
145*61046927SAndroid Build Coastguard Worker CONSTREG(0x4b800000U, 150U), /* 2^24 */
146*61046927SAndroid Build Coastguard Worker CONSTREG(0x7f7fffffU, 148U), /* FLT_MAX */
147*61046927SAndroid Build Coastguard Worker CONSTREG(0x7f800000U, 142U), /* Infinity */
148*61046927SAndroid Build Coastguard Worker CONSTREG(0x7fff7fffU, 144U), /* ARGB1555 mask */
149*61046927SAndroid Build Coastguard Worker CONSTREG(0x80000000U, 141U), /* -0.0f */
150*61046927SAndroid Build Coastguard Worker CONSTREG(0xffffffffU, 143U), /* -1 */
151*61046927SAndroid Build Coastguard Worker };
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker #undef CONSTREG
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker /**
156*61046927SAndroid Build Coastguard Worker * \brief Comparison function for bsearch() to support rogue_constreg_map.
157*61046927SAndroid Build Coastguard Worker *
158*61046927SAndroid Build Coastguard Worker * \param[in] lhs The left hand side of the comparison.
159*61046927SAndroid Build Coastguard Worker * \param[in] rhs The right hand side of the comparison.
160*61046927SAndroid Build Coastguard Worker * \return 0 if (lhs == rhs), -1 if (lhs < rhs), 1 if (lhs > rhs).
161*61046927SAndroid Build Coastguard Worker */
constreg_cmp(const void * lhs,const void * rhs)162*61046927SAndroid Build Coastguard Worker static int constreg_cmp(const void *lhs, const void *rhs)
163*61046927SAndroid Build Coastguard Worker {
164*61046927SAndroid Build Coastguard Worker const rogue_constreg_map *l = lhs;
165*61046927SAndroid Build Coastguard Worker const rogue_constreg_map *r = rhs;
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard Worker if (l->value < r->value)
168*61046927SAndroid Build Coastguard Worker return -1;
169*61046927SAndroid Build Coastguard Worker else if (l->value > r->value)
170*61046927SAndroid Build Coastguard Worker return 1;
171*61046927SAndroid Build Coastguard Worker
172*61046927SAndroid Build Coastguard Worker return 0;
173*61046927SAndroid Build Coastguard Worker }
174*61046927SAndroid Build Coastguard Worker
175*61046927SAndroid Build Coastguard Worker /**
176*61046927SAndroid Build Coastguard Worker * \brief Determines whether a given value exists in a constant register.
177*61046927SAndroid Build Coastguard Worker *
178*61046927SAndroid Build Coastguard Worker * \param[in] imm The immediate value required.
179*61046927SAndroid Build Coastguard Worker * \return The index of the constant register containing the value, or
180*61046927SAndroid Build Coastguard Worker * ROGUE_NO_CONST_REG if the value is not found.
181*61046927SAndroid Build Coastguard Worker */
182*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_constreg_lookup(rogue_imm_t imm)183*61046927SAndroid Build Coastguard Worker unsigned rogue_constreg_lookup(rogue_imm_t imm)
184*61046927SAndroid Build Coastguard Worker {
185*61046927SAndroid Build Coastguard Worker rogue_constreg_map constreg_target = {
186*61046927SAndroid Build Coastguard Worker .value = imm.u32,
187*61046927SAndroid Build Coastguard Worker };
188*61046927SAndroid Build Coastguard Worker const rogue_constreg_map *constreg;
189*61046927SAndroid Build Coastguard Worker
190*61046927SAndroid Build Coastguard Worker constreg = bsearch(&constreg_target,
191*61046927SAndroid Build Coastguard Worker const_regs,
192*61046927SAndroid Build Coastguard Worker ARRAY_SIZE(const_regs),
193*61046927SAndroid Build Coastguard Worker sizeof(rogue_constreg_map),
194*61046927SAndroid Build Coastguard Worker constreg_cmp);
195*61046927SAndroid Build Coastguard Worker if (!constreg)
196*61046927SAndroid Build Coastguard Worker return ROGUE_NO_CONST_REG;
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker return constreg->index;
199*61046927SAndroid Build Coastguard Worker }
200