instr-a3xx.h revision 70735643f4cf660dc3022f40f853a138aea738c2
1/* 2 * Copyright (c) 2013 Rob Clark <robdclark@gmail.com> 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 <stdint.h> 30#include <assert.h> 31 32/* size of largest OPC field of all the instruction categories: */ 33#define NOPC_BITS 6 34 35#define _OPC(cat, opc) (((cat) << NOPC_BITS) | opc) 36 37typedef enum { 38 /* category 0: */ 39 OPC_NOP = _OPC(0, 0), 40 OPC_BR = _OPC(0, 1), 41 OPC_JUMP = _OPC(0, 2), 42 OPC_CALL = _OPC(0, 3), 43 OPC_RET = _OPC(0, 4), 44 OPC_KILL = _OPC(0, 5), 45 OPC_END = _OPC(0, 6), 46 OPC_EMIT = _OPC(0, 7), 47 OPC_CUT = _OPC(0, 8), 48 OPC_CHMASK = _OPC(0, 9), 49 OPC_CHSH = _OPC(0, 10), 50 OPC_FLOW_REV = _OPC(0, 11), 51 52 /* category 1: */ 53 OPC_MOV = _OPC(1, 0), 54 55 /* category 2: */ 56 OPC_ADD_F = _OPC(2, 0), 57 OPC_MIN_F = _OPC(2, 1), 58 OPC_MAX_F = _OPC(2, 2), 59 OPC_MUL_F = _OPC(2, 3), 60 OPC_SIGN_F = _OPC(2, 4), 61 OPC_CMPS_F = _OPC(2, 5), 62 OPC_ABSNEG_F = _OPC(2, 6), 63 OPC_CMPV_F = _OPC(2, 7), 64 /* 8 - invalid */ 65 OPC_FLOOR_F = _OPC(2, 9), 66 OPC_CEIL_F = _OPC(2, 10), 67 OPC_RNDNE_F = _OPC(2, 11), 68 OPC_RNDAZ_F = _OPC(2, 12), 69 OPC_TRUNC_F = _OPC(2, 13), 70 /* 14-15 - invalid */ 71 OPC_ADD_U = _OPC(2, 16), 72 OPC_ADD_S = _OPC(2, 17), 73 OPC_SUB_U = _OPC(2, 18), 74 OPC_SUB_S = _OPC(2, 19), 75 OPC_CMPS_U = _OPC(2, 20), 76 OPC_CMPS_S = _OPC(2, 21), 77 OPC_MIN_U = _OPC(2, 22), 78 OPC_MIN_S = _OPC(2, 23), 79 OPC_MAX_U = _OPC(2, 24), 80 OPC_MAX_S = _OPC(2, 25), 81 OPC_ABSNEG_S = _OPC(2, 26), 82 /* 27 - invalid */ 83 OPC_AND_B = _OPC(2, 28), 84 OPC_OR_B = _OPC(2, 29), 85 OPC_NOT_B = _OPC(2, 30), 86 OPC_XOR_B = _OPC(2, 31), 87 /* 32 - invalid */ 88 OPC_CMPV_U = _OPC(2, 33), 89 OPC_CMPV_S = _OPC(2, 34), 90 /* 35-47 - invalid */ 91 OPC_MUL_U = _OPC(2, 48), 92 OPC_MUL_S = _OPC(2, 49), 93 OPC_MULL_U = _OPC(2, 50), 94 OPC_BFREV_B = _OPC(2, 51), 95 OPC_CLZ_S = _OPC(2, 52), 96 OPC_CLZ_B = _OPC(2, 53), 97 OPC_SHL_B = _OPC(2, 54), 98 OPC_SHR_B = _OPC(2, 55), 99 OPC_ASHR_B = _OPC(2, 56), 100 OPC_BARY_F = _OPC(2, 57), 101 OPC_MGEN_B = _OPC(2, 58), 102 OPC_GETBIT_B = _OPC(2, 59), 103 OPC_SETRM = _OPC(2, 60), 104 OPC_CBITS_B = _OPC(2, 61), 105 OPC_SHB = _OPC(2, 62), 106 OPC_MSAD = _OPC(2, 63), 107 108 /* category 3: */ 109 OPC_MAD_U16 = _OPC(3, 0), 110 OPC_MADSH_U16 = _OPC(3, 1), 111 OPC_MAD_S16 = _OPC(3, 2), 112 OPC_MADSH_M16 = _OPC(3, 3), /* should this be .s16? */ 113 OPC_MAD_U24 = _OPC(3, 4), 114 OPC_MAD_S24 = _OPC(3, 5), 115 OPC_MAD_F16 = _OPC(3, 6), 116 OPC_MAD_F32 = _OPC(3, 7), 117 OPC_SEL_B16 = _OPC(3, 8), 118 OPC_SEL_B32 = _OPC(3, 9), 119 OPC_SEL_S16 = _OPC(3, 10), 120 OPC_SEL_S32 = _OPC(3, 11), 121 OPC_SEL_F16 = _OPC(3, 12), 122 OPC_SEL_F32 = _OPC(3, 13), 123 OPC_SAD_S16 = _OPC(3, 14), 124 OPC_SAD_S32 = _OPC(3, 15), 125 126 /* category 4: */ 127 OPC_RCP = _OPC(4, 0), 128 OPC_RSQ = _OPC(4, 1), 129 OPC_LOG2 = _OPC(4, 2), 130 OPC_EXP2 = _OPC(4, 3), 131 OPC_SIN = _OPC(4, 4), 132 OPC_COS = _OPC(4, 5), 133 OPC_SQRT = _OPC(4, 6), 134 // 7-63 - invalid 135 136 /* category 5: */ 137 OPC_ISAM = _OPC(5, 0), 138 OPC_ISAML = _OPC(5, 1), 139 OPC_ISAMM = _OPC(5, 2), 140 OPC_SAM = _OPC(5, 3), 141 OPC_SAMB = _OPC(5, 4), 142 OPC_SAML = _OPC(5, 5), 143 OPC_SAMGQ = _OPC(5, 6), 144 OPC_GETLOD = _OPC(5, 7), 145 OPC_CONV = _OPC(5, 8), 146 OPC_CONVM = _OPC(5, 9), 147 OPC_GETSIZE = _OPC(5, 10), 148 OPC_GETBUF = _OPC(5, 11), 149 OPC_GETPOS = _OPC(5, 12), 150 OPC_GETINFO = _OPC(5, 13), 151 OPC_DSX = _OPC(5, 14), 152 OPC_DSY = _OPC(5, 15), 153 OPC_GATHER4R = _OPC(5, 16), 154 OPC_GATHER4G = _OPC(5, 17), 155 OPC_GATHER4B = _OPC(5, 18), 156 OPC_GATHER4A = _OPC(5, 19), 157 OPC_SAMGP0 = _OPC(5, 20), 158 OPC_SAMGP1 = _OPC(5, 21), 159 OPC_SAMGP2 = _OPC(5, 22), 160 OPC_SAMGP3 = _OPC(5, 23), 161 OPC_DSXPP_1 = _OPC(5, 24), 162 OPC_DSYPP_1 = _OPC(5, 25), 163 OPC_RGETPOS = _OPC(5, 26), 164 OPC_RGETINFO = _OPC(5, 27), 165 166 /* category 6: */ 167 OPC_LDG = _OPC(6, 0), /* load-global */ 168 OPC_LDL = _OPC(6, 1), 169 OPC_LDP = _OPC(6, 2), 170 OPC_STG = _OPC(6, 3), /* store-global */ 171 OPC_STL = _OPC(6, 4), 172 OPC_STP = _OPC(6, 5), 173 OPC_STI = _OPC(6, 6), 174 OPC_G2L = _OPC(6, 7), 175 OPC_L2G = _OPC(6, 8), 176 OPC_PREFETCH = _OPC(6, 9), 177 OPC_LDLW = _OPC(6, 10), 178 OPC_STLW = _OPC(6, 11), 179 OPC_RESFMT = _OPC(6, 14), 180 OPC_RESINFO = _OPC(6, 15), 181 OPC_ATOMIC_ADD = _OPC(6, 16), 182 OPC_ATOMIC_SUB = _OPC(6, 17), 183 OPC_ATOMIC_XCHG = _OPC(6, 18), 184 OPC_ATOMIC_INC = _OPC(6, 19), 185 OPC_ATOMIC_DEC = _OPC(6, 20), 186 OPC_ATOMIC_CMPXCHG = _OPC(6, 21), 187 OPC_ATOMIC_MIN = _OPC(6, 22), 188 OPC_ATOMIC_MAX = _OPC(6, 23), 189 OPC_ATOMIC_AND = _OPC(6, 24), 190 OPC_ATOMIC_OR = _OPC(6, 25), 191 OPC_ATOMIC_XOR = _OPC(6, 26), 192 OPC_LDGB_TYPED_4D = _OPC(6, 27), 193 OPC_STGB_4D_4 = _OPC(6, 28), 194 OPC_STIB = _OPC(6, 29), 195 OPC_LDC_4 = _OPC(6, 30), 196 OPC_LDLV = _OPC(6, 31), 197 198 /* meta instructions (category -1): */ 199 /* placeholder instr to mark shader inputs: */ 200 OPC_META_INPUT = _OPC(-1, 0), 201 OPC_META_PHI = _OPC(-1, 1), 202 /* The "fan-in" and "fan-out" instructions are used for keeping 203 * track of instructions that write to multiple dst registers 204 * (fan-out) like texture sample instructions, or read multiple 205 * consecutive scalar registers (fan-in) (bary.f, texture samp) 206 */ 207 OPC_META_FO = _OPC(-1, 2), 208 OPC_META_FI = _OPC(-1, 3), 209 210} opc_t; 211 212#define opc_cat(opc) ((int)((opc) >> NOPC_BITS)) 213#define opc_op(opc) ((unsigned)((opc) & ((1 << NOPC_BITS) - 1))) 214 215typedef enum { 216 TYPE_F16 = 0, 217 TYPE_F32 = 1, 218 TYPE_U16 = 2, 219 TYPE_U32 = 3, 220 TYPE_S16 = 4, 221 TYPE_S32 = 5, 222 TYPE_U8 = 6, 223 TYPE_S8 = 7, // XXX I assume? 224} type_t; 225 226static inline uint32_t type_size(type_t type) 227{ 228 switch (type) { 229 case TYPE_F32: 230 case TYPE_U32: 231 case TYPE_S32: 232 return 32; 233 case TYPE_F16: 234 case TYPE_U16: 235 case TYPE_S16: 236 return 16; 237 case TYPE_U8: 238 case TYPE_S8: 239 return 8; 240 default: 241 assert(0); /* invalid type */ 242 return 0; 243 } 244} 245 246static inline int type_float(type_t type) 247{ 248 return (type == TYPE_F32) || (type == TYPE_F16); 249} 250 251static inline int type_uint(type_t type) 252{ 253 return (type == TYPE_U32) || (type == TYPE_U16) || (type == TYPE_U8); 254} 255 256static inline int type_sint(type_t type) 257{ 258 return (type == TYPE_S32) || (type == TYPE_S16) || (type == TYPE_S8); 259} 260 261typedef union PACKED { 262 /* normal gpr or const src register: */ 263 struct PACKED { 264 uint32_t comp : 2; 265 uint32_t num : 10; 266 }; 267 /* for immediate val: */ 268 int32_t iim_val : 11; 269 /* to make compiler happy: */ 270 uint32_t dummy32; 271 uint32_t dummy10 : 10; 272 int32_t idummy10 : 10; 273 uint32_t dummy11 : 11; 274 uint32_t dummy12 : 12; 275 uint32_t dummy13 : 13; 276 uint32_t dummy8 : 8; 277} reg_t; 278 279/* special registers: */ 280#define REG_A0 61 /* address register */ 281#define REG_P0 62 /* predicate register */ 282 283static inline int reg_special(reg_t reg) 284{ 285 return (reg.num == REG_A0) || (reg.num == REG_P0); 286} 287 288typedef struct PACKED { 289 /* dword0: */ 290 union PACKED { 291 struct PACKED { 292 int16_t immed : 16; 293 uint32_t dummy1 : 16; 294 } a3xx; 295 struct PACKED { 296 int32_t immed : 20; 297 uint32_t dummy1 : 12; 298 } a4xx; 299 }; 300 301 /* dword1: */ 302 uint32_t dummy2 : 8; 303 uint32_t repeat : 3; 304 uint32_t dummy3 : 1; 305 uint32_t ss : 1; 306 uint32_t dummy4 : 7; 307 uint32_t inv : 1; 308 uint32_t comp : 2; 309 uint32_t opc : 4; 310 uint32_t jmp_tgt : 1; 311 uint32_t sync : 1; 312 uint32_t opc_cat : 3; 313} instr_cat0_t; 314 315typedef struct PACKED { 316 /* dword0: */ 317 union PACKED { 318 /* for normal src register: */ 319 struct PACKED { 320 uint32_t src : 11; 321 /* at least low bit of pad must be zero or it will 322 * look like a address relative src 323 */ 324 uint32_t pad : 21; 325 }; 326 /* for address relative: */ 327 struct PACKED { 328 int32_t off : 10; 329 uint32_t src_rel_c : 1; 330 uint32_t src_rel : 1; 331 uint32_t unknown : 20; 332 }; 333 /* for immediate: */ 334 int32_t iim_val; 335 uint32_t uim_val; 336 float fim_val; 337 }; 338 339 /* dword1: */ 340 uint32_t dst : 8; 341 uint32_t repeat : 3; 342 uint32_t src_r : 1; 343 uint32_t ss : 1; 344 uint32_t ul : 1; 345 uint32_t dst_type : 3; 346 uint32_t dst_rel : 1; 347 uint32_t src_type : 3; 348 uint32_t src_c : 1; 349 uint32_t src_im : 1; 350 uint32_t even : 1; 351 uint32_t pos_inf : 1; 352 uint32_t must_be_0 : 2; 353 uint32_t jmp_tgt : 1; 354 uint32_t sync : 1; 355 uint32_t opc_cat : 3; 356} instr_cat1_t; 357 358typedef struct PACKED { 359 /* dword0: */ 360 union PACKED { 361 struct PACKED { 362 uint32_t src1 : 11; 363 uint32_t must_be_zero1: 2; 364 uint32_t src1_im : 1; /* immediate */ 365 uint32_t src1_neg : 1; /* negate */ 366 uint32_t src1_abs : 1; /* absolute value */ 367 }; 368 struct PACKED { 369 uint32_t src1 : 10; 370 uint32_t src1_c : 1; /* relative-const */ 371 uint32_t src1_rel : 1; /* relative address */ 372 uint32_t must_be_zero : 1; 373 uint32_t dummy : 3; 374 } rel1; 375 struct PACKED { 376 uint32_t src1 : 12; 377 uint32_t src1_c : 1; /* const */ 378 uint32_t dummy : 3; 379 } c1; 380 }; 381 382 union PACKED { 383 struct PACKED { 384 uint32_t src2 : 11; 385 uint32_t must_be_zero2: 2; 386 uint32_t src2_im : 1; /* immediate */ 387 uint32_t src2_neg : 1; /* negate */ 388 uint32_t src2_abs : 1; /* absolute value */ 389 }; 390 struct PACKED { 391 uint32_t src2 : 10; 392 uint32_t src2_c : 1; /* relative-const */ 393 uint32_t src2_rel : 1; /* relative address */ 394 uint32_t must_be_zero : 1; 395 uint32_t dummy : 3; 396 } rel2; 397 struct PACKED { 398 uint32_t src2 : 12; 399 uint32_t src2_c : 1; /* const */ 400 uint32_t dummy : 3; 401 } c2; 402 }; 403 404 /* dword1: */ 405 uint32_t dst : 8; 406 uint32_t repeat : 3; 407 uint32_t src1_r : 1; 408 uint32_t ss : 1; 409 uint32_t ul : 1; /* dunno */ 410 uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */ 411 uint32_t ei : 1; 412 uint32_t cond : 3; 413 uint32_t src2_r : 1; 414 uint32_t full : 1; /* not half */ 415 uint32_t opc : 6; 416 uint32_t jmp_tgt : 1; 417 uint32_t sync : 1; 418 uint32_t opc_cat : 3; 419} instr_cat2_t; 420 421typedef struct PACKED { 422 /* dword0: */ 423 union PACKED { 424 struct PACKED { 425 uint32_t src1 : 11; 426 uint32_t must_be_zero1: 2; 427 uint32_t src2_c : 1; 428 uint32_t src1_neg : 1; 429 uint32_t src2_r : 1; 430 }; 431 struct PACKED { 432 uint32_t src1 : 10; 433 uint32_t src1_c : 1; 434 uint32_t src1_rel : 1; 435 uint32_t must_be_zero : 1; 436 uint32_t dummy : 3; 437 } rel1; 438 struct PACKED { 439 uint32_t src1 : 12; 440 uint32_t src1_c : 1; 441 uint32_t dummy : 3; 442 } c1; 443 }; 444 445 union PACKED { 446 struct PACKED { 447 uint32_t src3 : 11; 448 uint32_t must_be_zero2: 2; 449 uint32_t src3_r : 1; 450 uint32_t src2_neg : 1; 451 uint32_t src3_neg : 1; 452 }; 453 struct PACKED { 454 uint32_t src3 : 10; 455 uint32_t src3_c : 1; 456 uint32_t src3_rel : 1; 457 uint32_t must_be_zero : 1; 458 uint32_t dummy : 3; 459 } rel2; 460 struct PACKED { 461 uint32_t src3 : 12; 462 uint32_t src3_c : 1; 463 uint32_t dummy : 3; 464 } c2; 465 }; 466 467 /* dword1: */ 468 uint32_t dst : 8; 469 uint32_t repeat : 3; 470 uint32_t src1_r : 1; 471 uint32_t ss : 1; 472 uint32_t ul : 1; 473 uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */ 474 uint32_t src2 : 8; 475 uint32_t opc : 4; 476 uint32_t jmp_tgt : 1; 477 uint32_t sync : 1; 478 uint32_t opc_cat : 3; 479} instr_cat3_t; 480 481static inline bool instr_cat3_full(instr_cat3_t *cat3) 482{ 483 switch (_OPC(3, cat3->opc)) { 484 case OPC_MAD_F16: 485 case OPC_MAD_U16: 486 case OPC_MAD_S16: 487 case OPC_SEL_B16: 488 case OPC_SEL_S16: 489 case OPC_SEL_F16: 490 case OPC_SAD_S16: 491 case OPC_SAD_S32: // really?? 492 return false; 493 default: 494 return true; 495 } 496} 497 498typedef struct PACKED { 499 /* dword0: */ 500 union PACKED { 501 struct PACKED { 502 uint32_t src : 11; 503 uint32_t must_be_zero1: 2; 504 uint32_t src_im : 1; /* immediate */ 505 uint32_t src_neg : 1; /* negate */ 506 uint32_t src_abs : 1; /* absolute value */ 507 }; 508 struct PACKED { 509 uint32_t src : 10; 510 uint32_t src_c : 1; /* relative-const */ 511 uint32_t src_rel : 1; /* relative address */ 512 uint32_t must_be_zero : 1; 513 uint32_t dummy : 3; 514 } rel; 515 struct PACKED { 516 uint32_t src : 12; 517 uint32_t src_c : 1; /* const */ 518 uint32_t dummy : 3; 519 } c; 520 }; 521 uint32_t dummy1 : 16; /* seem to be ignored */ 522 523 /* dword1: */ 524 uint32_t dst : 8; 525 uint32_t repeat : 3; 526 uint32_t src_r : 1; 527 uint32_t ss : 1; 528 uint32_t ul : 1; 529 uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */ 530 uint32_t dummy2 : 5; /* seem to be ignored */ 531 uint32_t full : 1; /* not half */ 532 uint32_t opc : 6; 533 uint32_t jmp_tgt : 1; 534 uint32_t sync : 1; 535 uint32_t opc_cat : 3; 536} instr_cat4_t; 537 538typedef struct PACKED { 539 /* dword0: */ 540 union PACKED { 541 /* normal case: */ 542 struct PACKED { 543 uint32_t full : 1; /* not half */ 544 uint32_t src1 : 8; 545 uint32_t src2 : 8; 546 uint32_t dummy1 : 4; /* seem to be ignored */ 547 uint32_t samp : 4; 548 uint32_t tex : 7; 549 } norm; 550 /* s2en case: */ 551 struct PACKED { 552 uint32_t full : 1; /* not half */ 553 uint32_t src1 : 8; 554 uint32_t src2 : 11; 555 uint32_t dummy1 : 1; 556 uint32_t src3 : 8; 557 uint32_t dummy2 : 3; 558 } s2en; 559 /* same in either case: */ 560 // XXX I think, confirm this 561 struct PACKED { 562 uint32_t full : 1; /* not half */ 563 uint32_t src1 : 8; 564 uint32_t pad : 23; 565 }; 566 }; 567 568 /* dword1: */ 569 uint32_t dst : 8; 570 uint32_t wrmask : 4; /* write-mask */ 571 uint32_t type : 3; 572 uint32_t dummy2 : 1; /* seems to be ignored */ 573 uint32_t is_3d : 1; 574 575 uint32_t is_a : 1; 576 uint32_t is_s : 1; 577 uint32_t is_s2en : 1; 578 uint32_t is_o : 1; 579 uint32_t is_p : 1; 580 581 uint32_t opc : 5; 582 uint32_t jmp_tgt : 1; 583 uint32_t sync : 1; 584 uint32_t opc_cat : 3; 585} instr_cat5_t; 586 587/* dword0 encoding for src_off: [src1 + off], src2: */ 588typedef struct PACKED { 589 /* dword0: */ 590 uint32_t mustbe1 : 1; 591 int32_t off : 13; 592 uint32_t src1 : 8; 593 uint32_t src1_im : 1; 594 uint32_t src2_im : 1; 595 uint32_t src2 : 8; 596 597 /* dword1: */ 598 uint32_t dword1; 599} instr_cat6a_t; 600 601/* dword0 encoding for !src_off: [src1], src2 */ 602typedef struct PACKED { 603 /* dword0: */ 604 uint32_t mustbe0 : 1; 605 uint32_t src1 : 13; 606 uint32_t ignore0 : 8; 607 uint32_t src1_im : 1; 608 uint32_t src2_im : 1; 609 uint32_t src2 : 8; 610 611 /* dword1: */ 612 uint32_t dword1; 613} instr_cat6b_t; 614 615/* dword1 encoding for dst_off: */ 616typedef struct PACKED { 617 /* dword0: */ 618 uint32_t dword0; 619 620 /* note: there is some weird stuff going on where sometimes 621 * cat6->a.off is involved.. but that seems like a bug in 622 * the blob, since it is used even if !cat6->src_off 623 * It would make sense for there to be some more bits to 624 * bring us to 11 bits worth of offset, but not sure.. 625 */ 626 int32_t off : 8; 627 uint32_t mustbe1 : 1; 628 uint32_t dst : 8; 629 uint32_t pad1 : 15; 630} instr_cat6c_t; 631 632/* dword1 encoding for !dst_off: */ 633typedef struct PACKED { 634 /* dword0: */ 635 uint32_t dword0; 636 637 uint32_t dst : 8; 638 uint32_t mustbe0 : 1; 639 uint32_t pad0 : 23; 640} instr_cat6d_t; 641 642/* I think some of the other cat6 instructions use additional 643 * sub-encodings.. 644 */ 645 646typedef union PACKED { 647 instr_cat6a_t a; 648 instr_cat6b_t b; 649 instr_cat6c_t c; 650 instr_cat6d_t d; 651 struct PACKED { 652 /* dword0: */ 653 uint32_t src_off : 1; 654 uint32_t pad1 : 31; 655 656 /* dword1: */ 657 uint32_t pad2 : 8; 658 uint32_t dst_off : 1; 659 uint32_t pad3 : 8; 660 uint32_t type : 3; 661 uint32_t g : 1; /* or in some cases it means dst immed */ 662 uint32_t pad4 : 1; 663 uint32_t opc : 5; 664 uint32_t jmp_tgt : 1; 665 uint32_t sync : 1; 666 uint32_t opc_cat : 3; 667 }; 668} instr_cat6_t; 669 670typedef union PACKED { 671 instr_cat0_t cat0; 672 instr_cat1_t cat1; 673 instr_cat2_t cat2; 674 instr_cat3_t cat3; 675 instr_cat4_t cat4; 676 instr_cat5_t cat5; 677 instr_cat6_t cat6; 678 struct PACKED { 679 /* dword0: */ 680 uint64_t pad1 : 40; 681 uint32_t repeat : 3; /* cat0-cat4 */ 682 uint32_t pad2 : 1; 683 uint32_t ss : 1; /* cat1-cat4 (cat0??) */ 684 uint32_t ul : 1; /* cat2-cat4 (and cat1 in blob.. which may be bug??) */ 685 uint32_t pad3 : 13; 686 uint32_t jmp_tgt : 1; 687 uint32_t sync : 1; 688 uint32_t opc_cat : 3; 689 690 }; 691} instr_t; 692 693static inline uint32_t instr_opc(instr_t *instr) 694{ 695 switch (instr->opc_cat) { 696 case 0: return instr->cat0.opc; 697 case 1: return 0; 698 case 2: return instr->cat2.opc; 699 case 3: return instr->cat3.opc; 700 case 4: return instr->cat4.opc; 701 case 5: return instr->cat5.opc; 702 case 6: return instr->cat6.opc; 703 default: return 0; 704 } 705} 706 707static inline bool is_mad(opc_t opc) 708{ 709 switch (opc) { 710 case OPC_MAD_U16: 711 case OPC_MAD_S16: 712 case OPC_MAD_U24: 713 case OPC_MAD_S24: 714 case OPC_MAD_F16: 715 case OPC_MAD_F32: 716 return true; 717 default: 718 return false; 719 } 720} 721 722static inline bool is_madsh(opc_t opc) 723{ 724 switch (opc) { 725 case OPC_MADSH_U16: 726 case OPC_MADSH_M16: 727 return true; 728 default: 729 return false; 730 } 731} 732 733#endif /* INSTR_A3XX_H_ */ 734