xref: /aosp_15_r20/external/mesa3d/src/panfrost/compiler/valhall/valhall.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (C) 2021 Collabora Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  *
23  * Authors (Collabora):
24  *      Alyssa Rosenzweig <[email protected]>
25  */
26 
27 #ifndef __VALHALL_H
28 #define __VALHALL_H
29 
30 #include <stdint.h>
31 #include "bi_opcodes.h"
32 #include "valhall_enums.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #define VA_NUM_GENERAL_SLOTS 3
39 
40 extern const uint32_t valhall_immediates[32];
41 
42 enum va_size {
43    VA_SIZE_8 = 0,
44    VA_SIZE_16 = 1,
45    VA_SIZE_32 = 2,
46    VA_SIZE_64 = 3,
47 };
48 
49 enum va_unit {
50    /** Fused floating-point multiply-add */
51    VA_UNIT_FMA = 0,
52 
53    /** Type conversion and basic arithmetic */
54    VA_UNIT_CVT = 1,
55 
56    /** Special function unit */
57    VA_UNIT_SFU = 2,
58 
59    /** Varying */
60    VA_UNIT_V = 3,
61 
62    /** General load/store */
63    VA_UNIT_LS = 4,
64 
65    /** Texture */
66    VA_UNIT_T = 5,
67 
68    /** Fused varying and texture */
69    VA_UNIT_VT = 6,
70 
71    /** Produces a message for a unit not otherwise specified */
72    VA_UNIT_NONE = 7
73 };
74 
75 struct va_src_info {
76    bool absneg       : 1;
77    bool swizzle      : 1;
78    bool notted       : 1;
79    bool lane         : 1;
80    bool lanes        : 1;
81    bool halfswizzle  : 1;
82    bool widen        : 1;
83    bool combine      : 1;
84    enum va_size size : 2;
85 } __attribute__((packed));
86 
87 struct va_opcode_info {
88    uint64_t exact;
89    struct va_src_info srcs[4];
90    uint8_t type_size         : 8;
91    enum va_unit unit         : 3;
92    unsigned nr_srcs          : 3;
93    unsigned nr_staging_srcs  : 2;
94    unsigned nr_staging_dests : 2;
95    bool has_dest             : 1;
96    bool is_signed            : 1;
97    bool clamp                : 1;
98    bool saturate             : 1;
99    bool rhadd                : 1;
100    bool round_mode           : 1;
101    bool condition            : 1;
102    bool result_type          : 1;
103    bool vecsize              : 1;
104    bool register_format      : 1;
105    bool slot                 : 1;
106    bool sr_count             : 1;
107    bool sr_write_count       : 1;
108    unsigned sr_control       : 2;
109 };
110 
111 extern const struct va_opcode_info valhall_opcodes[BI_NUM_OPCODES];
112 
113 /* Bifrost specifies the source of bitwise operations as (A, B, shift), but
114  * Valhall specifies (A, shift, B). We follow Bifrost conventions in the
115  * compiler, so normalize.
116  *
117  * Bifrost specifies BLEND as staging + (coverage, blend descriptor), but
118  * Valhall specifies staging + (blend descriptor, coverage). Given we put
119  * staging sources first, this works out to the same swap as bitwise ops.
120  */
121 
122 static inline bool
va_swap_12(enum bi_opcode op)123 va_swap_12(enum bi_opcode op)
124 {
125    switch (op) {
126    case BI_OPCODE_BLEND:
127    case BI_OPCODE_LSHIFT_AND_I32:
128    case BI_OPCODE_LSHIFT_AND_V2I16:
129    case BI_OPCODE_LSHIFT_AND_V4I8:
130    case BI_OPCODE_LSHIFT_OR_I32:
131    case BI_OPCODE_LSHIFT_OR_V2I16:
132    case BI_OPCODE_LSHIFT_OR_V4I8:
133    case BI_OPCODE_LSHIFT_XOR_I32:
134    case BI_OPCODE_LSHIFT_XOR_V2I16:
135    case BI_OPCODE_LSHIFT_XOR_V4I8:
136    case BI_OPCODE_RSHIFT_AND_I32:
137    case BI_OPCODE_RSHIFT_AND_V2I16:
138    case BI_OPCODE_RSHIFT_AND_V4I8:
139    case BI_OPCODE_RSHIFT_OR_I32:
140    case BI_OPCODE_RSHIFT_OR_V2I16:
141    case BI_OPCODE_RSHIFT_OR_V4I8:
142    case BI_OPCODE_RSHIFT_XOR_I32:
143    case BI_OPCODE_RSHIFT_XOR_V2I16:
144    case BI_OPCODE_RSHIFT_XOR_V4I8:
145       return true;
146    default:
147       return false;
148    }
149 }
150 
151 static inline struct va_src_info
va_src_info(enum bi_opcode op,unsigned src)152 va_src_info(enum bi_opcode op, unsigned src)
153 {
154    unsigned idx = (va_swap_12(op) && (src == 1 || src == 2)) ? (3 - src) : src;
155    return valhall_opcodes[op].srcs[idx];
156 }
157 
158 static inline bool
va_flow_is_wait_or_none(enum va_flow flow)159 va_flow_is_wait_or_none(enum va_flow flow)
160 {
161    return (flow <= VA_FLOW_WAIT);
162 }
163 
164 static inline bool
va_is_valid_const_table(unsigned table)165 va_is_valid_const_table(unsigned table)
166 {
167    return (table >= 0 && table <= 11) || (table >= 60 && table <= 63);
168 }
169 
170 static inline uint32_t
va_res_fold_table_idx(uint32_t table)171 va_res_fold_table_idx(uint32_t table)
172 {
173    switch (table) {
174    case 0 ... 11:
175       return table;
176    case 60 ... 63:
177       return table + 12 - 60;
178    default:
179       assert(!"Can't pack table");
180       return 0;
181    }
182 }
183 
184 #ifdef __cplusplus
185 } /* extern C */
186 #endif
187 
188 #endif
189