1/* 2 * Copyright (C) 2009 Nicolai Haehnle. 3 * 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial 16 * portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 */ 27 28#include "radeon_opcodes.h" 29#include "radeon_program.h" 30 31#include "radeon_program_constants.h" 32 33#include "util/compiler.h" 34 35const struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = { 36 { 37 .Opcode = RC_OPCODE_NOP, 38 .Name = "NOP" 39 }, 40 { 41 .Opcode = RC_OPCODE_ILLEGAL_OPCODE, 42 .Name = "ILLEGAL OPCODE" 43 }, 44 { 45 .Opcode = RC_OPCODE_ADD, 46 .Name = "ADD", 47 .NumSrcRegs = 2, 48 .HasDstReg = 1, 49 .IsComponentwise = 1 50 }, 51 { 52 .Opcode = RC_OPCODE_ARL, 53 .Name = "ARL", 54 .NumSrcRegs = 1, 55 .HasDstReg = 1 56 }, 57 { 58 .Opcode = RC_OPCODE_ARR, 59 .Name = "ARR", 60 .NumSrcRegs = 1, 61 .HasDstReg = 1 62 }, 63 { 64 .Opcode = RC_OPCODE_CEIL, 65 .Name = "CEIL", 66 .NumSrcRegs = 1, 67 .HasDstReg = 1, 68 .IsComponentwise = 1 69 }, 70 { 71 .Opcode = RC_OPCODE_CMP, 72 .Name = "CMP", 73 .NumSrcRegs = 3, 74 .HasDstReg = 1, 75 .IsComponentwise = 1 76 }, 77 { 78 .Opcode = RC_OPCODE_CND, 79 .Name = "CND", 80 .NumSrcRegs = 3, 81 .HasDstReg = 1, 82 .IsComponentwise = 1 83 }, 84 { 85 .Opcode = RC_OPCODE_COS, 86 .Name = "COS", 87 .NumSrcRegs = 1, 88 .HasDstReg = 1, 89 .IsStandardScalar = 1 90 }, 91 { 92 .Opcode = RC_OPCODE_DDX, 93 .Name = "DDX", 94 .NumSrcRegs = 2, 95 .HasDstReg = 1, 96 .IsComponentwise = 1 97 }, 98 { 99 .Opcode = RC_OPCODE_DDY, 100 .Name = "DDY", 101 .NumSrcRegs = 2, 102 .HasDstReg = 1, 103 .IsComponentwise = 1 104 }, 105 { 106 .Opcode = RC_OPCODE_DP2, 107 .Name = "DP2", 108 .NumSrcRegs = 2, 109 .HasDstReg = 1 110 }, 111 { 112 .Opcode = RC_OPCODE_DP3, 113 .Name = "DP3", 114 .NumSrcRegs = 2, 115 .HasDstReg = 1 116 }, 117 { 118 .Opcode = RC_OPCODE_DP4, 119 .Name = "DP4", 120 .NumSrcRegs = 2, 121 .HasDstReg = 1 122 }, 123 { 124 .Opcode = RC_OPCODE_DST, 125 .Name = "DST", 126 .NumSrcRegs = 2, 127 .HasDstReg = 1 128 }, 129 { 130 .Opcode = RC_OPCODE_EX2, 131 .Name = "EX2", 132 .NumSrcRegs = 1, 133 .HasDstReg = 1, 134 .IsStandardScalar = 1 135 }, 136 { 137 .Opcode = RC_OPCODE_EXP, 138 .Name = "EXP", 139 .NumSrcRegs = 1, 140 .HasDstReg = 1 141 }, 142 { 143 .Opcode = RC_OPCODE_FLR, 144 .Name = "FLR", 145 .NumSrcRegs = 1, 146 .HasDstReg = 1, 147 .IsComponentwise = 1 148 }, 149 { 150 .Opcode = RC_OPCODE_FRC, 151 .Name = "FRC", 152 .NumSrcRegs = 1, 153 .HasDstReg = 1, 154 .IsComponentwise = 1 155 }, 156 { 157 .Opcode = RC_OPCODE_KIL, 158 .Name = "KIL", 159 .NumSrcRegs = 1 160 }, 161 { 162 .Opcode = RC_OPCODE_LG2, 163 .Name = "LG2", 164 .NumSrcRegs = 1, 165 .HasDstReg = 1, 166 .IsStandardScalar = 1 167 }, 168 { 169 .Opcode = RC_OPCODE_LIT, 170 .Name = "LIT", 171 .NumSrcRegs = 1, 172 .HasDstReg = 1 173 }, 174 { 175 .Opcode = RC_OPCODE_LOG, 176 .Name = "LOG", 177 .NumSrcRegs = 1, 178 .HasDstReg = 1 179 }, 180 { 181 .Opcode = RC_OPCODE_LRP, 182 .Name = "LRP", 183 .NumSrcRegs = 3, 184 .HasDstReg = 1, 185 .IsComponentwise = 1 186 }, 187 { 188 .Opcode = RC_OPCODE_MAD, 189 .Name = "MAD", 190 .NumSrcRegs = 3, 191 .HasDstReg = 1, 192 .IsComponentwise = 1 193 }, 194 { 195 .Opcode = RC_OPCODE_MAX, 196 .Name = "MAX", 197 .NumSrcRegs = 2, 198 .HasDstReg = 1, 199 .IsComponentwise = 1 200 }, 201 { 202 .Opcode = RC_OPCODE_MIN, 203 .Name = "MIN", 204 .NumSrcRegs = 2, 205 .HasDstReg = 1, 206 .IsComponentwise = 1 207 }, 208 { 209 .Opcode = RC_OPCODE_MOV, 210 .Name = "MOV", 211 .NumSrcRegs = 1, 212 .HasDstReg = 1, 213 .IsComponentwise = 1 214 }, 215 { 216 .Opcode = RC_OPCODE_MUL, 217 .Name = "MUL", 218 .NumSrcRegs = 2, 219 .HasDstReg = 1, 220 .IsComponentwise = 1 221 }, 222 { 223 .Opcode = RC_OPCODE_POW, 224 .Name = "POW", 225 .NumSrcRegs = 2, 226 .HasDstReg = 1, 227 .IsStandardScalar = 1 228 }, 229 { 230 .Opcode = RC_OPCODE_RCP, 231 .Name = "RCP", 232 .NumSrcRegs = 1, 233 .HasDstReg = 1, 234 .IsStandardScalar = 1 235 }, 236 { 237 .Opcode = RC_OPCODE_ROUND, 238 .Name = "ROUND", 239 .NumSrcRegs = 1, 240 .HasDstReg = 1, 241 .IsComponentwise = 1 242 }, 243 { 244 .Opcode = RC_OPCODE_RSQ, 245 .Name = "RSQ", 246 .NumSrcRegs = 1, 247 .HasDstReg = 1, 248 .IsStandardScalar = 1 249 }, 250 { 251 .Opcode = RC_OPCODE_SEQ, 252 .Name = "SEQ", 253 .NumSrcRegs = 2, 254 .HasDstReg = 1, 255 .IsComponentwise = 1 256 }, 257 { 258 .Opcode = RC_OPCODE_SGE, 259 .Name = "SGE", 260 .NumSrcRegs = 2, 261 .HasDstReg = 1, 262 .IsComponentwise = 1 263 }, 264 { 265 .Opcode = RC_OPCODE_SGT, 266 .Name = "SGT", 267 .NumSrcRegs = 2, 268 .HasDstReg = 1, 269 .IsComponentwise = 1 270 }, 271 { 272 .Opcode = RC_OPCODE_SIN, 273 .Name = "SIN", 274 .NumSrcRegs = 1, 275 .HasDstReg = 1, 276 .IsStandardScalar = 1 277 }, 278 { 279 .Opcode = RC_OPCODE_SLE, 280 .Name = "SLE", 281 .NumSrcRegs = 2, 282 .HasDstReg = 1, 283 .IsComponentwise = 1 284 }, 285 { 286 .Opcode = RC_OPCODE_SLT, 287 .Name = "SLT", 288 .NumSrcRegs = 2, 289 .HasDstReg = 1, 290 .IsComponentwise = 1 291 }, 292 { 293 .Opcode = RC_OPCODE_SNE, 294 .Name = "SNE", 295 .NumSrcRegs = 2, 296 .HasDstReg = 1, 297 .IsComponentwise = 1 298 }, 299 { 300 .Opcode = RC_OPCODE_SSG, 301 .Name = "SSG", 302 .NumSrcRegs = 1, 303 .HasDstReg = 1, 304 .IsComponentwise = 1 305 }, 306 { 307 .Opcode = RC_OPCODE_SUB, 308 .Name = "SUB", 309 .NumSrcRegs = 2, 310 .HasDstReg = 1, 311 .IsComponentwise = 1 312 }, 313 { 314 .Opcode = RC_OPCODE_TRUNC, 315 .Name = "TRUNC", 316 .NumSrcRegs = 1, 317 .HasDstReg = 1, 318 .IsComponentwise = 1 319 }, 320 { 321 .Opcode = RC_OPCODE_TEX, 322 .Name = "TEX", 323 .HasTexture = 1, 324 .NumSrcRegs = 1, 325 .HasDstReg = 1 326 }, 327 { 328 .Opcode = RC_OPCODE_TXB, 329 .Name = "TXB", 330 .HasTexture = 1, 331 .NumSrcRegs = 1, 332 .HasDstReg = 1 333 }, 334 { 335 .Opcode = RC_OPCODE_TXD, 336 .Name = "TXD", 337 .HasTexture = 1, 338 .NumSrcRegs = 3, 339 .HasDstReg = 1 340 }, 341 { 342 .Opcode = RC_OPCODE_TXL, 343 .Name = "TXL", 344 .HasTexture = 1, 345 .NumSrcRegs = 1, 346 .HasDstReg = 1 347 }, 348 { 349 .Opcode = RC_OPCODE_TXP, 350 .Name = "TXP", 351 .HasTexture = 1, 352 .NumSrcRegs = 1, 353 .HasDstReg = 1 354 }, 355 { 356 .Opcode = RC_OPCODE_IF, 357 .Name = "IF", 358 .IsFlowControl = 1, 359 .NumSrcRegs = 1 360 }, 361 { 362 .Opcode = RC_OPCODE_ELSE, 363 .Name = "ELSE", 364 .IsFlowControl = 1, 365 .NumSrcRegs = 0 366 }, 367 { 368 .Opcode = RC_OPCODE_ENDIF, 369 .Name = "ENDIF", 370 .IsFlowControl = 1, 371 .NumSrcRegs = 0 372 }, 373 { 374 .Opcode = RC_OPCODE_BGNLOOP, 375 .Name = "BGNLOOP", 376 .IsFlowControl = 1, 377 .NumSrcRegs = 0 378 }, 379 { 380 .Opcode = RC_OPCODE_BRK, 381 .Name = "BRK", 382 .IsFlowControl = 1, 383 .NumSrcRegs = 0 384 }, 385 { 386 .Opcode = RC_OPCODE_ENDLOOP, 387 .Name = "ENDLOOP", 388 .IsFlowControl = 1, 389 .NumSrcRegs = 0, 390 }, 391 { 392 .Opcode = RC_OPCODE_CONT, 393 .Name = "CONT", 394 .IsFlowControl = 1, 395 .NumSrcRegs = 0 396 }, 397 { 398 .Opcode = RC_OPCODE_REPL_ALPHA, 399 .Name = "REPL_ALPHA", 400 .HasDstReg = 1 401 }, 402 { 403 .Opcode = RC_OPCODE_BEGIN_TEX, 404 .Name = "BEGIN_TEX" 405 }, 406 { 407 .Opcode = RC_OPCODE_KILP, 408 .Name = "KILP", 409 }, 410 { 411 .Opcode = RC_ME_PRED_SEQ, 412 .Name = "ME_PRED_SEQ", 413 .NumSrcRegs = 1, 414 .HasDstReg = 1 415 }, 416 { 417 .Opcode = RC_ME_PRED_SGT, 418 .Name = "ME_PRED_SGT", 419 .NumSrcRegs = 1, 420 .HasDstReg = 1 421 }, 422 { 423 .Opcode = RC_ME_PRED_SGE, 424 .Name = "ME_PRED_SGE", 425 .NumSrcRegs = 1, 426 .HasDstReg = 1 427 }, 428 { 429 .Opcode = RC_ME_PRED_SNEQ, 430 .Name = "ME_PRED_SNEQ", 431 .NumSrcRegs = 1, 432 .HasDstReg = 1 433 }, 434 { 435 .Opcode = RC_ME_PRED_SET_CLR, 436 .Name = "ME_PRED_SET_CLEAR", 437 .NumSrcRegs = 1, 438 .HasDstReg = 1 439 }, 440 { 441 .Opcode = RC_ME_PRED_SET_INV, 442 .Name = "ME_PRED_SET_INV", 443 .NumSrcRegs = 1, 444 .HasDstReg = 1 445 }, 446 { 447 .Opcode = RC_ME_PRED_SET_POP, 448 .Name = "ME_PRED_SET_POP", 449 .NumSrcRegs = 1, 450 .HasDstReg = 1 451 }, 452 { 453 .Opcode = RC_ME_PRED_SET_RESTORE, 454 .Name = "ME_PRED_SET_RESTORE", 455 .NumSrcRegs = 1, 456 .HasDstReg = 1 457 }, 458 { 459 .Opcode = RC_VE_PRED_SEQ_PUSH, 460 .Name = "VE_PRED_SEQ_PUSH", 461 .NumSrcRegs = 2, 462 .HasDstReg = 1 463 }, 464 { 465 .Opcode = RC_VE_PRED_SGT_PUSH, 466 .Name = "VE_PRED_SGT_PUSH", 467 .NumSrcRegs = 2, 468 .HasDstReg = 1 469 }, 470 { 471 .Opcode = RC_VE_PRED_SGE_PUSH, 472 .Name = "VE_PRED_SGE_PUSH", 473 .NumSrcRegs = 2, 474 .HasDstReg = 1 475 }, 476 { 477 .Opcode = RC_VE_PRED_SNEQ_PUSH, 478 .Name = "VE_PRED_SNEQ_PUSH", 479 .NumSrcRegs = 2, 480 .HasDstReg = 1 481 } 482}; 483 484void rc_compute_sources_for_writemask( 485 const struct rc_instruction *inst, 486 unsigned int writemask, 487 unsigned int *srcmasks) 488{ 489 const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); 490 srcmasks[0] = 0; 491 srcmasks[1] = 0; 492 srcmasks[2] = 0; 493 494 if (opcode->Opcode == RC_OPCODE_KIL) 495 srcmasks[0] |= RC_MASK_XYZW; 496 else if (opcode->Opcode == RC_OPCODE_IF) 497 srcmasks[0] |= RC_MASK_X; 498 499 if (!writemask) 500 return; 501 502 if (opcode->IsComponentwise) { 503 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) 504 srcmasks[src] |= writemask; 505 } else if (opcode->IsStandardScalar) { 506 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) 507 srcmasks[src] |= writemask; 508 } else { 509 switch(opcode->Opcode) { 510 case RC_OPCODE_ARL: 511 case RC_OPCODE_ARR: 512 srcmasks[0] |= RC_MASK_X; 513 break; 514 case RC_OPCODE_DP2: 515 srcmasks[0] |= RC_MASK_XY; 516 srcmasks[1] |= RC_MASK_XY; 517 break; 518 case RC_OPCODE_DP3: 519 srcmasks[0] |= RC_MASK_XYZ; 520 srcmasks[1] |= RC_MASK_XYZ; 521 break; 522 case RC_OPCODE_DP4: 523 srcmasks[0] |= RC_MASK_XYZW; 524 srcmasks[1] |= RC_MASK_XYZW; 525 break; 526 case RC_OPCODE_TXB: 527 case RC_OPCODE_TXP: 528 case RC_OPCODE_TXL: 529 srcmasks[0] |= RC_MASK_W; 530 FALLTHROUGH; 531 case RC_OPCODE_TEX: 532 switch (inst->U.I.TexSrcTarget) { 533 case RC_TEXTURE_1D: 534 srcmasks[0] |= RC_MASK_X; 535 break; 536 case RC_TEXTURE_2D: 537 case RC_TEXTURE_RECT: 538 case RC_TEXTURE_1D_ARRAY: 539 srcmasks[0] |= RC_MASK_XY; 540 break; 541 case RC_TEXTURE_3D: 542 case RC_TEXTURE_CUBE: 543 case RC_TEXTURE_2D_ARRAY: 544 srcmasks[0] |= RC_MASK_XYZ; 545 break; 546 } 547 break; 548 case RC_OPCODE_TXD: 549 switch (inst->U.I.TexSrcTarget) { 550 case RC_TEXTURE_1D_ARRAY: 551 srcmasks[0] |= RC_MASK_Y; 552 FALLTHROUGH; 553 case RC_TEXTURE_1D: 554 srcmasks[0] |= RC_MASK_X; 555 srcmasks[1] |= RC_MASK_X; 556 srcmasks[2] |= RC_MASK_X; 557 break; 558 case RC_TEXTURE_2D_ARRAY: 559 srcmasks[0] |= RC_MASK_Z; 560 FALLTHROUGH; 561 case RC_TEXTURE_2D: 562 case RC_TEXTURE_RECT: 563 srcmasks[0] |= RC_MASK_XY; 564 srcmasks[1] |= RC_MASK_XY; 565 srcmasks[2] |= RC_MASK_XY; 566 break; 567 case RC_TEXTURE_3D: 568 case RC_TEXTURE_CUBE: 569 srcmasks[0] |= RC_MASK_XYZ; 570 srcmasks[1] |= RC_MASK_XYZ; 571 srcmasks[2] |= RC_MASK_XYZ; 572 break; 573 } 574 break; 575 case RC_OPCODE_DST: 576 srcmasks[0] |= RC_MASK_Y | RC_MASK_Z; 577 srcmasks[1] |= RC_MASK_Y | RC_MASK_W; 578 break; 579 case RC_OPCODE_EXP: 580 case RC_OPCODE_LOG: 581 srcmasks[0] |= RC_MASK_XY; 582 break; 583 case RC_OPCODE_LIT: 584 srcmasks[0] |= RC_MASK_X | RC_MASK_Y | RC_MASK_W; 585 break; 586 default: 587 break; 588 } 589 } 590} 591