Files
FC1/RenderDll/XRenderOGL/NVParse/vs1.0_inst.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

1438 lines
42 KiB
C++

#include "RenderPCH.h"
#include "nvparse.h"
#include "vs1.0_inst.h"
string vs10_transstring;
#if 0
VS10Reg::VS10Reg()
{
type = 0;
index = 0;
sign = 0;
mask = 0;
}
VS10Reg::VS10Reg(const VS10Reg &r)
{
type = r.type;
index = r.index;
sign = r.sign;
mask = r.mask;
}
VS10Reg& VS10Reg::operator=(const VS10Reg &r)
{
if ( this != &r )
{
type = r.type;
index = r.index;
sign = r.sign;
mask = r.mask;
}
return *this;
}
#endif
void VS10Reg::Init()
{
type = 0;
index = -1;
sign = 0;
mask[0] = 'j';
mask[1] = 'j';
mask[2] = 'j';
mask[3] = 'j';
}
int VS10Reg::ValidateIndex()
{
switch( type )
{
case TYPE_TEMPORARY_REG:
if ( index < 0 || index > 11 ) return 0;
else return 1;
break;
case TYPE_VERTEX_ATTRIB_REG:
if ( index < 0 || index > 15 ) return 0;
else return 1;
break;
case TYPE_ADDRESS_REG:
if ( index != 0 ) return 0;
else return 1;
break;
case TYPE_CONSTANT_MEM_REG:
if ( index < 0 || index > 95 ) return 0;
else return 1;
break;
case TYPE_CONSTANT_A0_REG:
case TYPE_CONSTANT_A0_OFFSET_REG:
return 1;
break;
case TYPE_POSITION_RESULT_REG:
return 1;
break;
case TYPE_COLOR_RESULT_REG:
if ( index < 0 || index > 1 ) return 0;
else return 1;
break;
case TYPE_TEXTURE_RESULT_REG:
if ( index < 0 || index > 3 ) return 0;
else return 1;
break;
case TYPE_FOG_RESULT_REG:
return 1;
break;
case TYPE_POINTS_RESULT_REG:
return 1;
break;
default:
errors.set( "VS10Reg::ValidateIndex() Internal Error: unknown register type\n" );
return 1;
}
}
void VS10Reg::Translate()
{
char str[16];
if ( sign == -1 )
vs10_transstring.append( "-" );
switch ( type )
{
case TYPE_TEMPORARY_REG:
sprintf( str, "R%d", index );
vs10_transstring.append( str );
break;
case TYPE_VERTEX_ATTRIB_REG:
sprintf( str, "v[%d]", index );
vs10_transstring.append( str );
break;
case TYPE_ADDRESS_REG:
sprintf( str, "a%d", index );
vs10_transstring.append( str );
break;
case TYPE_CONSTANT_MEM_REG:
sprintf( str, "c[%d]", index );
vs10_transstring.append( str );
break;
case TYPE_CONSTANT_A0_REG:
vs10_transstring.append( "c[ A0.x ]" );
break;
case TYPE_CONSTANT_A0_OFFSET_REG:
sprintf( str, "c[ A0.x + %d ]", index );
vs10_transstring.append( str );
break;
case TYPE_POSITION_RESULT_REG:
vs10_transstring.append( "o[HPOS]" );
break;
case TYPE_COLOR_RESULT_REG:
sprintf( str, "o[COL%d]", index );
vs10_transstring.append( str );
break;
case TYPE_TEXTURE_RESULT_REG:
sprintf( str, "o[TEX%d]", index );
vs10_transstring.append( str );
break;
case TYPE_FOG_RESULT_REG:
vs10_transstring.append( "o[FOGC]" );
break;
case TYPE_POINTS_RESULT_REG:
vs10_transstring.append( "o[PSIZ]" );
break;
default:
errors.set( "VS10Reg::Translate() Internal Error: unknown register type\n" );
}
if ( mask[0] != 0 )
{
str[0] = '.';
strncpy( str+1, mask, 4 );
str[5] = 0;
vs10_transstring.append( str );
}
}
VS10Inst::~VS10Inst()
{
if (comment != NULL ) delete [] comment;
}
VS10Inst::VS10Inst()
{
line = -1;
instid = -1;
dst.Init();
src[0].Init();
src[1].Init();
src[2].Init();
comment = NULL;
}
VS10Inst::VS10Inst( int currline )
{
line = currline;
instid = -1;
dst.Init();
src[0].Init();
src[1].Init();
src[2].Init();
comment = NULL;
}
VS10Inst::VS10Inst( const VS10Inst &inst )
{
line = inst.line;
instid = inst.instid;
dst = inst.dst;
src[0] = inst.src[0];
src[1] = inst.src[1];
src[2] = inst.src[2];
if ( inst.comment == NULL )
comment = NULL;
else
{
comment = new char[strlen(inst.comment)+1];
strcpy( comment, inst.comment );
}
}
VS10Inst& VS10Inst::operator=(const VS10Inst &inst)
{
if ( this != &inst )
{
line = inst.line;
instid = inst.instid;
dst = inst.dst;
src[0] = inst.src[0];
src[1] = inst.src[1];
src[2] = inst.src[2];
if ( inst.comment == NULL )
comment = NULL;
else
{
comment = new char[strlen(inst.comment)+1];
strcpy( comment, inst.comment );
}
}
return *this;
}
VS10Inst::VS10Inst(int currline, int inst)
{
line = currline;
instid = inst;
dst.Init();
src[0].Init();
src[1].Init();
src[2].Init();
comment = NULL;
}
VS10Inst::VS10Inst(int currline, int inst, char *cmt)
{
line = currline;
instid = inst;
dst.Init();
src[0].Init();
src[1].Init();
src[2].Init();
comment = cmt;
}
VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0)
{
line = currline;
instid = inst;
dst = dreg;
src[0] = src0;
src[1].Init();
src[2].Init();
comment = NULL;
}
VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1)
{
line = currline;
instid = inst;
dst = dreg;
src[0] = src0;
src[1] = src1;
src[2].Init();
comment = NULL;
}
VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1, VS10Reg src2)
{
line = currline;
instid = inst;
dst = dreg;
src[0] = src0;
src[1] = src1;
src[2] = src2;
comment = NULL;
}
void VS10Inst::Validate( int &vsflag )
{
// Handle comments, noops, and newlines.
if ( instid == VS10_COMMENT || instid == VS10_NOP || instid == -1 ) return;
// Handle the header case.
if ( instid == VS10_HEADER )
{
if ( vsflag == 0 )
{
vsflag = 1;
return;
}
else
{
char temp[128];
sprintf( temp, "(%d) Error: vs.1.0 token already encountered\n", line );
errors.set( temp );
return;
}
}
// Validate register indices are valid.
ValidateRegIndices();
// Verify destination masking is valid.
ValidateDestMask();
// Verify source swizzling is valid.
ValidateSrcMasks();
// Verify destination register is writable.
ValidateDestWritable();
// Verify source registers are readable.
ValidateSrcReadable();
// Verify not reading from multiple vertex attributes or constants
ValidateReadPorts();
}
void VS10Inst::ValidateRegIndices()
{
char temp[256];
int result;
// Destination register.
result = dst.ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: destination register index out of range\n", line );
errors.set( temp );
}
// Source register.
result = src[0].ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: source register index out of range\n", line );
errors.set( temp );
}
switch( instid )
{
// Vector operations.
case VS10_MOV:
case VS10_LIT:
break;
// Unary operations.
case VS10_FRC:
break;
// Scalar operations.
case VS10_EXP:
case VS10_EXPP:
case VS10_LOG:
case VS10_LOGP:
case VS10_RCP:
case VS10_RSQ:
break;
// Binary operations.
case VS10_ADD:
case VS10_DP3:
case VS10_DP4:
case VS10_DST:
case VS10_SGE:
case VS10_SLT:
case VS10_SUB:
case VS10_MAX:
case VS10_MIN:
case VS10_MUL:
result = src[1].ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: second source register index out of range\n", line );
errors.set( temp );
}
break;
case VS10_M3X2:
case VS10_M3X3:
case VS10_M3X4:
case VS10_M4X3:
case VS10_M4X4:
{
result = src[1].ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: second source register index out of range\n", line );
errors.set( temp );
}
int orig;
orig = src[1].index;
switch( instid )
{
case VS10_M3X2:
src[1].index = src[1].index + 1;
break;
case VS10_M3X3:
case VS10_M4X3:
src[1].index = src[1].index + 2;
break;
case VS10_M3X4:
case VS10_M4X4:
src[1].index = src[1].index + 3;
break;
}
result = src[1].ValidateIndex();
src[1].index = orig;
if ( !result )
{
sprintf( temp, "(%d) Error: macro expansion produces source register index out of range\n", line );
errors.set( temp );
}
}
break;
// Trinary operations.
case VS10_MAD:
result = src[1].ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: second source register index out of range\n", line );
errors.set( temp );
}
result = src[2].ValidateIndex();
if ( !result )
{
sprintf( temp, "(%d) Error: third source register index out of range\n", line );
errors.set( temp );
}
break;
default:
errors.set( "VS10Inst::ValidateRegIndices() Internal Error: unknown instruction type\n" );
break;
}
}
void VS10Inst::ValidateDestMask()
{
char temp[256];
if ( dst.mask[0] == 0 ) return;
int i = 1;
while ( i < 4 && dst.mask[i] != 0 )
{
if ( dst.mask[i-1] >= dst.mask[i] )
{
char mask[5];
strncpy( mask, dst.mask, 4 );
mask[4] = 0;
sprintf( temp, "(%d) Error: destination register has invalid mask: %s\n", line, mask );
errors.set( temp );
break;
}
i++;
}
}
void VS10Inst::ValidateSrcMasks()
{
char temp[256];
char mask[5];
size_t len;
switch( instid )
{
// Vector operations.
case VS10_MOV:
case VS10_LIT:
strncpy( mask, src[0].mask, 4 );
mask[4] = 0;
len = strlen( mask );
if ( len == 2 || len == 3 )
{
sprintf( temp, "(%d) Error: source register has invalid mask: %s\n", line, mask );
errors.set( temp );
}
break;
// Unary operations.
case VS10_FRC:
strncpy( mask, src[0].mask, 4 );
mask[4] = 0;
len = strlen( mask );
if ( len == 2 || len == 3 )
{
sprintf( temp, "(%d) Error: source register has invalid mask: %s\n", line, mask );
errors.set( temp );
}
break;
// Scalar operations.
case VS10_EXP:
case VS10_EXPP:
case VS10_LOG:
case VS10_LOGP:
case VS10_RCP:
case VS10_RSQ:
strncpy( mask, src[0].mask, 4 );
mask[4] = 0;
len = strlen( mask );
if ( len == 2 || len == 3 )
{
sprintf( temp, "(%d) Error: source register has invalid mask: %s\n", line, mask );
errors.set( temp );
}
break;
// Binary operations.
case VS10_ADD:
case VS10_DP3:
case VS10_DP4:
case VS10_DST:
case VS10_SGE:
case VS10_SLT:
case VS10_SUB:
case VS10_M3X2:
case VS10_M3X3:
case VS10_M3X4:
case VS10_M4X3:
case VS10_M4X4:
case VS10_MAX:
case VS10_MIN:
case VS10_MUL:
strncpy( mask, src[0].mask, 4 );
mask[4] = 0;
len = strlen( mask );
if ( len == 2 || len == 3 )
{
sprintf( temp, "(%d) Error: source register has invalid mask: %s\n", line, mask );
errors.set( temp );
}
strncpy( mask, src[1].mask, 4 );
mask[4] = 0;
len = strlen( mask );
if ( len == 2 || len == 3 )
{
sprintf( temp, "(%d) Error: second source register has invalid mask: %s\n", line, mask );
errors.set( temp );
}
break;
// Trinary operations.
case VS10_MAD:
strncpy( mask, src[0].mask, 4 );
mask[4] = 0;
len = strlen( mask );
if ( len == 2 || len == 3 )
{
sprintf( temp, "(%d) Error: source register has invalid mask: %s\n", line, mask );
errors.set( temp );
}
strncpy( mask, src[1].mask, 4 );
mask[4] = 0;
len = strlen( mask );
if ( len == 2 || len == 3 )
{
sprintf( temp, "(%d) Error: second source register has invalid mask: %s\n", line, mask );
errors.set( temp );
}
strncpy( mask, src[2].mask, 4 );
mask[4] = 0;
len = strlen( mask );
if ( len == 2 || len == 3 )
{
sprintf( temp, "(%d) Error: third source register has invalid mask: %s\n", line, mask );
errors.set( temp );
}
break;
default:
errors.set( "VS10Inst::ValidateSrcMasks() Internal Error: unknown instruction type\n" );
break;
}
}
void VS10Inst::ValidateDestWritable()
{
char temp[256];
switch ( dst.type )
{
case TYPE_TEMPORARY_REG:
case TYPE_POSITION_RESULT_REG:
case TYPE_COLOR_RESULT_REG:
case TYPE_TEXTURE_RESULT_REG:
case TYPE_FOG_RESULT_REG:
case TYPE_POINTS_RESULT_REG:
break;
case TYPE_VERTEX_ATTRIB_REG:
case TYPE_CONSTANT_MEM_REG:
case TYPE_CONSTANT_A0_REG:
case TYPE_CONSTANT_A0_OFFSET_REG:
sprintf( temp, "(%d) Error: destination register is not writable\n", line );
errors.set( temp );
break;
case TYPE_ADDRESS_REG:
if ( instid != VS10_MOV )
{
sprintf( temp, "(%d) Error: destination register is not writable using this instruction\n", line );
errors.set( temp );
}
break;
default:
errors.set( "VS10Inst::ValidateDestWritable() Internal Error: unknown register type\n" );
}
if ( instid == VS10_FRC && dst.type != TYPE_TEMPORARY_REG )
{
sprintf( temp, "(%d) Error: destination register must be a temporary register\n", line );
errors.set( temp );
}
}
void VS10Inst::ValidateSrcReadable()
{
char temp[256];
// Source register.
switch( src[0].type )
{
case TYPE_TEMPORARY_REG:
case TYPE_VERTEX_ATTRIB_REG:
case TYPE_CONSTANT_MEM_REG:
case TYPE_CONSTANT_A0_REG:
case TYPE_CONSTANT_A0_OFFSET_REG:
break;
case TYPE_ADDRESS_REG:
case TYPE_POSITION_RESULT_REG:
case TYPE_COLOR_RESULT_REG:
case TYPE_TEXTURE_RESULT_REG:
case TYPE_FOG_RESULT_REG:
case TYPE_POINTS_RESULT_REG:
sprintf( temp, "(%d) Error: source register is not readable\n", line );
errors.set( temp );
break;
default:
errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
}
switch( instid )
{
// Vector operations.
case VS10_MOV:
case VS10_LIT:
break;
// Unary operations.
case VS10_FRC:
break;
// Scalar operations.
case VS10_EXP:
case VS10_EXPP:
case VS10_LOG:
case VS10_LOGP:
case VS10_RCP:
case VS10_RSQ:
break;
// Binary operations.
case VS10_ADD:
case VS10_DP3:
case VS10_DP4:
case VS10_DST:
case VS10_SGE:
case VS10_SLT:
case VS10_SUB:
case VS10_M3X2:
case VS10_M3X3:
case VS10_M3X4:
case VS10_M4X3:
case VS10_M4X4:
case VS10_MAX:
case VS10_MIN:
case VS10_MUL:
switch( src[1].type )
{
case TYPE_TEMPORARY_REG:
case TYPE_VERTEX_ATTRIB_REG:
case TYPE_CONSTANT_MEM_REG:
case TYPE_CONSTANT_A0_REG:
case TYPE_CONSTANT_A0_OFFSET_REG:
break;
case TYPE_ADDRESS_REG:
case TYPE_POSITION_RESULT_REG:
case TYPE_COLOR_RESULT_REG:
case TYPE_TEXTURE_RESULT_REG:
case TYPE_FOG_RESULT_REG:
case TYPE_POINTS_RESULT_REG:
sprintf( temp, "(%d) Error: second source register is not readable\n", line );
errors.set( temp );
break;
default:
errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
}
break;
// Trinary operations.
case VS10_MAD:
switch( src[1].type )
{
case TYPE_TEMPORARY_REG:
case TYPE_VERTEX_ATTRIB_REG:
case TYPE_CONSTANT_MEM_REG:
case TYPE_CONSTANT_A0_REG:
case TYPE_CONSTANT_A0_OFFSET_REG:
break;
case TYPE_ADDRESS_REG:
case TYPE_POSITION_RESULT_REG:
case TYPE_COLOR_RESULT_REG:
case TYPE_TEXTURE_RESULT_REG:
case TYPE_FOG_RESULT_REG:
case TYPE_POINTS_RESULT_REG:
sprintf( temp, "(%d) Error: second source register is not readable\n", line );
errors.set( temp );
break;
default:
errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
}
switch( src[2].type )
{
case TYPE_TEMPORARY_REG:
case TYPE_VERTEX_ATTRIB_REG:
case TYPE_CONSTANT_MEM_REG:
case TYPE_CONSTANT_A0_REG:
case TYPE_CONSTANT_A0_OFFSET_REG:
break;
case TYPE_ADDRESS_REG:
case TYPE_POSITION_RESULT_REG:
case TYPE_COLOR_RESULT_REG:
case TYPE_TEXTURE_RESULT_REG:
case TYPE_FOG_RESULT_REG:
case TYPE_POINTS_RESULT_REG:
sprintf( temp, "(%d) Error: third source register is not readable\n", line );
errors.set( temp );
break;
default:
errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
}
break;
default:
errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
break;
}
}
void VS10Inst::ValidateReadPorts()
{
int constidx[3];
int attribidx[3];
int i;
int acount;
int ccount;
char temp[256];
switch( instid )
{
// Vector operations.
case VS10_MOV:
case VS10_LIT:
break;
// Unary operations.
case VS10_FRC:
break;
// Scalar operations.
case VS10_EXP:
case VS10_EXPP:
case VS10_LOG:
case VS10_LOGP:
case VS10_RCP:
case VS10_RSQ:
break;
// Binary operations.
case VS10_ADD:
case VS10_DP3:
case VS10_DP4:
case VS10_DST:
case VS10_SGE:
case VS10_SLT:
case VS10_SUB:
case VS10_M3X2:
case VS10_M3X3:
case VS10_M3X4:
case VS10_M4X3:
case VS10_M4X4:
case VS10_MAX:
case VS10_MIN:
case VS10_MUL:
acount = 0;
ccount = 0;
for ( i = 0; i < 2; i++ )
{
switch( src[i].type )
{
case TYPE_VERTEX_ATTRIB_REG:
attribidx[acount] = src[i].index;
acount++;
break;
case TYPE_CONSTANT_MEM_REG:
constidx[ccount] = src[i].index;
ccount++;
break;
case TYPE_CONSTANT_A0_REG:
constidx[ccount] = 100 + src[i].index;
ccount++;
break;
case TYPE_CONSTANT_A0_OFFSET_REG:
constidx[ccount] = 200 + src[i].index;
ccount++;
break;
case TYPE_TEMPORARY_REG:
case TYPE_ADDRESS_REG:
case TYPE_POSITION_RESULT_REG:
case TYPE_COLOR_RESULT_REG:
case TYPE_TEXTURE_RESULT_REG:
case TYPE_FOG_RESULT_REG:
case TYPE_POINTS_RESULT_REG:
break;
default:
errors.set( "VS10Inst::ValidateReadPorts() Internal Error: unknown register type\n" );
}
}
if ( acount == 2 )
{
if ( attribidx[0] != attribidx[1] )
{
sprintf( temp, "(%d) Error: multiple unique attribute registers accessed in this instruction\n", line );
errors.set( temp );
}
}
else if ( ccount == 2 )
{
if ( constidx[0] != constidx[1] )
{
sprintf( temp, "(%d) Error: multiple unique constant registers accessed in this instruction\n", line );
errors.set( temp );
}
}
break;
// Trinary operations.
case VS10_MAD:
acount = 0;
ccount = 0;
for ( i = 0; i < 3; i++ )
{
switch( src[i].type )
{
case TYPE_VERTEX_ATTRIB_REG:
attribidx[acount] = src[i].index;
acount++;
break;
case TYPE_CONSTANT_MEM_REG:
constidx[ccount] = src[i].index;
ccount++;
break;
case TYPE_CONSTANT_A0_REG:
constidx[ccount] = 100 + src[i].index;
ccount++;
break;
case TYPE_CONSTANT_A0_OFFSET_REG:
constidx[ccount] = 200 + src[i].index;
ccount++;
break;
case TYPE_TEMPORARY_REG:
case TYPE_ADDRESS_REG:
case TYPE_POSITION_RESULT_REG:
case TYPE_COLOR_RESULT_REG:
case TYPE_TEXTURE_RESULT_REG:
case TYPE_FOG_RESULT_REG:
case TYPE_POINTS_RESULT_REG:
break;
default:
errors.set( "VS10Inst::ValidateReadPorts() Internal Error: unknown register type\n" );
}
}
if ( acount == 3 )
{
if ( attribidx[0] != attribidx[1] || attribidx[1] != attribidx[2] )
{
sprintf( temp, "(%d) Error: multiple unique attribute registers accessed in this instruction\n", line );
errors.set( temp );
}
}
else if ( acount == 2 )
{
if ( attribidx[0] != attribidx[1] )
{
sprintf( temp, "(%d) Error: multiple unique attribute registers accessed in this instruction\n", line );
errors.set( temp );
}
}
else if ( ccount == 3 )
{
if ( constidx[0] != constidx[1] || constidx[1] != constidx[2] )
{
sprintf( temp, "(%d) Error: multiple unique constant registers accessed in this instruction\n", line );
errors.set( temp );
}
}
else if ( ccount == 2 )
{
if ( constidx[0] != constidx[1] )
{
sprintf( temp, "(%d) Error: multiple unique constant registers accessed in this instruction\n", line );
errors.set( temp );
}
}
break;
default:
errors.set( "VS10Inst::ValidateSrcReadable() Internal Error: unknown register type\n" );
break;
}
}
int VS10Inst::Translate()
{
int flag;
int ninstr;
#if DEBUGGING_PURPOSES
char mystr[16];
if ( instid == VS10_HEADER )
{
sprintf( mystr, "%d:\tvs.1.0 (skip)\n", line );
vs10_transstring.append( mystr );
return 0;
}
sprintf( mystr, "%d:\t", line );
vs10_transstring.append( mystr );
#endif
switch( instid )
{
case VS10_ADD:
vs10_transstring.append( "ADD " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
ninstr = 1;
break;
case VS10_DP3:
vs10_transstring.append( "DP3 " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
ninstr = 1;
break;
case VS10_DP4:
vs10_transstring.append( "DP4 " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
ninstr = 1;
break;
case VS10_DST:
vs10_transstring.append( "DST " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
ninstr = 1;
break;
case VS10_EXP:
vs10_transstring.append( "EXP " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
ninstr = 1;
break;
case VS10_EXPP:
vs10_transstring.append( "EXP " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
ninstr = 1;
break;
case VS10_FRC:
char temp[128];
sprintf( temp, "(%d) Error: FRC built-in macro not yet supported.\n", line );
errors.set( temp );
ninstr = 0;
break;
case VS10_LIT:
vs10_transstring.append( "LIT " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
ninstr = 1;
break;
case VS10_LOG:
vs10_transstring.append( "LOG " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
ninstr = 1;
break;
case VS10_LOGP:
vs10_transstring.append( "LOG " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
ninstr = 1;
break;
case VS10_M3X2:
case VS10_M3X3:
case VS10_M3X4:
if ( dst.mask[0] != 0 )
{
ninstr = 0;
int i = 0;
while ( i < 4 && dst.mask[i] != 0 )
{
if ( dst.mask[i] == 'x' )
{
char oldval;
vs10_transstring.append( "DP3 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".x, " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
vs10_transstring.append( ";\n" );
ninstr++;
}
if ( dst.mask[i] == 'y' )
{
char oldval;
int oldindex;
vs10_transstring.append( "DP3 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".y, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 1;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
}
if ( dst.mask[i] == 'z' && (instid == VS10_M3X3 || instid == VS10_M3X4) )
{
char oldval;
int oldindex;
vs10_transstring.append( "DP3 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".z, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 2;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
}
if ( dst.mask[i] == 'w' && instid == VS10_M3X4 )
{
char oldval;
int oldindex;
vs10_transstring.append( "DP3 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".w, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 3;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
}
i++;
}
return ninstr;
}
else
{
ninstr = 0;
char oldval;
int oldindex;
vs10_transstring.append( "DP3 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".x, " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
vs10_transstring.append( ";\n" );
ninstr++;
vs10_transstring.append( "DP3 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".y, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 1;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
if ( instid == VS10_M3X3 || instid == VS10_M3X4 )
{
vs10_transstring.append( "DP3 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".z, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 2;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
}
if ( instid == VS10_M3X4 )
{
vs10_transstring.append( "DP3 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".w, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 3;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
}
return ninstr;
}
break;
case VS10_M4X3:
case VS10_M4X4:
if ( dst.mask[0] != 0 )
{
ninstr = 0;
int i = 0;
while ( i < 4 && dst.mask[i] != 0 )
{
if ( dst.mask[i] == 'x' )
{
char oldval;
vs10_transstring.append( "DP4 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".x, " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
vs10_transstring.append( ";\n" );
ninstr++;
}
if ( dst.mask[i] == 'y' )
{
char oldval;
int oldindex;
vs10_transstring.append( "DP4 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".y, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 1;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
}
if ( dst.mask[i] == 'z' )
{
char oldval;
int oldindex;
vs10_transstring.append( "DP4 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".z, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 2;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
}
if ( dst.mask[i] == 'w' && instid == VS10_M4X4 )
{
char oldval;
int oldindex;
vs10_transstring.append( "DP4 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".w, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 3;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
}
i++;
}
return ninstr;
}
else
{
ninstr = 0;
char oldval;
int oldindex;
vs10_transstring.append( "DP4 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".x, " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
vs10_transstring.append( ";\n" );
ninstr++;
vs10_transstring.append( "DP4 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".y, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 1;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
vs10_transstring.append( "DP4 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".z, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 2;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
if ( instid == VS10_M4X4 )
{
vs10_transstring.append( "DP4 " );
oldval = dst.mask[0];
dst.mask[0] = 0;
dst.Translate();
dst.mask[0] = oldval;
vs10_transstring.append( ".w, " );
src[0].Translate();
vs10_transstring.append( ", " );
oldindex = src[1].index;
src[1].index = src[1].index + 3;
src[1].Translate();
src[1].index = oldindex;
vs10_transstring.append( ";\n" );
ninstr++;
}
return ninstr;
}
break;
case VS10_MAD:
vs10_transstring.append( "MAD " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
vs10_transstring.append( ", " );
src[2].Translate();
ninstr = 1;
break;
case VS10_MAX:
vs10_transstring.append( "MAX " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
ninstr = 1;
break;
case VS10_MIN:
vs10_transstring.append( "MIN " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
ninstr = 1;
break;
case VS10_MOV:
vs10_transstring.append( "MOV " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
ninstr = 1;
break;
case VS10_MUL:
vs10_transstring.append( "MUL " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
ninstr = 1;
break;
case VS10_NOP:
return 0;
break;
case VS10_RCP:
vs10_transstring.append( "RCP " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
ninstr = 1;
break;
case VS10_RSQ:
vs10_transstring.append( "RSQ " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
ninstr = 1;
break;
case VS10_SGE:
vs10_transstring.append( "SGE " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
ninstr = 1;
break;
case VS10_SLT:
vs10_transstring.append( "SLT " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
src[1].Translate();
ninstr = 1;
break;
case VS10_SUB:
vs10_transstring.append( "ADD " );
dst.Translate();
vs10_transstring.append( ", " );
src[0].Translate();
vs10_transstring.append( ", " );
flag = src[1].sign;
if ( flag == -1 ) src[1].sign = 1;
else src[1].sign = -1;
src[1].Translate();
src[1].sign = flag;
ninstr = 1;
break;
case VS10_COMMENT:
vs10_transstring.append( comment );
return 0;
break;
case VS10_HEADER:
//vs10_transstring.append( "!!VP1.0\n" );
return 0;
break;
case -1:
vs10_transstring.append( "\n" );
return 0;
default:
errors.set( "VS10Inst::Translate() Internal Error: unknown instruction type\n" );
}
vs10_transstring.append( ";\n" );
return ninstr;
}