Subversion Repositories Kolibri OS

Rev

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_ */