Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /* |
2 | * Copyright (c) 2013 Rob Clark |
||
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 | |||
24 | #ifndef INSTR_A3XX_H_ |
||
25 | #define INSTR_A3XX_H_ |
||
26 | |||
27 | #define PACKED __attribute__((__packed__)) |
||
28 | |||
29 | #include |
||
30 | #include |
||
31 | |||
32 | typedef enum { |
||
33 | /* category 0: */ |
||
34 | OPC_NOP = 0, |
||
35 | OPC_BR = 1, |
||
36 | OPC_JUMP = 2, |
||
37 | OPC_CALL = 3, |
||
38 | OPC_RET = 4, |
||
39 | OPC_KILL = 5, |
||
40 | OPC_END = 6, |
||
41 | OPC_EMIT = 7, |
||
42 | OPC_CUT = 8, |
||
43 | OPC_CHMASK = 9, |
||
44 | OPC_CHSH = 10, |
||
45 | OPC_FLOW_REV = 11, |
||
46 | |||
47 | /* category 1: */ |
||
48 | /* no opc.. all category 1 are variants of mov */ |
||
49 | |||
50 | /* category 2: */ |
||
51 | OPC_ADD_F = 0, |
||
52 | OPC_MIN_F = 1, |
||
53 | OPC_MAX_F = 2, |
||
54 | OPC_MUL_F = 3, |
||
55 | OPC_SIGN_F = 4, |
||
56 | OPC_CMPS_F = 5, |
||
57 | OPC_ABSNEG_F = 6, |
||
58 | OPC_CMPV_F = 7, |
||
59 | /* 8 - invalid */ |
||
60 | OPC_FLOOR_F = 9, |
||
61 | OPC_CEIL_F = 10, |
||
62 | OPC_RNDNE_F = 11, |
||
63 | OPC_RNDAZ_F = 12, |
||
64 | OPC_TRUNC_F = 13, |
||
65 | /* 14-15 - invalid */ |
||
66 | OPC_ADD_U = 16, |
||
67 | OPC_ADD_S = 17, |
||
68 | OPC_SUB_U = 18, |
||
69 | OPC_SUB_S = 19, |
||
70 | OPC_CMPS_U = 20, |
||
71 | OPC_CMPS_S = 21, |
||
72 | OPC_MIN_U = 22, |
||
73 | OPC_MIN_S = 23, |
||
74 | OPC_MAX_U = 24, |
||
75 | OPC_MAX_S = 25, |
||
76 | OPC_ABSNEG_S = 26, |
||
77 | /* 27 - invalid */ |
||
78 | OPC_AND_B = 28, |
||
79 | OPC_OR_B = 29, |
||
80 | OPC_NOT_B = 30, |
||
81 | OPC_XOR_B = 31, |
||
82 | /* 32 - invalid */ |
||
83 | OPC_CMPV_U = 33, |
||
84 | OPC_CMPV_S = 34, |
||
85 | /* 35-47 - invalid */ |
||
86 | OPC_MUL_U = 48, |
||
87 | OPC_MUL_S = 49, |
||
88 | OPC_MULL_U = 50, |
||
89 | OPC_BFREV_B = 51, |
||
90 | OPC_CLZ_S = 52, |
||
91 | OPC_CLZ_B = 53, |
||
92 | OPC_SHL_B = 54, |
||
93 | OPC_SHR_B = 55, |
||
94 | OPC_ASHR_B = 56, |
||
95 | OPC_BARY_F = 57, |
||
96 | OPC_MGEN_B = 58, |
||
97 | OPC_GETBIT_B = 59, |
||
98 | OPC_SETRM = 60, |
||
99 | OPC_CBITS_B = 61, |
||
100 | OPC_SHB = 62, |
||
101 | OPC_MSAD = 63, |
||
102 | |||
103 | /* category 3: */ |
||
104 | OPC_MAD_U16 = 0, |
||
105 | OPC_MADSH_U16 = 1, |
||
106 | OPC_MAD_S16 = 2, |
||
107 | OPC_MADSH_M16 = 3, /* should this be .s16? */ |
||
108 | OPC_MAD_U24 = 4, |
||
109 | OPC_MAD_S24 = 5, |
||
110 | OPC_MAD_F16 = 6, |
||
111 | OPC_MAD_F32 = 7, |
||
112 | OPC_SEL_B16 = 8, |
||
113 | OPC_SEL_B32 = 9, |
||
114 | OPC_SEL_S16 = 10, |
||
115 | OPC_SEL_S32 = 11, |
||
116 | OPC_SEL_F16 = 12, |
||
117 | OPC_SEL_F32 = 13, |
||
118 | OPC_SAD_S16 = 14, |
||
119 | OPC_SAD_S32 = 15, |
||
120 | |||
121 | /* category 4: */ |
||
122 | OPC_RCP = 0, |
||
123 | OPC_RSQ = 1, |
||
124 | OPC_LOG2 = 2, |
||
125 | OPC_EXP2 = 3, |
||
126 | OPC_SIN = 4, |
||
127 | OPC_COS = 5, |
||
128 | OPC_SQRT = 6, |
||
129 | // 7-63 - invalid |
||
130 | |||
131 | /* category 5: */ |
||
132 | OPC_ISAM = 0, |
||
133 | OPC_ISAML = 1, |
||
134 | OPC_ISAMM = 2, |
||
135 | OPC_SAM = 3, |
||
136 | OPC_SAMB = 4, |
||
137 | OPC_SAML = 5, |
||
138 | OPC_SAMGQ = 6, |
||
139 | OPC_GETLOD = 7, |
||
140 | OPC_CONV = 8, |
||
141 | OPC_CONVM = 9, |
||
142 | OPC_GETSIZE = 10, |
||
143 | OPC_GETBUF = 11, |
||
144 | OPC_GETPOS = 12, |
||
145 | OPC_GETINFO = 13, |
||
146 | OPC_DSX = 14, |
||
147 | OPC_DSY = 15, |
||
148 | OPC_GATHER4R = 16, |
||
149 | OPC_GATHER4G = 17, |
||
150 | OPC_GATHER4B = 18, |
||
151 | OPC_GATHER4A = 19, |
||
152 | OPC_SAMGP0 = 20, |
||
153 | OPC_SAMGP1 = 21, |
||
154 | OPC_SAMGP2 = 22, |
||
155 | OPC_SAMGP3 = 23, |
||
156 | OPC_DSXPP_1 = 24, |
||
157 | OPC_DSYPP_1 = 25, |
||
158 | OPC_RGETPOS = 26, |
||
159 | OPC_RGETINFO = 27, |
||
160 | |||
161 | /* category 6: */ |
||
162 | OPC_LDG = 0, /* load-global */ |
||
163 | OPC_LDL = 1, |
||
164 | OPC_LDP = 2, |
||
165 | OPC_STG = 3, /* store-global */ |
||
166 | OPC_STL = 4, |
||
167 | OPC_STP = 5, |
||
168 | OPC_STI = 6, |
||
169 | OPC_G2L = 7, |
||
170 | OPC_L2G = 8, |
||
171 | OPC_PREFETCH = 9, |
||
172 | OPC_LDLW = 10, |
||
173 | OPC_STLW = 11, |
||
174 | OPC_RESFMT = 14, |
||
175 | OPC_RESINFO = 15, |
||
176 | OPC_ATOMIC_ADD_L = 16, |
||
177 | OPC_ATOMIC_SUB_L = 17, |
||
178 | OPC_ATOMIC_XCHG_L = 18, |
||
179 | OPC_ATOMIC_INC_L = 19, |
||
180 | OPC_ATOMIC_DEC_L = 20, |
||
181 | OPC_ATOMIC_CMPXCHG_L = 21, |
||
182 | OPC_ATOMIC_MIN_L = 22, |
||
183 | OPC_ATOMIC_MAX_L = 23, |
||
184 | OPC_ATOMIC_AND_L = 24, |
||
185 | OPC_ATOMIC_OR_L = 25, |
||
186 | OPC_ATOMIC_XOR_L = 26, |
||
187 | OPC_LDGB_TYPED_4D = 27, |
||
188 | OPC_STGB_4D_4 = 28, |
||
189 | OPC_STIB = 29, |
||
190 | OPC_LDC_4 = 30, |
||
191 | OPC_LDLV = 31, |
||
192 | |||
193 | } opc_t; |
||
194 | |||
195 | typedef enum { |
||
196 | TYPE_F16 = 0, |
||
197 | TYPE_F32 = 1, |
||
198 | TYPE_U16 = 2, |
||
199 | TYPE_U32 = 3, |
||
200 | TYPE_S16 = 4, |
||
201 | TYPE_S32 = 5, |
||
202 | TYPE_U8 = 6, |
||
203 | TYPE_S8 = 7, // XXX I assume? |
||
204 | } type_t; |
||
205 | |||
206 | static inline uint32_t type_size(type_t type) |
||
207 | { |
||
208 | switch (type) { |
||
209 | case TYPE_F32: |
||
210 | case TYPE_U32: |
||
211 | case TYPE_S32: |
||
212 | return 32; |
||
213 | case TYPE_F16: |
||
214 | case TYPE_U16: |
||
215 | case TYPE_S16: |
||
216 | return 16; |
||
217 | case TYPE_U8: |
||
218 | case TYPE_S8: |
||
219 | return 8; |
||
220 | default: |
||
221 | assert(0); /* invalid type */ |
||
222 | return 0; |
||
223 | } |
||
224 | } |
||
225 | |||
226 | static inline int type_float(type_t type) |
||
227 | { |
||
228 | return (type == TYPE_F32) || (type == TYPE_F16); |
||
229 | } |
||
230 | |||
231 | typedef union PACKED { |
||
232 | /* normal gpr or const src register: */ |
||
233 | struct PACKED { |
||
234 | uint32_t comp : 2; |
||
235 | uint32_t num : 9; |
||
236 | }; |
||
237 | /* for immediate val: */ |
||
238 | int32_t iim_val : 11; |
||
239 | /* to make compiler happy: */ |
||
240 | uint32_t dummy32; |
||
241 | uint32_t dummy11 : 11; |
||
242 | uint32_t dummy8 : 8; |
||
243 | } reg_t; |
||
244 | |||
245 | /* special registers: */ |
||
246 | #define REG_A0 61 /* address register */ |
||
247 | #define REG_P0 62 /* predicate register */ |
||
248 | |||
249 | static inline int reg_special(reg_t reg) |
||
250 | { |
||
251 | return (reg.num == REG_A0) || (reg.num == REG_P0); |
||
252 | } |
||
253 | |||
254 | typedef struct PACKED { |
||
255 | /* dword0: */ |
||
256 | int16_t immed : 16; |
||
257 | uint32_t dummy1 : 16; |
||
258 | |||
259 | /* dword1: */ |
||
260 | uint32_t dummy2 : 8; |
||
261 | uint32_t repeat : 3; |
||
262 | uint32_t dummy3 : 1; |
||
263 | uint32_t ss : 1; |
||
264 | uint32_t dummy4 : 7; |
||
265 | uint32_t inv : 1; |
||
266 | uint32_t comp : 2; |
||
267 | uint32_t opc : 4; |
||
268 | uint32_t jmp_tgt : 1; |
||
269 | uint32_t sync : 1; |
||
270 | uint32_t opc_cat : 3; |
||
271 | } instr_cat0_t; |
||
272 | |||
273 | typedef struct PACKED { |
||
274 | /* dword0: */ |
||
275 | union PACKED { |
||
276 | /* for normal src register: */ |
||
277 | struct PACKED { |
||
278 | uint32_t src : 11; |
||
279 | uint32_t pad : 21; |
||
280 | }; |
||
281 | /* for address relative: */ |
||
282 | struct PACKED { |
||
283 | int32_t off : 10; |
||
284 | uint32_t must_be_3 : 2; |
||
285 | uint32_t unknown : 20; |
||
286 | }; |
||
287 | /* for immediate: */ |
||
288 | int32_t iim_val; |
||
289 | float fim_val; |
||
290 | }; |
||
291 | |||
292 | /* dword1: */ |
||
293 | uint32_t dst : 8; |
||
294 | uint32_t repeat : 3; |
||
295 | uint32_t src_r : 1; |
||
296 | uint32_t ss : 1; |
||
297 | uint32_t src_rel : 1; |
||
298 | uint32_t dst_type : 3; |
||
299 | uint32_t dst_rel : 1; |
||
300 | uint32_t src_type : 3; |
||
301 | uint32_t src_c : 1; |
||
302 | uint32_t src_im : 1; |
||
303 | uint32_t even : 1; |
||
304 | uint32_t pos_inf : 1; |
||
305 | uint32_t must_be_0 : 2; |
||
306 | uint32_t jmp_tgt : 1; |
||
307 | uint32_t sync : 1; |
||
308 | uint32_t opc_cat : 3; |
||
309 | } instr_cat1_t; |
||
310 | |||
311 | typedef struct PACKED { |
||
312 | /* dword0: */ |
||
313 | uint32_t src1 : 11; |
||
314 | uint32_t src1_rel : 1; /* relative address */ |
||
315 | uint32_t src1_c : 1; /* const */ |
||
316 | uint32_t src1_im : 1; /* immediate */ |
||
317 | uint32_t src1_neg : 1; /* negate */ |
||
318 | uint32_t src1_abs : 1; /* absolute value */ |
||
319 | |||
320 | uint32_t src2 : 11; |
||
321 | uint32_t src2_rel : 1; /* relative address */ |
||
322 | uint32_t src2_c : 1; /* const */ |
||
323 | uint32_t src2_im : 1; /* immediate */ |
||
324 | uint32_t src2_neg : 1; /* negate */ |
||
325 | uint32_t src2_abs : 1; /* absolute value */ |
||
326 | |||
327 | /* dword1: */ |
||
328 | uint32_t dst : 8; |
||
329 | uint32_t repeat : 3; |
||
330 | uint32_t src1_r : 1; |
||
331 | uint32_t ss : 1; |
||
332 | uint32_t ul : 1; /* dunno */ |
||
333 | uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */ |
||
334 | uint32_t ei : 1; |
||
335 | uint32_t cond : 3; |
||
336 | uint32_t src2_r : 1; |
||
337 | uint32_t full : 1; /* not half */ |
||
338 | uint32_t opc : 6; |
||
339 | uint32_t jmp_tgt : 1; |
||
340 | uint32_t sync : 1; |
||
341 | uint32_t opc_cat : 3; |
||
342 | } instr_cat2_t; |
||
343 | |||
344 | typedef struct PACKED { |
||
345 | /* dword0: */ |
||
346 | uint32_t src1 : 11; |
||
347 | uint32_t src1_rel : 1; |
||
348 | uint32_t src1_c : 1; |
||
349 | uint32_t src2_c : 1; |
||
350 | uint32_t src1_neg : 1; |
||
351 | uint32_t src2_r : 1; |
||
352 | uint32_t src3 : 11; |
||
353 | uint32_t src3_rel : 1; |
||
354 | uint32_t src3_c : 1; |
||
355 | uint32_t src3_r : 1; |
||
356 | uint32_t src2_neg : 1; |
||
357 | uint32_t src3_neg : 1; |
||
358 | |||
359 | /* dword1: */ |
||
360 | uint32_t dst : 8; |
||
361 | uint32_t repeat : 3; |
||
362 | uint32_t src1_r : 1; |
||
363 | uint32_t ss : 1; |
||
364 | uint32_t ul : 1; |
||
365 | uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */ |
||
366 | uint32_t src2 : 8; |
||
367 | uint32_t opc : 4; |
||
368 | uint32_t jmp_tgt : 1; |
||
369 | uint32_t sync : 1; |
||
370 | uint32_t opc_cat : 3; |
||
371 | } instr_cat3_t; |
||
372 | |||
373 | typedef struct PACKED { |
||
374 | /* dword0: */ |
||
375 | uint32_t src : 11; |
||
376 | uint32_t src_rel : 1; |
||
377 | uint32_t src_c : 1; |
||
378 | uint32_t src_im : 1; |
||
379 | uint32_t src_neg : 1; |
||
380 | uint32_t src_abs : 1; |
||
381 | uint32_t dummy1 : 16; /* seem to be ignored */ |
||
382 | |||
383 | /* dword1: */ |
||
384 | uint32_t dst : 8; |
||
385 | uint32_t repeat : 3; |
||
386 | uint32_t src_r : 1; |
||
387 | uint32_t ss : 1; |
||
388 | uint32_t ul : 1; |
||
389 | uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */ |
||
390 | uint32_t dummy2 : 5; /* seem to be ignored */ |
||
391 | uint32_t full : 1; /* not half */ |
||
392 | uint32_t opc : 6; |
||
393 | uint32_t jmp_tgt : 1; |
||
394 | uint32_t sync : 1; |
||
395 | uint32_t opc_cat : 3; |
||
396 | } instr_cat4_t; |
||
397 | |||
398 | typedef struct PACKED { |
||
399 | /* dword0: */ |
||
400 | union PACKED { |
||
401 | /* normal case: */ |
||
402 | struct PACKED { |
||
403 | uint32_t full : 1; /* not half */ |
||
404 | uint32_t src1 : 8; |
||
405 | uint32_t src2 : 8; |
||
406 | uint32_t dummy1 : 4; /* seem to be ignored */ |
||
407 | uint32_t samp : 4; |
||
408 | uint32_t tex : 7; |
||
409 | } norm; |
||
410 | /* s2en case: */ |
||
411 | struct PACKED { |
||
412 | uint32_t full : 1; /* not half */ |
||
413 | uint32_t src1 : 8; |
||
414 | uint32_t src2 : 11; |
||
415 | uint32_t dummy1 : 1; |
||
416 | uint32_t src3 : 8; |
||
417 | uint32_t dummy2 : 3; |
||
418 | } s2en; |
||
419 | /* same in either case: */ |
||
420 | // XXX I think, confirm this |
||
421 | struct PACKED { |
||
422 | uint32_t full : 1; /* not half */ |
||
423 | uint32_t src1 : 8; |
||
424 | uint32_t pad : 23; |
||
425 | }; |
||
426 | }; |
||
427 | |||
428 | /* dword1: */ |
||
429 | uint32_t dst : 8; |
||
430 | uint32_t wrmask : 4; /* write-mask */ |
||
431 | uint32_t type : 3; |
||
432 | uint32_t dummy2 : 1; /* seems to be ignored */ |
||
433 | uint32_t is_3d : 1; |
||
434 | |||
435 | uint32_t is_a : 1; |
||
436 | uint32_t is_s : 1; |
||
437 | uint32_t is_s2en : 1; |
||
438 | uint32_t is_o : 1; |
||
439 | uint32_t is_p : 1; |
||
440 | |||
441 | uint32_t opc : 5; |
||
442 | uint32_t jmp_tgt : 1; |
||
443 | uint32_t sync : 1; |
||
444 | uint32_t opc_cat : 3; |
||
445 | } instr_cat5_t; |
||
446 | |||
447 | /* used for load instructions: */ |
||
448 | typedef struct PACKED { |
||
449 | /* dword0: */ |
||
450 | uint32_t must_be_one1 : 1; |
||
451 | int16_t off : 13; |
||
452 | uint32_t src : 8; |
||
453 | uint32_t dummy1 : 1; |
||
454 | uint32_t must_be_one2 : 1; |
||
455 | int32_t iim_val : 8; |
||
456 | |||
457 | /* dword1: */ |
||
458 | uint32_t dst : 8; |
||
459 | uint32_t dummy2 : 9; |
||
460 | uint32_t type : 3; |
||
461 | uint32_t dummy3 : 2; |
||
462 | uint32_t opc : 5; |
||
463 | uint32_t jmp_tgt : 1; |
||
464 | uint32_t sync : 1; |
||
465 | uint32_t opc_cat : 3; |
||
466 | } instr_cat6a_t; |
||
467 | |||
468 | /* used for store instructions: */ |
||
469 | typedef struct PACKED { |
||
470 | /* dword0: */ |
||
471 | uint32_t must_be_zero1 : 1; |
||
472 | uint32_t src : 8; |
||
473 | uint32_t off_hi : 5; /* high bits of 'off'... ugly! */ |
||
474 | uint32_t dummy1 : 9; |
||
475 | uint32_t must_be_one1 : 1; |
||
476 | int32_t iim_val : 8; |
||
477 | |||
478 | /* dword1: */ |
||
479 | uint16_t off : 8; |
||
480 | uint32_t must_be_one2 : 1; |
||
481 | uint32_t dst : 8; |
||
482 | uint32_t type : 3; |
||
483 | uint32_t dummy2 : 2; |
||
484 | uint32_t opc : 5; |
||
485 | uint32_t jmp_tgt : 1; |
||
486 | uint32_t sync : 1; |
||
487 | uint32_t opc_cat : 3; |
||
488 | } instr_cat6b_t; |
||
489 | |||
490 | typedef union PACKED { |
||
491 | instr_cat6a_t a; |
||
492 | instr_cat6b_t b; |
||
493 | struct PACKED { |
||
494 | /* dword0: */ |
||
495 | uint32_t pad1 : 24; |
||
496 | int32_t iim_val : 8; |
||
497 | |||
498 | /* dword1: */ |
||
499 | uint32_t pad2 : 17; |
||
500 | uint32_t type : 3; |
||
501 | uint32_t pad3 : 2; |
||
502 | uint32_t opc : 5; |
||
503 | uint32_t jmp_tgt : 1; |
||
504 | uint32_t sync : 1; |
||
505 | uint32_t opc_cat : 3; |
||
506 | }; |
||
507 | } instr_cat6_t; |
||
508 | |||
509 | typedef union PACKED { |
||
510 | instr_cat0_t cat0; |
||
511 | instr_cat1_t cat1; |
||
512 | instr_cat2_t cat2; |
||
513 | instr_cat3_t cat3; |
||
514 | instr_cat4_t cat4; |
||
515 | instr_cat5_t cat5; |
||
516 | instr_cat6_t cat6; |
||
517 | struct PACKED { |
||
518 | /* dword0: */ |
||
519 | uint64_t pad1 : 40; |
||
520 | uint32_t repeat : 3; /* cat0-cat4 */ |
||
521 | uint32_t pad2 : 1; |
||
522 | uint32_t ss : 1; /* cat1-cat4 (cat0??) */ |
||
523 | uint32_t ul : 1; /* cat2-cat4 (and cat1 in blob.. which may be bug??) */ |
||
524 | uint32_t pad3 : 13; |
||
525 | uint32_t jmp_tgt : 1; |
||
526 | uint32_t sync : 1; |
||
527 | uint32_t opc_cat : 3; |
||
528 | |||
529 | }; |
||
530 | } instr_t; |
||
531 | |||
532 | #endif /* INSTR_A3XX_H_ */->->-> |