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 */
207 /* relative addressing */
221 TYPE_S8
= 7, // XXX I assume?
224 static inline uint32_t type_size(type_t type
)
239 assert(0); /* invalid type */
244 static inline int type_float(type_t type
)
246 return (type
== TYPE_F32
) || (type
== TYPE_F16
);
249 static inline int type_uint(type_t type
)
251 return (type
== TYPE_U32
) || (type
== TYPE_U16
) || (type
== TYPE_U8
);
254 static inline int type_sint(type_t type
)
256 return (type
== TYPE_S32
) || (type
== TYPE_S16
) || (type
== TYPE_S8
);
259 typedef union PACKED
{
260 /* normal gpr or const src register: */
265 /* for immediate val: */
266 int32_t iim_val
: 11;
267 /* to make compiler happy: */
269 uint32_t dummy10
: 10;
270 uint32_t dummy11
: 11;
271 uint32_t dummy12
: 12;
272 uint32_t dummy13
: 13;
276 /* special registers: */
277 #define REG_A0 61 /* address register */
278 #define REG_P0 62 /* predicate register */
280 static inline int reg_special(reg_t reg
)
282 return (reg
.num
== REG_A0
) || (reg
.num
== REG_P0
);
285 typedef struct PACKED
{
288 uint32_t dummy1
: 16;
299 uint32_t jmp_tgt
: 1;
301 uint32_t opc_cat
: 3;
304 typedef struct PACKED
{
307 /* for normal src register: */
310 /* at least low bit of pad must be zero or it will
311 * look like a address relative src
315 /* for address relative: */
318 uint32_t src_rel_c
: 1;
319 uint32_t src_rel
: 1;
320 uint32_t unknown
: 20;
333 uint32_t dst_type
: 3;
334 uint32_t dst_rel
: 1;
335 uint32_t src_type
: 3;
339 uint32_t pos_inf
: 1;
340 uint32_t must_be_0
: 2;
341 uint32_t jmp_tgt
: 1;
343 uint32_t opc_cat
: 3;
346 typedef struct PACKED
{
351 uint32_t must_be_zero1
: 2;
352 uint32_t src1_im
: 1; /* immediate */
353 uint32_t src1_neg
: 1; /* negate */
354 uint32_t src1_abs
: 1; /* absolute value */
358 uint32_t src1_c
: 1; /* relative-const */
359 uint32_t src1_rel
: 1; /* relative address */
360 uint32_t must_be_zero
: 1;
365 uint32_t src1_c
: 1; /* const */
373 uint32_t must_be_zero2
: 2;
374 uint32_t src2_im
: 1; /* immediate */
375 uint32_t src2_neg
: 1; /* negate */
376 uint32_t src2_abs
: 1; /* absolute value */
380 uint32_t src2_c
: 1; /* relative-const */
381 uint32_t src2_rel
: 1; /* relative address */
382 uint32_t must_be_zero
: 1;
387 uint32_t src2_c
: 1; /* const */
397 uint32_t ul
: 1; /* dunno */
398 uint32_t dst_half
: 1; /* or widen/narrow.. ie. dst hrN <-> rN */
402 uint32_t full
: 1; /* not half */
404 uint32_t jmp_tgt
: 1;
406 uint32_t opc_cat
: 3;
409 typedef struct PACKED
{
414 uint32_t must_be_zero1
: 2;
416 uint32_t src1_neg
: 1;
422 uint32_t src1_rel
: 1;
423 uint32_t must_be_zero
: 1;
436 uint32_t must_be_zero2
: 2;
438 uint32_t src2_neg
: 1;
439 uint32_t src3_neg
: 1;
444 uint32_t src3_rel
: 1;
445 uint32_t must_be_zero
: 1;
461 uint32_t dst_half
: 1; /* or widen/narrow.. ie. dst hrN <-> rN */
464 uint32_t jmp_tgt
: 1;
466 uint32_t opc_cat
: 3;
469 static inline bool instr_cat3_full(instr_cat3_t
*cat3
)
479 case OPC_SAD_S32
: // really??
486 typedef struct PACKED
{
491 uint32_t must_be_zero1
: 2;
492 uint32_t src_im
: 1; /* immediate */
493 uint32_t src_neg
: 1; /* negate */
494 uint32_t src_abs
: 1; /* absolute value */
498 uint32_t src_c
: 1; /* relative-const */
499 uint32_t src_rel
: 1; /* relative address */
500 uint32_t must_be_zero
: 1;
505 uint32_t src_c
: 1; /* const */
509 uint32_t dummy1
: 16; /* seem to be ignored */
517 uint32_t dst_half
: 1; /* or widen/narrow.. ie. dst hrN <-> rN */
518 uint32_t dummy2
: 5; /* seem to be ignored */
519 uint32_t full
: 1; /* not half */
521 uint32_t jmp_tgt
: 1;
523 uint32_t opc_cat
: 3;
526 typedef struct PACKED
{
531 uint32_t full
: 1; /* not half */
534 uint32_t dummy1
: 4; /* seem to be ignored */
540 uint32_t full
: 1; /* not half */
547 /* same in either case: */
548 // XXX I think, confirm this
550 uint32_t full
: 1; /* not half */
558 uint32_t wrmask
: 4; /* write-mask */
560 uint32_t dummy2
: 1; /* seems to be ignored */
565 uint32_t is_s2en
: 1;
570 uint32_t jmp_tgt
: 1;
572 uint32_t opc_cat
: 3;
575 /* used for load instructions: */
576 typedef struct PACKED
{
578 uint32_t must_be_one1
: 1;
582 uint32_t must_be_one2
: 1;
591 uint32_t jmp_tgt
: 1;
593 uint32_t opc_cat
: 3;
596 /* used for store instructions: */
597 typedef struct PACKED
{
599 uint32_t must_be_zero1
: 1;
601 uint32_t off_hi
: 5; /* high bits of 'off'... ugly! */
603 uint32_t must_be_one1
: 1;
608 uint32_t must_be_one2
: 1;
613 uint32_t jmp_tgt
: 1;
615 uint32_t opc_cat
: 3;
618 typedef union PACKED
{
631 uint32_t jmp_tgt
: 1;
633 uint32_t opc_cat
: 3;
637 typedef union PACKED
{
648 uint32_t repeat
: 3; /* cat0-cat4 */
650 uint32_t ss
: 1; /* cat1-cat4 (cat0??) */
651 uint32_t ul
: 1; /* cat2-cat4 (and cat1 in blob.. which may be bug??) */
653 uint32_t jmp_tgt
: 1;
655 uint32_t opc_cat
: 3;
660 static inline uint32_t instr_opc(instr_t
*instr
)
662 switch (instr
->opc_cat
) {
663 case 0: return instr
->cat0
.opc
;
665 case 2: return instr
->cat2
.opc
;
666 case 3: return instr
->cat3
.opc
;
667 case 4: return instr
->cat4
.opc
;
668 case 5: return instr
->cat5
.opc
;
669 case 6: return instr
->cat6
.opc
;
674 static inline bool is_mad(opc_t opc
)
691 #endif /* INSTR_A3XX_H_ */