Logo Search packages:      
Sourcecode: ogre version File versions

ps_1_4.cpp

/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/

 
 //---------------------------------------------------------------------------
#include "ps_1_4.h"

//---------------------------------------------------------------------------

/* ********************* START OF PS_1_4 CLASS STATIC DATA ********************************* */


// library of built in symbol types

bool PS_1_4::LibInitialized = false;

#define SYMSTART {
#define SYMDEF  ,0,0,0,0},{
#define SYMEND  ,0,0,0,0}

PS_1_4::SymbolDef PS_1_4::PS_1_4_SymbolTypeLib[] = {
      // pixel shader versions supported
      { sid_PS_1_4, GL_NONE, ckp_PS_BASE, ckp_PS_1_4, 0, 0, 0 },
      { sid_PS_1_1, GL_NONE, ckp_PS_BASE, ckp_PS_1_1, 0, 0, 0 },
      { sid_PS_1_2, GL_NONE, ckp_PS_BASE, ckp_PS_1_2 + ckp_PS_1_1, 0, 0, 0 },
      { sid_PS_1_3, GL_NONE, ckp_PS_BASE, ckp_PS_1_3 + ckp_PS_1_2 + ckp_PS_1_1, 0, 0, 0 },

      // PS_BASE

      // constants
      SYMSTART sid_C0, GL_CON_0_ATI, ckp_PS_BASE
      SYMDEF sid_C1, GL_CON_1_ATI, ckp_PS_BASE
      SYMDEF sid_C2, GL_CON_2_ATI, ckp_PS_BASE
      SYMDEF sid_C3, GL_CON_3_ATI, ckp_PS_BASE
      SYMDEF sid_C4, GL_CON_4_ATI, ckp_PS_BASE
      SYMDEF sid_C5, GL_CON_5_ATI, ckp_PS_BASE
      SYMDEF sid_C6, GL_CON_6_ATI, ckp_PS_BASE
      SYMDEF sid_C7, GL_CON_7_ATI, ckp_PS_BASE

      // colour
      SYMDEF sid_V0, GL_PRIMARY_COLOR_ARB,  ckp_PS_BASE
      SYMDEF sid_V1, GL_SECONDARY_INTERPOLATOR_ATI,  ckp_PS_BASE

      // instruction ops
      SYMDEF sid_ADD, GL_ADD_ATI, ckp_PS_BASE
      SYMDEF sid_SUB, GL_SUB_ATI, ckp_PS_BASE
      SYMDEF sid_MUL, GL_MUL_ATI, ckp_PS_BASE
      SYMDEF sid_MAD, GL_MAD_ATI, ckp_PS_BASE
      SYMDEF sid_LRP, GL_LERP_ATI, ckp_PS_BASE
      SYMDEF sid_MOV, GL_MOV_ATI, ckp_PS_BASE
      SYMDEF sid_CMP, GL_CND0_ATI, ckp_PS_BASE
      SYMDEF sid_CND, GL_CND_ATI, ckp_PS_BASE
      SYMDEF sid_DP3, GL_DOT3_ATI, ckp_PS_BASE
      SYMDEF sid_DP4, GL_DOT4_ATI, ckp_PS_BASE

      SYMDEF sid_DEF, GL_NONE, ckp_PS_BASE

      // Masks
      SYMDEF sid_R, GL_RED_BIT_ATI, ckp_PS_1_4
      SYMDEF sid_RA, GL_RED_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
      SYMDEF sid_G, GL_GREEN_BIT_ATI, ckp_PS_1_4
      SYMDEF sid_GA, GL_GREEN_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
      SYMDEF sid_B, GL_BLUE_BIT_ATI, ckp_PS_1_4
      SYMDEF sid_BA, GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
      SYMDEF sid_A, ALPHA_BIT, ckp_PS_BASE
      SYMDEF sid_RGBA, RGB_BITS | ALPHA_BIT, ckp_PS_BASE
      SYMDEF sid_RGB, RGB_BITS,  ckp_PS_BASE
      SYMDEF sid_RG, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI, ckp_PS_1_4
      SYMDEF sid_RGA, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
      SYMDEF sid_RB, GL_RED_BIT_ATI | GL_BLUE_BIT_ATI, ckp_PS_1_4
      SYMDEF sid_RBA, GL_RED_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4
      SYMDEF sid_GB, GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI, ckp_PS_1_4
      SYMDEF sid_GBA, GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4

      // Rep
      SYMDEF sid_RRRR, GL_RED, ckp_PS_1_4
      SYMDEF sid_GGGG, GL_GREEN, ckp_PS_1_4
      SYMDEF sid_BBBB, GL_BLUE, ckp_PS_BASE
      SYMDEF sid_AAAA, GL_ALPHA, ckp_PS_BASE


      // modifiers
      SYMDEF sid_X2, GL_2X_BIT_ATI, ckp_PS_BASE
      SYMDEF sid_X4, GL_4X_BIT_ATI, ckp_PS_BASE
      SYMDEF sid_D2, GL_HALF_BIT_ATI, ckp_PS_BASE
      SYMDEF sid_SAT, GL_SATURATE_BIT_ATI, ckp_PS_BASE

      // argument modifiers
      SYMDEF sid_BIAS, GL_BIAS_BIT_ATI, ckp_PS_BASE
      SYMDEF sid_INVERT, GL_COMP_BIT_ATI, ckp_PS_BASE
      SYMDEF sid_NEGATE, GL_NEGATE_BIT_ATI, ckp_PS_BASE
      SYMDEF sid_BX2, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI, ckp_PS_BASE
      
      // seperator characters
      SYMDEF sid_COMMA, GL_NONE, ckp_PS_BASE
      SYMDEF sid_VALUE, GL_NONE, ckp_PS_BASE

      // PS_1_4
      // temp R/W registers
      SYMDEF sid_R0, GL_REG_0_ATI, ckp_PS_1_4
      SYMDEF sid_R1, GL_REG_1_ATI, ckp_PS_1_4
      SYMDEF sid_R2, GL_REG_2_ATI, ckp_PS_1_4
      SYMDEF sid_R3, GL_REG_3_ATI, ckp_PS_1_4
      SYMDEF sid_R4, GL_REG_4_ATI, ckp_PS_1_4
      SYMDEF sid_R5, GL_REG_5_ATI, ckp_PS_1_4

      // textures
      SYMDEF sid_T0, GL_TEXTURE0_ARB, ckp_PS_1_4
      SYMDEF sid_T1, GL_TEXTURE1_ARB, ckp_PS_1_4
      SYMDEF sid_T2, GL_TEXTURE2_ARB, ckp_PS_1_4
      SYMDEF sid_T3, GL_TEXTURE3_ARB, ckp_PS_1_4
      SYMDEF sid_T4, GL_TEXTURE4_ARB, ckp_PS_1_4
      SYMDEF sid_T5, GL_TEXTURE5_ARB, ckp_PS_1_4
      SYMDEF sid_DP2ADD, GL_DOT2_ADD_ATI, ckp_PS_1_4

      // modifiers
      SYMDEF sid_X8, GL_8X_BIT_ATI, ckp_PS_1_4
      SYMDEF sid_D8, GL_EIGHTH_BIT_ATI, ckp_PS_1_4
      SYMDEF sid_D4, GL_QUARTER_BIT_ATI, ckp_PS_1_4

      // instructions
      SYMDEF sid_TEXCRD, GL_NONE, ckp_PS_1_4
      SYMDEF sid_TEXLD, GL_NONE, ckp_PS_1_4

      // texture swizzlers

      SYMDEF sid_STR, GL_SWIZZLE_STR_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4
      SYMDEF sid_STQ, GL_SWIZZLE_STQ_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4
      SYMDEF sid_STRDR, GL_SWIZZLE_STR_DR_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4
      SYMDEF sid_STQDQ, GL_SWIZZLE_STQ_DQ_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4 

      SYMDEF sid_BEM, GL_NONE, ckp_PS_1_4
      SYMDEF sid_PHASE, GL_NONE, ckp_PS_1_4

      // PS_1_1 
      // temp R/W registers
      // r0, r1 are mapped to r4, r5
      // t0 to t3 are mapped to r0 to r3
      SYMDEF sid_1R0, GL_REG_4_ATI, ckp_PS_1_1
      SYMDEF sid_1R1, GL_REG_5_ATI, ckp_PS_1_1
      SYMDEF sid_1T0, GL_REG_0_ATI, ckp_PS_1_1
      SYMDEF sid_1T1, GL_REG_1_ATI, ckp_PS_1_1
      SYMDEF sid_1T2, GL_REG_2_ATI, ckp_PS_1_1
      SYMDEF sid_1T3, GL_REG_3_ATI, ckp_PS_1_1

      // instructions common to PS_1_1, PS_1_2, PS_1_3
      SYMDEF sid_TEX, GL_NONE, ckp_PS_1_1
      SYMDEF sid_TEXCOORD, GL_NONE, ckp_PS_1_1
      SYMDEF sid_TEXM3X2PAD, GL_NONE, ckp_PS_1_1
      SYMDEF sid_TEXM3X2TEX, GL_NONE, ckp_PS_1_1
      SYMDEF sid_TEXM3X3PAD, GL_NONE, ckp_PS_1_1
      SYMDEF sid_TEXM3X3TEX, GL_NONE, ckp_PS_1_1
      SYMDEF sid_TEXM3X3SPEC, GL_NONE, ckp_PS_1_1
      SYMDEF sid_TEXM3X3VSPEC, GL_NONE, ckp_PS_1_1
      SYMDEF sid_TEXREG2AR, GL_NONE, ckp_PS_1_2
      SYMDEF sid_TEXREG2GB, GL_NONE, ckp_PS_1_2

      // PS_1_2 & PS_1_3
      SYMDEF sid_TEXREG2RGB, GL_NONE, ckp_PS_1_2
      SYMDEF sid_TEXDP3, GL_NONE, ckp_PS_1_2
      SYMDEF sid_TEXDP3TEX, GL_NONE, ckp_PS_1_2
      

      // Common
      SYMDEF sid_SKIP, GL_NONE, ckp_PS_BASE
      SYMDEF sid_PLUS, GL_NONE, ckp_PS_BASE

      // Non-Terminal Tokens
      SYMDEF sid_PROGRAM, GL_NONE, ckp_PS_BASE
      SYMDEF sid_PROGRAMTYPE, GL_NONE, ckp_PS_BASE
      SYMDEF sid_DECLCONSTS, GL_NONE, ckp_PS_BASE
      SYMDEF sid_DEFCONST, GL_NONE, ckp_PS_BASE
      SYMDEF sid_CONSTANT, GL_NONE, ckp_PS_BASE
      SYMDEF sid_COLOR, GL_NONE, ckp_PS_BASE 
      SYMDEF sid_TEXSWIZZLE, GL_NONE, ckp_PS_BASE
      SYMDEF sid_UNARYOP, GL_NONE, ckp_PS_BASE
      SYMDEF sid_NUMVAL, GL_NONE, ckp_PS_BASE
      SYMDEF sid_SEPERATOR, GL_NONE, ckp_PS_BASE
      SYMDEF sid_ALUOPS, GL_NONE, ckp_PS_BASE
      SYMDEF sid_TEXMASK, GL_NONE, ckp_PS_BASE
      SYMDEF sid_TEXOP_PS1_1_3, GL_NONE, ckp_PS_1_1 
      SYMDEF sid_TEXOP_PS1_4, GL_NONE, ckp_PS_1_4
      SYMDEF sid_ALU_STATEMENT, GL_NONE, ckp_PS_BASE
      SYMDEF sid_DSTMODSAT, GL_NONE, ckp_PS_BASE
      SYMDEF sid_UNARYOP_ARGS, GL_NONE, ckp_PS_BASE
      SYMDEF sid_REG_PS1_4, GL_NONE, ckp_PS_1_4
      SYMDEF sid_TEX_PS1_4, GL_NONE, ckp_PS_1_4
      SYMDEF sid_REG_PS1_1_3, GL_NONE, ckp_PS_1_1
      SYMDEF sid_TEX_PS1_1_3, GL_NONE, ckp_PS_1_1
      SYMDEF sid_DSTINFO, GL_NONE, ckp_PS_BASE
      SYMDEF sid_SRCINFO, GL_NONE, ckp_PS_BASE
      SYMDEF sid_BINARYOP_ARGS, GL_NONE, ckp_PS_BASE
      SYMDEF sid_TERNARYOP_ARGS, GL_NONE, ckp_PS_BASE
      SYMDEF sid_TEMPREG, GL_NONE, ckp_PS_BASE
      SYMDEF sid_DSTMASK, GL_NONE, ckp_PS_BASE
      SYMDEF sid_PRESRCMOD, GL_NONE, ckp_PS_BASE
      SYMDEF sid_SRCNAME, GL_NONE, ckp_PS_BASE
      SYMDEF sid_SRCREP, GL_NONE, ckp_PS_BASE
      SYMDEF sid_POSTSRCMOD, GL_NONE, ckp_PS_BASE
      SYMDEF sid_DSTMOD, GL_NONE, ckp_PS_BASE
      SYMDEF sid_DSTSAT, GL_NONE, ckp_PS_BASE
      SYMDEF sid_BINARYOP, GL_NONE, ckp_PS_BASE
      SYMDEF sid_TERNARYOP, GL_NONE, ckp_PS_BASE
      SYMDEF sid_TEXOPS_PHASE1, GL_NONE, ckp_PS_BASE
      SYMDEF sid_COISSUE, GL_NONE, ckp_PS_BASE
      SYMDEF sid_PHASEMARKER, GL_NONE, ckp_PS_1_4
      SYMDEF sid_TEXOPS_PHASE2, GL_NONE, ckp_PS_1_4
      SYMDEF sid_TEXREG_PS1_4, GL_NONE, ckp_PS_1_4
      SYMDEF sid_TEXOPS_PS1_4, GL_NONE, ckp_PS_1_4
      SYMDEF sid_TEXOPS_PS1_1_3, GL_NONE, ckp_PS_1_1
      SYMDEF sid_TEXCISCOP_PS1_1_3, GL_NONE, ckp_PS_1_1
      SYMEND
};


// Rule Path Database for ps.1.x code based on extended Backus Naur Form notation

// <> - non-terminal token
#define _rule_          {otRULE,          // ::=      - rule definition
#define _is_            ,0},{otAND,
#define _and_           ,0},{otAND,       //      - blank space is an implied "AND" meaning the token is required
#define _or_            ,0},{otOR,        // |  - or
#define _optional_      ,0},{otOPTIONAL,  // [] - optional
#define _repeat_  ,0},{otREPEAT,    // {} - repeat until fail
#define _end_           ,0},{otEND,0,0,0},
#define _nt_        ,0
// " "  - terminal token string

PS_1_4::TokenRule PS_1_4::PS_1_x_RulePath[] = {

      _rule_ sid_PROGRAM, "Program"

            _is_ sid_PROGRAMTYPE _nt_
            _optional_ sid_DECLCONSTS _nt_
            _optional_ sid_TEXOPS_PHASE1 _nt_
            _optional_ sid_ALUOPS _nt_
            _optional_ sid_PHASEMARKER _nt_
            _optional_ sid_TEXOPS_PHASE2 _nt_
            _optional_ sid_ALUOPS _nt_
            _end_ 

      _rule_ sid_PROGRAMTYPE, "<ProgramType>"

            _is_ sid_PS_1_4, "ps.1.4"
            _or_ sid_PS_1_1, "ps.1.1"
            _or_ sid_PS_1_2, "ps.1.2"
            _or_ sid_PS_1_3, "ps.1.3"
            _end_

      _rule_ sid_PHASEMARKER, "<PhaseMarker>"

            _is_ sid_PHASE, "phase"
            _end_

      _rule_ sid_DECLCONSTS, "<DeclareConstants>"

            _repeat_ sid_DEFCONST _nt_
            _end_


      _rule_ sid_TEXOPS_PHASE1, "<TexOps_Phase1>"

            _is_ sid_TEXOPS_PS1_1_3 _nt_
            _or_ sid_TEXOPS_PS1_4 _nt_
            _end_

      _rule_ sid_TEXOPS_PHASE2, "<TexOps_Phase2>"

            _is_ sid_TEXOPS_PS1_4 _nt_
            _end_

      _rule_ sid_NUMVAL, "<NumVal>"

            _is_ sid_VALUE, "Float Value"
            _end_

      _rule_ sid_TEXOPS_PS1_1_3, "<TexOps_PS1_1_3>"

            _repeat_ sid_TEXOP_PS1_1_3 _nt_
            _end_

      _rule_ sid_TEXOPS_PS1_4, "<TexOps_PS1_4>"

            _repeat_ sid_TEXOP_PS1_4 _nt_
            _end_

      _rule_ sid_TEXOP_PS1_1_3, "<TexOp_PS1_1_3>"

            _is_  sid_TEXCISCOP_PS1_1_3 _nt_
            _and_ sid_TEX_PS1_1_3 _nt_
            _and_ sid_SEPERATOR _nt_
            _and_ sid_TEX_PS1_1_3 _nt_

            _or_  sid_TEXCOORD, "texcoord"
            _and_ sid_TEX_PS1_1_3 _nt_

            _or_  sid_TEX, "tex"
            _and_ sid_TEX_PS1_1_3 _nt_



            _end_

      _rule_ sid_TEXOP_PS1_4, "<TexOp_PS1_4>"

            _is_  sid_TEXCRD, "texcrd"
            _and_ sid_REG_PS1_4 _nt_
            _optional_ sid_TEXMASK _nt_
            _and_ sid_SEPERATOR _nt_
            _and_ sid_TEXREG_PS1_4 _nt_

            _or_  sid_TEXLD, "texld"
            _and_ sid_REG_PS1_4 _nt_
            _optional_ sid_TEXMASK _nt_
            _and_ sid_SEPERATOR _nt_
            _and_ sid_TEXREG_PS1_4 _nt_
            _end_

      _rule_ sid_ALUOPS, "<ALUOps>"

            _repeat_ sid_ALU_STATEMENT _nt_
            _end_

      _rule_ sid_ALU_STATEMENT, "<ALUStatement>"

            _is_ sid_COISSUE _nt_
            _and_ sid_UNARYOP _nt_
            _optional_ sid_DSTMODSAT _nt_
            _and_ sid_UNARYOP_ARGS _nt_ 

            _or_ sid_COISSUE _nt_
            _and_ sid_BINARYOP _nt_
            _optional_ sid_DSTMODSAT _nt_
            _and_ sid_BINARYOP_ARGS _nt_
            
            _or_ sid_COISSUE _nt_
            _and_ sid_TERNARYOP _nt_
            _optional_ sid_DSTMODSAT _nt_
            _and_ sid_TERNARYOP_ARGS _nt_
            _end_


      _rule_ sid_TEXREG_PS1_4, "<TexReg_PS1_4>"

            _is_ sid_TEX_PS1_4  _nt_
            _optional_ sid_TEXSWIZZLE _nt_
            _or_ sid_REG_PS1_4  _nt_
            _optional_ sid_TEXSWIZZLE _nt_
            _end_

      _rule_ sid_UNARYOP_ARGS, "<UnaryOpArgs>"

            _is_  sid_DSTINFO _nt_
            _and_ sid_SRCINFO _nt_
            _end_

      _rule_ sid_BINARYOP_ARGS, "<BinaryOpArgs>"
      
            _is_  sid_DSTINFO _nt_
            _and_ sid_SRCINFO _nt_
            _and_ sid_SRCINFO _nt_
            _end_

      _rule_ sid_TERNARYOP_ARGS, "<TernaryOpArgs>"
            
            _is_  sid_DSTINFO _nt_
            _and_ sid_SRCINFO _nt_
            _and_ sid_SRCINFO _nt_
            _and_ sid_SRCINFO _nt_
            _end_
 
      _rule_ sid_DSTINFO, "<DstInfo>"

            _is_ sid_TEMPREG _nt_
            _optional_ sid_DSTMASK _nt_
            _end_

      _rule_ sid_SRCINFO, "<SrcInfo>"
      
            _is_ sid_SEPERATOR _nt_
            _optional_ sid_PRESRCMOD _nt_
            _and_ sid_SRCNAME _nt_
            _optional_ sid_POSTSRCMOD _nt_
            _optional_ sid_SRCREP _nt_
            _end_

      _rule_ sid_SRCNAME, "<SrcName>"
      
            _is_ sid_TEMPREG _nt_
            _or_ sid_CONSTANT _nt_
            _or_ sid_COLOR _nt_
            _end_

      _rule_ sid_DEFCONST, "<DefineConstant>"

            _is_ sid_DEF, "def"
            _and_ sid_CONSTANT _nt_
            _and_ sid_SEPERATOR _nt_
            _and_ sid_NUMVAL _nt_
            _and_ sid_SEPERATOR _nt_
            _and_ sid_NUMVAL _nt_
            _and_ sid_SEPERATOR _nt_
            _and_ sid_NUMVAL _nt_
            _and_ sid_SEPERATOR _nt_
            _and_ sid_NUMVAL _nt_
            _end_

      _rule_ sid_CONSTANT, "<Constant>"

            _is_ sid_C0, "c0"
            _or_ sid_C1, "c1"
            _or_ sid_C2, "c2"
            _or_ sid_C3, "c3"
            _or_ sid_C4, "c4"
            _or_ sid_C5, "c5"
            _or_ sid_C6, "c6"
            _or_ sid_C7, "c7"
            _end_


      _rule_ sid_TEXCISCOP_PS1_1_3, "<TexCISCOp_PS1_1_3>"

            _is_ sid_TEXDP3TEX,           "texdp3tex"
            _or_ sid_TEXDP3,        "texdp3"
            _or_ sid_TEXM3X2PAD,    "texm3x2pad"
            _or_ sid_TEXM3X2TEX,    "texm3x2tex"
            _or_ sid_TEXM3X3PAD,    "texm3x3pad"
            _or_ sid_TEXM3X3TEX,    "texm3x3tex"
            _or_ sid_TEXM3X3SPEC,   "texm3x3spec"
            _or_ sid_TEXM3X3VSPEC,  "texm3x3vspec"
            _or_ sid_TEXREG2RGB,    "texreg2rgb"
            _or_ sid_TEXREG2AR,           "texreg2ar"
            _or_ sid_TEXREG2GB,           "texreg2gb"
            _end_


      _rule_ sid_TEXSWIZZLE, "<TexSwizzle>"

            _is_ sid_STQDQ,   "_dw.xyw"
            _or_ sid_STQDQ,   "_dw"
            _or_ sid_STQDQ,   "_da.rga"
            _or_ sid_STQDQ,   "_da"
            _or_ sid_STRDR,   "_dz.xyz"
            _or_ sid_STRDR,   "_dz"
            _or_ sid_STRDR,   "_db.rgb"
            _or_ sid_STRDR,   "_db"
            _or_ sid_STR,     ".xyz"
            _or_ sid_STR,     ".rgb"
            _or_ sid_STQ,     ".xyw"
            _or_ sid_STQ,     ".rga"
            _end_ 

      _rule_ sid_TEXMASK, "<TexMask>"

            _is_ sid_RGB,     ".rgb"
            _or_ sid_RGB,     ".xyz"
            _or_ sid_RG,      ".rg"
            _or_ sid_RG,      ".xy"
            _end_

      _rule_ sid_SEPERATOR, "<Seperator>"

            _is_ sid_COMMA, ","
            _end_

      _rule_ sid_REG_PS1_4, "<Reg_PS1_4>"

            _is_ sid_R0, "r0"
            _or_ sid_R1, "r1"
            _or_ sid_R2, "r2"
            _or_ sid_R3, "r3"
            _or_ sid_R4, "r4"
            _or_ sid_R5, "r5"
            _end_

      _rule_ sid_TEX_PS1_4, "<Tex_PS1_4>"

            _is_ sid_T0, "t0"
            _or_ sid_T1, "t1"
            _or_ sid_T2, "t2"
            _or_ sid_T3, "t3"
            _or_ sid_T4, "t4"
            _or_ sid_T5, "t5"
            _end_

      _rule_ sid_REG_PS1_1_3, "<Reg_PS1_1_3>"

            _is_ sid_1R0, "r0"
            _or_ sid_1R1, "r1"
            _end_

      _rule_ sid_TEX_PS1_1_3, "<Tex_PS1_1_3>"

            _is_ sid_1T0, "t0"
            _or_ sid_1T1, "t1"
            _or_ sid_1T2, "t2"
            _or_ sid_1T3, "t3"
            _end_

      _rule_ sid_COLOR, "<Color>"

            _is_ sid_V0, "v0"
            _or_ sid_V1, "v1"
            _end_


      _rule_ sid_TEMPREG, "<TempReg>"

            _is_ sid_REG_PS1_4 _nt_
            _or_ sid_REG_PS1_1_3 _nt_
            _or_ sid_TEX_PS1_1_3 _nt_
            _end_

      _rule_ sid_DSTMODSAT, "<DstModSat>"
      
            _optional_ sid_DSTMOD _nt_
            _optional_ sid_DSTSAT _nt_
            _end_

      _rule_  sid_UNARYOP, "<UnaryOp>"

            _is_ sid_MOV, "mov"
            _end_

      _rule_ sid_BINARYOP, "<BinaryOP>"
      
            _is_ sid_ADD, "add"
            _or_ sid_MUL, "mul"
            _or_ sid_SUB, "sub"
            _or_ sid_DP3, "dp3"
            _or_ sid_DP4, "dp4"
            _or_ sid_BEM, "bem"
            _end_

      _rule_ sid_TERNARYOP, "<TernaryOp>"
      
            _is_ sid_MAD, "mad"
            _or_ sid_LRP, "lrp"
            _or_ sid_CND, "cnd"
            _or_ sid_CMP, "cmp"
            _end_

      _rule_ sid_DSTMASK, "<DstMask>"

            _is_ sid_RGBA,    ".rgba"
            _or_ sid_RGBA,    ".xyzw"
            _or_ sid_RGB,     ".rgb"
            _or_ sid_RGB,     ".xyz"
            _or_ sid_RGA,     ".xyw"
            _or_ sid_RGA,     ".rga"
            _or_ sid_RBA,     ".rba"
            _or_ sid_RBA,     ".xzw"
            _or_ sid_GBA,     ".gba"
            _or_ sid_GBA,     ".yzw"
            _or_ sid_RG,      ".rg"
            _or_ sid_RG,      ".xy"
            _or_ sid_RB,      ".xz"
            _or_ sid_RB,      ".rb"
            _or_ sid_RA,      ".xw"
            _or_ sid_RA,      ".ra"
            _or_ sid_GB,      ".gb"
            _or_ sid_GB,      ".yz"
            _or_ sid_GA,      ".yw"
            _or_ sid_GA,      ".ga"
            _or_ sid_BA,      ".zw"
            _or_ sid_BA,      ".ba"
            _or_ sid_R,       ".r"
            _or_ sid_R,       ".x"
            _or_ sid_G,       ".g"
            _or_ sid_G,       ".y"
            _or_ sid_B,       ".b"
            _or_ sid_B,       ".z"
            _or_ sid_A,       ".a"
            _or_ sid_A,       ".w"
            _end_

      _rule_ sid_SRCREP, "<SrcRep>"
      
            _is_ sid_RRRR, ".r"
            _or_ sid_RRRR, ".x"
            _or_ sid_GGGG, ".g"
            _or_ sid_GGGG, ".y"
            _or_ sid_BBBB, ".b"
            _or_ sid_BBBB, ".z"
            _or_ sid_AAAA, ".a"
            _or_ sid_AAAA, ".w"
            _end_

      _rule_ sid_PRESRCMOD, "<PreSrcMod>"

            _is_ sid_INVERT, "1-"
            _or_ sid_INVERT, "1 -"
            _or_ sid_NEGATE, "-"
            _end_

      _rule_ sid_POSTSRCMOD, "<PostSrcMod>"

            _is_ sid_BX2, "_bx2"
            _or_ sid_X2, "_x2"
            _or_ sid_BIAS, "_bias"
            _end_

      _rule_ sid_DSTMOD, "<DstMod>"

            _is_ sid_X2, "_x2"
            _or_ sid_X4, "_x4"
            _or_ sid_D2, "_d2"
            _or_ sid_X8, "_x8"
            _or_ sid_D4, "_d4"
            _or_ sid_D8, "_d8"
            _end_

      _rule_ sid_DSTSAT, "<DstSat>"

            _is_ sid_SAT, "_sat"
            _end_

      _rule_ sid_COISSUE, "<CoIssue>"

            _optional_ sid_PLUS, "+"
            _end_

};

//***************************** MACROs for PS1_1 , PS1_2, PS1_3 CISC instructions **************************************

// macro to make the macro text data easier to read
#define _token_ ,0,0},{
#define _token_end_ ,0,0}
// macro token expansion for ps_1_2 instruction: texreg2ar
PS_1_4::TokenInst PS_1_4::texreg2ar[] = {
      // mov r(x).r, r(y).a
      {           sid_UNARYOP,      sid_MOV
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_DSTMASK,    sid_R
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0
      _token_ sid_SRCREP,           sid_AAAA

      // mov r(x).g, r(y).r
      _token_ sid_UNARYOP,    sid_MOV
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_DSTMASK,    sid_G
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0
      _token_ sid_SRCREP,           sid_RRRR

      // texld r(x), r(x)
      _token_ sid_TEXOP_PS1_4, sid_TEXLD
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R1
      _token_end_
};

PS_1_4::RegModOffset PS_1_4::texreg2xx_RegMods[] = {
      {1, R_BASE, 0},
      {7, R_BASE, 0},
      {13, R_BASE, 0},
      {15, R_BASE, 0},
      {4, R_BASE, 1},
      {10, R_BASE, 1},

};

PS_1_4::MacroRegModify PS_1_4::texreg2ar_MacroMods = {
      texreg2ar, ARRAYSIZE(texreg2ar),
      texreg2xx_RegMods, ARRAYSIZE(texreg2xx_RegMods)
};

// macro token expansion for ps_1_2 instruction: texreg2gb
PS_1_4::TokenInst PS_1_4::texreg2gb[] = {
      // mov r(x).r, r(y).g
      {           sid_UNARYOP,      sid_MOV
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_DSTMASK,    sid_R
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0
      _token_ sid_SRCREP,           sid_GGGG

      // mov r(x).g, r(y).b
      _token_ sid_UNARYOP,    sid_MOV
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_DSTMASK,    sid_G
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0
      _token_ sid_SRCREP,           sid_BBBB

      // texld r(x), r(x)
      _token_ sid_TEXOP_PS1_4, sid_TEXLD
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R1
      _token_end_
};

PS_1_4::MacroRegModify PS_1_4::texreg2gb_MacroMods = {
      texreg2gb, ARRAYSIZE(texreg2gb),
      texreg2xx_RegMods, ARRAYSIZE(texreg2xx_RegMods)
};


// macro token expansion for ps_1_1 instruction: texdp3
PS_1_4::TokenInst PS_1_4::texdp3[] = {
      // texcoord t(x)
      {           sid_TEXOP_PS1_1_3, sid_TEXCOORD
      _token_ sid_TEX_PS1_1_3, sid_1T1

      // dp3 r(x), r(x), r(y)
      _token_ sid_BINARYOP,   sid_DP3
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0
      _token_end_
};


PS_1_4::RegModOffset PS_1_4::texdp3_RegMods[] = {
      {1, T_BASE, 0},
      {3, R_BASE, 0},
      {5, R_BASE, 0},
      {7, R_BASE, 1},

};


PS_1_4::MacroRegModify PS_1_4::texdp3_MacroMods = {
      texdp3, ARRAYSIZE(texdp3),
      texdp3_RegMods, ARRAYSIZE(texdp3_RegMods)
};


// macro token expansion for ps_1_1 instruction: texdp3tex
PS_1_4::TokenInst PS_1_4::texdp3tex[] = {
      // texcoord t(x)
      {           sid_TEXOP_PS1_1_3, sid_TEXCOORD
      _token_ sid_TEX_PS1_1_3, sid_1T1

      // dp3 r1, r(x), r(y)
      _token_ sid_BINARYOP,   sid_DP3
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0

      // texld r(x), r(x)
      _token_ sid_TEXOP_PS1_4, sid_TEXLD
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R1
      _token_end_
};


PS_1_4::RegModOffset PS_1_4::texdp3tex_RegMods[] = {
      {1, T_BASE, 0},
      {3, R_BASE, 0},
      {5, R_BASE, 0},
      {7, R_BASE, 1},
      {9, R_BASE, 1},
      {11, R_BASE, 1},

};


PS_1_4::MacroRegModify PS_1_4::texdp3tex_MacroMods = {
      texdp3tex, ARRAYSIZE(texdp3tex),
      texdp3tex_RegMods, ARRAYSIZE(texdp3tex_RegMods)
};


// macro token expansion for ps_1_1 instruction: texm3x2pad
PS_1_4::TokenInst PS_1_4::texm3x2pad[] = {
      // texcoord t(x)
      {           sid_TEXOP_PS1_1_3, sid_TEXCOORD
      _token_ sid_TEX_PS1_1_3, sid_1T0

      // dp3 r4.r, r(x), r(y)
      _token_ sid_BINARYOP,   sid_DP3
      _token_ sid_REG_PS1_4,  sid_R4
      _token_ sid_DSTMASK,    sid_R
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0
      _token_end_

};


PS_1_4::RegModOffset PS_1_4::texm3xxpad_RegMods[] = {
      {1, T_BASE, 0},
      {6, R_BASE, 0},
      {8, R_BASE, 1},
};


PS_1_4::MacroRegModify PS_1_4::texm3x2pad_MacroMods = {
      texm3x2pad, ARRAYSIZE(texm3x2pad),
      texm3xxpad_RegMods, ARRAYSIZE(texm3xxpad_RegMods)
};


// macro token expansion for ps_1_1 instruction: texm3x2tex
PS_1_4::TokenInst PS_1_4::texm3x2tex[] = {
      // texcoord t(x)
      {           sid_TEXOP_PS1_1_3, sid_TEXCOORD
      _token_ sid_TEX_PS1_1_3, sid_1T1

      // dp3 r4.g, r(x), r(y)
      _token_ sid_BINARYOP,   sid_DP3
      _token_ sid_REG_PS1_4,  sid_R4
      _token_ sid_DSTMASK,    sid_G
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0

      // texld r(x), r4
      _token_ sid_TEXOP_PS1_4, sid_TEXLD
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R4
      _token_end_

};

PS_1_4::RegModOffset PS_1_4::texm3xxtex_RegMods[] = {
      {1, T_BASE, 0},
      {6, R_BASE, 0},
      {8, R_BASE, 1},
      {10, R_BASE, 0}
};

PS_1_4::MacroRegModify PS_1_4::texm3x2tex_MacroMods = {
      texm3x2tex, ARRAYSIZE(texm3x2tex),
      texm3xxtex_RegMods, ARRAYSIZE(texm3xxtex_RegMods)
};

// macro token expansion for ps_1_1 instruction: texm3x3tex
PS_1_4::TokenInst PS_1_4::texm3x3pad[] = {
      // texcoord t(x)
      {           sid_TEXOP_PS1_1_3, sid_TEXCOORD
      _token_ sid_TEX_PS1_1_3, sid_1T0

      // dp3 r4.b, r(x), r(y)
      _token_ sid_BINARYOP,   sid_DP3
      _token_ sid_REG_PS1_4,  sid_R4
      _token_ sid_DSTMASK,    sid_B
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0
      _token_end_

};


PS_1_4::MacroRegModify PS_1_4::texm3x3pad_MacroMods = {
      texm3x3pad, ARRAYSIZE(texm3x3pad),
      texm3xxpad_RegMods, ARRAYSIZE(texm3xxpad_RegMods)
};


// macro token expansion for ps_1_1 instruction: texm3x3pad
PS_1_4::TokenInst PS_1_4::texm3x3tex[] = {
      // texcoord t(x)
      {           sid_TEXOP_PS1_1_3, sid_TEXCOORD
      _token_ sid_TEX_PS1_1_3, sid_1T1

      // dp3 r4.b, r(x), r(y)
      _token_ sid_BINARYOP,   sid_DP3
      _token_ sid_REG_PS1_4,  sid_R4
      _token_ sid_DSTMASK,    sid_B
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0

      // texld r1, r4
      _token_ sid_TEXOP_PS1_4, sid_TEXLD
      _token_ sid_REG_PS1_4,  sid_R1
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R4
      _token_end_
};






PS_1_4::MacroRegModify PS_1_4::texm3x3tex_MacroMods = {
      texm3x3tex, ARRAYSIZE(texm3x3tex),
      texm3xxtex_RegMods, ARRAYSIZE(texm3xxtex_RegMods)
};


// macro token expansion for ps_1_1 instruction: texm3x3spec
PS_1_4::TokenInst PS_1_4::texm3x3spec[] = {
      // texcoord t(x)
      {           sid_TEXOP_PS1_1_3, sid_TEXCOORD
      _token_ sid_TEX_PS1_1_3, sid_1T3

      // dp3 r4.b, r3, r(x)
      _token_ sid_BINARYOP,   sid_DP3
      _token_ sid_REG_PS1_4,  sid_R4
      _token_ sid_DSTMASK,    sid_B
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R3
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R0

      // dp3_x2 r3, r4, c(x)
      _token_ sid_BINARYOP,   sid_DP3
      _token_ sid_DSTMOD,           sid_X2
      _token_ sid_REG_PS1_4,  sid_R3
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R4
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_CONSTANT,   sid_C0

      // mul r3, r3, c(x)
      _token_ sid_UNARYOP,    sid_MUL
      _token_ sid_REG_PS1_4,  sid_R3
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R3
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_CONSTANT,   sid_C0

      // dp3 r2, r4, r4
      _token_ sid_BINARYOP,   sid_DP3
      _token_ sid_REG_PS1_4,  sid_R2
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R4
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R4

      // mad r4.rgb, 1-c(x), r2, r3
      _token_ sid_TERNARYOP,  sid_MAD
      _token_ sid_REG_PS1_4,  sid_R4
      _token_ sid_DSTMASK,    sid_RGB
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_PRESRCMOD,  sid_INVERT
      _token_ sid_CONSTANT,   sid_C0
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R2
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R3

      // + mov r4.a, r2.r
      _token_ sid_UNARYOP,    sid_MOV
      _token_ sid_REG_PS1_4,  sid_R4
      _token_ sid_DSTMASK,    sid_A
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R2
      _token_ sid_SRCREP,           sid_RRRR

      // texld r3, r4.xyz_dz
      _token_ sid_TEXOP_PS1_4, sid_TEXLD
      _token_ sid_REG_PS1_4,  sid_R3
      _token_ sid_SEPERATOR,  sid_COMMA
      _token_ sid_REG_PS1_4,  sid_R4
      _token_ sid_TEXSWIZZLE, sid_STRDR
      _token_end_

};

PS_1_4::RegModOffset PS_1_4::texm3x3spec_RegMods[] = {
      {8, R_BASE, 1},
      {15, R_BASE, 2},
      {21, C_BASE, 2},
      {33, C_BASE, 2},

};

PS_1_4::MacroRegModify PS_1_4::texm3x3spec_MacroMods = {
      texm3x3spec, ARRAYSIZE(texm3x3spec),
      texm3x3spec_RegMods, ARRAYSIZE(texm3x3spec_RegMods)
};


/* ********************* END OF CLASS STATIC DATA ********************************* */

PS_1_4::PS_1_4()
{
      // allocate enough room for a large pixel shader
      mPhase1TEX_mi.reserve(50);
      mPhase2TEX_mi.reserve(30);
      mPhase1ALU_mi.reserve(100);
      mPhase2ALU_mi.reserve(100);


      mSymbolTypeLib = PS_1_4_SymbolTypeLib;
      mSymbolTypeLibCnt = ARRAYSIZE(PS_1_4_SymbolTypeLib);
      mRootRulePath = PS_1_x_RulePath;
      mRulePathLibCnt = ARRAYSIZE(PS_1_x_RulePath);
      // tell compiler what the symbol id is for a numeric value
      mValueID = sid_VALUE;
      // The type library must have text definitions initialized
      // before compiler is invoked

      // only need to initialize the rule database once
      if(LibInitialized == false) {
            InitSymbolTypeLib();
            LibInitialized = true;
      }

      // set initial context to recognize PS base instructions
      mActiveContexts = ckp_PS_BASE;

}


bool PS_1_4::bindMachineInstInPassToFragmentShader(const MachineInstContainer & PassMachineInstructions)
{
  size_t instIDX = 0;
  size_t instCount = PassMachineInstructions.size();
  bool error = false;

  while ((instIDX < instCount) && !error) {
    switch(PassMachineInstructions[instIDX]) {
      case mi_COLOROP1:
        if((instIDX+7) < instCount)
          glColorFragmentOp1ATI(PassMachineInstructions[instIDX+1], // op
            PassMachineInstructions[instIDX+2], // dst
            PassMachineInstructions[instIDX+3], // dstMask
            PassMachineInstructions[instIDX+4], // dstMod
            PassMachineInstructions[instIDX+5], // arg1
            PassMachineInstructions[instIDX+6], // arg1Rep
            PassMachineInstructions[instIDX+7]);// arg1Mod
        instIDX += 8;
        break;

      case mi_COLOROP2:
        if((instIDX+10) < instCount)
          glColorFragmentOp2ATI(PassMachineInstructions[instIDX+1], // op
            PassMachineInstructions[instIDX+2], // dst
            PassMachineInstructions[instIDX+3], // dstMask
            PassMachineInstructions[instIDX+4], // dstMod
            PassMachineInstructions[instIDX+5], // arg1
            PassMachineInstructions[instIDX+6], // arg1Rep
            PassMachineInstructions[instIDX+7], // arg1Mod
            PassMachineInstructions[instIDX+8], // arg2
            PassMachineInstructions[instIDX+9], // arg2Rep
            PassMachineInstructions[instIDX+10]);// arg2Mod
        instIDX += 11;
        break;

      case mi_COLOROP3:
        if((instIDX+13) < instCount)
          glColorFragmentOp3ATI(PassMachineInstructions[instIDX+1], // op
            PassMachineInstructions[instIDX+2],  // dst
            PassMachineInstructions[instIDX+3],  // dstMask
            PassMachineInstructions[instIDX+4],  // dstMod
            PassMachineInstructions[instIDX+5],  // arg1
            PassMachineInstructions[instIDX+6],  // arg1Rep
            PassMachineInstructions[instIDX+7],  // arg1Mod
            PassMachineInstructions[instIDX+8],  // arg2
            PassMachineInstructions[instIDX+9],  // arg2Rep
            PassMachineInstructions[instIDX+10], // arg2Mod
            PassMachineInstructions[instIDX+11], // arg2
            PassMachineInstructions[instIDX+12], // arg2Rep
            PassMachineInstructions[instIDX+13]);// arg2Mod
        instIDX += 14;
        break;

      case mi_ALPHAOP1:
        if((instIDX+6) < instCount)
          glAlphaFragmentOp1ATI(PassMachineInstructions[instIDX+1], // op
            PassMachineInstructions[instIDX+2],   // dst
            PassMachineInstructions[instIDX+3],   // dstMod
            PassMachineInstructions[instIDX+4],   // arg1
            PassMachineInstructions[instIDX+5],   // arg1Rep
            PassMachineInstructions[instIDX+6]);  // arg1Mod
        instIDX += 7;
        break;

      case mi_ALPHAOP2:
        if((instIDX+9) < instCount)
          glAlphaFragmentOp2ATI(PassMachineInstructions[instIDX+1], // op
            PassMachineInstructions[instIDX+2],   // dst
            PassMachineInstructions[instIDX+3],   // dstMod
            PassMachineInstructions[instIDX+4],   // arg1
            PassMachineInstructions[instIDX+5],   // arg1Rep
            PassMachineInstructions[instIDX+6],   // arg1Mod
            PassMachineInstructions[instIDX+7],   // arg2
            PassMachineInstructions[instIDX+8],   // arg2Rep
            PassMachineInstructions[instIDX+9]);  // arg2Mod
        instIDX += 10;
        break;

      case mi_ALPHAOP3:
        if((instIDX+12) < instCount)
          glAlphaFragmentOp3ATI(PassMachineInstructions[instIDX+1], // op
            PassMachineInstructions[instIDX+2],   // dst
            PassMachineInstructions[instIDX+3],   // dstMod
            PassMachineInstructions[instIDX+4],   // arg1
            PassMachineInstructions[instIDX+5],   // arg1Rep
            PassMachineInstructions[instIDX+6],   // arg1Mod
            PassMachineInstructions[instIDX+7],   // arg2
            PassMachineInstructions[instIDX+8],   // arg2Rep
            PassMachineInstructions[instIDX+9],   // arg2Mod
            PassMachineInstructions[instIDX+10],  // arg2
            PassMachineInstructions[instIDX+11],  // arg2Rep
            PassMachineInstructions[instIDX+12]); // arg2Mod
        instIDX += 13;
        break;

      case mi_SETCONSTANTS:
        if((instIDX+2) < instCount)
          glSetFragmentShaderConstantATI(PassMachineInstructions[instIDX+1], // dst
            &mConstants[PassMachineInstructions[instIDX+2]]);
        instIDX += 3;
        break;

      case mi_PASSTEXCOORD:
        if((instIDX+3) < instCount)
          glPassTexCoordATI(PassMachineInstructions[instIDX+1], // dst
            PassMachineInstructions[instIDX+2], // coord
            PassMachineInstructions[instIDX+3]); // swizzle
        instIDX += 4;
        break;

      case mi_SAMPLEMAP:
        if((instIDX+3) < instCount)
          glSampleMapATI(PassMachineInstructions[instIDX+1], // dst
            PassMachineInstructions[instIDX+2], // interp
            PassMachineInstructions[instIDX+3]); // swizzle
        instIDX += 4;
        break;

        default:
            instIDX = instCount;
            // should generate an error since an unknown instruction was found
            // instead for now the bind process is terminated and the fragment program may still function
            // but its output may not be what was programmed

    } // end of switch

    error = (glGetError() != GL_NO_ERROR);
  }// end of while

  return !error;

}


size_t PS_1_4::getMachineInst( size_t Idx)
{
      if (Idx < mPhase1TEX_mi.size()) {
            return mPhase1TEX_mi[Idx];
      }
      else {
            Idx -= mPhase1TEX_mi.size();
            if (Idx < mPhase1ALU_mi.size()) {
                  return mPhase1ALU_mi[Idx];
            }
            else {
                  Idx -= mPhase1ALU_mi.size();
                  if (Idx < mPhase2TEX_mi.size()) {
                        return mPhase2TEX_mi[Idx];
                  }
                  else {
                        Idx -= mPhase2TEX_mi.size();
                        if (Idx < mPhase2ALU_mi.size()) {
                              return mPhase2ALU_mi[Idx];
                        }

                  }

            }

      }

      return 0;

}


void PS_1_4::addMachineInst(const PhaseType phase, const uint inst)
{
      switch(phase) {

            case ptPHASE1TEX:
                  mPhase1TEX_mi.push_back(inst);
                  break;

            case ptPHASE1ALU:
                  mPhase1ALU_mi.push_back(inst);
                  break;

            case ptPHASE2TEX:
                  mPhase2TEX_mi.push_back(inst);

                  break;

            case ptPHASE2ALU:
                  mPhase2ALU_mi.push_back(inst);
                  break;


      } // end switch(phase)

}

size_t PS_1_4::getMachineInstCount()
{

      return (mPhase1TEX_mi.size() + mPhase1ALU_mi.size() + mPhase2TEX_mi.size() + mPhase2ALU_mi.size());
}


bool PS_1_4::bindAllMachineInstToFragmentShader()
{
      bool passed;

      // there are 4 machine instruction ques to pass to the ATI fragment shader
      passed = bindMachineInstInPassToFragmentShader(mPhase1TEX_mi);
      passed &= bindMachineInstInPassToFragmentShader(mPhase1ALU_mi);
      passed &= bindMachineInstInPassToFragmentShader(mPhase2TEX_mi);
      passed &= bindMachineInstInPassToFragmentShader(mPhase2ALU_mi);
      return passed;

}


bool PS_1_4::expandMacro(const MacroRegModify & MacroMod)
{

      RegModOffset * regmod;

      // set source and destination registers in macro expansion
      for (uint i = 0; i < MacroMod.RegModSize; i++) {
            regmod = &MacroMod.RegMods[i];
            MacroMod.Macro[regmod->MacroOffset].mID = regmod->RegisterBase + mOpParrams[regmod->OpParramsIndex].Arg;

      }

      // turn macro support on so that ps.1.4 ALU instructions get put in phase 1 alu instruction sequence container
      mMacroOn = true;
      // pass macro tokens on to be turned into machine instructions
      // expand macro to ps.1.4 by doing recursive call to doPass2
      bool passed = Pass2scan(MacroMod.Macro, MacroMod.MacroSize);
      mMacroOn = false;

      return passed;
}


bool PS_1_4::BuildMachineInst()
{

      // check the states to see if a machine instruction can be assembled

      // assume all arguments have been set up
      bool passed = false;

      

      passed = true; // assume everything will go okay untill proven otherwise

      // start with machine NOP instuction
      // this is used after the switch to see if an instruction was set up
      // determine which MachineInstID is required based on the op instruction
      mOpType = mi_NOP;

      switch(mOpInst) {
            // ALU operations
            case sid_ADD:
            case sid_SUB:
            case sid_MUL:
            case sid_MAD:
            case sid_LRP:
            case sid_MOV:
            case sid_CMP:
            case sid_CND:
            case sid_DP2ADD:
            case sid_DP3:
            case sid_DP4:
                  mOpType = (MachineInstID)(mi_COLOROP1 + mArgCnt - 1);

                  // if context is ps.1.x and Macro not on or a phase marker was found then put all ALU ops in phase 2 ALU container
                  if (((mActiveContexts & ckp_PS_1_1) && !mMacroOn) || mPhaseMarkerFound) mInstructionPhase = ptPHASE2ALU;
                  else mInstructionPhase = ptPHASE1ALU;
                  // check for alpha op in destination register which is OpParrams[0]
                  // if no Mask for destination then make it .rgba
                  if(mOpParrams[0].MaskRep == 0) mOpParrams[0].MaskRep =
                  GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT;
                  if (mOpParrams[0].MaskRep & ALPHA_BIT) {
                        mDo_Alpha = true;
                        mOpParrams[0].MaskRep -= ALPHA_BIT;
                        if(mOpParrams[0].MaskRep == 0) mOpType = mi_NOP; // only do alpha op
                  }
                  break;

            case sid_TEXCRD:
                  mOpType = mi_PASSTEXCOORD;
                  if (mPhaseMarkerFound) mInstructionPhase = ptPHASE2TEX;
                  else mInstructionPhase = ptPHASE1TEX;
                  break;

            case sid_TEXLD:
                  mOpType = mi_SAMPLEMAP;
                  if (mPhaseMarkerFound) mInstructionPhase = ptPHASE2TEX;
                  else mInstructionPhase = ptPHASE1TEX;
                  break;

            case sid_TEX: // PS_1_1 emulation
                  mOpType = mi_TEX;
                  mInstructionPhase = ptPHASE1TEX;
                  break;

            case sid_TEXCOORD: // PS_1_1 emulation
                  mOpType = mi_TEXCOORD;
                  mInstructionPhase = ptPHASE1TEX;
                  break;

            case sid_TEXREG2AR:
                  passed = expandMacro(texreg2ar_MacroMods);
                  break;

            case sid_TEXREG2GB:
                  passed = expandMacro(texreg2gb_MacroMods);
                  break;

            case sid_TEXDP3:
                  passed = expandMacro(texdp3_MacroMods);
                  break;

            case sid_TEXDP3TEX:
                  passed = expandMacro(texdp3tex_MacroMods);
                  break;

            case sid_TEXM3X2PAD:
                  passed = expandMacro(texm3x2pad_MacroMods);
                  break;

            case sid_TEXM3X2TEX:
                  passed = expandMacro(texm3x2tex_MacroMods);
                  break;

            case sid_TEXM3X3PAD:
                  // only 2 texm3x3pad instructions allowed
                  // use count to modify macro to select which mask to use
                  if(mTexm3x3padCount<2) {
                        texm3x3pad[4].mID = sid_R + mTexm3x3padCount;
                        mTexm3x3padCount++;
                        passed = expandMacro(texm3x3pad_MacroMods);

                  }
                  else passed = false;

                  break;

            case sid_TEXM3X3TEX:
                  passed = expandMacro(texm3x3tex_MacroMods);
                  break;

            case sid_DEF:
                  mOpType = mi_SETCONSTANTS;
                  mInstructionPhase = ptPHASE1TEX;
                  break;

            case sid_PHASE: // PS_1_4 only
                  mPhaseMarkerFound = true;
                  break;

      } // end of switch

      if(passed) passed = expandMachineInstruction();

      return passed;
}


bool PS_1_4::expandMachineInstruction()
{
      // now push instructions onto MachineInstructions container
      // assume that an instruction will be expanded
      bool passed = true;

      if (mOpType != mi_NOP) {

            // a machine instruction will be built
            // this is currently the last one being built so keep track of it
            if (mInstructionPhase == ptPHASE2ALU) { 
                  mSecondLastInstructionPos = mLastInstructionPos;
                  mLastInstructionPos = mPhase2ALU_mi.size();
            }


            switch (mOpType) {
                  case mi_COLOROP1:
                  case mi_COLOROP2:
                  case mi_COLOROP3:
                        {
                              addMachineInst(mInstructionPhase, mOpType);
                              addMachineInst(mInstructionPhase, mSymbolTypeLib[mOpInst].mPass2Data);
                              // send all parameters to machine inst container
                              for(int i=0; i<=mArgCnt; i++) {
                                    addMachineInst(mInstructionPhase, mOpParrams[i].Arg);
                                    addMachineInst(mInstructionPhase, mOpParrams[i].MaskRep);
                                    addMachineInst(mInstructionPhase, mOpParrams[i].Mod);
                                    // check if source register read is valid in this phase
                                    passed &= isRegisterReadValid(mInstructionPhase, i);
                              }

                              // record which registers were written to and in which phase
                              // mOpParrams[0].Arg is always the destination register r0 -> r5
                              updateRegisterWriteState(mInstructionPhase);

                        }
                        break;

                  case mi_SETCONSTANTS:
                        addMachineInst(mInstructionPhase, mOpType);
                        addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst
                        addMachineInst(mInstructionPhase, mConstantsPos); // index into constants array
                        break;

                  case mi_PASSTEXCOORD:
                  case mi_SAMPLEMAP:
                        // if source is a temp register than place instruction in phase 2 Texture ops
                        if ((mOpParrams[1].Arg >= GL_REG_0_ATI) && (mOpParrams[1].Arg <= GL_REG_5_ATI)) {
                              mInstructionPhase = ptPHASE2TEX;
                        }

                        addMachineInst(mInstructionPhase, mOpType);
                        addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst
                        addMachineInst(mInstructionPhase, mOpParrams[1].Arg); // coord
                        addMachineInst(mInstructionPhase, mOpParrams[1].MaskRep + GL_SWIZZLE_STR_ATI); // swizzle
                        // record which registers were written to and in which phase
                        // mOpParrams[0].Arg is always the destination register r0 -> r5
                        updateRegisterWriteState(mInstructionPhase);
                        break;

                  case mi_TEX: // PS_1_1 emulation - turn CISC into RISC - phase 1
                        addMachineInst(mInstructionPhase, mi_SAMPLEMAP);
                        addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst
                        // tex tx becomes texld rx, tx with x: 0 - 3
                        addMachineInst(mInstructionPhase, mOpParrams[0].Arg - GL_REG_0_ATI + GL_TEXTURE0_ARB); // interp
                        // default to str which fills rgb of destination register
                        addMachineInst(mInstructionPhase, GL_SWIZZLE_STR_ATI); // swizzle
                        // record which registers were written to and in which phase
                        // mOpParrams[0].Arg is always the destination register r0 -> r5
                        updateRegisterWriteState(mInstructionPhase);
                        break;

                  case mi_TEXCOORD: // PS_1_1 emulation - turn CISC into RISC - phase 1
                        addMachineInst(mInstructionPhase, mi_PASSTEXCOORD);
                        addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst
                        // texcoord tx becomes texcrd rx, tx with x: 0 - 3
                        addMachineInst(mInstructionPhase, mOpParrams[0].Arg - GL_REG_0_ATI + GL_TEXTURE0_ARB); // interp
                        // default to str which fills rgb of destination register
                        addMachineInst(mInstructionPhase, GL_SWIZZLE_STR_ATI); // swizzle
                        // record which registers were written to and in which phase
                        // mOpParrams[0].Arg is always the destination register r0 -> r5
                        updateRegisterWriteState(mInstructionPhase);
                        break;

      


            } // end of switch (mOpType)
      } // end of if (mOpType != mi_NOP)

      if(mDo_Alpha) {
            // process alpha channel
            //
            // a scaler machine instruction will be built
            // this is currently the last one being built so keep track of it
            if (mInstructionPhase == ptPHASE2ALU) { 
                  mSecondLastInstructionPos = mLastInstructionPos;
                  mLastInstructionPos = mPhase2ALU_mi.size();
            }

            MachineInstID alphaoptype = (MachineInstID)(mi_ALPHAOP1 + mArgCnt - 1);
            addMachineInst(mInstructionPhase, alphaoptype);
            addMachineInst(mInstructionPhase, mSymbolTypeLib[mOpInst].mPass2Data);
            // put all parameters in instruction que
            for(int i=0; i<=mArgCnt; i++) {
                  addMachineInst(mInstructionPhase, mOpParrams[i].Arg);
                  // destination parameter has no mask since it is the alpha channel
                  // don't push mask for parrameter 0 (dst)
                  if(i>0) addMachineInst(mInstructionPhase, mOpParrams[i].MaskRep);
                  addMachineInst(mInstructionPhase, mOpParrams[i].Mod);
                  // check if source register read is valid in this phase
                  passed &= isRegisterReadValid(mInstructionPhase, i);
            }

            updateRegisterWriteState(mInstructionPhase);
      }

      // instruction passed on to machine instruction so clear the pipe
      clearMachineInstState();

      return passed;

}


void PS_1_4::updateRegisterWriteState(const PhaseType phase)
{
      int reg_offset = mOpParrams[0].Arg - GL_REG_0_ATI;

      switch(phase) {

            case ptPHASE1TEX:
            case ptPHASE1ALU:
                  Phase_RegisterUsage[reg_offset].Phase1Write = true;
                  break;

            case ptPHASE2TEX:
            case ptPHASE2ALU:
                  Phase_RegisterUsage[reg_offset].Phase2Write = true;
                  break;

      } // end switch(phase)

}


bool PS_1_4::isRegisterReadValid(const PhaseType phase, const int param)
{
      bool passed = true; // assume everything will go alright
      // if in phase 2 ALU and argument is a source
      if((phase == ptPHASE2ALU) && (param>0)) {
            // is source argument a temp register r0 - r5?
            if((mOpParrams[param].Arg >= GL_REG_0_ATI) && (mOpParrams[param].Arg <= GL_REG_5_ATI)) {
                  int reg_offset = mOpParrams[param].Arg - GL_REG_0_ATI;
                  // if register was not written to in phase 2 but was in phase 1
                  if((Phase_RegisterUsage[reg_offset].Phase2Write == false) && Phase_RegisterUsage[reg_offset].Phase1Write) {
                        // only perform register pass if there are ALU instructions in phase 1
                        
                        if(mPhase1ALU_mi.size() > 0) {
                              // build machine instructions for passing a register from phase 1 to phase 2
                              // NB: only rgb components of register will get passed

                              addMachineInst(ptPHASE2TEX, mi_PASSTEXCOORD);
                              addMachineInst(ptPHASE2TEX, mOpParrams[param].Arg); // dst
                              addMachineInst(ptPHASE2TEX, mOpParrams[param].Arg); // coord
                              addMachineInst(ptPHASE2TEX, GL_SWIZZLE_STR_ATI); // swizzle
                              // mark register as being written to
                              Phase_RegisterUsage[reg_offset].Phase2Write = true;
                        }

                  }
                  // register can not be used because it has not been written to previously
                  else passed = false;
            }

      }

      return passed;

}


void PS_1_4::optimize()
{
      // perform some optimizations on ps.1.1 machine instructions
      if (mActiveContexts & ckp_PS_1_1) {
            // need to check last few instructions to make sure r0 is set
            // ps.1.1 emulation uses r4 for r0 so last couple of instructions will probably require
            // changine destination register back to r0
            if (mLastInstructionPos < mPhase2ALU_mi.size()) {
                  // first argument at mLastInstructionPos + 2 is destination register for all ps.1.1 ALU instructions
                  mPhase2ALU_mi[mLastInstructionPos + 2] = GL_REG_0_ATI; 
                  // if was an alpha op only then modify second last instruction destination register
                  if ((mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP1) ||
                        (mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP2) ||
                        (mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP3)
                        
                        ) {

                        mPhase2ALU_mi[mSecondLastInstructionPos + 2] = GL_REG_0_ATI; 
                  }

            }// end if (mLastInstructionPos < mMachineInstructions.size())

      }// end if (mActiveContexts & ckp_PS_1_1)

}


void PS_1_4::clearMachineInstState()
{
      // set current Machine Instruction State to baseline
      mOpType = mi_NOP;
      mOpInst = sid_INVALID;
      mDo_Alpha = false;
      mArgCnt = 0;

      for(int i=0; i<MAXOPPARRAMS; i++) {
            mOpParrams[i].Arg = GL_NONE;
            mOpParrams[i].Filled = false;
            mOpParrams[i].MaskRep = GL_NONE;
            mOpParrams[i].Mod = GL_NONE;
      }

}


void PS_1_4::clearAllMachineInst()
{

      mPhase1TEX_mi.clear();
      mPhase1ALU_mi.clear();
      mPhase2TEX_mi.clear();
      mPhase2ALU_mi.clear();

      // reset write state for all registers
      for(int i = 0; i<6; i++) {
            Phase_RegisterUsage[i].Phase1Write = false;
            Phase_RegisterUsage[i].Phase2Write = false;

      }

      mPhaseMarkerFound = false;
      mConstantsPos = -4;
      // keep track of the last instruction built
      // this info is used at the end of pass 2 to optimize the machine code
      mLastInstructionPos = 0;
      mSecondLastInstructionPos = 0;

      mMacroOn = false;  // macro's off at the beginning
      mTexm3x3padCount = 0;

}

bool PS_1_4::doPass2()
{
      clearAllMachineInst();
      // if pass 2 was successful, optimize the machine instructions
      bool passed = Pass2scan(&mTokenInstructions[0], mTokenInstructions.size());
      if (passed) optimize();  

      return passed;

}


bool PS_1_4::Pass2scan(const TokenInst * Tokens, const size_t size)
{

      // execute TokenInstructions to build MachineInstructions
      bool passed = true;
      SymbolDef* cursymboldef;
      uint ActiveNTTRuleID;

      clearMachineInstState();


      // iterate through all the tokens and build machine instruction
      // for each machine instruction need: optype, opinst, and up to 5 parameters
      for(uint i = 0; i < size; i++) {
            // lookup instruction type in library

            cursymboldef = &mSymbolTypeLib[Tokens[i].mID];
            ActiveNTTRuleID = Tokens[i].mNTTRuleID;
            mCurrentLine = Tokens[i].mLine;
            mCharPos = Tokens[i].mPos;

            switch(ActiveNTTRuleID) {

                  case sid_CONSTANT:
                  case sid_COLOR:
                  case sid_REG_PS1_4:
                  case sid_TEX_PS1_4:
                  case sid_REG_PS1_1_3:
                  case sid_TEX_PS1_1_3:
                        // registars can be used for read and write so they can be used for dst and arg
                        passed = setOpParram(cursymboldef);
                        break;


                  case sid_DEFCONST:
                  case sid_UNARYOP:
                  case sid_BINARYOP:
                  case sid_TERNARYOP:
                  case sid_TEXOP_PS1_1_3:
                  case sid_TEXOP_PS1_4:
                  case sid_PHASEMARKER:
                  case sid_TEXCISCOP_PS1_1_3:
                        // if the last instruction has not been passed on then do it now
                        // make sure the pipe is clear for a new instruction
                        BuildMachineInst();
                        if(mOpInst == sid_INVALID) {
                              mOpInst = cursymboldef->mID;
                        }
                        else passed = false;
                        break;

                  case sid_DSTMASK:
                  case sid_SRCREP:
                  case sid_TEXSWIZZLE:
                        // could be a dst mask or a arg replicator
                        // if dst mask and alpha included then make up a alpha instruction: maybe best to wait until instruction args completed
                        mOpParrams[mArgCnt].MaskRep = cursymboldef->mPass2Data;
                        break;

                  case sid_DSTMOD:
                  case sid_DSTSAT:
                  case sid_PRESRCMOD:
                  case sid_POSTSRCMOD:
                        mOpParrams[mArgCnt].Mod |= cursymboldef->mPass2Data;
                        break;


                  case sid_NUMVAL:
                        passed = setOpParram(cursymboldef);
                        // keep track of how many values are used
                        // update Constants array position
                        mConstantsPos++;
                        break;

                  case sid_SEPERATOR:
                        mArgCnt++;
                        break;
            } // end of switch

            if(!passed) break;
      }// end of for: i<TokenInstCnt

      // check to see if there is still an instruction left in the pipe
      if(passed) {
            BuildMachineInst();
            // if there are no more instructions in the pipe than OpInst should be invalid
            if(mOpInst != sid_INVALID) passed = false;
      }


      return passed;
}



bool PS_1_4::setOpParram(const SymbolDef* symboldef)
{
  bool success = true;
  if(mArgCnt<MAXOPPARRAMS) {
    if(mOpParrams[mArgCnt].Filled) mArgCnt++;
  }
  if (mArgCnt<MAXOPPARRAMS) {
    mOpParrams[mArgCnt].Filled = true;
    mOpParrams[mArgCnt].Arg = symboldef->mPass2Data;
  }
  else success = false;

  return success;
}




// *********************************************************************************
//  this is where the tests are carried out to make sure the PS_1_4 compiler works

#ifdef _DEBUG
// check the functionality of functions in PS_1_4: each test will print to the output file PASSED of FAILED
void PS_1_4::test()
{
  

  struct test1result{
    char character;
    int line;
  };

  struct testfloatresult{
    char *teststr;
    float fvalue;
    int charsize;
  };

  char TestStr1[] = "   \n\r  //c  \n\r// test\n\r  \t  c   - \n\r ,  e";
  test1result test1results[] = {
    {'c', 4},
    {'-', 4},
    {',', 5},
    {'e', 5}
  };

  testfloatresult testfloatresults[] = {
    {"1 test", 1.0f, 1},
    {"2.3f test", 2.3f, 3},
    {"-0.5 test", -0.5f, 4},
    {" 23.6 test", 23.6f, 5},
    {"  -0.021 test", -0.021f, 8},
    {"12 test", 12.0f, 2},
    {"3test", 3.0f, 1}
  };



  SymbolID test3result[] = { sid_MOV, sid_COMMA, sid_MUL, sid_ADD, sid_NEGATE, sid_T0
  };

  #define PART2INST 17
  char TestStr3[] = "mov r0,c1";
  char TestSymbols[] = "mov";
  char passed[] = "PASSED\n";
  char failed[] = "***** FAILED *****\n";

  int resultID = 0;

  // loop variable used in for loops
  int i;
  fp = fopen("ASMTests.txt", "wt");

// **************************************************************
  // first test: see if positionToNextSymbol can find a valid Symbol
  fprintf(fp, "Testing: positionToNextSymbol\n");

  mSource = TestStr1;
  mCharPos = 0;
  mCurrentLine = 1;
  mEndOfSource = (int)strlen(mSource);
  while (positionToNextSymbol()) {
    fprintf(fp,"  character found: [%c]   Line:%d  : " , mSource[mCharPos], mCurrentLine);
    if( (mSource[mCharPos] == test1results[resultID].character) && (mCurrentLine==test1results[resultID].line)) fprintf(fp, passed);
    else fprintf(fp, failed);
    resultID++;
    mCharPos++;
  }
  fprintf(fp, "finished testing: positionToNextSymbol\n");


// **************************************************************
  // Second Test
  // did the type lib get initialized properly with a default name index
  fprintf(fp, "\nTesting: getTypeDefText\n");
  char* resultstr = getTypeDefText(sid_MOV);
  fprintf(fp, "  default name of mov is: [%s]: %s", resultstr, (strcmp("mov", resultstr)==0)?passed:failed);
  fprintf(fp, "finished testing: getTypeDefText\n");

// **************************************************************
// **************************************************************
  // fourth test - does isSymbol work correctly
  fprintf(fp, "\nTesting: isSymbol\n");
  mSource = TestStr3;
  mCharPos = 0;
  fprintf(fp, "  before: [%s]\n", mSource + mCharPos);
  fprintf(fp, "  symbol to find: [%s]\n", TestSymbols);
  if(isSymbol(TestSymbols, resultID)) {
    fprintf(fp, "  after: [%s] : %s", mSource + resultID + 1, (mSource[resultID + 1] == 'r')? passed:failed);
  }
  else fprintf(fp, failed);
  fprintf(fp,"  symbol size: %d\n", resultID);
  fprintf(fp, "finished testing: isSymbol\n");

// **************************************************************
  fprintf(fp, "\nTesting: isFloatValue\n");
  float fvalue = 0;
  int charsize = 0;
  char teststrfloat1[] = "1 test";
  mCharPos = 0;
  int testsize = ARRAYSIZE(testfloatresults);
  for(i=0; i<testsize; i++) {
    mSource = testfloatresults[i].teststr;
    fprintf(fp, "  test string [%s]\n", mSource);
    isFloatValue(fvalue, charsize);
    fprintf(fp, "   value is: %f should be %f: %s", fvalue, testfloatresults[i].fvalue, (fvalue == testfloatresults[i].fvalue)?passed:failed);
    fprintf(fp, "   char size is: %d should be %d: %s", charsize, testfloatresults[i].charsize, (charsize == testfloatresults[i].charsize)?passed:failed);
  }

  fprintf(fp, "finished testing: isFloatValue\n");


// **************************************************************

  // simple compile test:
  char CompileTest1src[] = "ps.1.4\n";
  SymbolID CompileTest1result[] = {sid_PS_1_4};

  testCompile("Basic PS_1_4", CompileTest1src, CompileTest1result, ARRAYSIZE(CompileTest1result));

// **************************************************************
  char CompileTest2src[] = "ps.1.1\n";
  SymbolID CompileTest2result[] = {sid_PS_1_1};

  testCompile("Basic PS_1_1", CompileTest2src, CompileTest2result, ARRAYSIZE(CompileTest2result));

// **************************************************************
  char CompileTest3src[] = "ps.1.4\ndef c0, 1.0, 2.0, 3.0, 4.0\n";
  SymbolID CompileTest3result[] = {sid_PS_1_4, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
            sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE};

  testCompile("PS_1_4 with defines", CompileTest3src, CompileTest3result, ARRAYSIZE(CompileTest3result));


// **************************************************************
  char CompileTest4src[] = "ps.1.4\n//test kkl \ndef c0, 1.0, 2.0, 3.0, 4.0\ndef c3, 1.0, 2.0, 3.0, 4.0\n";
  SymbolID CompileTest4result[] = {sid_PS_1_4, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
            sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE,sid_DEF, sid_C3, sid_COMMA, sid_VALUE, sid_COMMA,
            sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE};

  testCompile("PS_1_4 with 2 defines", CompileTest4src, CompileTest4result, ARRAYSIZE(CompileTest4result));

// **************************************************************
  char CompileTest5src[] = "ps.1.4\ndef c0, 1.0, 2.0, 3.0, 4.0\n";
  SymbolID CompileTest5result[] = {sid_PS_1_4, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
            sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE};
  GLuint CompileTest5MachinInstResults[] = {mi_SETCONSTANTS, GL_CON_0_ATI, 0};

  testCompile("PS_1_4 with defines", CompileTest3src, CompileTest3result, ARRAYSIZE(CompileTest3result), CompileTest5MachinInstResults, ARRAYSIZE(CompileTest5MachinInstResults));
// **************************************************************
  char CompileTest6Src[] = "ps.1.4\nmov r0.xzw, c1 \nmul r3, r2, c3";
  SymbolID CompileTest6result[] = {sid_PS_1_4, sid_MOV, sid_R0, sid_RBA, sid_COMMA, sid_C1,
        sid_MUL, sid_R3, sid_COMMA, sid_R2, sid_COMMA, sid_C3};
  
  testCompile("PS_1_4 ALU simple", CompileTest6Src, CompileTest6result, ARRAYSIZE(CompileTest6result));

// **************************************************************
  // test to see if PS_1_4 compile pass 2 generates the proper machine instructions
      char CompileTest7Src[] = "ps.1.4\ndef c0,1.0,2.0,3.0,4.0\nmov_x8 r1,v0\nmov r0,r1.g";

      SymbolID CompileTest7result[] = {
            sid_PS_1_4, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
            sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE, sid_MOV, sid_X8, sid_R1, sid_COMMA,
            sid_V0, sid_MOV, sid_R0, sid_COMMA, sid_R1, sid_GGGG
      };

      GLuint CompileTest7MachinInstResults[] = {
            mi_SETCONSTANTS, GL_CON_0_ATI, 0,
            mi_COLOROP1, GL_MOV_ATI, GL_REG_1_ATI, RGB_BITS, GL_8X_BIT_ATI,   GL_PRIMARY_COLOR_ARB, GL_NONE, GL_NONE,
            mi_ALPHAOP1, GL_MOV_ATI, GL_REG_1_ATI, GL_8X_BIT_ATI, GL_PRIMARY_COLOR_ARB, GL_NONE, GL_NONE,
            mi_COLOROP1, GL_MOV_ATI, GL_REG_0_ATI, RGB_BITS, GL_NONE,GL_REG_1_ATI, GL_GREEN, GL_NONE,
            mi_ALPHAOP1, GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_REG_1_ATI, GL_GREEN, GL_NONE,
      };


      testCompile("PS_1_4 ALU simple modifier", CompileTest7Src, CompileTest7result, ARRAYSIZE(CompileTest7result), CompileTest7MachinInstResults, ARRAYSIZE(CompileTest7MachinInstResults));

// **************************************************************
// test to see if a PS_1_1 can be compiled - pass 1 and pass 2 are checked

      char TestStr5[] = "ps.1.1\ndef c0,1.0,2.0,3.0,4.0\ntex t0\n// test\ntex t1\ndp3 t0.rgb, t0_bx2, t1_bx2\n+ mov r0,1 - t0";

      SymbolID test5result[] = {
            sid_PS_1_1, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
            sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE, sid_TEX, sid_1T0, sid_TEX, sid_1T1,
            sid_DP3, sid_1T0, sid_RGB, sid_COMMA, sid_1T0, sid_BX2, sid_COMMA, sid_1T1, sid_BX2,
            
            sid_PLUS, sid_MOV, sid_1R0, sid_COMMA, sid_INVERT, sid_1T0
      };

      GLuint test5MachinInstResults[] = {
            mi_SETCONSTANTS, GL_CON_0_ATI, 0, mi_SAMPLEMAP, GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI, mi_SAMPLEMAP, GL_REG_1_ATI, GL_TEXTURE1_ARB, GL_SWIZZLE_STR_ATI,
            mi_COLOROP2, GL_DOT3_ATI, GL_REG_0_ATI, RGB_BITS, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
            GL_REG_1_ATI, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
            mi_COLOROP1, GL_MOV_ATI, GL_REG_0_ATI, RGB_BITS, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_COMP_BIT_ATI, mi_ALPHAOP1, GL_MOV_ATI, GL_REG_0_ATI,
            GL_NONE, GL_REG_0_ATI, GL_NONE, GL_COMP_BIT_ATI,
      };


      testCompile("PS_1_1 Texture simple", TestStr5, test5result, ARRAYSIZE(test5result), test5MachinInstResults, ARRAYSIZE(test5MachinInstResults));


// **************************************************************
// test to see if a PS_1_2 CISC instructions can be compiled - pass 1 and pass 2 are checked

      char TestStr6[] = "ps.1.2\ndef c0,1.0,2.0,3.0,4.0\ntex t0\n// test\ntexreg2ar t1, t0";

      SymbolID test6result[] = {
            sid_PS_1_2, sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA,
            sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE,
            sid_TEX, sid_1T0,
            sid_TEXREG2AR, sid_1T1, sid_COMMA, sid_1T0
      };

      GLuint test6MachinInstResults[] = {
            // def c0
            mi_SETCONSTANTS, GL_CON_0_ATI, 0,
            // texld r0, t0.str
            mi_SAMPLEMAP, GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI,
            // mov r1.r, r0.a 
            mi_COLOROP1, GL_MOV_ATI, GL_REG_1_ATI, GL_RED_BIT_ATI, GL_NONE, GL_REG_0_ATI, GL_ALPHA, GL_NONE,
            // mov r1.g, r0.r
            mi_COLOROP1, GL_MOV_ATI, GL_REG_1_ATI, GL_GREEN_BIT_ATI, GL_NONE, GL_REG_0_ATI, GL_RED, GL_NONE,
            // texld r1, r1
            mi_SAMPLEMAP, GL_REG_1_ATI, GL_REG_1_ATI, GL_SWIZZLE_STR_ATI,
      };


      testCompile("PS_1_2 CISC instructions", TestStr6, test6result, ARRAYSIZE(test6result), test6MachinInstResults, ARRAYSIZE(test6MachinInstResults));

// **************************************************************
// test to see if a PS_1_4 two phase can be compiled - pass 1 and pass 2 are checked

      char TestStr7[] = "ps.1.4\ndef c0,1.0,2.0,3.0,4.0\ntexld r0, t0\n// test\nmul r0, r0, c0\nphase\ntexld r1, r0\nmul r0,r0,r1\n";

      SymbolID test7result[] = {
            sid_PS_1_4,
            // def c0,1.0,2.0,3.0,4.0
            sid_DEF, sid_C0, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE, sid_COMMA, sid_VALUE,
            // texld r0, t0
            sid_TEXLD, sid_R0, sid_COMMA, sid_T0,
            // mul r0, r0, c0
            sid_MUL, sid_R0, sid_COMMA, sid_R0, sid_COMMA, sid_C0,
            // phase
            sid_PHASE,
            // texld r1, r0
            sid_TEXLD, sid_R1, sid_COMMA, sid_R0,
            // mul r0, r0, r1
            sid_MUL, sid_R0, sid_COMMA, sid_R0, sid_COMMA, sid_R1,

      };

      GLuint test7MachinInstResults[] = {
            // def c0
            mi_SETCONSTANTS, GL_CON_0_ATI, 0,
            // texld r0, t0.str
            mi_SAMPLEMAP, GL_REG_0_ATI, GL_TEXTURE0_ARB, GL_SWIZZLE_STR_ATI,
            // mul r0, r0, c0
            mi_COLOROP2, GL_MUL_ATI, GL_REG_0_ATI, RGB_BITS, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_CON_0_ATI, GL_NONE, GL_NONE,
            mi_ALPHAOP2, GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_CON_0_ATI, GL_NONE, GL_NONE,
            // phase
            // texld r1, r0.str
            mi_SAMPLEMAP, GL_REG_1_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI,
            // pass ro register
            mi_PASSTEXCOORD, GL_REG_0_ATI, GL_REG_0_ATI, GL_SWIZZLE_STR_ATI,
            // mul r0, r0, r1
            mi_COLOROP2, GL_MUL_ATI, GL_REG_0_ATI, RGB_BITS, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_REG_1_ATI, GL_NONE, GL_NONE,
            // mul r0.a, r0
            mi_ALPHAOP2, GL_MUL_ATI, GL_REG_0_ATI, GL_NONE, GL_REG_0_ATI, GL_NONE, GL_NONE, GL_REG_1_ATI, GL_NONE, GL_NONE,
      };


      testCompile("PS_1_4 texture complex : Phase - instructions", TestStr7, test7result, ARRAYSIZE(test7result), test7MachinInstResults, ARRAYSIZE(test7MachinInstResults));


      fclose(fp);
      fp = NULL;
      //reset contexts

// **************************************************************
}

void PS_1_4::testCompile(char* testname, char* teststr, SymbolID* testresult, uint testresultsize, GLuint* MachinInstResults, uint MachinInstResultsSize)
{

      char passed[] = "PASSED\n";
      char failed[] = "***** FAILED ****\n";

      setActiveContexts(ckp_PS_BASE);

      fprintf(fp, "\n*** TESTING: %s Compile: Check Pass 1 and 2\n", testname);
      fprintf(fp, "  source to compile:\n[\n%s\n]\n", teststr);
      bool compiled = compile(teststr);
      fprintf(fp, "  Pass 1 Lines scaned: %d, Tokens produced: %d out of %d: %s",
            mCurrentLine, mTokenInstructions.size(), testresultsize,
            (mTokenInstructions.size() == (uint)testresultsize) ? passed : failed);

      fprintf(fp, "\n  Validating Pass 1:\n");

      fprintf(fp, "\n  Tokens:\n");
    uint i;
      for(i = 0; i<(mTokenInstructions.size()); i++) {
            fprintf(fp,"    Token[%d] [%s] %d: [%s] %d: %s", i, getTypeDefText(mTokenInstructions[i].mID),
                  mTokenInstructions[i].mID, getTypeDefText(testresult[i]), testresult[i],
                  (mTokenInstructions[i].mID == (uint)testresult[i]) ? passed : failed);
      }

      if(MachinInstResults != NULL) {
            fprintf(fp, "\n  Machine Instructions:\n");

            fprintf(fp, "  Pass 2 Machine Instructions generated: %d out of %d: %s", getMachineInstCount(),
                  MachinInstResultsSize, (getMachineInstCount() == MachinInstResultsSize) ? passed : failed);

            size_t MIcount = getMachineInstCount();

            fprintf(fp, "\n  Validating Pass 2:\n");
            for(i = 0; i<MIcount; i++) {
                  fprintf(fp,"    instruction[%d] = 0x%x : 0x%x : %s", i, getMachineInst(i), MachinInstResults[i], (getMachineInst(i) == MachinInstResults[i]) ? passed : failed);
            }

            fprintf(fp, "\n  Constants:\n");
            for(i=0; i<4; i++) {
                  fprintf(fp, "    Constants[%d] = %f : %s", i, mConstants[i], (mConstants[i] == (1.0f+i)) ? passed : failed);
            }
      }
      if(!compiled) fprintf(fp, failed);

      fprintf(fp, "\nfinished testing: %s Compile: Check Pass 2\n\n", testname);

      setActiveContexts(ckp_PS_BASE);
}

void PS_1_4::testbinder()
{
  FILE* fp;
  char BindTestStr[] = "mov_x8 r0,v0";
  char passed[] = "PASSED\n";
  char failed[] = "FAILED\n";
  #define BinderInstCnt 8
  GLuint BindMachinInst[BinderInstCnt] = {mi_COLOROP1, GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_8X_BIT_ATI,
   GL_PRIMARY_COLOR_ARB, GL_NONE, GL_NONE};

  fp = fopen("ASMTests.txt", "at");
  fprintf(fp,"Testing: bindMachineInstToFragmentShader\n");
  // fill Machin instruction container with predefined code
  clearAllMachineInst();
  for(int i=0; i<BinderInstCnt; i++) {
    mPhase2ALU_mi.push_back(BindMachinInst[i]);
  }
  fprintf(fp,"bindMachineInstToFragmentShader succes: %s\n",bindAllMachineInstToFragmentShader()?passed:failed);
  fprintf(fp,"finished testing: bindAllMachineInstToFragmentShader\n");
  fclose(fp);
}

#endif




Generated by  Doxygen 1.6.0   Back to index