1 /*
2 * Copyright © 2017 Intel Corporation
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "brw_reg.h"
25 #include "brw_eu_defines.h"
26 #include "dev/intel_device_info.h"
27
28 #define INVALID (-1)
29
30 enum hw_reg_type {
31 BRW_HW_REG_TYPE_UD = 0,
32 BRW_HW_REG_TYPE_D = 1,
33 BRW_HW_REG_TYPE_UW = 2,
34 BRW_HW_REG_TYPE_W = 3,
35 BRW_HW_REG_TYPE_F = 7,
36 GFX8_HW_REG_TYPE_UQ = 8,
37 GFX8_HW_REG_TYPE_Q = 9,
38
39 BRW_HW_REG_TYPE_UB = 4,
40 BRW_HW_REG_TYPE_B = 5,
41 GFX7_HW_REG_TYPE_DF = 6,
42 GFX8_HW_REG_TYPE_HF = 10,
43
44 GFX11_HW_REG_TYPE_UD = 0,
45 GFX11_HW_REG_TYPE_D = 1,
46 GFX11_HW_REG_TYPE_UW = 2,
47 GFX11_HW_REG_TYPE_W = 3,
48 GFX11_HW_REG_TYPE_UB = 4,
49 GFX11_HW_REG_TYPE_B = 5,
50 GFX11_HW_REG_TYPE_UQ = 6,
51 GFX11_HW_REG_TYPE_Q = 7,
52 GFX11_HW_REG_TYPE_HF = 8,
53 GFX11_HW_REG_TYPE_F = 9,
54 GFX11_HW_REG_TYPE_DF = 10,
55 GFX11_HW_REG_TYPE_NF = 11,
56 };
57
58 enum hw_imm_type {
59 BRW_HW_IMM_TYPE_UD = 0,
60 BRW_HW_IMM_TYPE_D = 1,
61 BRW_HW_IMM_TYPE_UW = 2,
62 BRW_HW_IMM_TYPE_W = 3,
63 BRW_HW_IMM_TYPE_F = 7,
64 GFX8_HW_IMM_TYPE_UQ = 8,
65 GFX8_HW_IMM_TYPE_Q = 9,
66
67 BRW_HW_IMM_TYPE_UV = 4,
68 BRW_HW_IMM_TYPE_VF = 5,
69 BRW_HW_IMM_TYPE_V = 6,
70 GFX8_HW_IMM_TYPE_DF = 10,
71 GFX8_HW_IMM_TYPE_HF = 11,
72
73 GFX11_HW_IMM_TYPE_UD = 0,
74 GFX11_HW_IMM_TYPE_D = 1,
75 GFX11_HW_IMM_TYPE_UW = 2,
76 GFX11_HW_IMM_TYPE_W = 3,
77 GFX11_HW_IMM_TYPE_UV = 4,
78 GFX11_HW_IMM_TYPE_V = 5,
79 GFX11_HW_IMM_TYPE_UQ = 6,
80 GFX11_HW_IMM_TYPE_Q = 7,
81 GFX11_HW_IMM_TYPE_HF = 8,
82 GFX11_HW_IMM_TYPE_F = 9,
83 GFX11_HW_IMM_TYPE_DF = 10,
84 GFX11_HW_IMM_TYPE_VF = 11,
85 };
86
87 #define GFX12_HW_REG_TYPE_UINT(n) (n)
88 #define GFX12_HW_REG_TYPE_SINT(n) (0x4 | (n))
89 #define GFX12_HW_REG_TYPE_FLOAT(n) (0x8 | (n))
90
91 static const struct hw_type {
92 enum hw_reg_type reg_type;
93 enum hw_imm_type imm_type;
94 } gfx4_hw_type[] = {
95 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
96
97 [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
98 [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
99
100 [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
101 [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
102 [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
103 [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
104 [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
105 [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
106 [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
107 }, gfx6_hw_type[] = {
108 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
109
110 [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
111 [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
112
113 [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
114 [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
115 [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
116 [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
117 [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
118 [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
119 [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
120 [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV },
121 }, gfx7_hw_type[] = {
122 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
123
124 [BRW_REGISTER_TYPE_DF] = { GFX7_HW_REG_TYPE_DF, INVALID },
125 [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
126 [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
127
128 [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
129 [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
130 [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
131 [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
132 [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
133 [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
134 [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
135 [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV },
136 }, gfx8_hw_type[] = {
137 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
138
139 [BRW_REGISTER_TYPE_DF] = { GFX7_HW_REG_TYPE_DF, GFX8_HW_IMM_TYPE_DF },
140 [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
141 [BRW_REGISTER_TYPE_HF] = { GFX8_HW_REG_TYPE_HF, GFX8_HW_IMM_TYPE_HF },
142 [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
143
144 [BRW_REGISTER_TYPE_Q] = { GFX8_HW_REG_TYPE_Q, GFX8_HW_IMM_TYPE_Q },
145 [BRW_REGISTER_TYPE_UQ] = { GFX8_HW_REG_TYPE_UQ, GFX8_HW_IMM_TYPE_UQ },
146 [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
147 [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
148 [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
149 [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
150 [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
151 [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
152 [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
153 [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV },
154 }, gfx11_hw_type[] = {
155 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
156
157 [BRW_REGISTER_TYPE_NF] = { GFX11_HW_REG_TYPE_NF, INVALID },
158 [BRW_REGISTER_TYPE_F] = { GFX11_HW_REG_TYPE_F, GFX11_HW_IMM_TYPE_F },
159 [BRW_REGISTER_TYPE_HF] = { GFX11_HW_REG_TYPE_HF, GFX11_HW_IMM_TYPE_HF },
160 [BRW_REGISTER_TYPE_VF] = { INVALID, GFX11_HW_IMM_TYPE_VF },
161
162 [BRW_REGISTER_TYPE_D] = { GFX11_HW_REG_TYPE_D, GFX11_HW_IMM_TYPE_D },
163 [BRW_REGISTER_TYPE_UD] = { GFX11_HW_REG_TYPE_UD, GFX11_HW_IMM_TYPE_UD },
164 [BRW_REGISTER_TYPE_W] = { GFX11_HW_REG_TYPE_W, GFX11_HW_IMM_TYPE_W },
165 [BRW_REGISTER_TYPE_UW] = { GFX11_HW_REG_TYPE_UW, GFX11_HW_IMM_TYPE_UW },
166 [BRW_REGISTER_TYPE_B] = { GFX11_HW_REG_TYPE_B, INVALID },
167 [BRW_REGISTER_TYPE_UB] = { GFX11_HW_REG_TYPE_UB, INVALID },
168 [BRW_REGISTER_TYPE_V] = { INVALID, GFX11_HW_IMM_TYPE_V },
169 [BRW_REGISTER_TYPE_UV] = { INVALID, GFX11_HW_IMM_TYPE_UV },
170 }, gfx12_hw_type[] = {
171 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
172
173 [BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_FLOAT(2), GFX12_HW_REG_TYPE_FLOAT(2) },
174 [BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_FLOAT(1), GFX12_HW_REG_TYPE_FLOAT(1) },
175 [BRW_REGISTER_TYPE_VF] = { INVALID, GFX12_HW_REG_TYPE_FLOAT(0) },
176
177 [BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), GFX12_HW_REG_TYPE_SINT(2) },
178 [BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), GFX12_HW_REG_TYPE_UINT(2) },
179 [BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), GFX12_HW_REG_TYPE_SINT(1) },
180 [BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), GFX12_HW_REG_TYPE_UINT(1) },
181 [BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), INVALID },
182 [BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), INVALID },
183 [BRW_REGISTER_TYPE_V] = { INVALID, GFX12_HW_REG_TYPE_SINT(0) },
184 [BRW_REGISTER_TYPE_UV] = { INVALID, GFX12_HW_REG_TYPE_UINT(0) },
185 }, gfx125_hw_type[] = {
186 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
187
188 [BRW_REGISTER_TYPE_DF] = { GFX12_HW_REG_TYPE_FLOAT(3), GFX12_HW_REG_TYPE_FLOAT(3) },
189 [BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_FLOAT(2), GFX12_HW_REG_TYPE_FLOAT(2) },
190 [BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_FLOAT(1), GFX12_HW_REG_TYPE_FLOAT(1) },
191 [BRW_REGISTER_TYPE_VF] = { INVALID, GFX12_HW_REG_TYPE_FLOAT(0) },
192
193 [BRW_REGISTER_TYPE_Q] = { GFX12_HW_REG_TYPE_SINT(3), GFX12_HW_REG_TYPE_SINT(3) },
194 [BRW_REGISTER_TYPE_UQ] = { GFX12_HW_REG_TYPE_UINT(3), GFX12_HW_REG_TYPE_UINT(3) },
195 [BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), GFX12_HW_REG_TYPE_SINT(2) },
196 [BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), GFX12_HW_REG_TYPE_UINT(2) },
197 [BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), GFX12_HW_REG_TYPE_SINT(1) },
198 [BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), GFX12_HW_REG_TYPE_UINT(1) },
199 [BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), INVALID },
200 [BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), INVALID },
201 [BRW_REGISTER_TYPE_V] = { INVALID, GFX12_HW_REG_TYPE_SINT(0) },
202 [BRW_REGISTER_TYPE_UV] = { INVALID, GFX12_HW_REG_TYPE_UINT(0) },
203 };
204
205 /* SNB adds 3-src instructions (MAD and LRP) that only operate on floats, so
206 * the types were implied. IVB adds BFE and BFI2 that operate on doublewords
207 * and unsigned doublewords, so a new field is also available in the da3src
208 * struct (part of struct brw_instruction.bits1 in brw_structs.h) to select
209 * dst and shared-src types.
210 *
211 * CNL adds support for 3-src instructions in align1 mode, and with it support
212 * for most register types.
213 */
214 enum hw_3src_reg_type {
215 GFX7_3SRC_TYPE_F = 0,
216 GFX7_3SRC_TYPE_D = 1,
217 GFX7_3SRC_TYPE_UD = 2,
218 GFX7_3SRC_TYPE_DF = 3,
219 GFX8_3SRC_TYPE_HF = 4,
220
221 /** When ExecutionDatatype is 1: @{ */
222 GFX10_ALIGN1_3SRC_REG_TYPE_HF = 0b000,
223 GFX10_ALIGN1_3SRC_REG_TYPE_F = 0b001,
224 GFX10_ALIGN1_3SRC_REG_TYPE_DF = 0b010,
225 GFX11_ALIGN1_3SRC_REG_TYPE_NF = 0b011,
226 /** @} */
227
228 /** When ExecutionDatatype is 0: @{ */
229 GFX10_ALIGN1_3SRC_REG_TYPE_UD = 0b000,
230 GFX10_ALIGN1_3SRC_REG_TYPE_D = 0b001,
231 GFX10_ALIGN1_3SRC_REG_TYPE_UW = 0b010,
232 GFX10_ALIGN1_3SRC_REG_TYPE_W = 0b011,
233 GFX10_ALIGN1_3SRC_REG_TYPE_UB = 0b100,
234 GFX10_ALIGN1_3SRC_REG_TYPE_B = 0b101,
235 /** @} */
236 };
237
238 static const struct hw_3src_type {
239 enum hw_3src_reg_type reg_type;
240 enum gfx10_align1_3src_exec_type exec_type;
241 } gfx6_hw_3src_type[] = {
242 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
243
244 [BRW_REGISTER_TYPE_F] = { GFX7_3SRC_TYPE_F },
245 }, gfx7_hw_3src_type[] = {
246 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
247
248 [BRW_REGISTER_TYPE_F] = { GFX7_3SRC_TYPE_F },
249 [BRW_REGISTER_TYPE_D] = { GFX7_3SRC_TYPE_D },
250 [BRW_REGISTER_TYPE_UD] = { GFX7_3SRC_TYPE_UD },
251 [BRW_REGISTER_TYPE_DF] = { GFX7_3SRC_TYPE_DF },
252 }, gfx8_hw_3src_type[] = {
253 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
254
255 [BRW_REGISTER_TYPE_F] = { GFX7_3SRC_TYPE_F },
256 [BRW_REGISTER_TYPE_D] = { GFX7_3SRC_TYPE_D },
257 [BRW_REGISTER_TYPE_UD] = { GFX7_3SRC_TYPE_UD },
258 [BRW_REGISTER_TYPE_DF] = { GFX7_3SRC_TYPE_DF },
259 [BRW_REGISTER_TYPE_HF] = { GFX8_3SRC_TYPE_HF },
260 }, gfx10_hw_3src_align1_type[] = {
261 #define E(x) BRW_ALIGN1_3SRC_EXEC_TYPE_##x
262 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
263
264 [BRW_REGISTER_TYPE_DF] = { GFX10_ALIGN1_3SRC_REG_TYPE_DF, E(FLOAT) },
265 [BRW_REGISTER_TYPE_F] = { GFX10_ALIGN1_3SRC_REG_TYPE_F, E(FLOAT) },
266 [BRW_REGISTER_TYPE_HF] = { GFX10_ALIGN1_3SRC_REG_TYPE_HF, E(FLOAT) },
267
268 [BRW_REGISTER_TYPE_D] = { GFX10_ALIGN1_3SRC_REG_TYPE_D, E(INT) },
269 [BRW_REGISTER_TYPE_UD] = { GFX10_ALIGN1_3SRC_REG_TYPE_UD, E(INT) },
270 [BRW_REGISTER_TYPE_W] = { GFX10_ALIGN1_3SRC_REG_TYPE_W, E(INT) },
271 [BRW_REGISTER_TYPE_UW] = { GFX10_ALIGN1_3SRC_REG_TYPE_UW, E(INT) },
272 [BRW_REGISTER_TYPE_B] = { GFX10_ALIGN1_3SRC_REG_TYPE_B, E(INT) },
273 [BRW_REGISTER_TYPE_UB] = { GFX10_ALIGN1_3SRC_REG_TYPE_UB, E(INT) },
274 }, gfx11_hw_3src_type[] = {
275 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
276
277 [BRW_REGISTER_TYPE_NF] = { GFX11_ALIGN1_3SRC_REG_TYPE_NF, E(FLOAT) },
278 [BRW_REGISTER_TYPE_F] = { GFX10_ALIGN1_3SRC_REG_TYPE_F, E(FLOAT) },
279 [BRW_REGISTER_TYPE_HF] = { GFX10_ALIGN1_3SRC_REG_TYPE_HF, E(FLOAT) },
280
281 [BRW_REGISTER_TYPE_D] = { GFX10_ALIGN1_3SRC_REG_TYPE_D, E(INT) },
282 [BRW_REGISTER_TYPE_UD] = { GFX10_ALIGN1_3SRC_REG_TYPE_UD, E(INT) },
283 [BRW_REGISTER_TYPE_W] = { GFX10_ALIGN1_3SRC_REG_TYPE_W, E(INT) },
284 [BRW_REGISTER_TYPE_UW] = { GFX10_ALIGN1_3SRC_REG_TYPE_UW, E(INT) },
285 [BRW_REGISTER_TYPE_B] = { GFX10_ALIGN1_3SRC_REG_TYPE_B, E(INT) },
286 [BRW_REGISTER_TYPE_UB] = { GFX10_ALIGN1_3SRC_REG_TYPE_UB, E(INT) },
287 }, gfx12_hw_3src_type[] = {
288 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
289
290 [BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_UINT(2), E(FLOAT), },
291 [BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_UINT(1), E(FLOAT), },
292
293 [BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), E(INT), },
294 [BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), E(INT), },
295 [BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), E(INT), },
296 [BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), E(INT), },
297 [BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), E(INT), },
298 [BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), E(INT), },
299 }, gfx125_hw_3src_type[] = {
300 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
301
302 [BRW_REGISTER_TYPE_DF] = { GFX12_HW_REG_TYPE_UINT(3), E(FLOAT), },
303 [BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_UINT(2), E(FLOAT), },
304 [BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_UINT(1), E(FLOAT), },
305
306 [BRW_REGISTER_TYPE_Q] = { GFX12_HW_REG_TYPE_SINT(3), E(INT), },
307 [BRW_REGISTER_TYPE_UQ] = { GFX12_HW_REG_TYPE_UINT(3), E(INT), },
308 [BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), E(INT), },
309 [BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), E(INT), },
310 [BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), E(INT), },
311 [BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), E(INT), },
312 [BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), E(INT), },
313 [BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), E(INT), },
314 #undef E
315 };
316
317 /**
318 * Convert a brw_reg_type enumeration value into the hardware representation.
319 *
320 * The hardware encoding may depend on whether the value is an immediate.
321 */
322 unsigned
brw_reg_type_to_hw_type(const struct intel_device_info * devinfo,enum brw_reg_file file,enum brw_reg_type type)323 brw_reg_type_to_hw_type(const struct intel_device_info *devinfo,
324 enum brw_reg_file file,
325 enum brw_reg_type type)
326 {
327 const struct hw_type *table;
328
329 if (devinfo->verx10 >= 125) {
330 assert(type < ARRAY_SIZE(gfx125_hw_type));
331 table = gfx125_hw_type;
332 } else if (devinfo->ver >= 12) {
333 assert(type < ARRAY_SIZE(gfx12_hw_type));
334 table = gfx12_hw_type;
335 } else if (devinfo->ver >= 11) {
336 assert(type < ARRAY_SIZE(gfx11_hw_type));
337 table = gfx11_hw_type;
338 } else if (devinfo->ver >= 8) {
339 assert(type < ARRAY_SIZE(gfx8_hw_type));
340 table = gfx8_hw_type;
341 } else if (devinfo->ver >= 7) {
342 assert(type < ARRAY_SIZE(gfx7_hw_type));
343 table = gfx7_hw_type;
344 } else if (devinfo->ver >= 6) {
345 assert(type < ARRAY_SIZE(gfx6_hw_type));
346 table = gfx6_hw_type;
347 } else {
348 assert(type < ARRAY_SIZE(gfx4_hw_type));
349 table = gfx4_hw_type;
350 }
351
352 if (file == BRW_IMMEDIATE_VALUE) {
353 assert(table[type].imm_type != (enum hw_imm_type)INVALID);
354 return table[type].imm_type;
355 } else {
356 assert(table[type].reg_type != (enum hw_reg_type)INVALID);
357 return table[type].reg_type;
358 }
359 }
360
361 /**
362 * Convert the hardware representation into a brw_reg_type enumeration value.
363 *
364 * The hardware encoding may depend on whether the value is an immediate.
365 */
366 enum brw_reg_type
brw_hw_type_to_reg_type(const struct intel_device_info * devinfo,enum brw_reg_file file,unsigned hw_type)367 brw_hw_type_to_reg_type(const struct intel_device_info *devinfo,
368 enum brw_reg_file file, unsigned hw_type)
369 {
370 const struct hw_type *table;
371
372 if (devinfo->verx10 >= 125) {
373 table = gfx125_hw_type;
374 } else if (devinfo->ver >= 12) {
375 table = gfx12_hw_type;
376 } else if (devinfo->ver >= 11) {
377 table = gfx11_hw_type;
378 } else if (devinfo->ver >= 8) {
379 table = gfx8_hw_type;
380 } else if (devinfo->ver >= 7) {
381 table = gfx7_hw_type;
382 } else if (devinfo->ver >= 6) {
383 table = gfx6_hw_type;
384 } else {
385 table = gfx4_hw_type;
386 }
387
388 if (file == BRW_IMMEDIATE_VALUE) {
389 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
390 if (table[i].imm_type == (enum hw_imm_type)hw_type) {
391 return i;
392 }
393 }
394 } else {
395 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
396 if (table[i].reg_type == (enum hw_reg_type)hw_type) {
397 return i;
398 }
399 }
400 }
401 return INVALID_REG_TYPE;
402 }
403
404 /**
405 * Convert a brw_reg_type enumeration value into the hardware representation
406 * for a 3-src align16 instruction
407 */
408 unsigned
brw_reg_type_to_a16_hw_3src_type(const struct intel_device_info * devinfo,enum brw_reg_type type)409 brw_reg_type_to_a16_hw_3src_type(const struct intel_device_info *devinfo,
410 enum brw_reg_type type)
411 {
412 const struct hw_3src_type *table;
413
414 if (devinfo->ver >= 8) {
415 assert(type < ARRAY_SIZE(gfx8_hw_3src_type));
416 table = gfx8_hw_3src_type;
417 } else if (devinfo->ver >= 7) {
418 assert(type < ARRAY_SIZE(gfx7_hw_3src_type));
419 table = gfx7_hw_3src_type;
420 } else {
421 assert(type < ARRAY_SIZE(gfx6_hw_3src_type));
422 table = gfx6_hw_3src_type;
423 }
424
425 assert(table[type].reg_type != (enum hw_3src_reg_type)INVALID);
426 return table[type].reg_type;
427 }
428
429 /**
430 * Convert a brw_reg_type enumeration value into the hardware representation
431 * for a 3-src align1 instruction
432 */
433 unsigned
brw_reg_type_to_a1_hw_3src_type(const struct intel_device_info * devinfo,enum brw_reg_type type)434 brw_reg_type_to_a1_hw_3src_type(const struct intel_device_info *devinfo,
435 enum brw_reg_type type)
436 {
437 if (devinfo->verx10 >= 125) {
438 assert(type < ARRAY_SIZE(gfx125_hw_3src_type));
439 return gfx125_hw_3src_type[type].reg_type;
440 } else if (devinfo->ver >= 12) {
441 assert(type < ARRAY_SIZE(gfx12_hw_3src_type));
442 return gfx12_hw_3src_type[type].reg_type;
443 } else if (devinfo->ver >= 11) {
444 assert(type < ARRAY_SIZE(gfx11_hw_3src_type));
445 return gfx11_hw_3src_type[type].reg_type;
446 } else {
447 assert(type < ARRAY_SIZE(gfx10_hw_3src_align1_type));
448 return gfx10_hw_3src_align1_type[type].reg_type;
449 }
450 }
451
452 /**
453 * Convert the hardware representation for a 3-src align16 instruction into a
454 * brw_reg_type enumeration value.
455 */
456 enum brw_reg_type
brw_a16_hw_3src_type_to_reg_type(const struct intel_device_info * devinfo,unsigned hw_type)457 brw_a16_hw_3src_type_to_reg_type(const struct intel_device_info *devinfo,
458 unsigned hw_type)
459 {
460 const struct hw_3src_type *table = NULL;
461
462 if (devinfo->ver >= 8) {
463 table = gfx8_hw_3src_type;
464 } else if (devinfo->ver >= 7) {
465 table = gfx7_hw_3src_type;
466 } else if (devinfo->ver >= 6) {
467 table = gfx6_hw_3src_type;
468 }
469
470 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
471 if (table[i].reg_type == hw_type) {
472 return i;
473 }
474 }
475 return INVALID_REG_TYPE;
476 }
477
478 /**
479 * Convert the hardware representation for a 3-src align1 instruction into a
480 * brw_reg_type enumeration value.
481 */
482 enum brw_reg_type
brw_a1_hw_3src_type_to_reg_type(const struct intel_device_info * devinfo,unsigned hw_type,unsigned exec_type)483 brw_a1_hw_3src_type_to_reg_type(const struct intel_device_info *devinfo,
484 unsigned hw_type, unsigned exec_type)
485 {
486 const struct hw_3src_type *table =
487 (devinfo->verx10 >= 125 ? gfx125_hw_3src_type :
488 devinfo->ver >= 12 ? gfx12_hw_3src_type :
489 devinfo->ver >= 11 ? gfx11_hw_3src_type :
490 gfx10_hw_3src_align1_type);
491
492 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
493 if (table[i].reg_type == hw_type &&
494 table[i].exec_type == exec_type) {
495 return i;
496 }
497 }
498 return INVALID_REG_TYPE;
499 }
500
501 /**
502 * Return the element size given a register type.
503 */
504 unsigned
brw_reg_type_to_size(enum brw_reg_type type)505 brw_reg_type_to_size(enum brw_reg_type type)
506 {
507 static const unsigned type_size[] = {
508 [BRW_REGISTER_TYPE_NF] = 8,
509 [BRW_REGISTER_TYPE_DF] = 8,
510 [BRW_REGISTER_TYPE_F] = 4,
511 [BRW_REGISTER_TYPE_HF] = 2,
512 [BRW_REGISTER_TYPE_VF] = 4,
513
514 [BRW_REGISTER_TYPE_Q] = 8,
515 [BRW_REGISTER_TYPE_UQ] = 8,
516 [BRW_REGISTER_TYPE_D] = 4,
517 [BRW_REGISTER_TYPE_UD] = 4,
518 [BRW_REGISTER_TYPE_W] = 2,
519 [BRW_REGISTER_TYPE_UW] = 2,
520 [BRW_REGISTER_TYPE_B] = 1,
521 [BRW_REGISTER_TYPE_UB] = 1,
522 [BRW_REGISTER_TYPE_V] = 2,
523 [BRW_REGISTER_TYPE_UV] = 2,
524 };
525 if (type >= ARRAY_SIZE(type_size))
526 return -1;
527
528 return type_size[type];
529 }
530
531 /**
532 * Converts a BRW_REGISTER_TYPE_* enum to a short string (F, UD, and so on).
533 *
534 * This is different than reg_encoding from brw_disasm.c in that it operates
535 * on the abstract enum values, rather than the generation-specific encoding.
536 */
537 const char *
brw_reg_type_to_letters(enum brw_reg_type type)538 brw_reg_type_to_letters(enum brw_reg_type type)
539 {
540 static const char letters[][3] = {
541 [BRW_REGISTER_TYPE_NF] = "NF",
542 [BRW_REGISTER_TYPE_DF] = "DF",
543 [BRW_REGISTER_TYPE_F] = "F",
544 [BRW_REGISTER_TYPE_HF] = "HF",
545 [BRW_REGISTER_TYPE_VF] = "VF",
546
547 [BRW_REGISTER_TYPE_Q] = "Q",
548 [BRW_REGISTER_TYPE_UQ] = "UQ",
549 [BRW_REGISTER_TYPE_D] = "D",
550 [BRW_REGISTER_TYPE_UD] = "UD",
551 [BRW_REGISTER_TYPE_W] = "W",
552 [BRW_REGISTER_TYPE_UW] = "UW",
553 [BRW_REGISTER_TYPE_B] = "B",
554 [BRW_REGISTER_TYPE_UB] = "UB",
555 [BRW_REGISTER_TYPE_V] = "V",
556 [BRW_REGISTER_TYPE_UV] = "UV",
557 };
558 if (type >= ARRAY_SIZE(letters))
559 return "INVALID";
560
561 assert(type < ARRAY_SIZE(letters));
562 return letters[type];
563 }
564