2 * Copyright (c) 2013 Rob Clark <robdclark@gmail.com>
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:
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
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
27 #define PACKED __attribute__((__packed__))
48 /* no opc.. all category 1 are variants of mov */
107 OPC_MADSH_M16
= 3, /* should this be .s16? */
162 OPC_LDG
= 0, /* load-global */
165 OPC_STG
= 3, /* store-global */
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,
193 /* meta instructions (category -1): */
194 /* placeholder instr to mark inputs/outputs: */
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)
204 /* branches/flow control */
219 TYPE_S8
= 7, // XXX I assume?
222 static inline uint32_t type_size(type_t type
)
237 assert(0); /* invalid type */
242 static inline int type_float(type_t type
)
244 return (type
== TYPE_F32
) || (type
== TYPE_F16
);
247 typedef union PACKED
{
248 /* normal gpr or const src register: */
253 /* for immediate val: */
254 int32_t iim_val
: 11;
255 /* to make compiler happy: */
257 uint32_t dummy10
: 10;
258 uint32_t dummy11
: 11;
259 uint32_t dummy12
: 12;
260 uint32_t dummy13
: 13;
264 /* special registers: */
265 #define REG_A0 61 /* address register */
266 #define REG_P0 62 /* predicate register */
268 static inline int reg_special(reg_t reg
)
270 return (reg
.num
== REG_A0
) || (reg
.num
== REG_P0
);
273 typedef struct PACKED
{
276 uint32_t dummy1
: 16;
287 uint32_t jmp_tgt
: 1;
289 uint32_t opc_cat
: 3;
292 typedef struct PACKED
{
295 /* for normal src register: */
298 /* at least low bit of pad must be zero or it will
299 * look like a address relative src
303 /* for address relative: */
306 uint32_t src_rel_c
: 1;
307 uint32_t src_rel
: 1;
308 uint32_t unknown
: 20;
321 uint32_t dst_type
: 3;
322 uint32_t dst_rel
: 1;
323 uint32_t src_type
: 3;
327 uint32_t pos_inf
: 1;
328 uint32_t must_be_0
: 2;
329 uint32_t jmp_tgt
: 1;
331 uint32_t opc_cat
: 3;
334 typedef struct PACKED
{
339 uint32_t must_be_zero1
: 2;
340 uint32_t src1_im
: 1; /* immediate */
341 uint32_t src1_neg
: 1; /* negate */
342 uint32_t src1_abs
: 1; /* absolute value */
346 uint32_t src1_c
: 1; /* relative-const */
347 uint32_t src1_rel
: 1; /* relative address */
348 uint32_t must_be_zero
: 1;
353 uint32_t src1_c
: 1; /* const */
361 uint32_t must_be_zero2
: 2;
362 uint32_t src2_im
: 1; /* immediate */
363 uint32_t src2_neg
: 1; /* negate */
364 uint32_t src2_abs
: 1; /* absolute value */
368 uint32_t src2_c
: 1; /* relative-const */
369 uint32_t src2_rel
: 1; /* relative address */
370 uint32_t must_be_zero
: 1;
375 uint32_t src2_c
: 1; /* const */
385 uint32_t ul
: 1; /* dunno */
386 uint32_t dst_half
: 1; /* or widen/narrow.. ie. dst hrN <-> rN */
390 uint32_t full
: 1; /* not half */
392 uint32_t jmp_tgt
: 1;
394 uint32_t opc_cat
: 3;
397 typedef struct PACKED
{
402 uint32_t must_be_zero1
: 2;
404 uint32_t src1_neg
: 1;
410 uint32_t src1_rel
: 1;
411 uint32_t must_be_zero
: 1;
424 uint32_t must_be_zero2
: 2;
426 uint32_t src2_neg
: 1;
427 uint32_t src3_neg
: 1;
432 uint32_t src3_rel
: 1;
433 uint32_t must_be_zero
: 1;
449 uint32_t dst_half
: 1; /* or widen/narrow.. ie. dst hrN <-> rN */
452 uint32_t jmp_tgt
: 1;
454 uint32_t opc_cat
: 3;
457 static inline bool instr_cat3_full(instr_cat3_t
*cat3
)
467 case OPC_SAD_S32
: // really??
474 typedef struct PACKED
{
479 uint32_t must_be_zero1
: 2;
480 uint32_t src_im
: 1; /* immediate */
481 uint32_t src_neg
: 1; /* negate */
482 uint32_t src_abs
: 1; /* absolute value */
486 uint32_t src_c
: 1; /* relative-const */
487 uint32_t src_rel
: 1; /* relative address */
488 uint32_t must_be_zero
: 1;
493 uint32_t src_c
: 1; /* const */
497 uint32_t dummy1
: 16; /* seem to be ignored */
505 uint32_t dst_half
: 1; /* or widen/narrow.. ie. dst hrN <-> rN */
506 uint32_t dummy2
: 5; /* seem to be ignored */
507 uint32_t full
: 1; /* not half */
509 uint32_t jmp_tgt
: 1;
511 uint32_t opc_cat
: 3;
514 typedef struct PACKED
{
519 uint32_t full
: 1; /* not half */
522 uint32_t dummy1
: 4; /* seem to be ignored */
528 uint32_t full
: 1; /* not half */
535 /* same in either case: */
536 // XXX I think, confirm this
538 uint32_t full
: 1; /* not half */
546 uint32_t wrmask
: 4; /* write-mask */
548 uint32_t dummy2
: 1; /* seems to be ignored */
553 uint32_t is_s2en
: 1;
558 uint32_t jmp_tgt
: 1;
560 uint32_t opc_cat
: 3;
563 /* used for load instructions: */
564 typedef struct PACKED
{
566 uint32_t must_be_one1
: 1;
570 uint32_t must_be_one2
: 1;
579 uint32_t jmp_tgt
: 1;
581 uint32_t opc_cat
: 3;
584 /* used for store instructions: */
585 typedef struct PACKED
{
587 uint32_t must_be_zero1
: 1;
589 uint32_t off_hi
: 5; /* high bits of 'off'... ugly! */
591 uint32_t must_be_one1
: 1;
596 uint32_t must_be_one2
: 1;
601 uint32_t jmp_tgt
: 1;
603 uint32_t opc_cat
: 3;
606 typedef union PACKED
{
619 uint32_t jmp_tgt
: 1;
621 uint32_t opc_cat
: 3;
625 typedef union PACKED
{
636 uint32_t repeat
: 3; /* cat0-cat4 */
638 uint32_t ss
: 1; /* cat1-cat4 (cat0??) */
639 uint32_t ul
: 1; /* cat2-cat4 (and cat1 in blob.. which may be bug??) */
641 uint32_t jmp_tgt
: 1;
643 uint32_t opc_cat
: 3;
648 static inline uint32_t instr_opc(instr_t
*instr
)
650 switch (instr
->opc_cat
) {
651 case 0: return instr
->cat0
.opc
;
653 case 2: return instr
->cat2
.opc
;
654 case 3: return instr
->cat3
.opc
;
655 case 4: return instr
->cat4
.opc
;
656 case 5: return instr
->cat5
.opc
;
657 case 6: return instr
->cat6
.opc
;
662 static inline bool is_mad(opc_t opc
)
679 #endif /* INSTR_A3XX_H_ */