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,
203 TYPE_S8
= 7, // XXX I assume?
206 static inline uint32_t type_size(type_t type
)
221 assert(0); /* invalid type */
226 static inline int type_float(type_t type
)
228 return (type
== TYPE_F32
) || (type
== TYPE_F16
);
231 typedef union PACKED
{
232 /* normal gpr or const src register: */
237 /* for immediate val: */
238 int32_t iim_val
: 11;
239 /* to make compiler happy: */
241 uint32_t dummy10
: 10;
242 uint32_t dummy11
: 11;
243 uint32_t dummy12
: 12;
244 uint32_t dummy13
: 13;
248 /* special registers: */
249 #define REG_A0 61 /* address register */
250 #define REG_P0 62 /* predicate register */
252 static inline int reg_special(reg_t reg
)
254 return (reg
.num
== REG_A0
) || (reg
.num
== REG_P0
);
257 typedef struct PACKED
{
260 uint32_t dummy1
: 16;
271 uint32_t jmp_tgt
: 1;
273 uint32_t opc_cat
: 3;
276 typedef struct PACKED
{
279 /* for normal src register: */
282 /* at least low bit of pad must be zero or it will
283 * look like a address relative src
287 /* for address relative: */
290 uint32_t src_rel_c
: 1;
291 uint32_t src_rel
: 1;
292 uint32_t unknown
: 20;
305 uint32_t dst_type
: 3;
306 uint32_t dst_rel
: 1;
307 uint32_t src_type
: 3;
311 uint32_t pos_inf
: 1;
312 uint32_t must_be_0
: 2;
313 uint32_t jmp_tgt
: 1;
315 uint32_t opc_cat
: 3;
318 typedef struct PACKED
{
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 */
330 uint32_t src1_c
: 1; /* relative-const */
331 uint32_t src1_rel
: 1; /* relative address */
332 uint32_t must_be_zero
: 1;
337 uint32_t src1_c
: 1; /* const */
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 */
352 uint32_t src2_c
: 1; /* relative-const */
353 uint32_t src2_rel
: 1; /* relative address */
354 uint32_t must_be_zero
: 1;
359 uint32_t src2_c
: 1; /* const */
369 uint32_t ul
: 1; /* dunno */
370 uint32_t dst_half
: 1; /* or widen/narrow.. ie. dst hrN <-> rN */
374 uint32_t full
: 1; /* not half */
376 uint32_t jmp_tgt
: 1;
378 uint32_t opc_cat
: 3;
381 typedef struct PACKED
{
386 uint32_t must_be_zero1
: 2;
388 uint32_t src1_neg
: 1;
394 uint32_t src1_rel
: 1;
395 uint32_t must_be_zero
: 1;
408 uint32_t must_be_zero2
: 2;
410 uint32_t src2_neg
: 1;
411 uint32_t src3_neg
: 1;
416 uint32_t src3_rel
: 1;
417 uint32_t must_be_zero
: 1;
433 uint32_t dst_half
: 1; /* or widen/narrow.. ie. dst hrN <-> rN */
436 uint32_t jmp_tgt
: 1;
438 uint32_t opc_cat
: 3;
441 static inline bool instr_cat3_full(instr_cat3_t
*cat3
)
451 case OPC_SAD_S32
: // really??
458 typedef struct PACKED
{
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 */
470 uint32_t src_c
: 1; /* relative-const */
471 uint32_t src_rel
: 1; /* relative address */
472 uint32_t must_be_zero
: 1;
477 uint32_t src_c
: 1; /* const */
481 uint32_t dummy1
: 16; /* seem to be ignored */
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 */
493 uint32_t jmp_tgt
: 1;
495 uint32_t opc_cat
: 3;
498 typedef struct PACKED
{
503 uint32_t full
: 1; /* not half */
506 uint32_t dummy1
: 4; /* seem to be ignored */
512 uint32_t full
: 1; /* not half */
519 /* same in either case: */
520 // XXX I think, confirm this
522 uint32_t full
: 1; /* not half */
530 uint32_t wrmask
: 4; /* write-mask */
532 uint32_t dummy2
: 1; /* seems to be ignored */
537 uint32_t is_s2en
: 1;
542 uint32_t jmp_tgt
: 1;
544 uint32_t opc_cat
: 3;
547 /* used for load instructions: */
548 typedef struct PACKED
{
550 uint32_t must_be_one1
: 1;
554 uint32_t must_be_one2
: 1;
563 uint32_t jmp_tgt
: 1;
565 uint32_t opc_cat
: 3;
568 /* used for store instructions: */
569 typedef struct PACKED
{
571 uint32_t must_be_zero1
: 1;
573 uint32_t off_hi
: 5; /* high bits of 'off'... ugly! */
575 uint32_t must_be_one1
: 1;
580 uint32_t must_be_one2
: 1;
585 uint32_t jmp_tgt
: 1;
587 uint32_t opc_cat
: 3;
590 typedef union PACKED
{
603 uint32_t jmp_tgt
: 1;
605 uint32_t opc_cat
: 3;
609 typedef union PACKED
{
620 uint32_t repeat
: 3; /* cat0-cat4 */
622 uint32_t ss
: 1; /* cat1-cat4 (cat0??) */
623 uint32_t ul
: 1; /* cat2-cat4 (and cat1 in blob.. which may be bug??) */
625 uint32_t jmp_tgt
: 1;
627 uint32_t opc_cat
: 3;
632 static inline uint32_t instr_opc(instr_t
*instr
)
634 switch (instr
->opc_cat
) {
635 case 0: return instr
->cat0
.opc
;
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
;
646 #endif /* INSTR_A3XX_H_ */