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