Home | History | Annotate | Download | only in compiler
      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 struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
     34 	{
     35 		.Opcode = RC_OPCODE_NOP,
     36 		.Name = "NOP"
     37 	},
     38 	{
     39 		.Opcode = RC_OPCODE_ILLEGAL_OPCODE,
     40 		.Name = "ILLEGAL OPCODE"
     41 	},
     42 	{
     43 		.Opcode = RC_OPCODE_ABS,
     44 		.Name = "ABS",
     45 		.NumSrcRegs = 1,
     46 		.HasDstReg = 1,
     47 		.IsComponentwise = 1
     48 	},
     49 	{
     50 		.Opcode = RC_OPCODE_ADD,
     51 		.Name = "ADD",
     52 		.NumSrcRegs = 2,
     53 		.HasDstReg = 1,
     54 		.IsComponentwise = 1
     55 	},
     56 	{
     57 		.Opcode = RC_OPCODE_ARL,
     58 		.Name = "ARL",
     59 		.NumSrcRegs = 1,
     60 		.HasDstReg = 1
     61 	},
     62 	{
     63 		.Opcode = RC_OPCODE_CEIL,
     64 		.Name = "CEIL",
     65 		.NumSrcRegs = 1,
     66 		.HasDstReg = 1,
     67 		.IsComponentwise = 1
     68 	},
     69 	{
     70 		.Opcode = RC_OPCODE_CLAMP,
     71 		.Name = "CLAMP",
     72 		.NumSrcRegs = 3,
     73 		.HasDstReg = 1,
     74 		.IsComponentwise = 1
     75 	},
     76 	{
     77 		.Opcode = RC_OPCODE_CMP,
     78 		.Name = "CMP",
     79 		.NumSrcRegs = 3,
     80 		.HasDstReg = 1,
     81 		.IsComponentwise = 1
     82 	},
     83 	{
     84 		.Opcode = RC_OPCODE_CND,
     85 		.Name = "CND",
     86 		.NumSrcRegs = 3,
     87 		.HasDstReg = 1,
     88 		.IsComponentwise = 1
     89 	},
     90 	{
     91 		.Opcode = RC_OPCODE_COS,
     92 		.Name = "COS",
     93 		.NumSrcRegs = 1,
     94 		.HasDstReg = 1,
     95 		.IsStandardScalar = 1
     96 	},
     97 	{
     98 		.Opcode = RC_OPCODE_DDX,
     99 		.Name = "DDX",
    100 		.NumSrcRegs = 2,
    101 		.HasDstReg = 1,
    102 		.IsComponentwise = 1
    103 	},
    104 	{
    105 		.Opcode = RC_OPCODE_DDY,
    106 		.Name = "DDY",
    107 		.NumSrcRegs = 2,
    108 		.HasDstReg = 1,
    109 		.IsComponentwise = 1
    110 	},
    111 	{
    112 		.Opcode = RC_OPCODE_DP2,
    113 		.Name = "DP2",
    114 		.NumSrcRegs = 2,
    115 		.HasDstReg = 1
    116 	},
    117 	{
    118 		.Opcode = RC_OPCODE_DP3,
    119 		.Name = "DP3",
    120 		.NumSrcRegs = 2,
    121 		.HasDstReg = 1
    122 	},
    123 	{
    124 		.Opcode = RC_OPCODE_DP4,
    125 		.Name = "DP4",
    126 		.NumSrcRegs = 2,
    127 		.HasDstReg = 1
    128 	},
    129 	{
    130 		.Opcode = RC_OPCODE_DPH,
    131 		.Name = "DPH",
    132 		.NumSrcRegs = 2,
    133 		.HasDstReg = 1
    134 	},
    135 	{
    136 		.Opcode = RC_OPCODE_DST,
    137 		.Name = "DST",
    138 		.NumSrcRegs = 2,
    139 		.HasDstReg = 1
    140 	},
    141 	{
    142 		.Opcode = RC_OPCODE_EX2,
    143 		.Name = "EX2",
    144 		.NumSrcRegs = 1,
    145 		.HasDstReg = 1,
    146 		.IsStandardScalar = 1
    147 	},
    148 	{
    149 		.Opcode = RC_OPCODE_EXP,
    150 		.Name = "EXP",
    151 		.NumSrcRegs = 1,
    152 		.HasDstReg = 1
    153 	},
    154 	{
    155 		.Opcode = RC_OPCODE_FLR,
    156 		.Name = "FLR",
    157 		.NumSrcRegs = 1,
    158 		.HasDstReg = 1,
    159 		.IsComponentwise = 1
    160 	},
    161 	{
    162 		.Opcode = RC_OPCODE_FRC,
    163 		.Name = "FRC",
    164 		.NumSrcRegs = 1,
    165 		.HasDstReg = 1,
    166 		.IsComponentwise = 1
    167 	},
    168 	{
    169 		.Opcode = RC_OPCODE_KIL,
    170 		.Name = "KIL",
    171 		.NumSrcRegs = 1
    172 	},
    173 	{
    174 		.Opcode = RC_OPCODE_LG2,
    175 		.Name = "LG2",
    176 		.NumSrcRegs = 1,
    177 		.HasDstReg = 1,
    178 		.IsStandardScalar = 1
    179 	},
    180 	{
    181 		.Opcode = RC_OPCODE_LIT,
    182 		.Name = "LIT",
    183 		.NumSrcRegs = 1,
    184 		.HasDstReg = 1
    185 	},
    186 	{
    187 		.Opcode = RC_OPCODE_LOG,
    188 		.Name = "LOG",
    189 		.NumSrcRegs = 1,
    190 		.HasDstReg = 1
    191 	},
    192 	{
    193 		.Opcode = RC_OPCODE_LRP,
    194 		.Name = "LRP",
    195 		.NumSrcRegs = 3,
    196 		.HasDstReg = 1,
    197 		.IsComponentwise = 1
    198 	},
    199 	{
    200 		.Opcode = RC_OPCODE_MAD,
    201 		.Name = "MAD",
    202 		.NumSrcRegs = 3,
    203 		.HasDstReg = 1,
    204 		.IsComponentwise = 1
    205 	},
    206 	{
    207 		.Opcode = RC_OPCODE_MAX,
    208 		.Name = "MAX",
    209 		.NumSrcRegs = 2,
    210 		.HasDstReg = 1,
    211 		.IsComponentwise = 1
    212 	},
    213 	{
    214 		.Opcode = RC_OPCODE_MIN,
    215 		.Name = "MIN",
    216 		.NumSrcRegs = 2,
    217 		.HasDstReg = 1,
    218 		.IsComponentwise = 1
    219 	},
    220 	{
    221 		.Opcode = RC_OPCODE_MOV,
    222 		.Name = "MOV",
    223 		.NumSrcRegs = 1,
    224 		.HasDstReg = 1,
    225 		.IsComponentwise = 1
    226 	},
    227 	{
    228 		.Opcode = RC_OPCODE_MUL,
    229 		.Name = "MUL",
    230 		.NumSrcRegs = 2,
    231 		.HasDstReg = 1,
    232 		.IsComponentwise = 1
    233 	},
    234 	{
    235 		.Opcode = RC_OPCODE_POW,
    236 		.Name = "POW",
    237 		.NumSrcRegs = 2,
    238 		.HasDstReg = 1,
    239 		.IsStandardScalar = 1
    240 	},
    241 	{
    242 		.Opcode = RC_OPCODE_RCP,
    243 		.Name = "RCP",
    244 		.NumSrcRegs = 1,
    245 		.HasDstReg = 1,
    246 		.IsStandardScalar = 1
    247 	},
    248 	{
    249 		.Opcode = RC_OPCODE_ROUND,
    250 		.Name = "ROUND",
    251 		.NumSrcRegs = 1,
    252 		.HasDstReg = 1,
    253 		.IsComponentwise = 1
    254 	},
    255 	{
    256 		.Opcode = RC_OPCODE_RSQ,
    257 		.Name = "RSQ",
    258 		.NumSrcRegs = 1,
    259 		.HasDstReg = 1,
    260 		.IsStandardScalar = 1
    261 	},
    262 	{
    263 		.Opcode = RC_OPCODE_SCS,
    264 		.Name = "SCS",
    265 		.NumSrcRegs = 1,
    266 		.HasDstReg = 1
    267 	},
    268 	{
    269 		.Opcode = RC_OPCODE_SEQ,
    270 		.Name = "SEQ",
    271 		.NumSrcRegs = 2,
    272 		.HasDstReg = 1,
    273 		.IsComponentwise = 1
    274 	},
    275 	{
    276 		.Opcode = RC_OPCODE_SFL,
    277 		.Name = "SFL",
    278 		.NumSrcRegs = 0,
    279 		.HasDstReg = 1,
    280 		.IsComponentwise = 1
    281 	},
    282 	{
    283 		.Opcode = RC_OPCODE_SGE,
    284 		.Name = "SGE",
    285 		.NumSrcRegs = 2,
    286 		.HasDstReg = 1,
    287 		.IsComponentwise = 1
    288 	},
    289 	{
    290 		.Opcode = RC_OPCODE_SGT,
    291 		.Name = "SGT",
    292 		.NumSrcRegs = 2,
    293 		.HasDstReg = 1,
    294 		.IsComponentwise = 1
    295 	},
    296 	{
    297 		.Opcode = RC_OPCODE_SIN,
    298 		.Name = "SIN",
    299 		.NumSrcRegs = 1,
    300 		.HasDstReg = 1,
    301 		.IsStandardScalar = 1
    302 	},
    303 	{
    304 		.Opcode = RC_OPCODE_SLE,
    305 		.Name = "SLE",
    306 		.NumSrcRegs = 2,
    307 		.HasDstReg = 1,
    308 		.IsComponentwise = 1
    309 	},
    310 	{
    311 		.Opcode = RC_OPCODE_SLT,
    312 		.Name = "SLT",
    313 		.NumSrcRegs = 2,
    314 		.HasDstReg = 1,
    315 		.IsComponentwise = 1
    316 	},
    317 	{
    318 		.Opcode = RC_OPCODE_SNE,
    319 		.Name = "SNE",
    320 		.NumSrcRegs = 2,
    321 		.HasDstReg = 1,
    322 		.IsComponentwise = 1
    323 	},
    324 	{
    325 		.Opcode = RC_OPCODE_SSG,
    326 		.Name = "SSG",
    327 		.NumSrcRegs = 1,
    328 		.HasDstReg = 1,
    329 		.IsComponentwise = 1
    330 	},
    331 	{
    332 		.Opcode = RC_OPCODE_SUB,
    333 		.Name = "SUB",
    334 		.NumSrcRegs = 2,
    335 		.HasDstReg = 1,
    336 		.IsComponentwise = 1
    337 	},
    338 	{
    339 		.Opcode = RC_OPCODE_SWZ,
    340 		.Name = "SWZ",
    341 		.NumSrcRegs = 1,
    342 		.HasDstReg = 1,
    343 		.IsComponentwise = 1
    344 	},
    345 	{
    346 		.Opcode = RC_OPCODE_TRUNC,
    347 		.Name = "TRUNC",
    348 		.NumSrcRegs = 1,
    349 		.HasDstReg = 1,
    350 		.IsComponentwise = 1
    351 	},
    352 	{
    353 		.Opcode = RC_OPCODE_XPD,
    354 		.Name = "XPD",
    355 		.NumSrcRegs = 2,
    356 		.HasDstReg = 1
    357 	},
    358 	{
    359 		.Opcode = RC_OPCODE_TEX,
    360 		.Name = "TEX",
    361 		.HasTexture = 1,
    362 		.NumSrcRegs = 1,
    363 		.HasDstReg = 1
    364 	},
    365 	{
    366 		.Opcode = RC_OPCODE_TXB,
    367 		.Name = "TXB",
    368 		.HasTexture = 1,
    369 		.NumSrcRegs = 1,
    370 		.HasDstReg = 1
    371 	},
    372 	{
    373 		.Opcode = RC_OPCODE_TXD,
    374 		.Name = "TXD",
    375 		.HasTexture = 1,
    376 		.NumSrcRegs = 3,
    377 		.HasDstReg = 1
    378 	},
    379 	{
    380 		.Opcode = RC_OPCODE_TXL,
    381 		.Name = "TXL",
    382 		.HasTexture = 1,
    383 		.NumSrcRegs = 1,
    384 		.HasDstReg = 1
    385 	},
    386 	{
    387 		.Opcode = RC_OPCODE_TXP,
    388 		.Name = "TXP",
    389 		.HasTexture = 1,
    390 		.NumSrcRegs = 1,
    391 		.HasDstReg = 1
    392 	},
    393 	{
    394 		.Opcode = RC_OPCODE_IF,
    395 		.Name = "IF",
    396 		.IsFlowControl = 1,
    397 		.NumSrcRegs = 1
    398 	},
    399 	{
    400 		.Opcode = RC_OPCODE_ELSE,
    401 		.Name = "ELSE",
    402 		.IsFlowControl = 1,
    403 		.NumSrcRegs = 0
    404 	},
    405 	{
    406 		.Opcode = RC_OPCODE_ENDIF,
    407 		.Name = "ENDIF",
    408 		.IsFlowControl = 1,
    409 		.NumSrcRegs = 0
    410 	},
    411 	{
    412 		.Opcode = RC_OPCODE_BGNLOOP,
    413 		.Name = "BGNLOOP",
    414 		.IsFlowControl = 1,
    415 		.NumSrcRegs = 0
    416 	},
    417 	{
    418 		.Opcode = RC_OPCODE_BRK,
    419 		.Name = "BRK",
    420 		.IsFlowControl = 1,
    421 		.NumSrcRegs = 0
    422 	},
    423 	{
    424 		.Opcode = RC_OPCODE_ENDLOOP,
    425 		.Name = "ENDLOOP",
    426 		.IsFlowControl = 1,
    427 		.NumSrcRegs = 0,
    428 	},
    429 	{
    430 		.Opcode = RC_OPCODE_CONT,
    431 		.Name = "CONT",
    432 		.IsFlowControl = 1,
    433 		.NumSrcRegs = 0
    434 	},
    435 	{
    436 		.Opcode = RC_OPCODE_REPL_ALPHA,
    437 		.Name = "REPL_ALPHA",
    438 		.HasDstReg = 1
    439 	},
    440 	{
    441 		.Opcode = RC_OPCODE_BEGIN_TEX,
    442 		.Name = "BEGIN_TEX"
    443 	},
    444 	{
    445 		.Opcode = RC_OPCODE_KILP,
    446 		.Name = "KILP",
    447 	},
    448 	{
    449 		.Opcode = RC_ME_PRED_SEQ,
    450 		.Name = "ME_PRED_SEQ",
    451 		.NumSrcRegs = 1,
    452 		.HasDstReg = 1
    453 	},
    454 	{
    455 		.Opcode = RC_ME_PRED_SGT,
    456 		.Name = "ME_PRED_SGT",
    457 		.NumSrcRegs = 1,
    458 		.HasDstReg = 1
    459 	},
    460 	{
    461 		.Opcode = RC_ME_PRED_SGE,
    462 		.Name = "ME_PRED_SGE",
    463 		.NumSrcRegs = 1,
    464 		.HasDstReg = 1
    465 	},
    466 	{
    467 		.Opcode = RC_ME_PRED_SNEQ,
    468 		.Name = "ME_PRED_SNEQ",
    469 		.NumSrcRegs = 1,
    470 		.HasDstReg = 1
    471 	},
    472 	{
    473 		.Opcode = RC_ME_PRED_SET_CLR,
    474 		.Name = "ME_PRED_SET_CLEAR",
    475 		.NumSrcRegs = 1,
    476 		.HasDstReg = 1
    477 	},
    478 	{
    479 		.Opcode = RC_ME_PRED_SET_INV,
    480 		.Name = "ME_PRED_SET_INV",
    481 		.NumSrcRegs = 1,
    482 		.HasDstReg = 1
    483 	},
    484 	{
    485 		.Opcode = RC_ME_PRED_SET_POP,
    486 		.Name = "ME_PRED_SET_POP",
    487 		.NumSrcRegs = 1,
    488 		.HasDstReg = 1
    489 	},
    490 	{
    491 		.Opcode = RC_ME_PRED_SET_RESTORE,
    492 		.Name = "ME_PRED_SET_RESTORE",
    493 		.NumSrcRegs = 1,
    494 		.HasDstReg = 1
    495 	},
    496 	{
    497 		.Opcode = RC_VE_PRED_SEQ_PUSH,
    498 		.Name = "VE_PRED_SEQ_PUSH",
    499 		.NumSrcRegs = 2,
    500 		.HasDstReg = 1
    501 	},
    502 	{
    503 		.Opcode = RC_VE_PRED_SGT_PUSH,
    504 		.Name = "VE_PRED_SGT_PUSH",
    505 		.NumSrcRegs = 2,
    506 		.HasDstReg = 1
    507 	},
    508 	{
    509 		.Opcode = RC_VE_PRED_SGE_PUSH,
    510 		.Name = "VE_PRED_SGE_PUSH",
    511 		.NumSrcRegs = 2,
    512 		.HasDstReg = 1
    513 	},
    514 	{
    515 		.Opcode = RC_VE_PRED_SNEQ_PUSH,
    516 		.Name = "VE_PRED_SNEQ_PUSH",
    517 		.NumSrcRegs = 2,
    518 		.HasDstReg = 1
    519 	}
    520 };
    521 
    522 void rc_compute_sources_for_writemask(
    523 		const struct rc_instruction *inst,
    524 		unsigned int writemask,
    525 		unsigned int *srcmasks)
    526 {
    527 	const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
    528 	srcmasks[0] = 0;
    529 	srcmasks[1] = 0;
    530 	srcmasks[2] = 0;
    531 
    532 	if (opcode->Opcode == RC_OPCODE_KIL)
    533 		srcmasks[0] |= RC_MASK_XYZW;
    534 	else if (opcode->Opcode == RC_OPCODE_IF)
    535 		srcmasks[0] |= RC_MASK_X;
    536 
    537 	if (!writemask)
    538 		return;
    539 
    540 	if (opcode->IsComponentwise) {
    541 		for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
    542 			srcmasks[src] |= writemask;
    543 	} else if (opcode->IsStandardScalar) {
    544 		for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
    545 			srcmasks[src] |= writemask;
    546 	} else {
    547 		switch(opcode->Opcode) {
    548 		case RC_OPCODE_ARL:
    549 			srcmasks[0] |= RC_MASK_X;
    550 			break;
    551 		case RC_OPCODE_DP2:
    552 			srcmasks[0] |= RC_MASK_XY;
    553 			srcmasks[1] |= RC_MASK_XY;
    554 			break;
    555 		case RC_OPCODE_DP3:
    556 		case RC_OPCODE_XPD:
    557 			srcmasks[0] |= RC_MASK_XYZ;
    558 			srcmasks[1] |= RC_MASK_XYZ;
    559 			break;
    560 		case RC_OPCODE_DP4:
    561 			srcmasks[0] |= RC_MASK_XYZW;
    562 			srcmasks[1] |= RC_MASK_XYZW;
    563 			break;
    564 		case RC_OPCODE_DPH:
    565 			srcmasks[0] |= RC_MASK_XYZ;
    566 			srcmasks[1] |= RC_MASK_XYZW;
    567 			break;
    568 		case RC_OPCODE_TXB:
    569 		case RC_OPCODE_TXP:
    570 		case RC_OPCODE_TXL:
    571 			srcmasks[0] |= RC_MASK_W;
    572 			/* Fall through */
    573 		case RC_OPCODE_TEX:
    574 			switch (inst->U.I.TexSrcTarget) {
    575 				case RC_TEXTURE_1D:
    576 					srcmasks[0] |= RC_MASK_X;
    577 					break;
    578 				case RC_TEXTURE_2D:
    579 				case RC_TEXTURE_RECT:
    580 				case RC_TEXTURE_1D_ARRAY:
    581 					srcmasks[0] |= RC_MASK_XY;
    582 					break;
    583 				case RC_TEXTURE_3D:
    584 				case RC_TEXTURE_CUBE:
    585 				case RC_TEXTURE_2D_ARRAY:
    586 					srcmasks[0] |= RC_MASK_XYZ;
    587 					break;
    588 			}
    589 			break;
    590 		case RC_OPCODE_TXD:
    591 			switch (inst->U.I.TexSrcTarget) {
    592 				case RC_TEXTURE_1D_ARRAY:
    593 					srcmasks[0] |= RC_MASK_Y;
    594 					/* Fall through. */
    595 				case RC_TEXTURE_1D:
    596 					srcmasks[0] |= RC_MASK_X;
    597 					srcmasks[1] |= RC_MASK_X;
    598 					srcmasks[2] |= RC_MASK_X;
    599 					break;
    600 				case RC_TEXTURE_2D_ARRAY:
    601 					srcmasks[0] |= RC_MASK_Z;
    602 					/* Fall through. */
    603 				case RC_TEXTURE_2D:
    604 				case RC_TEXTURE_RECT:
    605 					srcmasks[0] |= RC_MASK_XY;
    606 					srcmasks[1] |= RC_MASK_XY;
    607 					srcmasks[2] |= RC_MASK_XY;
    608 					break;
    609 				case RC_TEXTURE_3D:
    610 				case RC_TEXTURE_CUBE:
    611 					srcmasks[0] |= RC_MASK_XYZ;
    612 					srcmasks[1] |= RC_MASK_XYZ;
    613 					srcmasks[2] |= RC_MASK_XYZ;
    614 					break;
    615 			}
    616 			break;
    617 		case RC_OPCODE_DST:
    618 			srcmasks[0] |= RC_MASK_Y | RC_MASK_Z;
    619 			srcmasks[1] |= RC_MASK_Y | RC_MASK_W;
    620 			break;
    621 		case RC_OPCODE_EXP:
    622 		case RC_OPCODE_LOG:
    623 			srcmasks[0] |= RC_MASK_XY;
    624 			break;
    625 		case RC_OPCODE_LIT:
    626 			srcmasks[0] |= RC_MASK_X | RC_MASK_Y | RC_MASK_W;
    627 			break;
    628 		default:
    629 			break;
    630 		}
    631 	}
    632 }
    633