1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (C) 2019 Connor Abbott <cwabbott0@gmail.com>
3bf215546Sopenharmony_ci * Copyright (C) 2019 Lyude Paul <thatslyude@gmail.com>
4bf215546Sopenharmony_ci * Copyright (C) 2019 Ryan Houdek <Sonicadvance1@gmail.com>
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
12bf215546Sopenharmony_ci *
13bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
14bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
15bf215546Sopenharmony_ci * Software.
16bf215546Sopenharmony_ci *
17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23bf215546Sopenharmony_ci * SOFTWARE.
24bf215546Sopenharmony_ci */
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#ifndef __bifrost_h__
27bf215546Sopenharmony_ci#define __bifrost_h__
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include <stdint.h>
30bf215546Sopenharmony_ci#include <stdbool.h>
31bf215546Sopenharmony_ci#include <string.h>
32bf215546Sopenharmony_ci#include <assert.h>
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#ifdef __cplusplus
35bf215546Sopenharmony_ciextern "C" {
36bf215546Sopenharmony_ci#endif
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci#define BIFROST_DBG_MSGS        0x0001
39bf215546Sopenharmony_ci#define BIFROST_DBG_SHADERS     0x0002
40bf215546Sopenharmony_ci#define BIFROST_DBG_SHADERDB    0x0004
41bf215546Sopenharmony_ci#define BIFROST_DBG_VERBOSE     0x0008
42bf215546Sopenharmony_ci#define BIFROST_DBG_INTERNAL    0x0010
43bf215546Sopenharmony_ci#define BIFROST_DBG_NOSCHED     0x0020
44bf215546Sopenharmony_ci#define BIFROST_DBG_INORDER     0x0040
45bf215546Sopenharmony_ci#define BIFROST_DBG_NOVALIDATE  0x0080
46bf215546Sopenharmony_ci#define BIFROST_DBG_NOOPT       0x0100
47bf215546Sopenharmony_ci#define BIFROST_DBG_NOIDVS      0x0200
48bf215546Sopenharmony_ci#define BIFROST_DBG_NOSB        0x0400
49bf215546Sopenharmony_ci#define BIFROST_DBG_NOPRELOAD   0x0800
50bf215546Sopenharmony_ci#define BIFROST_DBG_SPILL       0x1000
51bf215546Sopenharmony_ci#define BIFROST_DBG_NOPSCHED    0x2000
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ciextern int bifrost_debug;
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_cienum bifrost_message_type {
56bf215546Sopenharmony_ci        BIFROST_MESSAGE_NONE       = 0,
57bf215546Sopenharmony_ci        BIFROST_MESSAGE_VARYING    = 1,
58bf215546Sopenharmony_ci        BIFROST_MESSAGE_ATTRIBUTE  = 2,
59bf215546Sopenharmony_ci        BIFROST_MESSAGE_TEX        = 3,
60bf215546Sopenharmony_ci        BIFROST_MESSAGE_VARTEX     = 4,
61bf215546Sopenharmony_ci        BIFROST_MESSAGE_LOAD       = 5,
62bf215546Sopenharmony_ci        BIFROST_MESSAGE_STORE      = 6,
63bf215546Sopenharmony_ci        BIFROST_MESSAGE_ATOMIC     = 7,
64bf215546Sopenharmony_ci        BIFROST_MESSAGE_BARRIER    = 8,
65bf215546Sopenharmony_ci        BIFROST_MESSAGE_BLEND      = 9,
66bf215546Sopenharmony_ci        BIFROST_MESSAGE_TILE       = 10,
67bf215546Sopenharmony_ci        /* type 11 reserved */
68bf215546Sopenharmony_ci        BIFROST_MESSAGE_Z_STENCIL  = 12,
69bf215546Sopenharmony_ci        BIFROST_MESSAGE_ATEST      = 13,
70bf215546Sopenharmony_ci        BIFROST_MESSAGE_JOB        = 14,
71bf215546Sopenharmony_ci        BIFROST_MESSAGE_64BIT      = 15
72bf215546Sopenharmony_ci};
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_cienum bifrost_ftz {
75bf215546Sopenharmony_ci        BIFROST_FTZ_DISABLE = 0,
76bf215546Sopenharmony_ci        BIFROST_FTZ_DX11 = 1,
77bf215546Sopenharmony_ci        BIFROST_FTZ_ALWAYS = 2,
78bf215546Sopenharmony_ci        BIFROST_FTZ_ABRUPT = 3
79bf215546Sopenharmony_ci};
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_cienum bifrost_exceptions {
82bf215546Sopenharmony_ci        BIFROST_EXCEPTIONS_ENABLED = 0,
83bf215546Sopenharmony_ci        BIFROST_EXCEPTIONS_DISABLED = 1,
84bf215546Sopenharmony_ci        BIFROST_EXCEPTIONS_PRECISE_DIVISION = 2,
85bf215546Sopenharmony_ci        BIFROST_EXCEPTIONS_PRECISE_SQRT = 3,
86bf215546Sopenharmony_ci};
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci/* Describes clause flow control, with respect to control flow and branch
89bf215546Sopenharmony_ci * reconvergence.
90bf215546Sopenharmony_ci *
91bf215546Sopenharmony_ci * Control flow may be considered back-to-back (execute clauses back-to-back),
92bf215546Sopenharmony_ci * non-back-to-back (switch warps after clause before the next clause), write
93bf215546Sopenharmony_ci * elision (back-to-back and elide register slot #3 write from the clause), or
94bf215546Sopenharmony_ci * end of shader.
95bf215546Sopenharmony_ci *
96bf215546Sopenharmony_ci * Branch reconvergence may be disabled, enabled unconditionally, or enabled
97bf215546Sopenharmony_ci * based on the program counter. A clause requires reconvergence if it has a
98bf215546Sopenharmony_ci * successor that can be executed without first executing the clause itself.
99bf215546Sopenharmony_ci * Separate iterations of a loop are treated separately here, so it is also the
100bf215546Sopenharmony_ci * case for a loop exit where the iteration count is not warp-invariant.
101bf215546Sopenharmony_ci *
102bf215546Sopenharmony_ci */
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_cienum bifrost_flow {
105bf215546Sopenharmony_ci        /* End-of-shader */
106bf215546Sopenharmony_ci        BIFROST_FLOW_END = 0,
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci        /* Non back-to-back, PC-encoded reconvergence */
109bf215546Sopenharmony_ci        BIFROST_FLOW_NBTB_PC = 1,
110bf215546Sopenharmony_ci
111bf215546Sopenharmony_ci        /* Non back-to-back, unconditional reconvergence */
112bf215546Sopenharmony_ci        BIFROST_FLOW_NBTB_UNCONDITIONAL = 2,
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci        /* Non back-to-back, no reconvergence */
115bf215546Sopenharmony_ci        BIFROST_FLOW_NBTB = 3,
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci        /* Back-to-back, unconditional reconvergence */
118bf215546Sopenharmony_ci        BIFROST_FLOW_BTB_UNCONDITIONAL = 4,
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci        /* Back-to-back, no reconvergence */
121bf215546Sopenharmony_ci        BIFROST_FLOW_BTB_NONE = 5,
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci        /* Write elision, unconditional reconvergence */
124bf215546Sopenharmony_ci        BIFROST_FLOW_WE_UNCONDITIONAL = 6,
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci        /* Write elision, no reconvergence */
127bf215546Sopenharmony_ci        BIFROST_FLOW_WE = 7,
128bf215546Sopenharmony_ci};
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_cienum bifrost_slot {
131bf215546Sopenharmony_ci        /* 0-5 are general purpose */
132bf215546Sopenharmony_ci        BIFROST_SLOT_ELDEST_DEPTH = 6,
133bf215546Sopenharmony_ci        BIFROST_SLOT_ELDEST_COLOUR = 7,
134bf215546Sopenharmony_ci};
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_cistruct bifrost_header {
137bf215546Sopenharmony_ci        /* Reserved */
138bf215546Sopenharmony_ci        unsigned zero1 : 5;
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci        /* Flush-to-zero mode, leave zero for GL */
141bf215546Sopenharmony_ci        enum bifrost_ftz flush_to_zero : 2;
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci        /* Convert any infinite result of any floating-point operation to the
144bf215546Sopenharmony_ci         * biggest representable number */
145bf215546Sopenharmony_ci        unsigned suppress_inf: 1;
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci        /* Convert NaN to +0.0 */
148bf215546Sopenharmony_ci        unsigned suppress_nan : 1;
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci        /* Floating-point excception handling mode */
151bf215546Sopenharmony_ci        enum bifrost_exceptions float_exceptions : 2;
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci        /* Enum describing the flow control, which matters for handling
154bf215546Sopenharmony_ci         * divergence and reconvergence efficiently */
155bf215546Sopenharmony_ci        enum bifrost_flow flow_control : 3;
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci        /* Reserved */
158bf215546Sopenharmony_ci        unsigned zero2 : 1;
159bf215546Sopenharmony_ci
160bf215546Sopenharmony_ci        /* Terminate discarded threads, rather than continuing execution. Set
161bf215546Sopenharmony_ci         * for fragment shaders for standard GL behaviour of DISCARD. Also in a
162bf215546Sopenharmony_ci         * fragment shader, this disables helper invocations, so cannot be used
163bf215546Sopenharmony_ci         * in a shader that requires derivatives or texture LOD computation */
164bf215546Sopenharmony_ci        unsigned terminate_discarded_threads : 1;
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci        /* If set, the hardware may prefetch the next clause. If false, the
167bf215546Sopenharmony_ci         * hardware may not. Clear for unconditional branches. */
168bf215546Sopenharmony_ci        unsigned next_clause_prefetch : 1;
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_ci        /* If set, a barrier will be inserted after the clause waiting for all
171bf215546Sopenharmony_ci         * message passing instructions to read their staging registers, such
172bf215546Sopenharmony_ci         * that it is safe for the next clause to write them. */
173bf215546Sopenharmony_ci        unsigned staging_barrier: 1;
174bf215546Sopenharmony_ci        unsigned staging_register : 6;
175bf215546Sopenharmony_ci
176bf215546Sopenharmony_ci        /* Slots to wait on and slot to be used for message passing
177bf215546Sopenharmony_ci         * instructions respectively */
178bf215546Sopenharmony_ci        unsigned dependency_wait : 8;
179bf215546Sopenharmony_ci        unsigned dependency_slot : 3;
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci        enum bifrost_message_type message_type : 5;
182bf215546Sopenharmony_ci        enum bifrost_message_type next_message_type : 5;
183bf215546Sopenharmony_ci} __attribute__((packed));
184bf215546Sopenharmony_ci
185bf215546Sopenharmony_cienum bifrost_packed_src {
186bf215546Sopenharmony_ci        BIFROST_SRC_PORT0    = 0,
187bf215546Sopenharmony_ci        BIFROST_SRC_PORT1    = 1,
188bf215546Sopenharmony_ci        BIFROST_SRC_PORT2    = 2,
189bf215546Sopenharmony_ci        BIFROST_SRC_STAGE    = 3,
190bf215546Sopenharmony_ci        BIFROST_SRC_FAU_LO   = 4,
191bf215546Sopenharmony_ci        BIFROST_SRC_FAU_HI   = 5,
192bf215546Sopenharmony_ci        BIFROST_SRC_PASS_FMA = 6,
193bf215546Sopenharmony_ci        BIFROST_SRC_PASS_ADD = 7,
194bf215546Sopenharmony_ci};
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_cistruct bifrost_fma_inst {
197bf215546Sopenharmony_ci        unsigned src0 : 3;
198bf215546Sopenharmony_ci        unsigned op   : 20;
199bf215546Sopenharmony_ci} __attribute__((packed));
200bf215546Sopenharmony_ci
201bf215546Sopenharmony_cistruct bifrost_add_inst {
202bf215546Sopenharmony_ci        unsigned src0 : 3;
203bf215546Sopenharmony_ci        unsigned op   : 17;
204bf215546Sopenharmony_ci} __attribute__((packed));
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_cienum branch_bit_size {
207bf215546Sopenharmony_ci        BR_SIZE_32 = 0,
208bf215546Sopenharmony_ci        BR_SIZE_16XX = 1,
209bf215546Sopenharmony_ci        BR_SIZE_16YY = 2,
210bf215546Sopenharmony_ci        // For the above combinations of bitsize and location, an extra bit is
211bf215546Sopenharmony_ci        // encoded via comparing the sources. The only possible source of ambiguity
212bf215546Sopenharmony_ci        // would be if the sources were the same, but then the branch condition
213bf215546Sopenharmony_ci        // would be always true or always false anyways, so we can ignore it. But
214bf215546Sopenharmony_ci        // this no longer works when comparing the y component to the x component,
215bf215546Sopenharmony_ci        // since it's valid to compare the y component of a source against its own
216bf215546Sopenharmony_ci        // x component. Instead, the extra bit is encoded via an extra bitsize.
217bf215546Sopenharmony_ci        BR_SIZE_16YX0 = 3,
218bf215546Sopenharmony_ci        BR_SIZE_16YX1 = 4,
219bf215546Sopenharmony_ci        BR_SIZE_32_AND_16X = 5,
220bf215546Sopenharmony_ci        BR_SIZE_32_AND_16Y = 6,
221bf215546Sopenharmony_ci        // Used for comparisons with zero and always-true, see below. I think this
222bf215546Sopenharmony_ci        // only works for integer comparisons.
223bf215546Sopenharmony_ci        BR_SIZE_ZERO = 7,
224bf215546Sopenharmony_ci};
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_cistruct bifrost_regs {
227bf215546Sopenharmony_ci        unsigned fau_idx : 8;
228bf215546Sopenharmony_ci        unsigned reg3 : 6;
229bf215546Sopenharmony_ci        unsigned reg2 : 6;
230bf215546Sopenharmony_ci        unsigned reg0 : 5;
231bf215546Sopenharmony_ci        unsigned reg1 : 6;
232bf215546Sopenharmony_ci        unsigned ctrl : 4;
233bf215546Sopenharmony_ci} __attribute__((packed));
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci#define BIFROST_FMTC_CONSTANTS       0b0011
236bf215546Sopenharmony_ci#define BIFROST_FMTC_FINAL           0b0111
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_cistruct bifrost_fmt_constant {
239bf215546Sopenharmony_ci        unsigned pos : 4;
240bf215546Sopenharmony_ci        unsigned tag : 4;
241bf215546Sopenharmony_ci        uint64_t imm_1 : 60;
242bf215546Sopenharmony_ci        uint64_t imm_2 : 60;
243bf215546Sopenharmony_ci} __attribute__((packed));
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_ci/* Clause formats, encoded in a table */
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_cienum bi_clause_subword {
248bf215546Sopenharmony_ci        /* Literal 3-bit values */
249bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_LITERAL_0 = 0,
250bf215546Sopenharmony_ci        /* etc */
251bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_LITERAL_7 = 7,
252bf215546Sopenharmony_ci
253bf215546Sopenharmony_ci        /* The value of the corresponding tuple in the corresponding bits */
254bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_TUPLE_0 = 8,
255bf215546Sopenharmony_ci        /* etc */
256bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_TUPLE_7 = 15,
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_ci        /* Clause header */
259bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_HEADER = 16,
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci        /* Leave zero, but semantically distinct from literal 0 */
262bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_RESERVED = 17,
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_ci        /* Embedded constant 0 */
265bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_CONSTANT = 18,
266bf215546Sopenharmony_ci
267bf215546Sopenharmony_ci        /* M bits controlling modifier for the constant */
268bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_M = 19,
269bf215546Sopenharmony_ci
270bf215546Sopenharmony_ci        /* Z bit: 1 to begin encoding constants, 0 to terminate the clause */
271bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_Z = 20,
272bf215546Sopenharmony_ci
273bf215546Sopenharmony_ci        /* Upper 3-bits of a given tuple and zero extended */
274bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_UPPER_0 = 32,
275bf215546Sopenharmony_ci        /* etc */
276bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_UPPER_7 = BI_CLAUSE_SUBWORD_UPPER_0 + 7,
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ci        /* Upper 3-bits of two tuples, concatenated and zero-extended */
279bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_UPPER_23 = BI_CLAUSE_SUBWORD_UPPER_0 + 23,
280bf215546Sopenharmony_ci        BI_CLAUSE_SUBWORD_UPPER_56 = BI_CLAUSE_SUBWORD_UPPER_0 + 56,
281bf215546Sopenharmony_ci};
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci#define L(x) ((enum bi_clause_subword)(BI_CLAUSE_SUBWORD_LITERAL_0 + x))
284bf215546Sopenharmony_ci#define U(x) ((enum bi_clause_subword)(BI_CLAUSE_SUBWORD_UPPER_0 + x))
285bf215546Sopenharmony_ci#define T(x) ((enum bi_clause_subword)(BI_CLAUSE_SUBWORD_TUPLE_0 + x))
286bf215546Sopenharmony_ci#define EC   BI_CLAUSE_SUBWORD_CONSTANT
287bf215546Sopenharmony_ci#define M    BI_CLAUSE_SUBWORD_M
288bf215546Sopenharmony_ci#define Z    BI_CLAUSE_SUBWORD_Z
289bf215546Sopenharmony_ci#define H    BI_CLAUSE_SUBWORD_HEADER
290bf215546Sopenharmony_ci#define R    BI_CLAUSE_SUBWORD_RESERVED
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_cistruct bi_clause_format {
293bf215546Sopenharmony_ci        unsigned format; /* format number */
294bf215546Sopenharmony_ci        unsigned pos; /* index in the clause */
295bf215546Sopenharmony_ci        enum bi_clause_subword tag_1; /* 2-bits */
296bf215546Sopenharmony_ci        enum bi_clause_subword tag_2; /* 3-bits */
297bf215546Sopenharmony_ci        enum bi_clause_subword tag_3; /* 3-bits */
298bf215546Sopenharmony_ci        enum bi_clause_subword s0_s3; /* 60 bits */
299bf215546Sopenharmony_ci        enum bi_clause_subword s4; /* 15 bits */
300bf215546Sopenharmony_ci        enum bi_clause_subword s5_s6; /* 30 bits */
301bf215546Sopenharmony_ci        enum bi_clause_subword s7; /* 15 bits */
302bf215546Sopenharmony_ci};
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_cistatic const struct bi_clause_format bi_clause_formats[] = {
305bf215546Sopenharmony_ci        {  0, 0, L(0), L(5), U(0), T(0), T(0), H,    H     },
306bf215546Sopenharmony_ci        {  0, 0, Z,    L(1), U(0), T(0), T(0), H,    H     },
307bf215546Sopenharmony_ci        {  1, 1, Z,    L(0), L(3), T(1), T(1), R,    U(1)  },
308bf215546Sopenharmony_ci        {  2, 1, L(0), L(4), U(1), T(1), T(1), T(2), T(2)  },
309bf215546Sopenharmony_ci        {  3, 2, Z,    L(0), L(4), EC,   M,    T(2), U(2)  },
310bf215546Sopenharmony_ci        {  4, 2, L(0), L(0), L(1), T(3), T(3), T(2), U(23) },
311bf215546Sopenharmony_ci        {  4, 2, Z,    L(0), L(5), T(3), T(3), T(2), U(23) },
312bf215546Sopenharmony_ci        {  5, 2, L(2), U(3), U(2), T(3), T(3), T(2), EC    },
313bf215546Sopenharmony_ci        {  6, 3, Z,    L(2), U(4), T(4), T(4), EC,   EC    },
314bf215546Sopenharmony_ci        {  7, 3, L(1), L(4), U(4), T(4), T(4), T(5), T(5)  },
315bf215546Sopenharmony_ci        {  8, 4, Z,    L(0), L(6), EC,   M,    T(5), U(5)  },
316bf215546Sopenharmony_ci        {  9, 4, Z,    L(0), L(7), T(6), T(6), T(5), U(56) },
317bf215546Sopenharmony_ci        { 10, 4, L(3), U(6), U(5), T(6), T(6), T(5), EC    },
318bf215546Sopenharmony_ci        { 11, 5, Z,    L(3), U(7), T(7), T(7), EC,   EC    },
319bf215546Sopenharmony_ci};
320bf215546Sopenharmony_ci
321bf215546Sopenharmony_ci#undef L
322bf215546Sopenharmony_ci#undef U
323bf215546Sopenharmony_ci#undef T
324bf215546Sopenharmony_ci#undef EC
325bf215546Sopenharmony_ci#undef M
326bf215546Sopenharmony_ci#undef Z
327bf215546Sopenharmony_ci#undef H
328bf215546Sopenharmony_ci#undef R
329bf215546Sopenharmony_ci
330bf215546Sopenharmony_ci/* 32-bit modes for slots 2/3, as encoded in the register block. Other values
331bf215546Sopenharmony_ci * are reserved. First part specifies behaviour of slot 2 (Idle, Read, Write
332bf215546Sopenharmony_ci * Full, Write Low, Write High), second part behaviour of slot 3, and the last
333bf215546Sopenharmony_ci * part specifies the source for the write (FMA, ADD, or MIX for FMA/ADD).
334bf215546Sopenharmony_ci *
335bf215546Sopenharmony_ci * IDLE is a special mode disabling both slots, except for the first
336bf215546Sopenharmony_ci * instruction in the clause which uses IDLE_1 for the same purpose.
337bf215546Sopenharmony_ci *
338bf215546Sopenharmony_ci * All fields 0 used as sentinel for reserved encoding, so IDLE(_1) have FMA
339bf215546Sopenharmony_ci * set (and ignored) as a placeholder to differentiate from reserved.
340bf215546Sopenharmony_ci */
341bf215546Sopenharmony_cienum bifrost_reg_mode {
342bf215546Sopenharmony_ci        BIFROST_R_WL_FMA  = 1,
343bf215546Sopenharmony_ci        BIFROST_R_WH_FMA  = 2,
344bf215546Sopenharmony_ci        BIFROST_R_W_FMA   = 3,
345bf215546Sopenharmony_ci        BIFROST_R_WL_ADD  = 4,
346bf215546Sopenharmony_ci        BIFROST_R_WH_ADD  = 5,
347bf215546Sopenharmony_ci        BIFROST_R_W_ADD   = 6,
348bf215546Sopenharmony_ci        BIFROST_WL_WL_ADD = 7,
349bf215546Sopenharmony_ci        BIFROST_WL_WH_ADD = 8,
350bf215546Sopenharmony_ci        BIFROST_WL_W_ADD  = 9,
351bf215546Sopenharmony_ci        BIFROST_WH_WL_ADD = 10,
352bf215546Sopenharmony_ci        BIFROST_WH_WH_ADD = 11,
353bf215546Sopenharmony_ci        BIFROST_WH_W_ADD  = 12,
354bf215546Sopenharmony_ci        BIFROST_W_WL_ADD  = 13,
355bf215546Sopenharmony_ci        BIFROST_W_WH_ADD  = 14,
356bf215546Sopenharmony_ci        BIFROST_W_W_ADD   = 15,
357bf215546Sopenharmony_ci        BIFROST_IDLE_1    = 16,
358bf215546Sopenharmony_ci        BIFROST_I_W_FMA   = 17,
359bf215546Sopenharmony_ci        BIFROST_I_WL_FMA  = 18,
360bf215546Sopenharmony_ci        BIFROST_I_WH_FMA  = 19,
361bf215546Sopenharmony_ci        BIFROST_R_I       = 20,
362bf215546Sopenharmony_ci        BIFROST_I_W_ADD   = 21,
363bf215546Sopenharmony_ci        BIFROST_I_WL_ADD  = 22,
364bf215546Sopenharmony_ci        BIFROST_I_WH_ADD  = 23,
365bf215546Sopenharmony_ci        BIFROST_WL_WH_MIX = 24,
366bf215546Sopenharmony_ci        BIFROST_WH_WL_MIX = 26,
367bf215546Sopenharmony_ci        BIFROST_IDLE      = 27,
368bf215546Sopenharmony_ci};
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_cienum bifrost_reg_op {
371bf215546Sopenharmony_ci        BIFROST_OP_IDLE = 0,
372bf215546Sopenharmony_ci        BIFROST_OP_READ = 1,
373bf215546Sopenharmony_ci        BIFROST_OP_WRITE = 2,
374bf215546Sopenharmony_ci        BIFROST_OP_WRITE_LO = 3,
375bf215546Sopenharmony_ci        BIFROST_OP_WRITE_HI = 4,
376bf215546Sopenharmony_ci};
377bf215546Sopenharmony_ci
378bf215546Sopenharmony_cistruct bifrost_reg_ctrl_23 {
379bf215546Sopenharmony_ci        enum bifrost_reg_op slot2;
380bf215546Sopenharmony_ci        enum bifrost_reg_op slot3;
381bf215546Sopenharmony_ci        bool slot3_fma;
382bf215546Sopenharmony_ci};
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ci#ifndef __cplusplus
385bf215546Sopenharmony_cistatic const struct bifrost_reg_ctrl_23 bifrost_reg_ctrl_lut[32] = {
386bf215546Sopenharmony_ci        [BIFROST_R_WL_FMA]  = { BIFROST_OP_READ,     BIFROST_OP_WRITE_LO, true },
387bf215546Sopenharmony_ci        [BIFROST_R_WH_FMA]  = { BIFROST_OP_READ,     BIFROST_OP_WRITE_HI, true },
388bf215546Sopenharmony_ci        [BIFROST_R_W_FMA]   = { BIFROST_OP_READ,     BIFROST_OP_WRITE,    true },
389bf215546Sopenharmony_ci        [BIFROST_R_WL_ADD]  = { BIFROST_OP_READ,     BIFROST_OP_WRITE_LO, false },
390bf215546Sopenharmony_ci        [BIFROST_R_WH_ADD]  = { BIFROST_OP_READ,     BIFROST_OP_WRITE_HI, false },
391bf215546Sopenharmony_ci        [BIFROST_R_W_ADD]   = { BIFROST_OP_READ,     BIFROST_OP_WRITE,    false },
392bf215546Sopenharmony_ci        [BIFROST_WL_WL_ADD] = { BIFROST_OP_WRITE_LO, BIFROST_OP_WRITE_LO, false },
393bf215546Sopenharmony_ci        [BIFROST_WL_WH_ADD] = { BIFROST_OP_WRITE_LO, BIFROST_OP_WRITE_HI, false },
394bf215546Sopenharmony_ci        [BIFROST_WL_W_ADD]  = { BIFROST_OP_WRITE_LO, BIFROST_OP_WRITE,    false },
395bf215546Sopenharmony_ci        [BIFROST_WH_WL_ADD] = { BIFROST_OP_WRITE_HI, BIFROST_OP_WRITE_LO, false },
396bf215546Sopenharmony_ci        [BIFROST_WH_WH_ADD] = { BIFROST_OP_WRITE_HI, BIFROST_OP_WRITE_HI, false },
397bf215546Sopenharmony_ci        [BIFROST_WH_W_ADD]  = { BIFROST_OP_WRITE_HI, BIFROST_OP_WRITE,    false },
398bf215546Sopenharmony_ci        [BIFROST_W_WL_ADD]  = { BIFROST_OP_WRITE,    BIFROST_OP_WRITE_LO, false },
399bf215546Sopenharmony_ci        [BIFROST_W_WH_ADD]  = { BIFROST_OP_WRITE,    BIFROST_OP_WRITE_HI, false },
400bf215546Sopenharmony_ci        [BIFROST_W_W_ADD]   = { BIFROST_OP_WRITE,    BIFROST_OP_WRITE,    false },
401bf215546Sopenharmony_ci        [BIFROST_IDLE_1]    = { BIFROST_OP_IDLE,     BIFROST_OP_IDLE,     true },
402bf215546Sopenharmony_ci        [BIFROST_I_W_FMA]   = { BIFROST_OP_IDLE,     BIFROST_OP_WRITE,    true },
403bf215546Sopenharmony_ci        [BIFROST_I_WL_FMA]  = { BIFROST_OP_IDLE,     BIFROST_OP_WRITE_LO, true },
404bf215546Sopenharmony_ci        [BIFROST_I_WH_FMA]  = { BIFROST_OP_IDLE,     BIFROST_OP_WRITE_HI, true },
405bf215546Sopenharmony_ci        [BIFROST_R_I]       = { BIFROST_OP_READ,     BIFROST_OP_IDLE,     false },
406bf215546Sopenharmony_ci        [BIFROST_I_W_ADD]   = { BIFROST_OP_IDLE,     BIFROST_OP_WRITE,    false },
407bf215546Sopenharmony_ci        [BIFROST_I_WL_ADD]  = { BIFROST_OP_IDLE,     BIFROST_OP_WRITE_LO, false },
408bf215546Sopenharmony_ci        [BIFROST_I_WH_ADD]  = { BIFROST_OP_IDLE,     BIFROST_OP_WRITE_HI, false },
409bf215546Sopenharmony_ci        [BIFROST_WL_WH_MIX] = { BIFROST_OP_WRITE_LO, BIFROST_OP_WRITE_HI, false },
410bf215546Sopenharmony_ci        [BIFROST_WH_WL_MIX] = { BIFROST_OP_WRITE_HI, BIFROST_OP_WRITE_LO, false },
411bf215546Sopenharmony_ci        [BIFROST_IDLE]      = { BIFROST_OP_IDLE,     BIFROST_OP_IDLE,     true },
412bf215546Sopenharmony_ci};
413bf215546Sopenharmony_ci#endif
414bf215546Sopenharmony_ci
415bf215546Sopenharmony_ci/* Texture operator descriptors in various states. Usually packed in the
416bf215546Sopenharmony_ci * compiler and stored as a constant */
417bf215546Sopenharmony_ci
418bf215546Sopenharmony_cienum bifrost_texture_operation_mode {
419bf215546Sopenharmony_ci        /* Dual texturing */
420bf215546Sopenharmony_ci        BIFROST_TEXTURE_OPERATION_DUAL = 1,
421bf215546Sopenharmony_ci
422bf215546Sopenharmony_ci        /* Single texturing */
423bf215546Sopenharmony_ci        BIFROST_TEXTURE_OPERATION_SINGLE = 3,
424bf215546Sopenharmony_ci};
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_cienum bifrost_index {
427bf215546Sopenharmony_ci        /* Both texture/sampler index immediate */
428bf215546Sopenharmony_ci        BIFROST_INDEX_IMMEDIATE_SHARED = 0,
429bf215546Sopenharmony_ci
430bf215546Sopenharmony_ci        /* Sampler index immediate, texture index from staging */
431bf215546Sopenharmony_ci        BIFROST_INDEX_IMMEDIATE_SAMPLER = 1,
432bf215546Sopenharmony_ci
433bf215546Sopenharmony_ci        /* Texture index immediate, sampler index from staging */
434bf215546Sopenharmony_ci        BIFROST_INDEX_IMMEDIATE_TEXTURE = 2,
435bf215546Sopenharmony_ci
436bf215546Sopenharmony_ci        /* Both indices from (separate) staging registers */
437bf215546Sopenharmony_ci        BIFROST_INDEX_REGISTER = 3,
438bf215546Sopenharmony_ci};
439bf215546Sopenharmony_ci
440bf215546Sopenharmony_cienum bifrost_tex_op {
441bf215546Sopenharmony_ci        /* Given explicit derivatives, compute a gradient descriptor */
442bf215546Sopenharmony_ci        BIFROST_TEX_OP_GRDESC_DER = 4,
443bf215546Sopenharmony_ci
444bf215546Sopenharmony_ci        /* Given implicit derivatives (texture coordinates in a fragment
445bf215546Sopenharmony_ci         * shader), compute a gradient descriptor */
446bf215546Sopenharmony_ci        BIFROST_TEX_OP_GRDESC = 5,
447bf215546Sopenharmony_ci
448bf215546Sopenharmony_ci        /* Fetch a texel. Takes a staging register with LOD level / face index
449bf215546Sopenharmony_ci         * packed 16:16 */
450bf215546Sopenharmony_ci        BIFROST_TEX_OP_FETCH = 6,
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_ci        /* Filtered texture */
453bf215546Sopenharmony_ci        BIFROST_TEX_OP_TEX = 7,
454bf215546Sopenharmony_ci};
455bf215546Sopenharmony_ci
456bf215546Sopenharmony_cienum bifrost_lod_mode {
457bf215546Sopenharmony_ci        /* Takes two staging registers forming a 64-bit gradient descriptor
458bf215546Sopenharmony_ci         * (computed by a previous GRDESC or GRDESC_DER operation) */
459bf215546Sopenharmony_ci        BIFROST_LOD_MODE_GRDESC = 3,
460bf215546Sopenharmony_ci
461bf215546Sopenharmony_ci        /* Take a staging register with 8:8 fixed-point in bottom 16-bits
462bf215546Sopenharmony_ci         * specifying an explicit LOD */
463bf215546Sopenharmony_ci        BIFROST_LOD_MODE_EXPLICIT = 4,
464bf215546Sopenharmony_ci
465bf215546Sopenharmony_ci        /* Takes a staging register with bottom 16-bits as 8:8 fixed-point LOD
466bf215546Sopenharmony_ci         * bias and top 16-bit as 8:8 fixed-point lower bound (generally left
467bf215546Sopenharmony_ci         * zero), added and clamped to a computed LOD */
468bf215546Sopenharmony_ci        BIFROST_LOD_MODE_BIAS = 5,
469bf215546Sopenharmony_ci
470bf215546Sopenharmony_ci        /* Set LOD to zero */
471bf215546Sopenharmony_ci        BIFROST_LOD_MODE_ZERO = 6,
472bf215546Sopenharmony_ci
473bf215546Sopenharmony_ci        /* Compute LOD */
474bf215546Sopenharmony_ci        BIFROST_LOD_MODE_COMPUTE = 7,
475bf215546Sopenharmony_ci};
476bf215546Sopenharmony_ci
477bf215546Sopenharmony_cienum bifrost_texture_format {
478bf215546Sopenharmony_ci        /* 16-bit floating point, with optional clamping */
479bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_F16 = 0,
480bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_F16_POS = 1,
481bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_F16_PM1 = 2,
482bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_F16_1 = 3,
483bf215546Sopenharmony_ci
484bf215546Sopenharmony_ci        /* 32-bit floating point, with optional clamping */
485bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_F32 = 4,
486bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_F32_POS = 5,
487bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_F32_PM1 = 6,
488bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_F32_1 = 7,
489bf215546Sopenharmony_ci};
490bf215546Sopenharmony_ci
491bf215546Sopenharmony_cienum bifrost_texture_format_full {
492bf215546Sopenharmony_ci        /* Transclude bifrost_texture_format from above */
493bf215546Sopenharmony_ci
494bf215546Sopenharmony_ci        /* Integers, unclamped */
495bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_U16 = 12,
496bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_S16 = 13,
497bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_U32 = 14,
498bf215546Sopenharmony_ci        BIFROST_TEXTURE_FORMAT_S32 = 15,
499bf215546Sopenharmony_ci};
500bf215546Sopenharmony_ci
501bf215546Sopenharmony_cienum bifrost_texture_fetch {
502bf215546Sopenharmony_ci        /* Default texelFetch */
503bf215546Sopenharmony_ci        BIFROST_TEXTURE_FETCH_TEXEL = 1,
504bf215546Sopenharmony_ci
505bf215546Sopenharmony_ci        /* Deprecated, fetches 4x U32 of a U8 x 4 texture. Do not use. */
506bf215546Sopenharmony_ci        BIFROST_TEXTURE_FETCH_GATHER4_RGBA = 3,
507bf215546Sopenharmony_ci
508bf215546Sopenharmony_ci        /* Gathers */
509bf215546Sopenharmony_ci        BIFROST_TEXTURE_FETCH_GATHER4_R = 4,
510bf215546Sopenharmony_ci        BIFROST_TEXTURE_FETCH_GATHER4_G = 5,
511bf215546Sopenharmony_ci        BIFROST_TEXTURE_FETCH_GATHER4_B = 6,
512bf215546Sopenharmony_ci        BIFROST_TEXTURE_FETCH_GATHER4_A = 7
513bf215546Sopenharmony_ci};
514bf215546Sopenharmony_ci
515bf215546Sopenharmony_cistruct bifrost_texture_operation {
516bf215546Sopenharmony_ci        /* If immediate_indices is set:
517bf215546Sopenharmony_ci         *     - immediate sampler index
518bf215546Sopenharmony_ci         *     - index used as texture index
519bf215546Sopenharmony_ci         * Otherwise:
520bf215546Sopenharmony_ci         *      - bifrost_single_index in lower 2 bits
521bf215546Sopenharmony_ci         *      - 0x3 in upper 2 bits (single-texturing)
522bf215546Sopenharmony_ci         */
523bf215546Sopenharmony_ci        unsigned sampler_index_or_mode : 4;
524bf215546Sopenharmony_ci        unsigned index : 7;
525bf215546Sopenharmony_ci        bool immediate_indices : 1;
526bf215546Sopenharmony_ci        enum bifrost_tex_op op : 3;
527bf215546Sopenharmony_ci
528bf215546Sopenharmony_ci        /* If set for TEX/FETCH, loads texel offsets and multisample index from
529bf215546Sopenharmony_ci         * a staging register containing offset_x:offset_y:offset_z:ms_index
530bf215546Sopenharmony_ci         * packed 8:8:8:8. Offsets must be in [-31, +31]. If set for
531bf215546Sopenharmony_ci         * GRDESC(_DER), disable LOD bias. */
532bf215546Sopenharmony_ci        bool offset_or_bias_disable : 1;
533bf215546Sopenharmony_ci
534bf215546Sopenharmony_ci        /* If set for TEX/FETCH, loads fp32 shadow comparison value from a
535bf215546Sopenharmony_ci         * staging register. Implies fetch_component = gather4_r. If set for
536bf215546Sopenharmony_ci         * GRDESC(_DER), disables LOD clamping. */
537bf215546Sopenharmony_ci        bool shadow_or_clamp_disable : 1;
538bf215546Sopenharmony_ci
539bf215546Sopenharmony_ci        /* If set, loads an uint32 array index from a staging register. */
540bf215546Sopenharmony_ci        bool array : 1;
541bf215546Sopenharmony_ci
542bf215546Sopenharmony_ci        /* Texture dimension, or 0 for a cubemap */
543bf215546Sopenharmony_ci        unsigned dimension : 2;
544bf215546Sopenharmony_ci
545bf215546Sopenharmony_ci        /* Method to compute LOD value or for a FETCH, the
546bf215546Sopenharmony_ci         * bifrost_texture_fetch component specification */
547bf215546Sopenharmony_ci        enum bifrost_lod_mode lod_or_fetch : 3;
548bf215546Sopenharmony_ci
549bf215546Sopenharmony_ci        /* Reserved */
550bf215546Sopenharmony_ci        unsigned zero : 1;
551bf215546Sopenharmony_ci
552bf215546Sopenharmony_ci        /* Register format for the result */
553bf215546Sopenharmony_ci        enum bifrost_texture_format_full format : 4;
554bf215546Sopenharmony_ci
555bf215546Sopenharmony_ci        /* Write mask for the result */
556bf215546Sopenharmony_ci        unsigned mask : 4;
557bf215546Sopenharmony_ci} __attribute__((packed));
558bf215546Sopenharmony_ci
559bf215546Sopenharmony_cistruct bifrost_dual_texture_operation {
560bf215546Sopenharmony_ci        unsigned primary_sampler_index : 2;
561bf215546Sopenharmony_ci        unsigned mode : 2; /* 0x1 for dual */
562bf215546Sopenharmony_ci        unsigned primary_texture_index : 2;
563bf215546Sopenharmony_ci        unsigned secondary_sampler_index : 2;
564bf215546Sopenharmony_ci        unsigned secondary_texture_index : 2;
565bf215546Sopenharmony_ci
566bf215546Sopenharmony_ci        /* Leave zero for dual texturing */
567bf215546Sopenharmony_ci        unsigned reserved : 1;
568bf215546Sopenharmony_ci        unsigned index_mode_zero : 1;
569bf215546Sopenharmony_ci
570bf215546Sopenharmony_ci        /* Base staging register to write the secondary results to */
571bf215546Sopenharmony_ci        unsigned secondary_register : 6;
572bf215546Sopenharmony_ci
573bf215546Sopenharmony_ci        /* Format/mask for each texture */
574bf215546Sopenharmony_ci        enum bifrost_texture_format secondary_format : 3;
575bf215546Sopenharmony_ci        unsigned secondary_mask : 4;
576bf215546Sopenharmony_ci
577bf215546Sopenharmony_ci        enum bifrost_texture_format primary_format : 3;
578bf215546Sopenharmony_ci        unsigned primary_mask : 4;
579bf215546Sopenharmony_ci} __attribute__((packed));
580bf215546Sopenharmony_ci
581bf215546Sopenharmony_cistatic inline uint32_t
582bf215546Sopenharmony_cibi_dual_tex_as_u32(struct bifrost_dual_texture_operation desc)
583bf215546Sopenharmony_ci{
584bf215546Sopenharmony_ci        uint32_t desc_u;
585bf215546Sopenharmony_ci        memcpy(&desc_u, &desc, sizeof(desc));
586bf215546Sopenharmony_ci
587bf215546Sopenharmony_ci        return desc_u;
588bf215546Sopenharmony_ci}
589bf215546Sopenharmony_ci
590bf215546Sopenharmony_ci#define BIFROST_MEGA_SAMPLE 128
591bf215546Sopenharmony_ci#define BIFROST_ALL_SAMPLES 255
592bf215546Sopenharmony_ci#define BIFROST_CURRENT_PIXEL 255
593bf215546Sopenharmony_ci
594bf215546Sopenharmony_cistruct bifrost_pixel_indices {
595bf215546Sopenharmony_ci        unsigned sample : 8;
596bf215546Sopenharmony_ci        unsigned rt : 8;
597bf215546Sopenharmony_ci        unsigned x : 8;
598bf215546Sopenharmony_ci        unsigned y : 8;
599bf215546Sopenharmony_ci} __attribute__((packed));
600bf215546Sopenharmony_ci
601bf215546Sopenharmony_cienum bi_constmod {
602bf215546Sopenharmony_ci        BI_CONSTMOD_NONE,
603bf215546Sopenharmony_ci        BI_CONSTMOD_PC_LO,
604bf215546Sopenharmony_ci        BI_CONSTMOD_PC_HI,
605bf215546Sopenharmony_ci        BI_CONSTMOD_PC_LO_HI
606bf215546Sopenharmony_ci};
607bf215546Sopenharmony_ci
608bf215546Sopenharmony_cistruct bi_constants {
609bf215546Sopenharmony_ci        /* Raw constant values */
610bf215546Sopenharmony_ci        uint64_t raw[6];
611bf215546Sopenharmony_ci
612bf215546Sopenharmony_ci        /* Associated modifier derived from M values */
613bf215546Sopenharmony_ci        enum bi_constmod mods[6];
614bf215546Sopenharmony_ci};
615bf215546Sopenharmony_ci
616bf215546Sopenharmony_ci/* FAU selectors for constants are out-of-order, construct the top bits
617bf215546Sopenharmony_ci * here given a embedded constant index in a clause */
618bf215546Sopenharmony_ci
619bf215546Sopenharmony_cistatic inline unsigned
620bf215546Sopenharmony_cibi_constant_field(unsigned idx)
621bf215546Sopenharmony_ci{
622bf215546Sopenharmony_ci        const unsigned values[] = {
623bf215546Sopenharmony_ci                4, 5, 6, 7, 2, 3
624bf215546Sopenharmony_ci        };
625bf215546Sopenharmony_ci
626bf215546Sopenharmony_ci        assert(idx <= 5);
627bf215546Sopenharmony_ci        return values[idx] << 4;
628bf215546Sopenharmony_ci}
629bf215546Sopenharmony_ci
630bf215546Sopenharmony_ci#ifdef __cplusplus
631bf215546Sopenharmony_ci} /* extern C */
632bf215546Sopenharmony_ci#endif
633bf215546Sopenharmony_ci
634bf215546Sopenharmony_ci#endif
635