/*
* Copyright (C) 2009 Nicolai Haehnle.
*
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "radeon_opcodes.h"
#include "radeon_program.h"
#include "radeon_program_constants.h"
struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
{
.Opcode = RC_OPCODE_NOP,
.Name = "NOP"
},
{
.Opcode = RC_OPCODE_ILLEGAL_OPCODE,
.Name = "ILLEGAL OPCODE"
},
{
.Opcode = RC_OPCODE_ABS,
.Name = "ABS",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_ADD,
.Name = "ADD",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_ARL,
.Name = "ARL",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_CEIL,
.Name = "CEIL",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_CLAMP,
.Name = "CLAMP",
.NumSrcRegs = 3,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_CMP,
.Name = "CMP",
.NumSrcRegs = 3,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_CND,
.Name = "CND",
.NumSrcRegs = 3,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_COS,
.Name = "COS",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsStandardScalar = 1
},
{
.Opcode = RC_OPCODE_DDX,
.Name = "DDX",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_DDY,
.Name = "DDY",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_DP2,
.Name = "DP2",
.NumSrcRegs = 2,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_DP3,
.Name = "DP3",
.NumSrcRegs = 2,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_DP4,
.Name = "DP4",
.NumSrcRegs = 2,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_DPH,
.Name = "DPH",
.NumSrcRegs = 2,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_DST,
.Name = "DST",
.NumSrcRegs = 2,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_EX2,
.Name = "EX2",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsStandardScalar = 1
},
{
.Opcode = RC_OPCODE_EXP,
.Name = "EXP",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_FLR,
.Name = "FLR",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_FRC,
.Name = "FRC",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_KIL,
.Name = "KIL",
.NumSrcRegs = 1
},
{
.Opcode = RC_OPCODE_LG2,
.Name = "LG2",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsStandardScalar = 1
},
{
.Opcode = RC_OPCODE_LIT,
.Name = "LIT",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_LOG,
.Name = "LOG",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_LRP,
.Name = "LRP",
.NumSrcRegs = 3,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_MAD,
.Name = "MAD",
.NumSrcRegs = 3,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_MAX,
.Name = "MAX",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_MIN,
.Name = "MIN",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_MOV,
.Name = "MOV",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_MUL,
.Name = "MUL",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_POW,
.Name = "POW",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsStandardScalar = 1
},
{
.Opcode = RC_OPCODE_RCP,
.Name = "RCP",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsStandardScalar = 1
},
{
.Opcode = RC_OPCODE_ROUND,
.Name = "ROUND",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_RSQ,
.Name = "RSQ",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsStandardScalar = 1
},
{
.Opcode = RC_OPCODE_SCS,
.Name = "SCS",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_SEQ,
.Name = "SEQ",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_SFL,
.Name = "SFL",
.NumSrcRegs = 0,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_SGE,
.Name = "SGE",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_SGT,
.Name = "SGT",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_SIN,
.Name = "SIN",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsStandardScalar = 1
},
{
.Opcode = RC_OPCODE_SLE,
.Name = "SLE",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_SLT,
.Name = "SLT",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_SNE,
.Name = "SNE",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_SSG,
.Name = "SSG",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_SUB,
.Name = "SUB",
.NumSrcRegs = 2,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_SWZ,
.Name = "SWZ",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_TRUNC,
.Name = "TRUNC",
.NumSrcRegs = 1,
.HasDstReg = 1,
.IsComponentwise = 1
},
{
.Opcode = RC_OPCODE_XPD,
.Name = "XPD",
.NumSrcRegs = 2,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_TEX,
.Name = "TEX",
.HasTexture = 1,
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_TXB,
.Name = "TXB",
.HasTexture = 1,
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_TXD,
.Name = "TXD",
.HasTexture = 1,
.NumSrcRegs = 3,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_TXL,
.Name = "TXL",
.HasTexture = 1,
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_TXP,
.Name = "TXP",
.HasTexture = 1,
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_IF,
.Name = "IF",
.IsFlowControl = 1,
.NumSrcRegs = 1
},
{
.Opcode = RC_OPCODE_ELSE,
.Name = "ELSE",
.IsFlowControl = 1,
.NumSrcRegs = 0
},
{
.Opcode = RC_OPCODE_ENDIF,
.Name = "ENDIF",
.IsFlowControl = 1,
.NumSrcRegs = 0
},
{
.Opcode = RC_OPCODE_BGNLOOP,
.Name = "BGNLOOP",
.IsFlowControl = 1,
.NumSrcRegs = 0
},
{
.Opcode = RC_OPCODE_BRK,
.Name = "BRK",
.IsFlowControl = 1,
.NumSrcRegs = 0
},
{
.Opcode = RC_OPCODE_ENDLOOP,
.Name = "ENDLOOP",
.IsFlowControl = 1,
.NumSrcRegs = 0,
},
{
.Opcode = RC_OPCODE_CONT,
.Name = "CONT",
.IsFlowControl = 1,
.NumSrcRegs = 0
},
{
.Opcode = RC_OPCODE_REPL_ALPHA,
.Name = "REPL_ALPHA",
.HasDstReg = 1
},
{
.Opcode = RC_OPCODE_BEGIN_TEX,
.Name = "BEGIN_TEX"
},
{
.Opcode = RC_OPCODE_KILP,
.Name = "KILP",
},
{
.Opcode = RC_ME_PRED_SEQ,
.Name = "ME_PRED_SEQ",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_ME_PRED_SGT,
.Name = "ME_PRED_SGT",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_ME_PRED_SGE,
.Name = "ME_PRED_SGE",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_ME_PRED_SNEQ,
.Name = "ME_PRED_SNEQ",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_ME_PRED_SET_CLR,
.Name = "ME_PRED_SET_CLEAR",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_ME_PRED_SET_INV,
.Name = "ME_PRED_SET_INV",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_ME_PRED_SET_POP,
.Name = "ME_PRED_SET_POP",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_ME_PRED_SET_RESTORE,
.Name = "ME_PRED_SET_RESTORE",
.NumSrcRegs = 1,
.HasDstReg = 1
},
{
.Opcode = RC_VE_PRED_SEQ_PUSH,
.Name = "VE_PRED_SEQ_PUSH",
.NumSrcRegs = 2,
.HasDstReg = 1
},
{
.Opcode = RC_VE_PRED_SGT_PUSH,
.Name = "VE_PRED_SGT_PUSH",
.NumSrcRegs = 2,
.HasDstReg = 1
},
{
.Opcode = RC_VE_PRED_SGE_PUSH,
.Name = "VE_PRED_SGE_PUSH",
.NumSrcRegs = 2,
.HasDstReg = 1
},
{
.Opcode = RC_VE_PRED_SNEQ_PUSH,
.Name = "VE_PRED_SNEQ_PUSH",
.NumSrcRegs = 2,
.HasDstReg = 1
}
};
void rc_compute_sources_for_writemask(
const struct rc_instruction *inst,
unsigned int writemask,
unsigned int *srcmasks)
{
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
srcmasks[0] = 0;
srcmasks[1] = 0;
srcmasks[2] = 0;
if (opcode->Opcode == RC_OPCODE_KIL)
srcmasks[0] |= RC_MASK_XYZW;
else if (opcode->Opcode == RC_OPCODE_IF)
srcmasks[0] |= RC_MASK_X;
if (!writemask)
return;
if (opcode->IsComponentwise) {
for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
srcmasks[src] |= writemask;
} else if (opcode->IsStandardScalar) {
for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
srcmasks[src] |= writemask;
} else {
switch(opcode->Opcode) {
case RC_OPCODE_ARL:
srcmasks[0] |= RC_MASK_X;
break;
case RC_OPCODE_DP2:
srcmasks[0] |= RC_MASK_XY;
srcmasks[1] |= RC_MASK_XY;
break;
case RC_OPCODE_DP3:
case RC_OPCODE_XPD:
srcmasks[0] |= RC_MASK_XYZ;
srcmasks[1] |= RC_MASK_XYZ;
break;
case RC_OPCODE_DP4:
srcmasks[0] |= RC_MASK_XYZW;
srcmasks[1] |= RC_MASK_XYZW;
break;
case RC_OPCODE_DPH:
srcmasks[0] |= RC_MASK_XYZ;
srcmasks[1] |= RC_MASK_XYZW;
break;
case RC_OPCODE_TXB:
case RC_OPCODE_TXP:
case RC_OPCODE_TXL:
srcmasks[0] |= RC_MASK_W;
/* Fall through */
case RC_OPCODE_TEX:
switch (inst->U.I.TexSrcTarget) {
case RC_TEXTURE_1D:
srcmasks[0] |= RC_MASK_X;
break;
case RC_TEXTURE_2D:
case RC_TEXTURE_RECT:
case RC_TEXTURE_1D_ARRAY:
srcmasks[0] |= RC_MASK_XY;
break;
case RC_TEXTURE_3D:
case RC_TEXTURE_CUBE:
case RC_TEXTURE_2D_ARRAY:
srcmasks[0] |= RC_MASK_XYZ;
break;
}
break;
case RC_OPCODE_TXD:
switch (inst->U.I.TexSrcTarget) {
case RC_TEXTURE_1D_ARRAY:
srcmasks[0] |= RC_MASK_Y;
/* Fall through. */
case RC_TEXTURE_1D:
srcmasks[0] |= RC_MASK_X;
srcmasks[1] |= RC_MASK_X;
srcmasks[2] |= RC_MASK_X;
break;
case RC_TEXTURE_2D_ARRAY:
srcmasks[0] |= RC_MASK_Z;
/* Fall through. */
case RC_TEXTURE_2D:
case RC_TEXTURE_RECT:
srcmasks[0] |= RC_MASK_XY;
srcmasks[1] |= RC_MASK_XY;
srcmasks[2] |= RC_MASK_XY;
break;
case RC_TEXTURE_3D:
case RC_TEXTURE_CUBE:
srcmasks[0] |= RC_MASK_XYZ;
srcmasks[1] |= RC_MASK_XYZ;
srcmasks[2] |= RC_MASK_XYZ;
break;
}
break;
case RC_OPCODE_DST:
srcmasks[0] |= RC_MASK_Y | RC_MASK_Z;
srcmasks[1] |= RC_MASK_Y | RC_MASK_W;
break;
case RC_OPCODE_EXP:
case RC_OPCODE_LOG:
srcmasks[0] |= RC_MASK_XY;
break;
case RC_OPCODE_LIT:
srcmasks[0] |= RC_MASK_X | RC_MASK_Y | RC_MASK_W;
break;
default:
break;
}
}
}