Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 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
	/* meta instructions (category -1): */
194
	/* placeholder instr to mark inputs/outputs: */
195
	OPC_META_INPUT = 0,
196
	OPC_META_OUTPUT = 1,
197
	/* The "fan-in" and "fan-out" instructions are used for keeping
198
	 * track of instructions that write to multiple dst registers
199
	 * (fan-out) like texture sample instructions, or read multiple
200
	 * consecutive scalar registers (fan-in) (bary.f, texture samp)
201
	 */
202
	OPC_META_FO = 2,
203
	OPC_META_FI = 3,
204
	/* branches/flow control */
205
	OPC_META_FLOW = 4,
206
	OPC_META_PHI = 5,
207
 
208
} opc_t;
209
 
210
typedef enum {
211
	TYPE_F16 = 0,
212
	TYPE_F32 = 1,
213
	TYPE_U16 = 2,
214
	TYPE_U32 = 3,
215
	TYPE_S16 = 4,
216
	TYPE_S32 = 5,
217
	TYPE_U8  = 6,
218
	TYPE_S8  = 7,  // XXX I assume?
219
} type_t;
220
 
221
static inline uint32_t type_size(type_t type)
222
{
223
	switch (type) {
224
	case TYPE_F32:
225
	case TYPE_U32:
226
	case TYPE_S32:
227
		return 32;
228
	case TYPE_F16:
229
	case TYPE_U16:
230
	case TYPE_S16:
231
		return 16;
232
	case TYPE_U8:
233
	case TYPE_S8:
234
		return 8;
235
	default:
236
		assert(0); /* invalid type */
237
		return 0;
238
	}
239
}
240
 
241
static inline int type_float(type_t type)
242
{
243
	return (type == TYPE_F32) || (type == TYPE_F16);
244
}
245
 
246
static inline int type_uint(type_t type)
247
{
248
	return (type == TYPE_U32) || (type == TYPE_U16) || (type == TYPE_U8);
249
}
250
 
251
static inline int type_sint(type_t type)
252
{
253
	return (type == TYPE_S32) || (type == TYPE_S16) || (type == TYPE_S8);
254
}
255
 
256
typedef union PACKED {
257
	/* normal gpr or const src register: */
258
	struct PACKED {
259
		uint32_t comp  : 2;
260
		uint32_t num   : 10;
261
	};
262
	/* for immediate val: */
263
	int32_t  iim_val   : 11;
264
	/* to make compiler happy: */
265
	uint32_t dummy32;
266
	uint32_t dummy10   : 10;
267
	uint32_t dummy11   : 11;
268
	uint32_t dummy12   : 12;
269
	uint32_t dummy13   : 13;
270
	uint32_t dummy8    : 8;
271
} reg_t;
272
 
273
/* special registers: */
274
#define REG_A0 61       /* address register */
275
#define REG_P0 62       /* predicate register */
276
 
277
static inline int reg_special(reg_t reg)
278
{
279
	return (reg.num == REG_A0) || (reg.num == REG_P0);
280
}
281
 
282
typedef struct PACKED {
283
	/* dword0: */
284
	int16_t  immed    : 16;
285
	uint32_t dummy1   : 16;
286
 
287
	/* dword1: */
288
	uint32_t dummy2   : 8;
289
	uint32_t repeat   : 3;
290
	uint32_t dummy3   : 1;
291
	uint32_t ss       : 1;
292
	uint32_t dummy4   : 7;
293
	uint32_t inv      : 1;
294
	uint32_t comp     : 2;
295
	uint32_t opc      : 4;
296
	uint32_t jmp_tgt  : 1;
297
	uint32_t sync     : 1;
298
	uint32_t opc_cat  : 3;
299
} instr_cat0_t;
300
 
301
typedef struct PACKED {
302
	/* dword0: */
303
	union PACKED {
304
		/* for normal src register: */
305
		struct PACKED {
306
			uint32_t src : 11;
307
			/* at least low bit of pad must be zero or it will
308
			 * look like a address relative src
309
			 */
310
			uint32_t pad : 21;
311
		};
312
		/* for address relative: */
313
		struct PACKED {
314
			int32_t  off : 10;
315
			uint32_t src_rel_c : 1;
316
			uint32_t src_rel : 1;
317
			uint32_t unknown : 20;
318
		};
319
		/* for immediate: */
320
		int32_t  iim_val;
321
		uint32_t uim_val;
322
		float    fim_val;
323
	};
324
 
325
	/* dword1: */
326
	uint32_t dst        : 8;
327
	uint32_t repeat     : 3;
328
	uint32_t src_r      : 1;
329
	uint32_t ss         : 1;
330
	uint32_t ul         : 1;
331
	uint32_t dst_type   : 3;
332
	uint32_t dst_rel    : 1;
333
	uint32_t src_type   : 3;
334
	uint32_t src_c      : 1;
335
	uint32_t src_im     : 1;
336
	uint32_t even       : 1;
337
	uint32_t pos_inf    : 1;
338
	uint32_t must_be_0  : 2;
339
	uint32_t jmp_tgt    : 1;
340
	uint32_t sync       : 1;
341
	uint32_t opc_cat    : 3;
342
} instr_cat1_t;
343
 
344
typedef struct PACKED {
345
	/* dword0: */
346
	union PACKED {
347
		struct PACKED {
348
			uint32_t src1         : 11;
349
			uint32_t must_be_zero1: 2;
350
			uint32_t src1_im      : 1;   /* immediate */
351
			uint32_t src1_neg     : 1;   /* negate */
352
			uint32_t src1_abs     : 1;   /* absolute value */
353
		};
354
		struct PACKED {
355
			uint32_t src1         : 10;
356
			uint32_t src1_c       : 1;   /* relative-const */
357
			uint32_t src1_rel     : 1;   /* relative address */
358
			uint32_t must_be_zero : 1;
359
			uint32_t dummy        : 3;
360
		} rel1;
361
		struct PACKED {
362
			uint32_t src1         : 12;
363
			uint32_t src1_c       : 1;   /* const */
364
			uint32_t dummy        : 3;
365
		} c1;
366
	};
367
 
368
	union PACKED {
369
		struct PACKED {
370
			uint32_t src2         : 11;
371
			uint32_t must_be_zero2: 2;
372
			uint32_t src2_im      : 1;   /* immediate */
373
			uint32_t src2_neg     : 1;   /* negate */
374
			uint32_t src2_abs     : 1;   /* absolute value */
375
		};
376
		struct PACKED {
377
			uint32_t src2         : 10;
378
			uint32_t src2_c       : 1;   /* relative-const */
379
			uint32_t src2_rel     : 1;   /* relative address */
380
			uint32_t must_be_zero : 1;
381
			uint32_t dummy        : 3;
382
		} rel2;
383
		struct PACKED {
384
			uint32_t src2         : 12;
385
			uint32_t src2_c       : 1;   /* const */
386
			uint32_t dummy        : 3;
387
		} c2;
388
	};
389
 
390
	/* dword1: */
391
	uint32_t dst      : 8;
392
	uint32_t repeat   : 3;
393
	uint32_t src1_r   : 1;
394
	uint32_t ss       : 1;
395
	uint32_t ul       : 1;   /* dunno */
396
	uint32_t dst_half : 1;   /* or widen/narrow.. ie. dst hrN <-> rN */
397
	uint32_t ei       : 1;
398
	uint32_t cond     : 3;
399
	uint32_t src2_r   : 1;
400
	uint32_t full     : 1;   /* not half */
401
	uint32_t opc      : 6;
402
	uint32_t jmp_tgt  : 1;
403
	uint32_t sync     : 1;
404
	uint32_t opc_cat  : 3;
405
} instr_cat2_t;
406
 
407
typedef struct PACKED {
408
	/* dword0: */
409
	union PACKED {
410
		struct PACKED {
411
			uint32_t src1         : 11;
412
			uint32_t must_be_zero1: 2;
413
			uint32_t src2_c       : 1;
414
			uint32_t src1_neg     : 1;
415
			uint32_t src2_r       : 1;
416
		};
417
		struct PACKED {
418
			uint32_t src1         : 10;
419
			uint32_t src1_c       : 1;
420
			uint32_t src1_rel     : 1;
421
			uint32_t must_be_zero : 1;
422
			uint32_t dummy        : 3;
423
		} rel1;
424
		struct PACKED {
425
			uint32_t src1         : 12;
426
			uint32_t src1_c       : 1;
427
			uint32_t dummy        : 3;
428
		} c1;
429
	};
430
 
431
	union PACKED {
432
		struct PACKED {
433
			uint32_t src3         : 11;
434
			uint32_t must_be_zero2: 2;
435
			uint32_t src3_r       : 1;
436
			uint32_t src2_neg     : 1;
437
			uint32_t src3_neg     : 1;
438
		};
439
		struct PACKED {
440
			uint32_t src3         : 10;
441
			uint32_t src3_c       : 1;
442
			uint32_t src3_rel     : 1;
443
			uint32_t must_be_zero : 1;
444
			uint32_t dummy        : 3;
445
		} rel2;
446
		struct PACKED {
447
			uint32_t src3         : 12;
448
			uint32_t src3_c       : 1;
449
			uint32_t dummy        : 3;
450
		} c2;
451
	};
452
 
453
	/* dword1: */
454
	uint32_t dst      : 8;
455
	uint32_t repeat   : 3;
456
	uint32_t src1_r   : 1;
457
	uint32_t ss       : 1;
458
	uint32_t ul       : 1;
459
	uint32_t dst_half : 1;   /* or widen/narrow.. ie. dst hrN <-> rN */
460
	uint32_t src2     : 8;
461
	uint32_t opc      : 4;
462
	uint32_t jmp_tgt  : 1;
463
	uint32_t sync     : 1;
464
	uint32_t opc_cat  : 3;
465
} instr_cat3_t;
466
 
467
static inline bool instr_cat3_full(instr_cat3_t *cat3)
468
{
469
	switch (cat3->opc) {
470
	case OPC_MAD_F16:
471
	case OPC_MAD_U16:
472
	case OPC_MAD_S16:
473
	case OPC_SEL_B16:
474
	case OPC_SEL_S16:
475
	case OPC_SEL_F16:
476
	case OPC_SAD_S16:
477
	case OPC_SAD_S32:  // really??
478
		return false;
479
	default:
480
		return true;
481
	}
482
}
483
 
484
typedef struct PACKED {
485
	/* dword0: */
486
	union PACKED {
487
		struct PACKED {
488
			uint32_t src          : 11;
489
			uint32_t must_be_zero1: 2;
490
			uint32_t src_im       : 1;   /* immediate */
491
			uint32_t src_neg      : 1;   /* negate */
492
			uint32_t src_abs      : 1;   /* absolute value */
493
		};
494
		struct PACKED {
495
			uint32_t src          : 10;
496
			uint32_t src_c        : 1;   /* relative-const */
497
			uint32_t src_rel      : 1;   /* relative address */
498
			uint32_t must_be_zero : 1;
499
			uint32_t dummy        : 3;
500
		} rel;
501
		struct PACKED {
502
			uint32_t src          : 12;
503
			uint32_t src_c        : 1;   /* const */
504
			uint32_t dummy        : 3;
505
		} c;
506
	};
507
	uint32_t dummy1   : 16;  /* seem to be ignored */
508
 
509
	/* dword1: */
510
	uint32_t dst      : 8;
511
	uint32_t repeat   : 3;
512
	uint32_t src_r    : 1;
513
	uint32_t ss       : 1;
514
	uint32_t ul       : 1;
515
	uint32_t dst_half : 1;   /* or widen/narrow.. ie. dst hrN <-> rN */
516
	uint32_t dummy2   : 5;   /* seem to be ignored */
517
	uint32_t full     : 1;   /* not half */
518
	uint32_t opc      : 6;
519
	uint32_t jmp_tgt  : 1;
520
	uint32_t sync     : 1;
521
	uint32_t opc_cat  : 3;
522
} instr_cat4_t;
523
 
524
typedef struct PACKED {
525
	/* dword0: */
526
	union PACKED {
527
		/* normal case: */
528
		struct PACKED {
529
			uint32_t full     : 1;   /* not half */
530
			uint32_t src1     : 8;
531
			uint32_t src2     : 8;
532
			uint32_t dummy1   : 4;   /* seem to be ignored */
533
			uint32_t samp     : 4;
534
			uint32_t tex      : 7;
535
		} norm;
536
		/* s2en case: */
537
		struct PACKED {
538
			uint32_t full     : 1;   /* not half */
539
			uint32_t src1     : 8;
540
			uint32_t src2     : 11;
541
			uint32_t dummy1   : 1;
542
			uint32_t src3     : 8;
543
			uint32_t dummy2   : 3;
544
		} s2en;
545
		/* same in either case: */
546
		// XXX I think, confirm this
547
		struct PACKED {
548
			uint32_t full     : 1;   /* not half */
549
			uint32_t src1     : 8;
550
			uint32_t pad      : 23;
551
		};
552
	};
553
 
554
	/* dword1: */
555
	uint32_t dst      : 8;
556
	uint32_t wrmask   : 4;   /* write-mask */
557
	uint32_t type     : 3;
558
	uint32_t dummy2   : 1;   /* seems to be ignored */
559
	uint32_t is_3d    : 1;
560
 
561
	uint32_t is_a     : 1;
562
	uint32_t is_s     : 1;
563
	uint32_t is_s2en  : 1;
564
	uint32_t is_o     : 1;
565
	uint32_t is_p     : 1;
566
 
567
	uint32_t opc      : 5;
568
	uint32_t jmp_tgt  : 1;
569
	uint32_t sync     : 1;
570
	uint32_t opc_cat  : 3;
571
} instr_cat5_t;
572
 
573
/* [src1 + off], src2: */
574
typedef struct PACKED {
575
	/* dword0: */
576
	uint32_t mustbe1  : 1;
577
	int32_t  off      : 13;
578
	uint32_t src1     : 8;
579
	uint32_t src1_im  : 1;
580
	uint32_t src2_im  : 1;
581
	uint32_t src2     : 8;
582
 
583
	/* dword1: */
584
	uint32_t dst      : 8;
585
	uint32_t dummy2   : 9;
586
	uint32_t type     : 3;
587
	uint32_t dummy3   : 2;
588
	uint32_t opc      : 5;
589
	uint32_t jmp_tgt  : 1;
590
	uint32_t sync     : 1;
591
	uint32_t opc_cat  : 3;
592
} instr_cat6a_t;
593
 
594
/* [src1], src2: */
595
typedef struct PACKED {
596
	/* dword0: */
597
	uint32_t mustbe0  : 1;
598
	uint32_t src1     : 8;
599
	uint32_t ignore0  : 13;
600
	uint32_t src1_im  : 1;
601
	uint32_t src2_im  : 1;
602
	uint32_t src2     : 8;
603
 
604
	/* dword1: */
605
	uint32_t dst      : 8;
606
	uint32_t dummy2   : 9;
607
	uint32_t type     : 3;
608
	uint32_t dummy3   : 2;
609
	uint32_t opc      : 5;
610
	uint32_t jmp_tgt  : 1;
611
	uint32_t sync     : 1;
612
	uint32_t opc_cat  : 3;
613
} instr_cat6b_t;
614
 
615
/* I think some of the other cat6 instructions use additional
616
 * sub-encodings..
617
 */
618
 
619
typedef union PACKED {
620
	instr_cat6a_t a;
621
	instr_cat6b_t b;
622
	struct PACKED {
623
		/* dword0: */
624
		uint32_t has_off  : 1;
625
		uint32_t pad1     : 31;
626
 
627
		/* dword1: */
628
		uint32_t dst      : 8;
629
		uint32_t dummy2   : 9;
630
		uint32_t type     : 3;
631
		uint32_t dummy3   : 2;
632
		uint32_t opc      : 5;
633
		uint32_t jmp_tgt  : 1;
634
		uint32_t sync     : 1;
635
		uint32_t opc_cat  : 3;
636
	};
637
} instr_cat6_t;
638
 
639
typedef union PACKED {
640
	instr_cat0_t cat0;
641
	instr_cat1_t cat1;
642
	instr_cat2_t cat2;
643
	instr_cat3_t cat3;
644
	instr_cat4_t cat4;
645
	instr_cat5_t cat5;
646
	instr_cat6_t cat6;
647
	struct PACKED {
648
		/* dword0: */
649
		uint64_t pad1     : 40;
650
		uint32_t repeat   : 3;  /* cat0-cat4 */
651
		uint32_t pad2     : 1;
652
		uint32_t ss       : 1;  /* cat1-cat4 (cat0??) */
653
		uint32_t ul       : 1;  /* cat2-cat4 (and cat1 in blob.. which may be bug??) */
654
		uint32_t pad3     : 13;
655
		uint32_t jmp_tgt  : 1;
656
		uint32_t sync     : 1;
657
		uint32_t opc_cat  : 3;
658
 
659
	};
660
} instr_t;
661
 
662
static inline uint32_t instr_opc(instr_t *instr)
663
{
664
	switch (instr->opc_cat) {
665
	case 0:  return instr->cat0.opc;
666
	case 1:  return 0;
667
	case 2:  return instr->cat2.opc;
668
	case 3:  return instr->cat3.opc;
669
	case 4:  return instr->cat4.opc;
670
	case 5:  return instr->cat5.opc;
671
	case 6:  return instr->cat6.opc;
672
	default: return 0;
673
	}
674
}
675
 
676
static inline bool is_mad(opc_t opc)
677
{
678
	switch (opc) {
679
	case OPC_MAD_U16:
680
	case OPC_MAD_S16:
681
	case OPC_MAD_U24:
682
	case OPC_MAD_S24:
683
	case OPC_MAD_F16:
684
	case OPC_MAD_F32:
685
		return true;
686
	default:
687
		return false;
688
	}
689
}
690
 
691
static inline bool is_madsh(opc_t opc)
692
{
693
	switch (opc) {
694
	case OPC_MADSH_U16:
695
	case OPC_MADSH_M16:
696
		return true;
697
	default:
698
		return false;
699
	}
700
}
701
 
702
#endif /* INSTR_A3XX_H_ */