1085ddf8c12e5423f3ce4e47849d6286aa7c85fa
[mesa.git] / src / gallium / drivers / freedreno / a3xx / instr-a3xx.h
1 /*
2 * Copyright (c) 2013 Rob Clark <robdclark@gmail.com>
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 <stdint.h>
30 #include <assert.h>
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 : 10;
236 };
237 /* for immediate val: */
238 int32_t iim_val : 11;
239 /* to make compiler happy: */
240 uint32_t dummy32;
241 uint32_t dummy10 : 10;
242 uint32_t dummy11 : 11;
243 uint32_t dummy12 : 12;
244 uint32_t dummy13 : 13;
245 uint32_t dummy8 : 8;
246 } reg_t;
247
248 /* special registers: */
249 #define REG_A0 61 /* address register */
250 #define REG_P0 62 /* predicate register */
251
252 static inline int reg_special(reg_t reg)
253 {
254 return (reg.num == REG_A0) || (reg.num == REG_P0);
255 }
256
257 typedef struct PACKED {
258 /* dword0: */
259 int16_t immed : 16;
260 uint32_t dummy1 : 16;
261
262 /* dword1: */
263 uint32_t dummy2 : 8;
264 uint32_t repeat : 3;
265 uint32_t dummy3 : 1;
266 uint32_t ss : 1;
267 uint32_t dummy4 : 7;
268 uint32_t inv : 1;
269 uint32_t comp : 2;
270 uint32_t opc : 4;
271 uint32_t jmp_tgt : 1;
272 uint32_t sync : 1;
273 uint32_t opc_cat : 3;
274 } instr_cat0_t;
275
276 typedef struct PACKED {
277 /* dword0: */
278 union PACKED {
279 /* for normal src register: */
280 struct PACKED {
281 uint32_t src : 11;
282 /* at least low bit of pad must be zero or it will
283 * look like a address relative src
284 */
285 uint32_t pad : 21;
286 };
287 /* for address relative: */
288 struct PACKED {
289 int32_t off : 10;
290 uint32_t src_rel_c : 1;
291 uint32_t src_rel : 1;
292 uint32_t unknown : 20;
293 };
294 /* for immediate: */
295 int32_t iim_val;
296 float fim_val;
297 };
298
299 /* dword1: */
300 uint32_t dst : 8;
301 uint32_t repeat : 3;
302 uint32_t src_r : 1;
303 uint32_t ss : 1;
304 uint32_t ul : 1;
305 uint32_t dst_type : 3;
306 uint32_t dst_rel : 1;
307 uint32_t src_type : 3;
308 uint32_t src_c : 1;
309 uint32_t src_im : 1;
310 uint32_t even : 1;
311 uint32_t pos_inf : 1;
312 uint32_t must_be_0 : 2;
313 uint32_t jmp_tgt : 1;
314 uint32_t sync : 1;
315 uint32_t opc_cat : 3;
316 } instr_cat1_t;
317
318 typedef struct PACKED {
319 /* dword0: */
320 union PACKED {
321 struct PACKED {
322 uint32_t src1 : 11;
323 uint32_t must_be_zero1: 2;
324 uint32_t src1_im : 1; /* immediate */
325 uint32_t src1_neg : 1; /* negate */
326 uint32_t src1_abs : 1; /* absolute value */
327 };
328 struct PACKED {
329 uint32_t src1 : 10;
330 uint32_t src1_c : 1; /* relative-const */
331 uint32_t src1_rel : 1; /* relative address */
332 uint32_t must_be_zero : 1;
333 uint32_t dummy : 3;
334 } rel1;
335 struct PACKED {
336 uint32_t src1 : 12;
337 uint32_t src1_c : 1; /* const */
338 uint32_t dummy : 3;
339 } c1;
340 };
341
342 union PACKED {
343 struct PACKED {
344 uint32_t src2 : 11;
345 uint32_t must_be_zero2: 2;
346 uint32_t src2_im : 1; /* immediate */
347 uint32_t src2_neg : 1; /* negate */
348 uint32_t src2_abs : 1; /* absolute value */
349 };
350 struct PACKED {
351 uint32_t src2 : 10;
352 uint32_t src2_c : 1; /* relative-const */
353 uint32_t src2_rel : 1; /* relative address */
354 uint32_t must_be_zero : 1;
355 uint32_t dummy : 3;
356 } rel2;
357 struct PACKED {
358 uint32_t src2 : 12;
359 uint32_t src2_c : 1; /* const */
360 uint32_t dummy : 3;
361 } c2;
362 };
363
364 /* dword1: */
365 uint32_t dst : 8;
366 uint32_t repeat : 3;
367 uint32_t src1_r : 1;
368 uint32_t ss : 1;
369 uint32_t ul : 1; /* dunno */
370 uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */
371 uint32_t ei : 1;
372 uint32_t cond : 3;
373 uint32_t src2_r : 1;
374 uint32_t full : 1; /* not half */
375 uint32_t opc : 6;
376 uint32_t jmp_tgt : 1;
377 uint32_t sync : 1;
378 uint32_t opc_cat : 3;
379 } instr_cat2_t;
380
381 typedef struct PACKED {
382 /* dword0: */
383 union PACKED {
384 struct PACKED {
385 uint32_t src1 : 11;
386 uint32_t must_be_zero1: 2;
387 uint32_t src2_c : 1;
388 uint32_t src1_neg : 1;
389 uint32_t src2_r : 1;
390 };
391 struct PACKED {
392 uint32_t src1 : 10;
393 uint32_t src1_c : 1;
394 uint32_t src1_rel : 1;
395 uint32_t must_be_zero : 1;
396 uint32_t dummy : 3;
397 } rel1;
398 struct PACKED {
399 uint32_t src1 : 12;
400 uint32_t src1_c : 1;
401 uint32_t dummy : 3;
402 } c1;
403 };
404
405 union PACKED {
406 struct PACKED {
407 uint32_t src3 : 11;
408 uint32_t must_be_zero2: 2;
409 uint32_t src3_r : 1;
410 uint32_t src2_neg : 1;
411 uint32_t src3_neg : 1;
412 };
413 struct PACKED {
414 uint32_t src3 : 10;
415 uint32_t src3_c : 1;
416 uint32_t src3_rel : 1;
417 uint32_t must_be_zero : 1;
418 uint32_t dummy : 3;
419 } rel2;
420 struct PACKED {
421 uint32_t src3 : 12;
422 uint32_t src3_c : 1;
423 uint32_t dummy : 3;
424 } c2;
425 };
426
427 /* dword1: */
428 uint32_t dst : 8;
429 uint32_t repeat : 3;
430 uint32_t src1_r : 1;
431 uint32_t ss : 1;
432 uint32_t ul : 1;
433 uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */
434 uint32_t src2 : 8;
435 uint32_t opc : 4;
436 uint32_t jmp_tgt : 1;
437 uint32_t sync : 1;
438 uint32_t opc_cat : 3;
439 } instr_cat3_t;
440
441 typedef struct PACKED {
442 /* dword0: */
443 union PACKED {
444 struct PACKED {
445 uint32_t src : 11;
446 uint32_t must_be_zero1: 2;
447 uint32_t src_im : 1; /* immediate */
448 uint32_t src_neg : 1; /* negate */
449 uint32_t src_abs : 1; /* absolute value */
450 };
451 struct PACKED {
452 uint32_t src : 10;
453 uint32_t src_c : 1; /* relative-const */
454 uint32_t src_rel : 1; /* relative address */
455 uint32_t must_be_zero : 1;
456 uint32_t dummy : 3;
457 } rel;
458 struct PACKED {
459 uint32_t src : 12;
460 uint32_t src_c : 1; /* const */
461 uint32_t dummy : 3;
462 } c;
463 };
464 uint32_t dummy1 : 16; /* seem to be ignored */
465
466 /* dword1: */
467 uint32_t dst : 8;
468 uint32_t repeat : 3;
469 uint32_t src_r : 1;
470 uint32_t ss : 1;
471 uint32_t ul : 1;
472 uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */
473 uint32_t dummy2 : 5; /* seem to be ignored */
474 uint32_t full : 1; /* not half */
475 uint32_t opc : 6;
476 uint32_t jmp_tgt : 1;
477 uint32_t sync : 1;
478 uint32_t opc_cat : 3;
479 } instr_cat4_t;
480
481 typedef struct PACKED {
482 /* dword0: */
483 union PACKED {
484 /* normal case: */
485 struct PACKED {
486 uint32_t full : 1; /* not half */
487 uint32_t src1 : 8;
488 uint32_t src2 : 8;
489 uint32_t dummy1 : 4; /* seem to be ignored */
490 uint32_t samp : 4;
491 uint32_t tex : 7;
492 } norm;
493 /* s2en case: */
494 struct PACKED {
495 uint32_t full : 1; /* not half */
496 uint32_t src1 : 8;
497 uint32_t src2 : 11;
498 uint32_t dummy1 : 1;
499 uint32_t src3 : 8;
500 uint32_t dummy2 : 3;
501 } s2en;
502 /* same in either case: */
503 // XXX I think, confirm this
504 struct PACKED {
505 uint32_t full : 1; /* not half */
506 uint32_t src1 : 8;
507 uint32_t pad : 23;
508 };
509 };
510
511 /* dword1: */
512 uint32_t dst : 8;
513 uint32_t wrmask : 4; /* write-mask */
514 uint32_t type : 3;
515 uint32_t dummy2 : 1; /* seems to be ignored */
516 uint32_t is_3d : 1;
517
518 uint32_t is_a : 1;
519 uint32_t is_s : 1;
520 uint32_t is_s2en : 1;
521 uint32_t is_o : 1;
522 uint32_t is_p : 1;
523
524 uint32_t opc : 5;
525 uint32_t jmp_tgt : 1;
526 uint32_t sync : 1;
527 uint32_t opc_cat : 3;
528 } instr_cat5_t;
529
530 /* used for load instructions: */
531 typedef struct PACKED {
532 /* dword0: */
533 uint32_t must_be_one1 : 1;
534 int16_t off : 13;
535 uint32_t src : 8;
536 uint32_t dummy1 : 1;
537 uint32_t must_be_one2 : 1;
538 int32_t iim_val : 8;
539
540 /* dword1: */
541 uint32_t dst : 8;
542 uint32_t dummy2 : 9;
543 uint32_t type : 3;
544 uint32_t dummy3 : 2;
545 uint32_t opc : 5;
546 uint32_t jmp_tgt : 1;
547 uint32_t sync : 1;
548 uint32_t opc_cat : 3;
549 } instr_cat6a_t;
550
551 /* used for store instructions: */
552 typedef struct PACKED {
553 /* dword0: */
554 uint32_t must_be_zero1 : 1;
555 uint32_t src : 8;
556 uint32_t off_hi : 5; /* high bits of 'off'... ugly! */
557 uint32_t dummy1 : 9;
558 uint32_t must_be_one1 : 1;
559 int32_t iim_val : 8;
560
561 /* dword1: */
562 uint16_t off : 8;
563 uint32_t must_be_one2 : 1;
564 uint32_t dst : 8;
565 uint32_t type : 3;
566 uint32_t dummy2 : 2;
567 uint32_t opc : 5;
568 uint32_t jmp_tgt : 1;
569 uint32_t sync : 1;
570 uint32_t opc_cat : 3;
571 } instr_cat6b_t;
572
573 typedef union PACKED {
574 instr_cat6a_t a;
575 instr_cat6b_t b;
576 struct PACKED {
577 /* dword0: */
578 uint32_t pad1 : 24;
579 int32_t iim_val : 8;
580
581 /* dword1: */
582 uint32_t pad2 : 17;
583 uint32_t type : 3;
584 uint32_t pad3 : 2;
585 uint32_t opc : 5;
586 uint32_t jmp_tgt : 1;
587 uint32_t sync : 1;
588 uint32_t opc_cat : 3;
589 };
590 } instr_cat6_t;
591
592 typedef union PACKED {
593 instr_cat0_t cat0;
594 instr_cat1_t cat1;
595 instr_cat2_t cat2;
596 instr_cat3_t cat3;
597 instr_cat4_t cat4;
598 instr_cat5_t cat5;
599 instr_cat6_t cat6;
600 struct PACKED {
601 /* dword0: */
602 uint64_t pad1 : 40;
603 uint32_t repeat : 3; /* cat0-cat4 */
604 uint32_t pad2 : 1;
605 uint32_t ss : 1; /* cat1-cat4 (cat0??) */
606 uint32_t ul : 1; /* cat2-cat4 (and cat1 in blob.. which may be bug??) */
607 uint32_t pad3 : 13;
608 uint32_t jmp_tgt : 1;
609 uint32_t sync : 1;
610 uint32_t opc_cat : 3;
611
612 };
613 } instr_t;
614
615 #endif /* INSTR_A3XX_H_ */