freedreno/a3xx/compiler: prepare for new compiler
[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 static inline bool instr_cat3_full(instr_cat3_t *cat3)
442 {
443 switch (cat3->opc) {
444 case OPC_MAD_F16:
445 case OPC_MAD_U16:
446 case OPC_MAD_S16:
447 case OPC_SEL_B16:
448 case OPC_SEL_S16:
449 case OPC_SEL_F16:
450 case OPC_SAD_S16:
451 case OPC_SAD_S32: // really??
452 return false;
453 default:
454 return true;
455 }
456 }
457
458 typedef struct PACKED {
459 /* dword0: */
460 union PACKED {
461 struct PACKED {
462 uint32_t src : 11;
463 uint32_t must_be_zero1: 2;
464 uint32_t src_im : 1; /* immediate */
465 uint32_t src_neg : 1; /* negate */
466 uint32_t src_abs : 1; /* absolute value */
467 };
468 struct PACKED {
469 uint32_t src : 10;
470 uint32_t src_c : 1; /* relative-const */
471 uint32_t src_rel : 1; /* relative address */
472 uint32_t must_be_zero : 1;
473 uint32_t dummy : 3;
474 } rel;
475 struct PACKED {
476 uint32_t src : 12;
477 uint32_t src_c : 1; /* const */
478 uint32_t dummy : 3;
479 } c;
480 };
481 uint32_t dummy1 : 16; /* seem to be ignored */
482
483 /* dword1: */
484 uint32_t dst : 8;
485 uint32_t repeat : 3;
486 uint32_t src_r : 1;
487 uint32_t ss : 1;
488 uint32_t ul : 1;
489 uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */
490 uint32_t dummy2 : 5; /* seem to be ignored */
491 uint32_t full : 1; /* not half */
492 uint32_t opc : 6;
493 uint32_t jmp_tgt : 1;
494 uint32_t sync : 1;
495 uint32_t opc_cat : 3;
496 } instr_cat4_t;
497
498 typedef struct PACKED {
499 /* dword0: */
500 union PACKED {
501 /* normal case: */
502 struct PACKED {
503 uint32_t full : 1; /* not half */
504 uint32_t src1 : 8;
505 uint32_t src2 : 8;
506 uint32_t dummy1 : 4; /* seem to be ignored */
507 uint32_t samp : 4;
508 uint32_t tex : 7;
509 } norm;
510 /* s2en case: */
511 struct PACKED {
512 uint32_t full : 1; /* not half */
513 uint32_t src1 : 8;
514 uint32_t src2 : 11;
515 uint32_t dummy1 : 1;
516 uint32_t src3 : 8;
517 uint32_t dummy2 : 3;
518 } s2en;
519 /* same in either case: */
520 // XXX I think, confirm this
521 struct PACKED {
522 uint32_t full : 1; /* not half */
523 uint32_t src1 : 8;
524 uint32_t pad : 23;
525 };
526 };
527
528 /* dword1: */
529 uint32_t dst : 8;
530 uint32_t wrmask : 4; /* write-mask */
531 uint32_t type : 3;
532 uint32_t dummy2 : 1; /* seems to be ignored */
533 uint32_t is_3d : 1;
534
535 uint32_t is_a : 1;
536 uint32_t is_s : 1;
537 uint32_t is_s2en : 1;
538 uint32_t is_o : 1;
539 uint32_t is_p : 1;
540
541 uint32_t opc : 5;
542 uint32_t jmp_tgt : 1;
543 uint32_t sync : 1;
544 uint32_t opc_cat : 3;
545 } instr_cat5_t;
546
547 /* used for load instructions: */
548 typedef struct PACKED {
549 /* dword0: */
550 uint32_t must_be_one1 : 1;
551 int16_t off : 13;
552 uint32_t src : 8;
553 uint32_t dummy1 : 1;
554 uint32_t must_be_one2 : 1;
555 int32_t iim_val : 8;
556
557 /* dword1: */
558 uint32_t dst : 8;
559 uint32_t dummy2 : 9;
560 uint32_t type : 3;
561 uint32_t dummy3 : 2;
562 uint32_t opc : 5;
563 uint32_t jmp_tgt : 1;
564 uint32_t sync : 1;
565 uint32_t opc_cat : 3;
566 } instr_cat6a_t;
567
568 /* used for store instructions: */
569 typedef struct PACKED {
570 /* dword0: */
571 uint32_t must_be_zero1 : 1;
572 uint32_t src : 8;
573 uint32_t off_hi : 5; /* high bits of 'off'... ugly! */
574 uint32_t dummy1 : 9;
575 uint32_t must_be_one1 : 1;
576 int32_t iim_val : 8;
577
578 /* dword1: */
579 uint16_t off : 8;
580 uint32_t must_be_one2 : 1;
581 uint32_t dst : 8;
582 uint32_t type : 3;
583 uint32_t dummy2 : 2;
584 uint32_t opc : 5;
585 uint32_t jmp_tgt : 1;
586 uint32_t sync : 1;
587 uint32_t opc_cat : 3;
588 } instr_cat6b_t;
589
590 typedef union PACKED {
591 instr_cat6a_t a;
592 instr_cat6b_t b;
593 struct PACKED {
594 /* dword0: */
595 uint32_t pad1 : 24;
596 int32_t iim_val : 8;
597
598 /* dword1: */
599 uint32_t pad2 : 17;
600 uint32_t type : 3;
601 uint32_t pad3 : 2;
602 uint32_t opc : 5;
603 uint32_t jmp_tgt : 1;
604 uint32_t sync : 1;
605 uint32_t opc_cat : 3;
606 };
607 } instr_cat6_t;
608
609 typedef union PACKED {
610 instr_cat0_t cat0;
611 instr_cat1_t cat1;
612 instr_cat2_t cat2;
613 instr_cat3_t cat3;
614 instr_cat4_t cat4;
615 instr_cat5_t cat5;
616 instr_cat6_t cat6;
617 struct PACKED {
618 /* dword0: */
619 uint64_t pad1 : 40;
620 uint32_t repeat : 3; /* cat0-cat4 */
621 uint32_t pad2 : 1;
622 uint32_t ss : 1; /* cat1-cat4 (cat0??) */
623 uint32_t ul : 1; /* cat2-cat4 (and cat1 in blob.. which may be bug??) */
624 uint32_t pad3 : 13;
625 uint32_t jmp_tgt : 1;
626 uint32_t sync : 1;
627 uint32_t opc_cat : 3;
628
629 };
630 } instr_t;
631
632 static inline uint32_t instr_opc(instr_t *instr)
633 {
634 switch (instr->opc_cat) {
635 case 0: return instr->cat0.opc;
636 case 1: return 0;
637 case 2: return instr->cat2.opc;
638 case 3: return instr->cat3.opc;
639 case 4: return instr->cat4.opc;
640 case 5: return instr->cat5.opc;
641 case 6: return instr->cat6.opc;
642 default: return 0;
643 }
644 }
645
646 #endif /* INSTR_A3XX_H_ */