OpenCores
URL https://opencores.org/ocsvn/theia_gpu/theia_gpu/trunk

Subversion Repositories theia_gpu

[/] [theia_gpu/] [branches/] [beta_2.0/] [compiler/] [src/] [vp_compiler/] [parser.y] - Diff between revs 227 and 230

Only display areas with differences | Details | Blame | View Log

Rev 227 Rev 230
/**********************************************************************************
/**********************************************************************************
Theia, Ray Cast Programable graphic Processing Unit.
Theia, Ray Cast Programable graphic Processing Unit.
Copyright (C) 2012  Diego Valverde (diego.valverde.g@gmail.com)
Copyright (C) 2012  Diego Valverde (diego.valverde.g@gmail.com)
This program is free software; you can redistribute it and/or
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
***********************************************************************************/
***********************************************************************************/
%require "2.4.1"
%require "2.4.1"
%skeleton "lalr1.cc"
%skeleton "lalr1.cc"
%defines
%defines
%error-verbose
%error-verbose
%locations
%locations
%define namespace "Theia"
%define namespace "Theia"
%define parser_class_name "Parser"
%define parser_class_name "Parser"
%parse-param { Theia::Scanner &scanner }
%parse-param { Theia::Scanner &scanner }
%parse-param { std::map  & mSymbolMap }
%parse-param { std::map  & mSymbolMap }
%parse-param { std::vector< Instruction > &mInstructions }
%parse-param { std::vector< Instruction > &mInstructions }
%parse-param { bool &mGenerateFixedPointArithmetic }
%parse-param { bool &mGenerateFixedPointArithmetic }
%lex-param   { Theia::Scanner &scanner }
%lex-param   { Theia::Scanner &scanner }
%code requires {
%code requires {
        #include 
        #include 
        #include 
        #include 
        #include 
        #include 
        #include 
        #include 
        #include 
        #include 
        #include "Instruction.h"
        #include "Instruction.h"
        #include 
        #include 
        // We want to return a string
        // We want to return a string
        #define YYSTYPE std::string
        #define YYSTYPE std::string
                namespace Theia
                namespace Theia
                {
                {
                        // Forward-declare the Scanner class; the Parser needs to be assigned a
                        // Forward-declare the Scanner class; the Parser needs to be assigned a
                        // Scanner, but the Scanner can't be declared without the Parser
                        // Scanner, but the Scanner can't be declared without the Parser
                        class Scanner;
                        class Scanner;
                        // We use a map to store the INI data
                        // We use a map to store the INI data
                        typedef std::map > mapData;
                        typedef std::map > mapData;
                }
                }
}
}
%code
%code
{
{
        #include "Instruction.h"
        #include "Instruction.h"
        #include 
        #include 
        Instruction I,tmpI;
        Instruction I,tmpI;
        std::vector< unsigned int > gBranchStack;
        std::vector< unsigned int > gBranchStack;
        static int gInsertedInstructions = 0;
        static int gInsertedInstructions = 0;
        static int gWhileLoopAddress = 0;
        static int gWhileLoopAddress = 0;
#define FUNCTION_PARAM_START_REGION 4
#define FUNCTION_PARAM_START_REGION 4
#define FUNCTION_PARAM_LAST_REGION  10
#define FUNCTION_PARAM_LAST_REGION  10
        std::map gFunctionParameters;
        std::map gFunctionParameters;
        std::map gAutoVarMap;
        std::map gAutoVarMap;
        std::map gThreadMap; //Key: Symbol, value: start code addr
        std::map gThreadMap; //Key: Symbol, value: start code addr
        bool gThreadScope = false;
        bool gThreadScope = false;
#define AUTOVAR_START_REGION 9
#define AUTOVAR_START_REGION 9
#define THREAD_OFFSET 128
#define THREAD_OFFSET 128
unsigned int gExtraDestModifications = 0;
unsigned int gExtraDestModifications = 0;
unsigned int gAutoVarIndex = AUTOVAR_START_REGION;
unsigned int gAutoVarIndex = AUTOVAR_START_REGION;
unsigned int gThreadAutoVarIndex = THREAD_OFFSET;
unsigned int gThreadAutoVarIndex = THREAD_OFFSET;
unsigned int gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;
unsigned int gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;
//----------------------------------------------------------
//----------------------------------------------------------
unsigned int GetNextFunctionParamRegister()
unsigned int GetNextFunctionParamRegister()
{
{
        unsigned Ret = gFunctionParameterIndex++;
        unsigned Ret = gFunctionParameterIndex++;
        return Ret;
        return Ret;
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void AddFunctionParameter( std::string aVar, Theia::Parser::location_type  yylloc)
void AddFunctionParameter( std::string aVar, Theia::Parser::location_type  yylloc)
{
{
        ////std::cout << "Adding " << aVar << "\n";
        ////std::cout << "Adding " << aVar << "\n";
        if (gFunctionParameterIndex+1 > FUNCTION_PARAM_LAST_REGION)
        if (gFunctionParameterIndex+1 > FUNCTION_PARAM_LAST_REGION)
        {
        {
                        std::ostringstream ret;
                        std::ostringstream ret;
                        ret << "Cannot allocate more parameters '" << aVar << "' at line " << yylloc << " \n";
                        ret << "Cannot allocate more parameters '" << aVar << "' at line " << yylloc << " \n";
                        throw ret.str();
                        throw ret.str();
        }
        }
        if (gFunctionParameters.find(aVar) != gFunctionParameters.end())
        if (gFunctionParameters.find(aVar) != gFunctionParameters.end())
        {
        {
                        std::ostringstream ret;
                        std::ostringstream ret;
                        ret << "Parameter '" << aVar << "' at line " << yylloc << " is already defined\n";
                        ret << "Parameter '" << aVar << "' at line " << yylloc << " is already defined\n";
                        throw ret.str();
                        throw ret.str();
        }
        }
        gFunctionParameters[ aVar ] = gFunctionParameterIndex++;
        gFunctionParameters[ aVar ] = gFunctionParameterIndex++;
}
}
//----------------------------------------------------------
//----------------------------------------------------------
std::string  GetRegisterFromFunctionParameter( std::string aVar )
std::string  GetRegisterFromFunctionParameter( std::string aVar )
{
{
        ////std::cout << "Looking for " << aVar << "\n";
        ////std::cout << "Looking for " << aVar << "\n";
        if (gFunctionParameters.find(aVar) == gFunctionParameters.end())
        if (gFunctionParameters.find(aVar) == gFunctionParameters.end())
                return "NULL";
                return "NULL";
        std::ostringstream ss;
        std::ostringstream ss;
        ss << gFunctionParameters[ aVar ];
        ss << gFunctionParameters[ aVar ];
        return  ("R" + ss.str());
        return  ("R" + ss.str());
}
}
//----------------------------------------------------------
//----------------------------------------------------------
unsigned int GetCurretAutoVarFrameSize()
unsigned int GetCurretAutoVarFrameSize()
{
{
        return gAutoVarMap.size();
        return gAutoVarMap.size();
}
}
//----------------------------------------------------------
//----------------------------------------------------------
std::string GetRegisterFromAutoVar( std::string aVar, Theia::Parser::location_type  yylloc )
std::string GetRegisterFromAutoVar( std::string aVar, Theia::Parser::location_type  yylloc )
{
{
        if (gAutoVarMap.find(aVar) == gAutoVarMap.end())
        if (gAutoVarMap.find(aVar) == gAutoVarMap.end())
        {
        {
                        std::ostringstream ret;
                        std::ostringstream ret;
                        ret << "Undefined variable '" << aVar << "' at line " << yylloc << " \n";
                        ret << "Undefined variable '" << aVar << "' at line " << yylloc << " \n";
                        throw ret.str();
                        throw ret.str();
        }
        }
                std::ostringstream ss;
                std::ostringstream ss;
                ss << gAutoVarMap[ aVar ];
                ss << gAutoVarMap[ aVar ];
                return  ("R" + ss.str());
                return  ("R" + ss.str());
}
}
//----------------------------------------------------------
//----------------------------------------------------------
int GetCurrentLineNumber( const Theia::Parser::location_type &loc )
int GetCurrentLineNumber( const Theia::Parser::location_type &loc )
{
{
                int ret = -1;
                int ret = -1;
                std::stringstream ss2;
                std::stringstream ss2;
                std::string where;
                std::string where;
                ss2 << loc;
                ss2 << loc;
                ss2 >> where;
                ss2 >> where;
                where.erase(where.find_first_of("."));
                where.erase(where.find_first_of("."));
                std::stringstream ss3;
                std::stringstream ss3;
                ss3 << where;
                ss3 << where;
                ss3 >> ret;
                ss3 >> ret;
                return ret;
                return ret;
}
}
//----------------------------------------------------------
//----------------------------------------------------------
unsigned int AllocAutoVar( unsigned int aSize = 1)
unsigned int AllocAutoVar( unsigned int aSize = 1)
{
{
        if (!gThreadScope)
        if (!gThreadScope)
        {
        {
                gAutoVarIndex += aSize;
                gAutoVarIndex += aSize;
                return gAutoVarIndex - (aSize-1);
                return gAutoVarIndex - (aSize-1);
        }else{
        }else{
                gThreadAutoVarIndex += aSize;
                gThreadAutoVarIndex += aSize;
                return (gThreadAutoVarIndex - (aSize-1));
                return (gThreadAutoVarIndex - (aSize-1));
        }
        }
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void ClearFunctionParameterMap()
void ClearFunctionParameterMap()
{
{
        gFunctionParameters.clear();
        gFunctionParameters.clear();
        gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;
        gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void ClearAutoVarMap()
void ClearAutoVarMap()
{
{
        gAutoVarMap.clear();
        gAutoVarMap.clear();
        gAutoVarIndex = AUTOVAR_START_REGION;
        gAutoVarIndex = AUTOVAR_START_REGION;
}
}
//----------------------------------------------------------
//----------------------------------------------------------
unsigned int gTempRegisterIndex = 1;
unsigned int gTempRegisterIndex = 1;
unsigned int GetFreeTempRegister( )
unsigned int GetFreeTempRegister( )
{
{
        if (!gThreadScope)
        if (!gThreadScope)
                return gAutoVarIndex + (gTempRegisterIndex++);
                return gAutoVarIndex + (gTempRegisterIndex++);
        else
        else
                return gThreadAutoVarIndex + (gTempRegisterIndex++);
                return gThreadAutoVarIndex + (gTempRegisterIndex++);
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void ResetTempRegisterIndex( void )
void ResetTempRegisterIndex( void )
{
{
        gTempRegisterIndex = 1;
        gTempRegisterIndex = 1;
}
}
//----------------------------------------------------------
//----------------------------------------------------------
bool IsSwizzled( std::string aSource)
bool IsSwizzled( std::string aSource)
{
{
        if (aSource.find(".") != std::string::npos)
        if (aSource.find(".") != std::string::npos)
                return true;
                return true;
        else
        else
                return false;
                return false;
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void SetSwizzleAndSign( unsigned int aSourceIndex, std::string aSwizzle, Instruction & I )
void SetSwizzleAndSign( unsigned int aSourceIndex, std::string aSwizzle, Instruction & I )
{
{
        std::string Reg,X,Y,Z, junk;
        std::string Reg,X,Y,Z, junk;
        std::stringstream ss( aSwizzle );
        std::stringstream ss( aSwizzle );
        ss >> Reg >> junk >> X >> Y >> Z;
        ss >> Reg >> junk >> X >> Y >> Z;
        if (aSourceIndex == 1)
        if (aSourceIndex == 1)
        {
        {
                if (X == "X") { I.SetSrc1SwizzleX(SWX_X);       }
                if (X == "X") { I.SetSrc1SwizzleX(SWX_X);       }
                if (X == "Y") { I.SetSrc1SwizzleX(SWX_Y);       }
                if (X == "Y") { I.SetSrc1SwizzleX(SWX_Y);       }
                if (X == "Z") { I.SetSrc1SwizzleX(SWX_Z);       }
                if (X == "Z") { I.SetSrc1SwizzleX(SWX_Z);       }
                if (X == "-X") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_X);      }
                if (X == "-X") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_X);      }
                if (X == "-Y") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Y);      }
                if (X == "-Y") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Y);      }
                if (X == "-Z") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Z);      }
                if (X == "-Z") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Z);      }
                if (Y == "X") { I.SetSrc1SwizzleY(SWY_X);       }
                if (Y == "X") { I.SetSrc1SwizzleY(SWY_X);       }
                if (Y == "Y") { I.SetSrc1SwizzleY(SWY_Y);       }
                if (Y == "Y") { I.SetSrc1SwizzleY(SWY_Y);       }
                if (Y == "Z") { I.SetSrc1SwizzleY(SWY_Z);       }
                if (Y == "Z") { I.SetSrc1SwizzleY(SWY_Z);       }
                if (Y == "-X") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_X);      }
                if (Y == "-X") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_X);      }
                if (Y == "-Y") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Y);      }
                if (Y == "-Y") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Y);      }
                if (Y == "-Z") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Z);      }
                if (Y == "-Z") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Z);      }
                if (Z == "X") { I.SetSrc1SwizzleZ(SWZ_X);       }
                if (Z == "X") { I.SetSrc1SwizzleZ(SWZ_X);       }
                if (Z == "Y") { I.SetSrc1SwizzleZ(SWZ_Y);       }
                if (Z == "Y") { I.SetSrc1SwizzleZ(SWZ_Y);       }
                if (Z == "Z") { I.SetSrc1SwizzleZ(SWZ_Z);       }
                if (Z == "Z") { I.SetSrc1SwizzleZ(SWZ_Z);       }
                if (Z == "-X") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_X);      }
                if (Z == "-X") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_X);      }
                if (Z == "-Y") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Y);      }
                if (Z == "-Y") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Y);      }
                if (Z == "-Z") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Z);      }
                if (Z == "-Z") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Z);      }
        } else {
        } else {
                if (X == "X") { I.SetSrc0SwizzleX(SWX_X);       }
                if (X == "X") { I.SetSrc0SwizzleX(SWX_X);       }
                if (X == "Y") { I.SetSrc0SwizzleX(SWX_Y);       }
                if (X == "Y") { I.SetSrc0SwizzleX(SWX_Y);       }
                if (X == "Z") { I.SetSrc0SwizzleX(SWX_Z);       }
                if (X == "Z") { I.SetSrc0SwizzleX(SWX_Z);       }
                if (X == "-X") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_X);      }
                if (X == "-X") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_X);      }
                if (X == "-Y") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Y);      }
                if (X == "-Y") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Y);      }
                if (X == "-Z") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Z);      }
                if (X == "-Z") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Z);      }
                if (Y == "X") { I.SetSrc0SwizzleY(SWY_X);       }
                if (Y == "X") { I.SetSrc0SwizzleY(SWY_X);       }
                if (Y == "Y") { I.SetSrc0SwizzleY(SWY_Y);       }
                if (Y == "Y") { I.SetSrc0SwizzleY(SWY_Y);       }
                if (Y == "Z") { I.SetSrc0SwizzleY(SWY_Z);       }
                if (Y == "Z") { I.SetSrc0SwizzleY(SWY_Z);       }
                if (Y == "-X") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_X);      }
                if (Y == "-X") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_X);      }
                if (Y == "-Y") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Y);      }
                if (Y == "-Y") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Y);      }
                if (Y == "-Z") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Z);      }
                if (Y == "-Z") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Z);      }
                if (Z == "X") { I.SetSrc0SwizzleZ(SWZ_X);       }
                if (Z == "X") { I.SetSrc0SwizzleZ(SWZ_X);       }
                if (Z == "Y") { I.SetSrc0SwizzleZ(SWZ_Y);       }
                if (Z == "Y") { I.SetSrc0SwizzleZ(SWZ_Y);       }
                if (Z == "Z") { I.SetSrc0SwizzleZ(SWZ_Z);       }
                if (Z == "Z") { I.SetSrc0SwizzleZ(SWZ_Z);       }
                if (Z == "-X") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_X);      }
                if (Z == "-X") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_X);      }
                if (Z == "-Y") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Y);      }
                if (Z == "-Y") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Y);      }
                if (Z == "-Z") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Z);      }
                if (Z == "-Z") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Z);      }
        }
        }
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void StoreReturnAddress( std::vector & aInstructions, Theia::Parser::location_type & yylloc )
void StoreReturnAddress( std::vector & aInstructions, Theia::Parser::location_type & yylloc )
{
{
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "store return address**";
                I.mComment = "store return address**";
                I.SetImm( aInstructions.size()+4 );
                I.SetImm( aInstructions.size()+4 );
                I.SetWriteChannel(ECHANNEL_X);
                I.SetWriteChannel(ECHANNEL_X);
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
                I.SetDestZero( true );
                I.SetDestZero( true );
                I.mSourceLine = GetCurrentLineNumber( yylloc );
                I.mSourceLine = GetCurrentLineNumber( yylloc );
                aInstructions.push_back( I );
                aInstructions.push_back( I );
                I.Clear();
                I.Clear();
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void SavePreviousFramePointer( std::vector & aInstructions )
void SavePreviousFramePointer( std::vector & aInstructions )
{
{
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "store current frame offset";
                I.mComment = "store current frame offset";
                I.SetWriteChannel(ECHANNEL_Y);
                I.SetWriteChannel(ECHANNEL_Y);
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
                I.SetSrc1SwizzleX(SWX_X);
                I.SetSrc1SwizzleX(SWX_X);
                I.SetSrc1SwizzleY(SWY_X);
                I.SetSrc1SwizzleY(SWY_X);
                I.SetSrc1SwizzleZ(SWZ_X);
                I.SetSrc1SwizzleZ(SWZ_X);
                I.SetSrc0Address(0);
                I.SetSrc0Address(0);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                aInstructions.push_back( I );
                aInstructions.push_back( I );
                I.Clear();
                I.Clear();
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void SetIndexRegister( unsigned int aIndex, std::vector & aInstructions  )
void SetIndexRegister( unsigned int aIndex, std::vector & aInstructions  )
{
{
                Instruction Tmp;
                Instruction Tmp;
                Tmp.SetCode( EOPERATION_ADD );
                Tmp.SetCode( EOPERATION_ADD );
                Tmp.mComment = "store array index register";
                Tmp.mComment = "store array index register";
                Tmp.SetWriteChannel(ECHANNEL_Z);
                Tmp.SetWriteChannel(ECHANNEL_Z);
                Tmp.SetDestinationAddress( SPR_CONTROL_REGISTER );
                Tmp.SetDestinationAddress( SPR_CONTROL_REGISTER );
                Tmp.SetSrc1Address( aIndex );
                Tmp.SetSrc1Address( aIndex );
                Tmp.SetSrc1Displace( true );
                Tmp.SetSrc1Displace( true );
                Tmp.SetSrc1SwizzleX(SWX_X);
                Tmp.SetSrc1SwizzleX(SWX_X);
                Tmp.SetSrc1SwizzleY(SWY_X);
                Tmp.SetSrc1SwizzleY(SWY_X);
                Tmp.SetSrc1SwizzleZ(SWZ_X);
                Tmp.SetSrc1SwizzleZ(SWZ_X);
                Tmp.SetSrc0Address(0);
                Tmp.SetSrc0Address(0);
                Tmp.SetSrc0SwizzleX(SWX_X);
                Tmp.SetSrc0SwizzleX(SWX_X);
                Tmp.SetSrc0SwizzleY(SWY_X);
                Tmp.SetSrc0SwizzleY(SWY_X);
                Tmp.SetSrc0SwizzleZ(SWZ_X);
                Tmp.SetSrc0SwizzleZ(SWZ_X);
                //Tmp.SetImm( aIndex );
                //Tmp.SetImm( aIndex );
                //Tmp.SetDestZero( true );
                //Tmp.SetDestZero( true );
                aInstructions.push_back( Tmp );
                aInstructions.push_back( Tmp );
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void UpdateFramePointer( std::vector & aInstructions )
void UpdateFramePointer( std::vector & aInstructions )
{
{
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "displace next frame offset by the number of auto variables in current frame";
                I.mComment = "displace next frame offset by the number of auto variables in current frame";
                I.SetWriteChannel(ECHANNEL_X);
                I.SetWriteChannel(ECHANNEL_X);
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetImm( GetCurretAutoVarFrameSize() );
                I.SetImm( GetCurretAutoVarFrameSize() );
                I.SetDestZero( false );
                I.SetDestZero( false );
                aInstructions.push_back( I );
                aInstructions.push_back( I );
                I.Clear();
                I.Clear();
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void CallFunction( std::string aFunctionName,  std::vector & aInstructions, std::map  &  aSymbolMap)
void CallFunction( std::string aFunctionName,  std::vector & aInstructions, std::map  &  aSymbolMap)
{
{
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "call the function";
                I.mComment = "call the function";
                I.SetBranchFlag( true );
                I.SetBranchFlag( true );
                I.SetBranchType( EBRANCH_ALWAYS );
                I.SetBranchType( EBRANCH_ALWAYS );
                //Now do the branch
                //Now do the branch
                if (aSymbolMap.find(aFunctionName) == aSymbolMap.end())
                if (aSymbolMap.find(aFunctionName) == aSymbolMap.end())
                        I.SetDestinationSymbol( "@"+aFunctionName );
                        I.SetDestinationSymbol( "@"+aFunctionName );
                else
                else
                        I.SetDestinationAddress( aSymbolMap[ aFunctionName ] );
                        I.SetDestinationAddress( aSymbolMap[ aFunctionName ] );
                aInstructions.push_back( I );
                aInstructions.push_back( I );
                I.Clear();
                I.Clear();
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void SetDestinationFromRegister( std::string aDestination, Instruction & aInst, bool Imm  )
void SetDestinationFromRegister( std::string aDestination, Instruction & aInst, bool Imm  )
{
{
                //Look for displament addressing mode
                //Look for displament addressing mode
                if (aDestination.find("OFFSET") != std::string::npos)
                if (aDestination.find("OFFSET") != std::string::npos)
                {
                {
                        aDestination.erase(aDestination.find("OFFSET"));
                        aDestination.erase(aDestination.find("OFFSET"));
                        ////std::cout << "^_^ left_hand_side " << Destination << "\n";
                        ////std::cout << "^_^ left_hand_side " << Destination << "\n";
                        if (Imm == true)
                        if (Imm == true)
                                aInst.SetSrc0Displace( true ); //When Imm == 0, then setting this makes offset
                                aInst.SetSrc0Displace( true ); //When Imm == 0, then setting this makes offset
                        else
                        else
                                aInst.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
                                aInst.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
                }
                }
                if (aDestination.find(".") != std::string::npos)
                if (aDestination.find(".") != std::string::npos)
                {
                {
                        aInst.ClearWriteChannel();
                        aInst.ClearWriteChannel();
                        if (aDestination.find("x") != std::string::npos)
                        if (aDestination.find("x") != std::string::npos)
                                aInst.SetWriteChannel(ECHANNEL_X);
                                aInst.SetWriteChannel(ECHANNEL_X);
                        if (aDestination.find("y") != std::string::npos)
                        if (aDestination.find("y") != std::string::npos)
                                aInst.SetWriteChannel(ECHANNEL_Y);
                                aInst.SetWriteChannel(ECHANNEL_Y);
                        if (aDestination.find("z") != std::string::npos)
                        if (aDestination.find("z") != std::string::npos)
                                aInst.SetWriteChannel(ECHANNEL_Z);
                                aInst.SetWriteChannel(ECHANNEL_Z);
                        aDestination.erase(aDestination.find("."));
                        aDestination.erase(aDestination.find("."));
                }
                }
                aInst.SetDestinationAddress( atoi(aDestination.c_str()+1) );
                aInst.SetDestinationAddress( atoi(aDestination.c_str()+1) );
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void PopulateSourceRegisters( std::string a1, std::string a2, Instruction & I, std::vector & aInstructions )
void PopulateSourceRegisters( std::string a1, std::string a2, Instruction & I, std::vector & aInstructions )
{
{
                        if ( a1.find("R") == std::string::npos )
                        if ( a1.find("R") == std::string::npos )
                        {
                        {
                                //This is for constants
                                //This is for constants
                                unsigned int ImmediateValue;
                                unsigned int ImmediateValue;
                                std::string StringHex = a1;
                                std::string StringHex = a1;
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << std::hex << StringHex;
                                ss << std::hex << StringHex;
                                ss >> ImmediateValue;
                                ss >> ImmediateValue;
                                I.SetImm( ImmediateValue );
                                I.SetImm( ImmediateValue );
                        } else {
                        } else {
                                if (a1.find("array_element") != std::string::npos)
                                if (a1.find("array_element") != std::string::npos)
                                {
                                {
                                        std::string Index = a1.substr(a1.find("array_element"));
                                        std::string Index = a1.substr(a1.find("array_element"));
                                        ////std::cout << "XXXXX " << Index << "\n\n\n";
                                        ////std::cout << "XXXXX " << Index << "\n\n\n";
                                        Index = Index.substr(Index.find_first_not_of("array_element R"));
                                        Index = Index.substr(Index.find_first_not_of("array_element R"));
                                        ////std::cout << "XXXXX " << Index << "\n\n\n";
                                        ////std::cout << "XXXXX " << Index << "\n\n\n";
                                        SetIndexRegister( atoi(Index.c_str()), aInstructions );
                                        SetIndexRegister( atoi(Index.c_str()), aInstructions );
                                        a1.erase(a1.find("array_element"));
                                        a1.erase(a1.find("array_element"));
                                        I.SetSrc0Displace( true );
                                        I.SetSrc0Displace( true );
                                        I.SetSrc1Displace( true );
                                        I.SetSrc1Displace( true );
                                        I.SetImmBit( true );
                                        I.SetImmBit( true );
                                }
                                }
                                        //Look for displament addressing mode
                                        //Look for displament addressing mode
                                else if (a1.find("OFFSET") != std::string::npos)
                                else if (a1.find("OFFSET") != std::string::npos)
                                {
                                {
                                        a1.erase(a1.find("OFFSET"));
                                        a1.erase(a1.find("OFFSET"));
                                        ////std::cout << "^_^ a1" << a1 << "\n";
                                        ////std::cout << "^_^ a1" << a1 << "\n";
                                        I.SetSrc1Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
                                        I.SetSrc1Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
                                }
                                }
                                std::string Src1 = a1;
                                std::string Src1 = a1;
                                if (IsSwizzled( Src1 ))
                                if (IsSwizzled( Src1 ))
                                {
                                {
                                        SetSwizzleAndSign( 1, Src1,  I );
                                        SetSwizzleAndSign( 1, Src1,  I );
                                        Src1.erase(Src1.find("."));
                                        Src1.erase(Src1.find("."));
                                }
                                }
                                I.SetSrc1Address( atoi( Src1.c_str()+1 ) );
                                I.SetSrc1Address( atoi( Src1.c_str()+1 ) );
                        }
                        }
                        if ( a2.find("R") == std::string::npos)
                        if ( a2.find("R") == std::string::npos)
                        {
                        {
                        } else {
                        } else {
                                //Look for displament addressing mode
                                //Look for displament addressing mode
                                if (a2.find("OFFSET") != std::string::npos)
                                if (a2.find("OFFSET") != std::string::npos)
                                {
                                {
                                        a2.erase(a2.find("OFFSET"));
                                        a2.erase(a2.find("OFFSET"));
                                        ////std::cout << "^_^ a2 " << a2 << "\n";
                                        ////std::cout << "^_^ a2 " << a2 << "\n";
                                        I.SetSrc0Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
                                        I.SetSrc0Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
                                }
                                }
                                std::string Src0 = a2;
                                std::string Src0 = a2;
                                if (IsSwizzled( Src0 ))
                                if (IsSwizzled( Src0 ))
                                {
                                {
                                        SetSwizzleAndSign( 0, Src0,  I );
                                        SetSwizzleAndSign( 0, Src0,  I );
                                        Src0.erase(Src0.find("."));
                                        Src0.erase(Src0.find("."));
                                }
                                }
                                I.SetSrc0Address( atoi( Src0.c_str()+1 ) );
                                I.SetSrc0Address( atoi( Src0.c_str()+1 ) );
                        }
                        }
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void ClearNextFunctionParamRegister()
void ClearNextFunctionParamRegister()
{
{
        gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;
        gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void AddFunctionInputList( std::string aVar, std::vector & aInstructions,Theia::Parser::location_type  yylloc)
void AddFunctionInputList( std::string aVar, std::vector & aInstructions,Theia::Parser::location_type  yylloc)
{
{
        //Get the value from the variable
        //Get the value from the variable
        DCOUT << "Calling AddFunctionInputList input arg: " << aVar << " \n";
        DCOUT << "Calling AddFunctionInputList input arg: " << aVar << " \n";
        //Copy the value into function parameter register
        //Copy the value into function parameter register
        unsigned FunctionParamReg = GetNextFunctionParamRegister();
        unsigned FunctionParamReg = GetNextFunctionParamRegister();
        I.Clear();
        I.Clear();
        I.SetCode( EOPERATION_ADD );
        I.SetCode( EOPERATION_ADD );
        I.mComment = "copy the value into function parameter register";
        I.mComment = "copy the value into function parameter register";
        I.SetWriteChannel(ECHANNEL_XYZ);
        I.SetWriteChannel(ECHANNEL_XYZ);
        //I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
        //I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
        I.SetDestinationAddress( FunctionParamReg );
        I.SetDestinationAddress( FunctionParamReg );
        if (aVar.find("R") != std::string::npos)
        if (aVar.find("R") != std::string::npos)
        {
        {
                if (aVar.find("OFFSET") != std::string::npos)
                if (aVar.find("OFFSET") != std::string::npos)
                {
                {
                        I.SetSrc1Displace( true );
                        I.SetSrc1Displace( true );
                        aVar.erase(aVar.find("OFFSET"));
                        aVar.erase(aVar.find("OFFSET"));
                }
                }
                I.SetSrc1Address(atoi(aVar.c_str()+1));
                I.SetSrc1Address(atoi(aVar.c_str()+1));
                I.SetSrc1SwizzleX(SWX_X);
                I.SetSrc1SwizzleX(SWX_X);
                I.SetSrc1SwizzleY(SWY_Y);
                I.SetSrc1SwizzleY(SWY_Y);
                I.SetSrc1SwizzleZ(SWZ_Z);
                I.SetSrc1SwizzleZ(SWZ_Z);
                I.SetSrc0Address(0);
                I.SetSrc0Address(0);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                aInstructions.push_back( I );
                aInstructions.push_back( I );
                I.Clear();
                I.Clear();
                return;
                return;
        }
        }
        std::string Reg = GetRegisterFromFunctionParameter( aVar );
        std::string Reg = GetRegisterFromFunctionParameter( aVar );
        if (Reg == "NULL")
        if (Reg == "NULL")
        {
        {
                Reg = GetRegisterFromAutoVar( aVar, yylloc );
                Reg = GetRegisterFromAutoVar( aVar, yylloc );
                I.SetSrc1Address(atoi(Reg.c_str()+1));
                I.SetSrc1Address(atoi(Reg.c_str()+1));
                I.SetSrc1Displace( true );
                I.SetSrc1Displace( true );
        } else {
        } else {
                I.SetSrc1Address(atoi(Reg.c_str()+1));
                I.SetSrc1Address(atoi(Reg.c_str()+1));
                I.SetSrc1Displace( false );
                I.SetSrc1Displace( false );
        }
        }
        I.SetSrc1SwizzleX(SWX_X);
        I.SetSrc1SwizzleX(SWX_X);
        I.SetSrc1SwizzleY(SWY_Y);
        I.SetSrc1SwizzleY(SWY_Y);
        I.SetSrc1SwizzleZ(SWZ_Z);
        I.SetSrc1SwizzleZ(SWZ_Z);
        I.SetSrc0Address(0);
        I.SetSrc0Address(0);
        I.SetSrc0SwizzleX(SWX_X);
        I.SetSrc0SwizzleX(SWX_X);
        I.SetSrc0SwizzleY(SWY_X);
        I.SetSrc0SwizzleY(SWY_X);
        I.SetSrc0SwizzleZ(SWZ_X);
        I.SetSrc0SwizzleZ(SWZ_X);
        aInstructions.push_back( I );
        aInstructions.push_back( I );
        I.Clear();
        I.Clear();
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void SetExpressionDestination( std::string aStringDestination, Instruction & I )
void SetExpressionDestination( std::string aStringDestination, Instruction & I )
{
{
                std::string Destination = aStringDestination;
                std::string Destination = aStringDestination;
                //Look for indirect addressing
                //Look for indirect addressing
                if (Destination.find("INDEX") != std::string::npos)
                if (Destination.find("INDEX") != std::string::npos)
                {
                {
                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
                        Destination.erase(Destination.find("INDEX"));
                        Destination.erase(Destination.find("INDEX"));
                        I.SetImm( 0 );
                        I.SetImm( 0 );
                        I.SetCode( EOPERATION_ADD );
                        I.SetCode( EOPERATION_ADD );
                        if (Destination.find(".") != std::string::npos)
                        if (Destination.find(".") != std::string::npos)
                        {
                        {
                                I.ClearWriteChannel();
                                I.ClearWriteChannel();
                                if (Destination.find("x") != std::string::npos)
                                if (Destination.find("x") != std::string::npos)
                                        I.SetWriteChannel(ECHANNEL_X);
                                        I.SetWriteChannel(ECHANNEL_X);
                                if (Destination.find("y") != std::string::npos)
                                if (Destination.find("y") != std::string::npos)
                                        I.SetWriteChannel(ECHANNEL_Y);
                                        I.SetWriteChannel(ECHANNEL_Y);
                                if (Destination.find("z") != std::string::npos)
                                if (Destination.find("z") != std::string::npos)
                                        I.SetWriteChannel(ECHANNEL_Z);
                                        I.SetWriteChannel(ECHANNEL_Z);
                                Destination.erase(Destination.find("."));
                                Destination.erase(Destination.find("."));
                        }
                        }
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
                } else {
                } else {
                        //Look for displament addressing mode
                        //Look for displament addressing mode
                        if (Destination.find("OFFSET") != std::string::npos)
                        if (Destination.find("OFFSET") != std::string::npos)
                        {
                        {
                                Destination.erase(Destination.find("OFFSET"));
                                Destination.erase(Destination.find("OFFSET"));
                                I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
                                I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
                        }
                        }
                        if (Destination.find(".") != std::string::npos)
                        if (Destination.find(".") != std::string::npos)
                        {
                        {
                                I.ClearWriteChannel();
                                I.ClearWriteChannel();
                                if (Destination.find("x") != std::string::npos)
                                if (Destination.find("x") != std::string::npos)
                                        I.SetWriteChannel(ECHANNEL_X);
                                        I.SetWriteChannel(ECHANNEL_X);
                                if (Destination.find("y") != std::string::npos)
                                if (Destination.find("y") != std::string::npos)
                                        I.SetWriteChannel(ECHANNEL_Y);
                                        I.SetWriteChannel(ECHANNEL_Y);
                                if (Destination.find("z") != std::string::npos)
                                if (Destination.find("z") != std::string::npos)
                                        I.SetWriteChannel(ECHANNEL_Z);
                                        I.SetWriteChannel(ECHANNEL_Z);
                                Destination.erase(Destination.find("."));
                                Destination.erase(Destination.find("."));
                        }
                        }
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
                }
                }
}
}
//----------------------------------------------------------
//----------------------------------------------------------
bool SourceNull( std::string aSource )
bool SourceNull( std::string aSource )
{
{
        if (aSource == "NULL")
        if (aSource == "NULL")
                return true;
                return true;
        return false;
        return false;
}
}
//----------------------------------------------------------
//----------------------------------------------------------
void PopulateInstruction( std::string aDestination, std::string aSource1, std::string aSource0, Instruction & I, Theia::Parser::location_type  yylloc, bool aHasLiteral = false, unsigned int aLiteral = 0)
void PopulateInstruction( std::string aDestination, std::string aSource1, std::string aSource0, Instruction & I, Theia::Parser::location_type  yylloc, bool aHasLiteral = false, unsigned int aLiteral = 0)
{
{
        bool DestinationHasOffset  = false;
        bool DestinationHasOffset  = false;
        bool DetinationHasIndex    = false;
        bool DetinationHasIndex    = false;
        bool Source0HasOffset      = false;
        bool Source0HasOffset      = false;
        bool Source1HasOffset      = false;
        bool Source1HasOffset      = false;
        bool Source1HasIndex       = false;
        bool Source1HasIndex       = false;
        bool Source0HasIndex       = false;
        bool Source0HasIndex       = false;
        if (aDestination.find("INDEX") != std::string::npos)
        if (aDestination.find("INDEX") != std::string::npos)
        {
        {
                std::string ArrayIndex = aDestination.substr(aDestination.find("INDEX")+5);
                std::string ArrayIndex = aDestination.substr(aDestination.find("INDEX")+5);
                aSource1 = ArrayIndex;
                aSource1 = ArrayIndex;
                DetinationHasIndex      = true;
                DetinationHasIndex      = true;
        }
        }
        if (aSource1.find("INDEX") != std::string::npos)
        if (aSource1.find("INDEX") != std::string::npos)
                Source1HasIndex = true;
                Source1HasIndex = true;
        if (aSource0.find("INDEX") != std::string::npos)
        if (aSource0.find("INDEX") != std::string::npos)
                Source0HasIndex = true;
                Source0HasIndex = true;
        if (aDestination.find("OFFSET") != std::string::npos)
        if (aDestination.find("OFFSET") != std::string::npos)
                DestinationHasOffset = true;
                DestinationHasOffset = true;
        if      (aSource0.find("OFFSET") != std::string::npos)
        if      (aSource0.find("OFFSET") != std::string::npos)
                Source0HasOffset = true;
                Source0HasOffset = true;
        if      (aSource1.find("OFFSET") != std::string::npos)
        if      (aSource1.find("OFFSET") != std::string::npos)
                Source1HasOffset = true;
                Source1HasOffset = true;
        if (IsSwizzled( aSource1 ))
        if (IsSwizzled( aSource1 ))
                SetSwizzleAndSign( 1, aSource1,  I );
                SetSwizzleAndSign( 1, aSource1,  I );
        I.SetSrc1Address( atoi( aSource1.c_str()+1 ) );
        I.SetSrc1Address( atoi( aSource1.c_str()+1 ) );
        if (IsSwizzled( aSource0 ))
        if (IsSwizzled( aSource0 ))
                SetSwizzleAndSign( 0, aSource0,  I );
                SetSwizzleAndSign( 0, aSource0,  I );
        I.SetSrc0Address( atoi( aSource0.c_str()+1 ) );
        I.SetSrc0Address( atoi( aSource0.c_str()+1 ) );
        //Fisrt take care of the destination write channel
        //Fisrt take care of the destination write channel
        if (aDestination.find(".") != std::string::npos)
        if (aDestination.find(".") != std::string::npos)
                {
                {
                        I.ClearWriteChannel();
                        I.ClearWriteChannel();
                        if (aDestination.find("x") != std::string::npos)
                        if (aDestination.find("x") != std::string::npos)
                                I.SetWriteChannel(ECHANNEL_X);
                                I.SetWriteChannel(ECHANNEL_X);
                        if (aDestination.find("y") != std::string::npos)
                        if (aDestination.find("y") != std::string::npos)
                                I.SetWriteChannel(ECHANNEL_Y);
                                I.SetWriteChannel(ECHANNEL_Y);
                        if (aDestination.find("z") != std::string::npos)
                        if (aDestination.find("z") != std::string::npos)
                                I.SetWriteChannel(ECHANNEL_Z);
                                I.SetWriteChannel(ECHANNEL_Z);
                        aDestination.erase(aDestination.find("."));
                        aDestination.erase(aDestination.find("."));
        } else {
        } else {
                I.SetWriteChannel(ECHANNEL_XYZ);
                I.SetWriteChannel(ECHANNEL_XYZ);
        }
        }
        //Now set the destination Index
        //Now set the destination Index
        I.SetDestinationAddress( atoi(aDestination.c_str()+1) );
        I.SetDestinationAddress( atoi(aDestination.c_str()+1) );
        //Now determine the addressing mode
        //Now determine the addressing mode
        //Simple addressing modes
        //Simple addressing modes
        if (!aHasLiteral &&     !DetinationHasIndex && !Source0HasIndex && !Source1HasIndex)
        if (!aHasLiteral &&     !DetinationHasIndex && !Source0HasIndex && !Source1HasIndex)
        {
        {
                I.SetAddressingMode( DestinationHasOffset,Source1HasOffset,Source0HasOffset);
                I.SetAddressingMode( DestinationHasOffset,Source1HasOffset,Source0HasOffset);
                return;
                return;
        }
        }
        I.SetImmBit( true ); //This is to set the IMM bit = 1, may be overwritten latter
        I.SetImmBit( true ); //This is to set the IMM bit = 1, may be overwritten latter
        //Complex addressing modes
        //Complex addressing modes
        if
        if
        (
        (
        aHasLiteral &&
        aHasLiteral &&
        !SourceNull( aSource0 ) &&
        !SourceNull( aSource0 ) &&
        !Source0HasOffset &&
        !Source0HasOffset &&
        !Source1HasOffset &&
        !Source1HasOffset &&
        !DestinationHasOffset
        !DestinationHasOffset
        )
        )
        {
        {
                I.SetAddressingMode( false,false,false);
                I.SetAddressingMode( false,false,false);
                I.SetImm( aLiteral );
                I.SetImm( aLiteral );
        }
        }
        else
        else
        if
        if
        (
        (
        aHasLiteral &&
        aHasLiteral &&
        !SourceNull( aSource0 ) &&
        !SourceNull( aSource0 ) &&
        Source0HasOffset &&
        Source0HasOffset &&
        !Source0HasIndex &&
        !Source0HasIndex &&
        DestinationHasOffset
        DestinationHasOffset
        )
        )
        {
        {
                I.SetAddressingMode( false,false,true);
                I.SetAddressingMode( false,false,true);
                I.SetImm( aLiteral );
                I.SetImm( aLiteral );
        }
        }
        else
        else
        if
        if
        (
        (
        !aHasLiteral &&
        !aHasLiteral &&
        !SourceNull( aSource1 ) &&
        !SourceNull( aSource1 ) &&
        !Source1HasOffset &&
        !Source1HasOffset &&
        !SourceNull( aSource0 ) &&
        !SourceNull( aSource0 ) &&
        Source0HasOffset &&
        Source0HasOffset &&
        Source0HasIndex &&
        Source0HasIndex &&
        DestinationHasOffset
        DestinationHasOffset
        )
        )
        {
        {
                I.SetAddressingMode( false,true,false);
                I.SetAddressingMode( false,true,false);
        }
        }
        else
        else
        if
        if
        (
        (
        !aHasLiteral &&
        !aHasLiteral &&
        !Source1HasOffset &&
        !Source1HasOffset &&
        !SourceNull( aSource0 ) &&
        !SourceNull( aSource0 ) &&
        Source0HasOffset &&
        Source0HasOffset &&
        !Source0HasIndex &&
        !Source0HasIndex &&
        DestinationHasOffset &&
        DestinationHasOffset &&
        DetinationHasIndex
        DetinationHasIndex
        )
        )
        {
        {
                I.SetAddressingMode( false,true,true);
                I.SetAddressingMode( false,true,true);
        }
        }
        else
        else
        if
        if
        (
        (
        aHasLiteral &&
        aHasLiteral &&
        SourceNull( aSource0 ) &&
        SourceNull( aSource0 ) &&
        !DestinationHasOffset &&
        !DestinationHasOffset &&
        !DetinationHasIndex
        !DetinationHasIndex
        )
        )
        {
        {
                I.SetAddressingMode( true,false,false);
                I.SetAddressingMode( true,false,false);
                I.SetImm( aLiteral );
                I.SetImm( aLiteral );
        }
        }
        else
        else
        if
        if
        (
        (
        aHasLiteral &&
        aHasLiteral &&
        SourceNull( aSource0 ) &&
        SourceNull( aSource0 ) &&
        DestinationHasOffset &&
        DestinationHasOffset &&
        !DetinationHasIndex
        !DetinationHasIndex
        )
        )
        {
        {
                I.SetAddressingMode( true,false,true);
                I.SetAddressingMode( true,false,true);
                I.SetImm( aLiteral );
                I.SetImm( aLiteral );
        }
        }
        else
        else
        if
        if
        (
        (
        !aHasLiteral &&
        !aHasLiteral &&
        Source1HasOffset &&
        Source1HasOffset &&
        Source1HasIndex &&
        Source1HasIndex &&
        SourceNull( aSource0 ) &&
        SourceNull( aSource0 ) &&
        DestinationHasOffset &&
        DestinationHasOffset &&
        !DetinationHasIndex
        !DetinationHasIndex
        )
        )
        {
        {
                I.SetAddressingMode( true,true,false);
                I.SetAddressingMode( true,true,false);
        }
        }
        else
        else
        if
        if
        (
        (
        !aHasLiteral &&
        !aHasLiteral &&
        Source1HasOffset &&
        Source1HasOffset &&
        Source1HasIndex &&
        Source1HasIndex &&
        Source0HasOffset &&
        Source0HasOffset &&
        !Source0HasIndex &&
        !Source0HasIndex &&
        DestinationHasOffset &&
        DestinationHasOffset &&
        !DetinationHasIndex
        !DetinationHasIndex
        )
        )
        {
        {
                I.SetAddressingMode( true,true,true);
                I.SetAddressingMode( true,true,true);
        } else {
        } else {
                        std::ostringstream ret;
                        std::ostringstream ret;
                        ret << "Could not determine addressing mode  at line " << yylloc << " \n";
                        ret << "Could not determine addressing mode  at line " << yylloc << " \n";
                        throw ret.str();
                        throw ret.str();
        }
        }
}
}
//-------------------------------------------------------------
//-------------------------------------------------------------
void PopulateBoolean(EBRANCHTYPE aBranchType, std::string Source1, std::string Source0, Instruction & I, std::vector & aInstructions, Theia::Parser::location_type & yylloc )
void PopulateBoolean(EBRANCHTYPE aBranchType, std::string Source1, std::string Source0, Instruction & I, std::vector & aInstructions, Theia::Parser::location_type & yylloc )
{
{
                                        if (Source0.find("R") == std::string::npos)
                                        if (Source0.find("R") == std::string::npos)
                                        {
                                        {
                                                I.mSourceLine = GetCurrentLineNumber( yylloc );
                                                I.mSourceLine = GetCurrentLineNumber( yylloc );
                                                I.SetCode( EOPERATION_ADD );
                                                I.SetCode( EOPERATION_ADD );
                                                unsigned int TempRegIndex  = GetFreeTempRegister();
                                                unsigned int TempRegIndex  = GetFreeTempRegister();
                                                I.SetDestinationAddress( TempRegIndex );
                                                I.SetDestinationAddress( TempRegIndex );
                                                unsigned int ImmediateValue;
                                                unsigned int ImmediateValue;
                                                std::string StringHex = Source0;
                                                std::string StringHex = Source0;
                                                std::stringstream ss;
                                                std::stringstream ss;
                                                ss << std::hex << StringHex;
                                                ss << std::hex << StringHex;
                                                ss >> ImmediateValue;
                                                ss >> ImmediateValue;
                                                I.SetImm( ImmediateValue );
                                                I.SetImm( ImmediateValue );
                                                I.SetDestZero( true );
                                                I.SetDestZero( true );
                                                I.SetSrc0Displace( true );
                                                I.SetSrc0Displace( true );
                                                I.SetWriteChannel(ECHANNEL_X);
                                                I.SetWriteChannel(ECHANNEL_X);
                                                I.SetWriteChannel(ECHANNEL_Y);
                                                I.SetWriteChannel(ECHANNEL_Y);
                                                I.SetWriteChannel(ECHANNEL_Z);
                                                I.SetWriteChannel(ECHANNEL_Z);
                                                aInstructions.push_back(I);
                                                aInstructions.push_back(I);
                                                I.Clear();
                                                I.Clear();
                                                std::stringstream ss2;
                                                std::stringstream ss2;
                                                ss2 << "R" << TempRegIndex;
                                                ss2 << "R" << TempRegIndex;
                                                ss2 >> Source0;
                                                ss2 >> Source0;
                                                Source0 += " OFFSET ";
                                                Source0 += " OFFSET ";
                                        }
                                        }
                                        else
                                        else
                                                I.mSourceLine = GetCurrentLineNumber( yylloc );
                                                I.mSourceLine = GetCurrentLineNumber( yylloc );
                                        I.SetCode( EOPERATION_ADD );
                                        I.SetCode( EOPERATION_ADD );
                                        I.SetSrc0SignX( true );
                                        I.SetSrc0SignX( true );
                                        I.SetSrc0SignY( true );
                                        I.SetSrc0SignY( true );
                                        I.SetSrc0SignZ( true );
                                        I.SetSrc0SignZ( true );
                                        I.SetBranchFlag( true );
                                        I.SetBranchFlag( true );
                                        I.ClearWriteChannel();
                                        I.ClearWriteChannel();
                                        I.SetBranchType( aBranchType );
                                        I.SetBranchType( aBranchType );
                                        PopulateSourceRegisters( Source1, Source0, I, aInstructions);
                                        PopulateSourceRegisters( Source1, Source0, I, aInstructions);
                                        aInstructions.push_back(I);
                                        aInstructions.push_back(I);
                                        I.Clear();
                                        I.Clear();
                                        ////std::cout << "pushing code at position " << (mInstructions.size() - 1) << "\n";
                                        ////std::cout << "pushing code at position " << (mInstructions.size() - 1) << "\n";
                                        gBranchStack.push_back(aInstructions.size() - 1);
                                        gBranchStack.push_back(aInstructions.size() - 1);
                                        ResetTempRegisterIndex();
                                        ResetTempRegisterIndex();
}
}
//-------------------------------------------------------------
//-------------------------------------------------------------
        // Prototype for the yylex function
        // Prototype for the yylex function
        static int yylex(Theia::Parser::semantic_type * yylval,
        static int yylex(Theia::Parser::semantic_type * yylval,
                         Theia::Parser::location_type * yylloc,
                         Theia::Parser::location_type * yylloc,
                         Theia::Scanner &scanner);
                         Theia::Scanner &scanner);
}
}
%token AUTO RETURN FUNCTION JMP EXIT EQUAL NOT_EQUAL GREATER_THAN LESS_THAN LESS_OR_EQUAL_THAN GREATER_OR_EQUAL_THAN IF ELSE OPEN_ROUND_BRACE CLOSE_ROUND_BRACE OPEN_BRACE CLOSE_BRACE ASSIGN DIV MUL ADD DECCONST HEXCONST BINCONST EOS DOT MINUS TK_X TK_Y TK_Z TK_N REG
%token AUTO RETURN FUNCTION JMP EXIT EQUAL NOT_EQUAL GREATER_THAN LESS_THAN LESS_OR_EQUAL_THAN GREATER_OR_EQUAL_THAN IF ELSE OPEN_ROUND_BRACE CLOSE_ROUND_BRACE OPEN_BRACE CLOSE_BRACE ASSIGN DIV MUL ADD DECCONST HEXCONST BINCONST EOS DOT MINUS TK_X TK_Y TK_Z TK_N REG
%token IDENTIFIER SQRT SCALE UNSCALE USING FIXED_POINT COMMA OPEN_SQUARE_BRACE CLOSE_SQUARE_BRACE WHILE ADD_EQ THREAD START BITWISE_AND BITWISE_OR OUT
%token IDENTIFIER SQRT SCALE UNSCALE USING FIXED_POINT COMMA OPEN_SQUARE_BRACE CLOSE_SQUARE_BRACE WHILE ADD_EQ THREAD START BITWISE_AND BITWISE_OR OUT IN
%%
%%
statement_list: //empty
statement_list: //empty
        |
        |
        statement_list statement
        statement_list statement
        |
        |
        statement
        statement
        ;
        ;
statement
statement
        :
        :
        AUTO auto_var_list EOS
        AUTO auto_var_list EOS
        |
        |
        USING FIXED_POINT EOS
        USING FIXED_POINT EOS
        {
        {
                mGenerateFixedPointArithmetic = true;
                mGenerateFixedPointArithmetic = true;
        }
        }
        |
        |
        EXIT EOS
        EXIT EOS
        {
        {
                //Insert a stupid NOP before the exit... is a bug but easier to just patch like this...
                //Insert a stupid NOP before the exit... is a bug but easier to just patch like this...
                I.Clear();
                I.Clear();
                I.mComment = "NOP";
                I.mComment = "NOP";
                I.SetCode( EOPERATION_NOP );
                I.SetCode( EOPERATION_NOP );
                mInstructions.push_back(I);
                mInstructions.push_back(I);
                I.Clear();
                I.Clear();
                I.SetEofFlag(true);
                I.SetEofFlag(true);
                I.mComment = "Set the Exit bit";
                I.mComment = "Set the Exit bit";
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                mInstructions.push_back(I);
                mInstructions.push_back(I);
                I.Clear();
                I.Clear();
        }
        }
        |
        |
        RETURN expression EOS
        RETURN expression EOS
        {
        {
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                // This means this that the expression was just a constant.
                // This means this that the expression was just a constant.
                // No operations were inserted
                // No operations were inserted
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                if (gInsertedInstructions == 0)
                if (gInsertedInstructions == 0)
                {
                {
                        I.Clear();
                        I.Clear();
                        I.SetCode(EOPERATION_ADD);
                        I.SetCode(EOPERATION_ADD);
                        I.mComment ="Set the return value";
                        I.mComment ="Set the return value";
                        if ($3.find("R") != std::string::npos)
                        if ($3.find("R") != std::string::npos)
                        {
                        {
                                PopulateInstruction( "R1", $2,"R0 . X X X",I,yylloc);
                                PopulateInstruction( "R1", $2,"R0 . X X X",I,yylloc);
                        }
                        }
                        else
                        else
                        {
                        {
                                unsigned int ImmediateValue = 0;
                                unsigned int ImmediateValue = 0;
                                std::string StringHex = $3;
                                std::string StringHex = $3;
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << std::hex << StringHex;
                                ss << std::hex << StringHex;
                                ss >> ImmediateValue;
                                ss >> ImmediateValue;
                                PopulateInstruction( "R1", $3,"NULL",I, yylloc, true, ImmediateValue);
                                PopulateInstruction( "R1", $3,"NULL",I, yylloc, true, ImmediateValue);
                        }
                        }
                        mInstructions.push_back(I);
                        mInstructions.push_back(I);
                        I.Clear();
                        I.Clear();
                } else {
                } else {
                        mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc);
                        mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc);
                        gInsertedInstructions = 0;
                        gInsertedInstructions = 0;
                        mInstructions.back().mComment ="Assigning return value";
                        mInstructions.back().mComment ="Assigning return value";
                        mInstructions.back().SetDestinationAddress( RETURN_VALUE_REGISTER );
                        mInstructions.back().SetDestinationAddress( RETURN_VALUE_REGISTER );
                }
                }
                ResetTempRegisterIndex();
                ResetTempRegisterIndex();
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "Restore previous function frame offset";
                I.mComment = "Restore previous function frame offset";
                I.ClearWriteChannel();
                I.ClearWriteChannel();
                I.SetWriteChannel(ECHANNEL_X);
                I.SetWriteChannel(ECHANNEL_X);
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
                I.SetSrc1SwizzleX(SWX_Y);
                I.SetSrc1SwizzleX(SWX_Y);
                I.SetSrc1SwizzleY(SWY_Y);
                I.SetSrc1SwizzleY(SWY_Y);
                I.SetSrc1SwizzleZ(SWZ_Y);
                I.SetSrc1SwizzleZ(SWZ_Y);
                I.SetSrc0Address(0);
                I.SetSrc0Address(0);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                mInstructions.push_back( I );
                mInstructions.push_back( I );
                I.Clear();
                I.Clear();
                //Now return
                //Now return
                I.SetImm( 0 );
                I.SetImm( 0 );
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "return from function";
                I.mComment = "return from function";
                I.SetBranchFlag( true );
                I.SetBranchFlag( true );
                I.SetBranchType( EBRANCH_ALWAYS );
                I.SetBranchType( EBRANCH_ALWAYS );
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
                mInstructions.push_back(I);
                mInstructions.push_back(I);
                I.Clear();
                I.Clear();
        }
        }
        |
        |
        RETURN EOS
        RETURN EOS
        {
        {
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "Restore previous function frame offset";
                I.mComment = "Restore previous function frame offset";
                I.SetWriteChannel(ECHANNEL_X);
                I.SetWriteChannel(ECHANNEL_X);
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
                I.SetSrc1SwizzleX(SWX_Y);
                I.SetSrc1SwizzleX(SWX_Y);
                I.SetSrc1SwizzleY(SWY_Y);
                I.SetSrc1SwizzleY(SWY_Y);
                I.SetSrc1SwizzleZ(SWZ_Y);
                I.SetSrc1SwizzleZ(SWZ_Y);
                I.SetSrc0Address(0);
                I.SetSrc0Address(0);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                mInstructions.push_back( I );
                mInstructions.push_back( I );
                I.Clear();
                I.Clear();
                I.SetImm( 0 );
                I.SetImm( 0 );
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "return from function";
                I.mComment = "return from function";
                I.SetBranchFlag( true );
                I.SetBranchFlag( true );
                I.SetBranchType( EBRANCH_ALWAYS );
                I.SetBranchType( EBRANCH_ALWAYS );
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
                mInstructions.push_back(I);
                mInstructions.push_back(I);
                I.Clear();
                I.Clear();
        }
        }
         |
         |
         left_hand_side ADD_EQ constant EOS
         left_hand_side ADD_EQ constant EOS
          {
          {
                 I.mSourceLine = GetCurrentLineNumber( yylloc );
                 I.mSourceLine = GetCurrentLineNumber( yylloc );
                 I.SetCode( EOPERATION_ADD );
                 I.SetCode( EOPERATION_ADD );
                 SetDestinationFromRegister( $1, I , true);
                 SetDestinationFromRegister( $1, I , true);
                 unsigned int ImmediateValue;
                 unsigned int ImmediateValue;
                 std::string StringHex = $3;
                 std::string StringHex = $3;
                 std::stringstream ss;
                 std::stringstream ss;
                 ss << std::hex << StringHex;
                 ss << std::hex << StringHex;
                 ss >> ImmediateValue;
                 ss >> ImmediateValue;
                 I.SetImm( ImmediateValue );
                 I.SetImm( ImmediateValue );
                 I.SetDestZero( false );
                 I.SetDestZero( false );
                 mInstructions.push_back( I );
                 mInstructions.push_back( I );
                 I.Clear();
                 I.Clear();
         }
         }
         |
         |
         left_hand_side MINUS MINUS EOS
         left_hand_side MINUS MINUS EOS
         {
         {
                I.mSourceLine = GetCurrentLineNumber( yylloc );
                I.mSourceLine = GetCurrentLineNumber( yylloc );
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                SetDestinationFromRegister( $1, I, false );
                SetDestinationFromRegister( $1, I, false );
                I.SetSrc0SignX( true );
                I.SetSrc0SignX( true );
                I.SetSrc0SignY( true );
                I.SetSrc0SignY( true );
                I.SetSrc0SignZ( true );
                I.SetSrc0SignZ( true );
                std::string Destination = $1;
                std::string Destination = $1;
                if (Destination.find("OFFSET") != std::string::npos)
                if (Destination.find("OFFSET") != std::string::npos)
                {
                {
                        I.SetSrc1Displace( true );
                        I.SetSrc1Displace( true );
                        Destination.erase(Destination.find("OFFSET"));
                        Destination.erase(Destination.find("OFFSET"));
                }
                }
                if (Destination.find(".") != std::string::npos)
                if (Destination.find(".") != std::string::npos)
                        Destination.erase(Destination.find("."));
                        Destination.erase(Destination.find("."));
                I.SetSrc1Address(atoi(Destination.c_str()+1));
                I.SetSrc1Address(atoi(Destination.c_str()+1));
                I.SetSrc0Address(0);
                I.SetSrc0Address(0);
                I.SetSrc0SwizzleX(SWX_Y);
                I.SetSrc0SwizzleX(SWX_Y);
                I.SetSrc0SwizzleY(SWY_Y);
                I.SetSrc0SwizzleY(SWY_Y);
                I.SetSrc0SwizzleZ(SWZ_Y);
                I.SetSrc0SwizzleZ(SWZ_Y);
                mInstructions.push_back( I );
                mInstructions.push_back( I );
                I.Clear();
                I.Clear();
         }
         }
         |
         |
         left_hand_side ADD ADD EOS
         left_hand_side ADD ADD EOS
         {
         {
                I.mSourceLine = GetCurrentLineNumber( yylloc );
                I.mSourceLine = GetCurrentLineNumber( yylloc );
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                SetDestinationFromRegister( $1, I, false );
                SetDestinationFromRegister( $1, I, false );
                std::string Destination = $1;
                std::string Destination = $1;
                if (Destination.find("OFFSET") != std::string::npos)
                if (Destination.find("OFFSET") != std::string::npos)
                {
                {
                        I.SetSrc1Displace( true );
                        I.SetSrc1Displace( true );
                        Destination.erase(Destination.find("OFFSET"));
                        Destination.erase(Destination.find("OFFSET"));
                }
                }
                if (Destination.find(".") != std::string::npos)
                if (Destination.find(".") != std::string::npos)
                        Destination.erase(Destination.find("."));
                        Destination.erase(Destination.find("."));
                I.SetSrc1Address(atoi(Destination.c_str()+1));
                I.SetSrc1Address(atoi(Destination.c_str()+1));
                I.SetSrc0Address(0);
                I.SetSrc0Address(0);
                I.SetSrc0SwizzleX(SWX_Y);
                I.SetSrc0SwizzleX(SWX_Y);
                I.SetSrc0SwizzleY(SWY_Y);
                I.SetSrc0SwizzleY(SWY_Y);
                I.SetSrc0SwizzleZ(SWZ_Y);
                I.SetSrc0SwizzleZ(SWZ_Y);
                mInstructions.push_back( I );
                mInstructions.push_back( I );
                I.Clear();
                I.Clear();
         }
         }
         |
         |
         left_hand_side ASSIGN expression  EOS
         left_hand_side ASSIGN expression  EOS
        {
        {
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
 
                // This means this that the expression will read from the T memory
 
                // variable index
 
                // For example:
 
                //          vector MyAddress,MyReadValue;
 
                //          MyReadValue = in [ MyAddress ];
 
                //
 
                //////////////////////////////////////////////////////////////////////////////
 
 
 
                DCOUT << $3 << " YYY \n";
 
                if ($3.find("IN") != std::string::npos )
 
                {
 
 
 
                        std::string ReadAddress = $3;
 
 
 
                        std::string SourceAddrRegister = ReadAddress.substr(ReadAddress.find("INDEX")+5);
 
                        DCOUT << "!!!!!!!!!!!!!!!!!   " << ReadAddress << "\n";
 
                        ReadAddress.erase(0,ReadAddress.find("IN")+3);
 
                        DCOUT << "!!!!!!!!!!!!!!!!!   " << ReadAddress << "\n";
 
 
 
                        I.SetDestZero( true ); //Use indexing for DST
 
                        I.SetWriteChannel(ECHANNEL_XYZ);
 
 
 
 
 
                        PopulateSourceRegisters( ReadAddress, "R0", I, mInstructions );
 
 
 
                        SetDestinationFromRegister( $1, I, false );
 
                        I.mSourceLine = GetCurrentLineNumber(yylloc);
 
                        I.SetCode( EOPERATION_IO );
 
                        I.SetIOOperation( EIO_TMREAD );
 
 
 
 
 
                        mInstructions.push_back( I );
 
                        I.Clear();
 
                        ResetTempRegisterIndex();
 
                        goto LABEL_EXPRESSION_DONE;
 
                }
 
                //////////////////////////////////////////////////////////////////////////////
                // This means this that the expression will write into the output memory
                // This means this that the expression will write into the output memory
                // constant index
                // constant index
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                if ($1.find("OUT") != std::string::npos && $1.find("INDEX") == std::string::npos )
                if ($1.find("OUT") != std::string::npos && $1.find("INDEX") == std::string::npos )
                {
                {
                        //PopulateInstruction( "R0", "R0 . X X X",$3,I,yylloc);
                        //PopulateInstruction( "R0", "R0 . X X X",$3,I,yylloc);
 
 
                        I.SetCode(EOPERATION_OUT);
                        I.SetCode(EOPERATION_IO);
 
                        I.SetIOOperation( EIO_OMWRITE );
 
 
                        $1.erase($1.find("OUT"),3);
                        $1.erase($1.find("OUT"),3);
                        unsigned int ImmediateValue;
                        unsigned int ImmediateValue;
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << std::hex << $1;
                        ss << std::hex << $1;
                        ss >> ImmediateValue;
                        ss >> ImmediateValue;
                        PopulateInstruction( $3, "R0 OFFSET", "R0 OFFSET", I, yylloc, true, ImmediateValue );
                        PopulateInstruction( $3, "R0 OFFSET", "R0 OFFSET", I, yylloc, true, ImmediateValue );
                        #ifdef DEBUG
                        #ifdef DEBUG
                        I.PrintFields();
                        I.PrintFields();
                        #endif
                        #endif
                        mInstructions.push_back(I);
                        mInstructions.push_back(I);
                        I.Clear();
                        I.Clear();
                        ResetTempRegisterIndex();
                        ResetTempRegisterIndex();
                        goto LABEL_EXPRESSION_DONE;
                        goto LABEL_EXPRESSION_DONE;
                }
                }
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                // This means this that the expression will write into the output memory
                // This means this that the expression will write into the output memory
                // variable index
                // variable index
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                if ($1.find("OUT") != std::string::npos && $1.find("INDEX") != std::string::npos )
                if ($1.find("OUT") != std::string::npos && $1.find("INDEX") != std::string::npos )
                {
                {
                        std::string Destination = $1;
                        std::string Destination = $1;
                        DCOUT << "!!!!!!!!!!!!!!!!!Destination " << Destination << "\n";
                        DCOUT << "!!!!!!!!!!!!!!!!!Destination " << Destination << "\n";
                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
                        Destination.erase(Destination.find("INDEX"));
                        Destination.erase(Destination.find("INDEX"));
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetWriteChannel(ECHANNEL_XYZ);
                //      PopulateSourceRegisters( IndexRegister + " OFFSET ", $3, I, mInstructions );
                //      PopulateSourceRegisters( IndexRegister + " OFFSET ", $3, I, mInstructions );
                        PopulateSourceRegisters( IndexRegister, $3, I, mInstructions );
                        PopulateSourceRegisters( IndexRegister, $3, I, mInstructions );
                        //I.SetImm( 0 );
                        //I.SetImm( 0 );
                        I.SetCode( EOPERATION_OUT );
                        I.SetCode( EOPERATION_IO );
                        std::string Source0 = $3;
                        I.SetIOOperation( EIO_OMWRITE );
                        DCOUT << "!!!!!!!!!!!!!!!!!Source0 '" << Source0 << "'\n";
 
                /*      if (Source0.find("OFFSET") != std::string::npos)
 
                        {
 
                                        Source0.erase(Source0.find("OFFSET"));
 
                                        I.SetSrc0Displace(1);
 
                        }
 
                        I.SetSrc1Address(atoi(IndexRegister.c_str()+1));
 
                        I.SetSrc0Address(atoi(Source0.c_str()+1));*/
 
 
 
                /*      if (Destination.find(".") != std::string::npos)
 
                        {
 
                                I.ClearWriteChannel();
 
                                if (Destination.find("x") != std::string::npos)
 
                                        I.SetWriteChannel(ECHANNEL_X);
 
                                if (Destination.find("y") != std::string::npos)
 
                                        I.SetWriteChannel(ECHANNEL_Y);
 
                                if (Destination.find("z") != std::string::npos)
 
                                        I.SetWriteChannel(ECHANNEL_Z);
 
 
 
                                Destination.erase(Destination.find("."));
 
 
 
                        }
 
 
 
                        std::string Source0 = $3;
                        std::string Source0 = $3;
                        if (Source0.find("OFFSET") != std::string::npos)
                        DCOUT << "!!!!!!!!!!!!!!!!!Source0 '" << Source0 << "'\n";
                        {
 
                                        Source0.erase(Source0.find("OFFSET"));
 
                                        I.SetSrc0Displace(1);
 
                        }
 
                        I.SetSrc1Address(atoi(IndexRegister.c_str()+1));
 
                        I.SetSrc0Address(atoi(Source0.c_str()+1));
 
 
 
 
 
                                //      I.SetSrc0Address(mInstructions.back().GetDestinationAddress());
 
                        I.SetDestZero(0);
 
                        I.SetSrc1Displace(1);
 
                        I.SetSrc0Displace(1);
 
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );*/
 
                        mInstructions.push_back( I );
                        mInstructions.push_back( I );
                        I.Clear();
                        I.Clear();
                        ResetTempRegisterIndex();
                        ResetTempRegisterIndex();
                        goto LABEL_EXPRESSION_DONE;
                        goto LABEL_EXPRESSION_DONE;
                }
                }
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                // This means this that the expression was just a constant.
                // This means this that the expression was just a constant.
                // No operations were inserted
                // No operations were inserted
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                if (gInsertedInstructions == 0)
                if (gInsertedInstructions == 0)
                {
                {
                        I.Clear();
                        I.Clear();
                        I.SetCode(EOPERATION_ADD);
                        I.SetCode(EOPERATION_ADD);
                        I.mSourceLine = GetCurrentLineNumber(yylloc);
                        I.mSourceLine = GetCurrentLineNumber(yylloc);
                        if ($3.find("R") != std::string::npos)
                        if ($3.find("R") != std::string::npos)
                        {
                        {
                        // case 1:
                        // case 1:
                        // foo = 0;        //$$ = R0 . X X X
                        // foo = 0;        //$$ = R0 . X X X
                        /*      SetDestinationFromRegister( $1, I, false );
                        /*      SetDestinationFromRegister( $1, I, false );
                                PopulateSourceRegisters( $3, "R0 . X X X", I, mInstructions);*/
                                PopulateSourceRegisters( $3, "R0 . X X X", I, mInstructions);*/
                                PopulateInstruction( $1, "R0 . X X X",$3,I,yylloc);
                                PopulateInstruction( $1, "R0 . X X X",$3,I,yylloc);
                        } else {
                        } else {
                        // case 2:
                        // case 2:
                        // foo = 0xcafe;  //$$ = 0xcafe
                        // foo = 0xcafe;  //$$ = 0xcafe
                                SetDestinationFromRegister( $1, I, true );
                                SetDestinationFromRegister( $1, I, true );
                                unsigned int ImmediateValue = 0;
                                unsigned int ImmediateValue = 0;
                                std::string StringHex = $3;
                                std::string StringHex = $3;
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << std::hex << StringHex;
                                ss << std::hex << StringHex;
                                ss >> ImmediateValue;
                                ss >> ImmediateValue;
                                PopulateInstruction( $1, $3,"NULL",I, yylloc, true, ImmediateValue);
                                PopulateInstruction( $1, $3,"NULL",I, yylloc, true, ImmediateValue);
                        }
                        }
                        std::string strConstant = $3;
                        std::string strConstant = $3;
                        mInstructions.push_back(I);
                        mInstructions.push_back(I);
                        I.Clear();
                        I.Clear();
                        ResetTempRegisterIndex();
                        ResetTempRegisterIndex();
                        goto LABEL_EXPRESSION_DONE;
                        goto LABEL_EXPRESSION_DONE;
                }
                }
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                // This means that the last instruction which was inserted was a tripple
                // This means that the last instruction which was inserted was a tripple
                // constant assignement, like foo = (1,2,3)
                // constant assignement, like foo = (1,2,3)
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                if (mInstructions.back().mBisonFlagTrippleConstAssign)
                if (mInstructions.back().mBisonFlagTrippleConstAssign)
                {
                {
                        unsigned int LastIndex = mInstructions.size() - 1;
                        unsigned int LastIndex = mInstructions.size() - 1;
                        mInstructions[LastIndex].SetDestinationAddress(atoi($1.c_str()+1));
                        mInstructions[LastIndex].SetDestinationAddress(atoi($1.c_str()+1));
                        mInstructions[LastIndex-1].SetDestinationAddress(atoi($1.c_str()+1));
                        mInstructions[LastIndex-1].SetDestinationAddress(atoi($1.c_str()+1));
                        mInstructions[LastIndex-2].SetDestinationAddress(atoi($1.c_str()+1));
                        mInstructions[LastIndex-2].SetDestinationAddress(atoi($1.c_str()+1));
                        mInstructions[LastIndex-2].mSourceLine = GetCurrentLineNumber( yylloc );
                        mInstructions[LastIndex-2].mSourceLine = GetCurrentLineNumber( yylloc );
                        if($1.find("OFFSET") == std::string::npos)
                        if($1.find("OFFSET") == std::string::npos)
                        {
                        {
                                mInstructions[LastIndex].SetAddressingMode(true,false,false);
                                mInstructions[LastIndex].SetAddressingMode(true,false,false);
                                mInstructions[LastIndex-1].SetAddressingMode(true,false,false);
                                mInstructions[LastIndex-1].SetAddressingMode(true,false,false);
                                mInstructions[LastIndex-2].SetAddressingMode(true,false,false);
                                mInstructions[LastIndex-2].SetAddressingMode(true,false,false);
                        }
                        }
                        ResetTempRegisterIndex();
                        ResetTempRegisterIndex();
                        goto LABEL_EXPRESSION_DONE;
                        goto LABEL_EXPRESSION_DONE;
                }
                }
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                // Handle the case where the destination is an array of vector
                // Handle the case where the destination is an array of vector
                // ej: R = v1[ i ]  + V2
                // ej: R = v1[ i ]  + V2
                //////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////
                if (I.GetOperation() == 0 && $3.find("array_element") != std::string::npos)
                if (I.GetOperation() == 0 && $3.find("array_element") != std::string::npos)
                {
                {
                        //No operation meaning the the expression only has a single variable
                        //No operation meaning the the expression only has a single variable
                        //See if the expression returned is an array_element
                        //See if the expression returned is an array_element
                        if ($3.find("array_element") != std::string::npos)
                        if ($3.find("array_element") != std::string::npos)
                        {
                        {
                                ////std::cout << "expression is an array element\n\n";
                                ////std::cout << "expression is an array element\n\n";
                                std::string Index = $3.substr($3.find("array_element"));
                                std::string Index = $3.substr($3.find("array_element"));
                                Index = Index.substr(Index.find_first_not_of("array_element R"));
                                Index = Index.substr(Index.find_first_not_of("array_element R"));
                                SetIndexRegister( atoi(Index.c_str()), mInstructions );
                                SetIndexRegister( atoi(Index.c_str()), mInstructions );
                                $3.erase($3.find("array_element"));
                                $3.erase($3.find("array_element"));
                                SetExpressionDestination( $1, I );
                                SetExpressionDestination( $1, I );
                                I.SetCode(EOPERATION_ADD);
                                I.SetCode(EOPERATION_ADD);
                                I.SetImmBit( true );
                                I.SetImmBit( true );
                                I.SetDestZero( true );
                                I.SetDestZero( true );
                                I.SetSrc1Displace( true );
                                I.SetSrc1Displace( true );
                                I.SetSrc0Displace( false );
                                I.SetSrc0Displace( false );
                                I.mSourceLine = GetCurrentLineNumber(yylloc);
                                I.mSourceLine = GetCurrentLineNumber(yylloc);
                                if ($3.find("OFFSET") != std::string::npos)
                                if ($3.find("OFFSET") != std::string::npos)
                                        $3.erase($3.find("OFFSET"));
                                        $3.erase($3.find("OFFSET"));
                                I.SetSrc1Address(atoi($3.c_str()+1));
                                I.SetSrc1Address(atoi($3.c_str()+1));
                                I.SetSrc0Address(0);
                                I.SetSrc0Address(0);
                                mInstructions.push_back(I);
                                mInstructions.push_back(I);
                                I.Clear();
                                I.Clear();
                        }
                        }
                }
                }
                else
                else
                {
                {
                                mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc);
                                mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc);
                                gInsertedInstructions = 0;
                                gInsertedInstructions = 0;
                                std::string Destination = $1;
                                std::string Destination = $1;
                                //std::cout << "DST " << Destination << " \n";
                                //std::cout << "DST " << Destination << " \n";
                                //Look for indirect addressing
                                //Look for indirect addressing
                                if (Destination.find("INDEX") != std::string::npos)
                                if (Destination.find("INDEX") != std::string::npos)
                                {
                                {
                                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
                                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
                                        Destination.erase(Destination.find("INDEX"));
                                        Destination.erase(Destination.find("INDEX"));
                                        I.SetImm( 0 );
                                        I.SetImm( 0 );
                                        I.SetCode( EOPERATION_ADD );
                                        I.SetCode( EOPERATION_ADD );
                                        if (Destination.find(".") != std::string::npos)
                                        if (Destination.find(".") != std::string::npos)
                                        {
                                        {
                                                I.ClearWriteChannel();
                                                I.ClearWriteChannel();
                                                if (Destination.find("x") != std::string::npos)
                                                if (Destination.find("x") != std::string::npos)
                                                        I.SetWriteChannel(ECHANNEL_X);
                                                        I.SetWriteChannel(ECHANNEL_X);
                                                if (Destination.find("y") != std::string::npos)
                                                if (Destination.find("y") != std::string::npos)
                                                        I.SetWriteChannel(ECHANNEL_Y);
                                                        I.SetWriteChannel(ECHANNEL_Y);
                                                if (Destination.find("z") != std::string::npos)
                                                if (Destination.find("z") != std::string::npos)
                                                        I.SetWriteChannel(ECHANNEL_Z);
                                                        I.SetWriteChannel(ECHANNEL_Z);
                                                Destination.erase(Destination.find("."));
                                                Destination.erase(Destination.find("."));
                                        }
                                        }
                                        std::string Source0 = $3;
                                        std::string Source0 = $3;
                                        if (Source0.find("OFFSET") != std::string::npos)
                                        if (Source0.find("OFFSET") != std::string::npos)
                                        {
                                        {
                                                Source0.erase(Source0.find("OFFSET"));
                                                Source0.erase(Source0.find("OFFSET"));
                                                I.SetSrc0Displace(1);
                                                I.SetSrc0Displace(1);
                                        }
                                        }
                                        I.SetSrc1Address(atoi(IndexRegister.c_str()+1));
                                        I.SetSrc1Address(atoi(IndexRegister.c_str()+1));
                                        I.SetSrc0Address(atoi(Source0.c_str()+1));
                                        I.SetSrc0Address(atoi(Source0.c_str()+1));
                                //      I.SetSrc0Address(mInstructions.back().GetDestinationAddress());
                                //      I.SetSrc0Address(mInstructions.back().GetDestinationAddress());
                                        I.SetDestZero(0);
                                        I.SetDestZero(0);
                                        I.SetSrc1Displace(1);
                                        I.SetSrc1Displace(1);
                                        I.SetSrc0Displace(1);
                                        I.SetSrc0Displace(1);
                                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
                                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
                                        mInstructions.push_back( I );
                                        mInstructions.push_back( I );
                                        I.Clear();
                                        I.Clear();
                                } else {
                                } else {
                                        if (mInstructions.back().GetImm())
                                        if (mInstructions.back().GetImm())
                                        {
                                        {
                                                //Look for displament addressing mode
                                                //Look for displament addressing mode
                                                unsigned int AddressingMode = mInstructions.back().GetAddressingMode();
                                                unsigned int AddressingMode = mInstructions.back().GetAddressingMode();
                                                if (Destination.find("OFFSET") != std::string::npos)
                                                if (Destination.find("OFFSET") != std::string::npos)
                                                {
                                                {
                                                        //This means AddressMode is '101', so leave the way it is
                                                        //This means AddressMode is '101', so leave the way it is
                                                        mInstructions.back().ClearWriteChannel();
                                                        mInstructions.back().ClearWriteChannel();
                                                        mInstructions.back().SetWriteChannel(ECHANNEL_Z);
                                                        mInstructions.back().SetWriteChannel(ECHANNEL_Z);
                                                        Destination.erase(Destination.find("OFFSET"));
                                                        Destination.erase(Destination.find("OFFSET"));
                                                } else {
                                                } else {
                                                        //This is not supposed to have index, so change addressing mode to '100'
                                                        //This is not supposed to have index, so change addressing mode to '100'
                                                        mInstructions.back().SetDestZero( true );
                                                        mInstructions.back().SetDestZero( true );
                                                        mInstructions.back().SetSrc1Displace( false );
                                                        mInstructions.back().SetSrc1Displace( false );
                                                        mInstructions.back().SetSrc0Displace( false );
                                                        mInstructions.back().SetSrc0Displace( false );
                                                        mInstructions.back().ClearWriteChannel();
                                                        mInstructions.back().ClearWriteChannel();
                                                        mInstructions.back().SetWriteChannel(ECHANNEL_Z);
                                                        mInstructions.back().SetWriteChannel(ECHANNEL_Z);
                                                }
                                                }
                                        } else {
                                        } else {
                                                mInstructions.back().SetDestZero( false ); //First assume no offset was used
                                                mInstructions.back().SetDestZero( false ); //First assume no offset was used
                                                //Look for displament addressing mode
                                                //Look for displament addressing mode
                                                if (Destination.find("OFFSET") != std::string::npos)
                                                if (Destination.find("OFFSET") != std::string::npos)
                                                {
                                                {
                                                        Destination.erase(Destination.find("OFFSET"));
                                                        Destination.erase(Destination.find("OFFSET"));
                                                        mInstructions.back().SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
                                                        mInstructions.back().SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
                                                }
                                                }
                                        }
                                        }
                                                if (Destination.find(".") != std::string::npos)
                                                if (Destination.find(".") != std::string::npos)
                                                {
                                                {
                                                        mInstructions.back().ClearWriteChannel();
                                                        mInstructions.back().ClearWriteChannel();
                                                        if (Destination.find("x") != std::string::npos)
                                                        if (Destination.find("x") != std::string::npos)
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_X);
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_X);
                                                        if (Destination.find("y") != std::string::npos)
                                                        if (Destination.find("y") != std::string::npos)
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_Y);
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_Y);
                                                        if (Destination.find("z") != std::string::npos)
                                                        if (Destination.find("z") != std::string::npos)
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_Z);
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_Z);
                                                        Destination.erase(Destination.find("."));
                                                        Destination.erase(Destination.find("."));
                                                }
                                                }
                                                mInstructions.back().SetDestinationAddress( atoi($1.c_str()+1) );
                                                mInstructions.back().SetDestinationAddress( atoi($1.c_str()+1) );
                                                for (int i = 1; i <= gExtraDestModifications; i++ )
                                                for (int i = 1; i <= gExtraDestModifications; i++ )
                                                {
                                                {
                                                        int idx = (mInstructions.size()-1)-i;
                                                        int idx = (mInstructions.size()-1)-i;
                                                        mInstructions[idx].SetDestinationAddress( atoi($1.c_str()+1) );
                                                        mInstructions[idx].SetDestinationAddress( atoi($1.c_str()+1) );
                                                        if (mInstructions[idx].GetImm())
                                                        if (mInstructions[idx].GetImm())
                                                        {
                                                        {
                                                                //This is not supposed to have index, so change addressing mode to '100'
                                                                //This is not supposed to have index, so change addressing mode to '100'
                                                                mInstructions[idx].SetDestZero( true );
                                                                mInstructions[idx].SetDestZero( true );
                                                                mInstructions[idx].SetSrc1Displace( false );
                                                                mInstructions[idx].SetSrc1Displace( false );
                                                                mInstructions[idx].SetSrc0Displace( false );
                                                                mInstructions[idx].SetSrc0Displace( false );
                                                        }
                                                        }
                                                }
                                                }
                                                gExtraDestModifications = 0;
                                                gExtraDestModifications = 0;
                                }
                                }
                                ResetTempRegisterIndex();
                                ResetTempRegisterIndex();
                }
                }
                LABEL_EXPRESSION_DONE:
                LABEL_EXPRESSION_DONE:
                gInsertedInstructions = 0;
                gInsertedInstructions = 0;
                while(0);
                while(0);
        }
        }
        |
        |
        WHILE { /*Middle rule here, get me the loop address*/ ;gWhileLoopAddress = (mInstructions.size());}OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE OPEN_BRACE statement_list CLOSE_BRACE
        WHILE { /*Middle rule here, get me the loop address*/ ;gWhileLoopAddress = (mInstructions.size());}OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE OPEN_BRACE statement_list CLOSE_BRACE
        {
        {
                mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()+1);
                mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()+1);
                gBranchStack.pop_back();
                gBranchStack.pop_back();
                //Now I need to put a GOTO so that the while gets evaluated again...
                //Now I need to put a GOTO so that the while gets evaluated again...
                //jump out of the if
                //jump out of the if
           I.Clear();
           I.Clear();
           I.SetCode( EOPERATION_ADD );
           I.SetCode( EOPERATION_ADD );
           I.mComment = "while loop goto re-eval boolean";
           I.mComment = "while loop goto re-eval boolean";
           I.SetDestinationAddress( gWhileLoopAddress );
           I.SetDestinationAddress( gWhileLoopAddress );
           I.SetBranchFlag( true );
           I.SetBranchFlag( true );
           I.SetBranchType( EBRANCH_ALWAYS );
           I.SetBranchType( EBRANCH_ALWAYS );
           mInstructions.push_back(I);
           mInstructions.push_back(I);
           I.Clear();
           I.Clear();
        }
        }
 
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
        /////                                                                                                                                                                                                             /////
 
        /////   If-else                                                                                                                                                                                   /////
 
        /////                                                                                                                                                                                                             /////
 
        /////   if ()                                                                                                                             /////
 
        /////   {                                                                                                                                                                                                         /////
 
        /////                                                                                                                                                                             /////
 
        /////                                                                                                                                                                                                             /////
 
        /////   } else {                                                                                                                                                                                          /////
 
        /////                                                                                                                                                                             /////
 
        /////   }                                                                                                                                                                                                         /////
 
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        | IF
        | IF
          OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE
          OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE
          OPEN_BRACE statement_list CLOSE_BRACE
          OPEN_BRACE statement_list CLOSE_BRACE
      ELSE
      ELSE
        {
        { //Start of middle rule
 
 
           //jump out of the if
           //jump out of the if
           I.Clear();
           I.Clear();
           I.SetCode( EOPERATION_ADD );
           I.SetCode( EOPERATION_ADD );
           I.SetBranchFlag( true );
           I.SetBranchFlag( true );
           I.SetBranchType( EBRANCH_ALWAYS );
           I.SetBranchType( EBRANCH_ALWAYS );
           mInstructions.push_back(I);
           mInstructions.push_back(I);
           I.Clear();
           I.Clear();
           //Take care of the destination addr of the if statement.
           //Take care of the destination addr of the if statement.
           mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
           mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
          gBranchStack.pop_back();
          gBranchStack.pop_back();
          //push the inconditional jump into the stack
          //push the inconditional jump into the stack
          gBranchStack.push_back(mInstructions.size() - 1);
          gBranchStack.push_back(mInstructions.size() - 1);
          ////std::cout << "else\n";
 
 
 
        }
 
 
        } //End of middle rule
          OPEN_BRACE  statement_list CLOSE_BRACE
          OPEN_BRACE  statement_list CLOSE_BRACE
        {
        {
           mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
           mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
           gBranchStack.pop_back();
           gBranchStack.pop_back();
           //Now push the JMP
 
 
 
                ////std::cout << "END elseif\n";
 
        }
        }
 
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
        /////                                                                                                                                                                                                             /////
 
        /////   If statement                                                                                                                                                                      /////
 
        /////                                                                                                                                                                                                             /////
 
        /////   if ()                                                                                                                             /////
 
        /////   {                                                                                                                                                                                                         /////
 
        /////                                                                                                                                                                             /////
 
        /////                                                                                                                                                                                                             /////
 
        /////   }                                                                                                                                                                                                         /////
 
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        |
        |
        //NOW the if statement
 
        IF OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE OPEN_BRACE statement_list CLOSE_BRACE
        IF OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE OPEN_BRACE statement_list CLOSE_BRACE
        {
        {
                mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
                mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
                //mInstructions[gBranchStack.back()].mSourceLine = GetCurrentLineNumber(yylloc);
                //mInstructions[gBranchStack.back()].mSourceLine = GetCurrentLineNumber(yylloc);
                gBranchStack.pop_back();
                gBranchStack.pop_back();
                ////std::cout << "if closing at " << mInstructions.size() << "\n";
                ////std::cout << "if closing at " << mInstructions.size() << "\n";
        }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////   Function declaration                                                                                                                                                              /////
        /////   Function declaration                                                                                                                                                              /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////   function  ( [ , ... , ])                                                                                                          /////
        /////   function  ( [ , ... , ])                                                                                                          /////
        /////   {                                                                                                                                                                                                         /////
        /////   {                                                                                                                                                                                                         /////
        /////                                                                                                                                                                             /////
        /////                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////   }                                                                                                                                                                                                         /////
        /////   }                                                                                                                                                                                                         /////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        |
        |
        FUNCTION IDENTIFIER OPEN_ROUND_BRACE function_argument_list CLOSE_ROUND_BRACE
        FUNCTION IDENTIFIER OPEN_ROUND_BRACE function_argument_list CLOSE_ROUND_BRACE
        {
        {
          DCOUT << "Function declaration for " << $2 << " at " << mInstructions.size() << "\n" ;
          DCOUT << "Function declaration for " << $2 << " at " << mInstructions.size() << "\n" ;
          mSymbolMap[ $2 ] = mInstructions.size();
          mSymbolMap[ $2 ] = mInstructions.size();
        } OPEN_BRACE statement_list CLOSE_BRACE
        } OPEN_BRACE statement_list CLOSE_BRACE
        {
        {
                //Clear the auto var index now that we leave the function scope
                //Clear the auto var index now that we leave the function scope
                ClearAutoVarMap();
                ClearAutoVarMap();
                ClearFunctionParameterMap();
                ClearFunctionParameterMap();
                //Now uddate the current SPR_CONTROL_REGISTER.x = SPR_CONTROL_REGISTER.y
                //Now uddate the current SPR_CONTROL_REGISTER.x = SPR_CONTROL_REGISTER.y
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "Restore previous function frame offset";
                I.mComment = "Restore previous function frame offset";
                I.SetWriteChannel(ECHANNEL_X);
                I.SetWriteChannel(ECHANNEL_X);
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
                I.SetSrc1SwizzleX(SWX_Y);
                I.SetSrc1SwizzleX(SWX_Y);
                I.SetSrc1SwizzleY(SWY_Y);
                I.SetSrc1SwizzleY(SWY_Y);
                I.SetSrc1SwizzleZ(SWZ_Y);
                I.SetSrc1SwizzleZ(SWZ_Y);
                I.SetSrc0Address(0);
                I.SetSrc0Address(0);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                mInstructions.push_back( I );
                mInstructions.push_back( I );
                I.Clear();
                I.Clear();
        }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////   Thread declaration                                                                                                                                                                        /////
        /////   Thread declaration                                                                                                                                                                        /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////   thread  ( )                                                                                                                                                       /////
        /////   thread  ( )                                                                                                                                                       /////
        /////   {                                                                                                                                                                                                         /////
        /////   {                                                                                                                                                                                                         /////
        /////                                                                                                                                                                             /////
        /////                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////   }                                                                                                                                                                                                         /////
        /////   }                                                                                                                                                                                                         /////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        |
        |
        //Thread declaration
        //Thread declaration
        THREAD IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE
        THREAD IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE
        {
        {
                gThreadMap[ $2 ] = mInstructions.size();
                gThreadMap[ $2 ] = mInstructions.size();
                gThreadScope = true;
                gThreadScope = true;
        }
        }
        OPEN_BRACE statement_list CLOSE_BRACE
        OPEN_BRACE statement_list CLOSE_BRACE
        {
        {
                ////std::cout << "Defining thread" << "\n";
                ////std::cout << "Defining thread" << "\n";
                gThreadScope = false;
                gThreadScope = false;
                ClearAutoVarMap();
                ClearAutoVarMap();
                //Since the thread is done, then disable threading
                //Since the thread is done, then disable threading
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "Disable multi-threading";
                I.mComment = "Disable multi-threading";
                I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
                I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
                unsigned int Value = 0;
                unsigned int Value = 0;
                I.SetImm( Value );
                I.SetImm( Value );
                I.SetDestZero( true );
                I.SetDestZero( true );
                I.SetWriteChannel(ECHANNEL_Z);
                I.SetWriteChannel(ECHANNEL_Z);
                mInstructions.push_back( I );
                mInstructions.push_back( I );
                I.Clear();
                I.Clear();
        }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////   Start thread                                                                                                                                                                              /////
        /////   Start thread                                                                                                                                                                              /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////   start  ( );                                                                                                                                                       /////
        /////   start  ( );                                                                                                                                                       /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        |
        |
        START IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE EOS
        START IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE EOS
        {
        {
                unsigned int ThreadCodeOffset = 0;
                unsigned int ThreadCodeOffset = 0;
                ////std::cout << "Starting thread" << "\n";
                ////std::cout << "Starting thread" << "\n";
                if (gThreadMap.find($2) == gThreadMap.end())
                if (gThreadMap.find($2) == gThreadMap.end())
                {
                {
                        std::ostringstream ret;
                        std::ostringstream ret;
                        ret << "Undefined thread '" << $2 << "' at line " << yylloc << " \n";
                        ret << "Undefined thread '" << $2 << "' at line " << yylloc << " \n";
                        ret << "Current version of the compiler needs thread defintion prior of thread instantiation\n";
                        ret << "Current version of the compiler needs thread defintion prior of thread instantiation\n";
                        throw ret.str();
                        throw ret.str();
                } else {
                } else {
                        ThreadCodeOffset = gThreadMap[$2];
                        ThreadCodeOffset = gThreadMap[$2];
                        //Now enable the multithreading and set instruction offset
                        //Now enable the multithreading and set instruction offset
                        I.SetCode( EOPERATION_ADD );
                        I.SetCode( EOPERATION_ADD );
                        std::ostringstream ss;
                        std::ostringstream ss;
                        ss << "Set thread instruction offset to 8'd" << ThreadCodeOffset;
                        ss << "Set thread instruction offset to 8'd" << ThreadCodeOffset;
                        I.mComment = ss.str();
                        I.mComment = ss.str();
                        I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
                        I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
                        unsigned int Value = (ThreadCodeOffset << 1);
                        unsigned int Value = (ThreadCodeOffset << 1);
                        I.SetImm( Value );
                        I.SetImm( Value );
                        I.SetDestZero( true );
                        I.SetDestZero( true );
                        I.SetWriteChannel(ECHANNEL_Z);
                        I.SetWriteChannel(ECHANNEL_Z);
                        mInstructions.push_back( I );
                        mInstructions.push_back( I );
                        I.Clear();
                        I.Clear();
                        I.SetCode( EOPERATION_ADD );
                        I.SetCode( EOPERATION_ADD );
                        I.mComment = "Enable multi-threading";
                        I.mComment = "Enable multi-threading";
                        I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
                        I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
                        Value = (ThreadCodeOffset << 1 | 1);
                        Value = (ThreadCodeOffset << 1 | 1);
                        I.SetImm( Value );
                        I.SetImm( Value );
                        I.SetDestZero( true );
                        I.SetDestZero( true );
                        I.SetWriteChannel(ECHANNEL_Z);
                        I.SetWriteChannel(ECHANNEL_Z);
                        mInstructions.push_back( I );
                        mInstructions.push_back( I );
                        I.Clear();
                        I.Clear();
                }
                }
        }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////   Function call and assign return value to variable                                                                                                         /////
        /////   Function call and assign return value to variable                                                                                                         /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////    =  ( [ , ... , ]);                                                                                       /////
        /////    =  ( [ , ... , ]);                                                                                       /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        |
        |
        left_hand_side ASSIGN IDENTIFIER OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS
        left_hand_side ASSIGN IDENTIFIER OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS
        {
        {
                ////std::cout << "Function call returning to var\n";
                ////std::cout << "Function call returning to var\n";
                StoreReturnAddress( mInstructions, yylloc );
                StoreReturnAddress( mInstructions, yylloc );
                SavePreviousFramePointer( mInstructions );
                SavePreviousFramePointer( mInstructions );
                UpdateFramePointer( mInstructions );
                UpdateFramePointer( mInstructions );
                CallFunction( $3, mInstructions, mSymbolMap );
                CallFunction( $3, mInstructions, mSymbolMap );
                //Return value comes in R1, so let's store this in our variable
                //Return value comes in R1, so let's store this in our variable
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                SetDestinationFromRegister( $1, I, false );
                SetDestinationFromRegister( $1, I, false );
                I.mComment = "grab the return value from the function";
                I.mComment = "grab the return value from the function";
                I.SetSrc1Address( RETURN_VALUE_REGISTER);
                I.SetSrc1Address( RETURN_VALUE_REGISTER);
                I.SetSrc0Address(0);
                I.SetSrc0Address(0);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                mInstructions.push_back( I );
                mInstructions.push_back( I );
                I.Clear();
                I.Clear();
                ClearNextFunctionParamRegister();
                ClearNextFunctionParamRegister();
        }
        }
        |
        |
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////   Function call (return value is ignored)                                                                                                                           /////
        /////   Function call (return value is ignored)                                                                                                                           /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////    ( [ , ... , ]);                                                                                                                          /////
        /////    ( [ , ... , ]);                                                                                                                          /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        /////                                                                                                                                                                                                             /////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        IDENTIFIER  OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS
        IDENTIFIER  OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS
        {
        {
                //Store the return address
                //Store the return address
                StoreReturnAddress( mInstructions, yylloc );
                StoreReturnAddress( mInstructions, yylloc );
                //Store the current SPR_CONTROL_REGISTER.x into the previous SPR_CONTROL_REGISTER.y
                //Store the current SPR_CONTROL_REGISTER.x into the previous SPR_CONTROL_REGISTER.y
                //SPR_CONTROL_REGISTER.y = SPR_CONTROL_REGISTER.xxx + 0;
                //SPR_CONTROL_REGISTER.y = SPR_CONTROL_REGISTER.xxx + 0;
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "store current frame offset";
                I.mComment = "store current frame offset";
                I.SetWriteChannel(ECHANNEL_Y);
                I.SetWriteChannel(ECHANNEL_Y);
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
                I.SetSrc1SwizzleX(SWX_X);
                I.SetSrc1SwizzleX(SWX_X);
                I.SetSrc1SwizzleY(SWY_X);
                I.SetSrc1SwizzleY(SWY_X);
                I.SetSrc1SwizzleZ(SWZ_X);
                I.SetSrc1SwizzleZ(SWZ_X);
                I.SetSrc0Address(0);
                I.SetSrc0Address(0);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleX(SWX_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleY(SWY_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                I.SetSrc0SwizzleZ(SWZ_X);
                mInstructions.push_back( I );
                mInstructions.push_back( I );
                I.Clear();
                I.Clear();
                //Now uddate the current SPR_CONTROL_REGISTER.x += number of auto variables
                //Now uddate the current SPR_CONTROL_REGISTER.x += number of auto variables
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "displace next frame offset by the number of auto variables in current frame";
                I.mComment = "displace next frame offset by the number of auto variables in current frame";
                I.SetWriteChannel(ECHANNEL_X);
                I.SetWriteChannel(ECHANNEL_X);
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
                I.SetImm( GetCurretAutoVarFrameSize() );
                I.SetImm( GetCurretAutoVarFrameSize() );
                I.SetDestZero( false );
                I.SetDestZero( false );
                mInstructions.push_back( I );
                mInstructions.push_back( I );
                I.Clear();
                I.Clear();
                //Call the function with a JMP
                //Call the function with a JMP
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mComment = "call the function";
                I.mComment = "call the function";
                I.SetBranchFlag( true );
                I.SetBranchFlag( true );
                I.SetBranchType( EBRANCH_ALWAYS );
                I.SetBranchType( EBRANCH_ALWAYS );
                //Now assign the destination of the branch (our function virtual address)
                //Now assign the destination of the branch (our function virtual address)
                if (mSymbolMap.find($1) == mSymbolMap.end())
                if (mSymbolMap.find($1) == mSymbolMap.end())
                {
                {
                        //The destination is not yet declared
                        //The destination is not yet declared
                        //so leave it as a symbol so that it can latter
                        //so leave it as a symbol so that it can latter
                        //resolved by the linker
                        //resolved by the linker
                        I.SetDestinationSymbol( "@"+$1 );
                        I.SetDestinationSymbol( "@"+$1 );
                } else {
                } else {
                        //The destination symbol has already been declared
                        //The destination symbol has already been declared
                        //so assign it right away
                        //so assign it right away
                        I.SetDestinationAddress( mSymbolMap[ $1 ] );
                        I.SetDestinationAddress( mSymbolMap[ $1 ] );
                }
                }
                //Push the last instruction in the sequence and clean up
                //Push the last instruction in the sequence and clean up
                mInstructions.push_back( I );
                mInstructions.push_back( I );
                I.Clear();
                I.Clear();
        }
        }
        ;
        ;
        function_input_list
        function_input_list
                                          :
                                          :
                                          |//empty
                                          |//empty
                                          expression COMMA function_input_list
                                          expression COMMA function_input_list
                                          {
                                          {
                                                AddFunctionInputList( $1, mInstructions,yylloc );
                                                AddFunctionInputList( $1, mInstructions,yylloc );
                                          }
                                          }
                                          |
                                          |
                                          expression
                                          expression
                                          {
                                          {
                                                AddFunctionInputList( $1,mInstructions, yylloc );
                                                AddFunctionInputList( $1,mInstructions, yylloc );
                                          }
                                          }
                                          ;
                                          ;
        function_argument_list
        function_argument_list
                                                :
                                                :
                                                | //empty
                                                | //empty
                                                IDENTIFIER COMMA function_argument_list
                                                IDENTIFIER COMMA function_argument_list
                                                {
                                                {
                                                        AddFunctionParameter( $1, yylloc );
                                                        AddFunctionParameter( $1, yylloc );
                                                }
                                                }
                                                |
                                                |
                                                IDENTIFIER
                                                IDENTIFIER
                                                {
                                                {
                                                        AddFunctionParameter( $1, yylloc );
                                                        AddFunctionParameter( $1, yylloc );
                                                }
                                                }
                                                ;
                                                ;
 
 
//  ::=  +  |
 
          //  -  |
 
          // 
 
 
 
//  ::=  *  |
 
           //  /  |
 
           // 
 
 
 
//  ::= x | y | ... |
 
             // (  ) |
 
             // -  |
 
             // 
 
 
 
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
/////                                                                                                                                                                                                             /////
 
/////   Expression declaration.                                                                                                                                           /////
 
/////                                                                                                                                                                                                             /////
 
/////   This is the definition for the expressions which make the Right Hand values                                                       /////
 
/////   The expressions follow the general shape of Expression made of "Terms" which in turn are made our of  /////                                                                                                                                                                                               /////
 
/////   "factors". This so the order operations is taken into cosiderations and subexpressions can be grouped /////
 
/////   using parenthesis. The expressions follow th BNF format as described next                             /////
 
/////                                                                                                                                                                                                         /////
 
/////  ::=  +  |                                                                              /////
 
/////           -   |                                                                              /////
 
/////                                                                                                   /////
 
/////                                                                                                         /////
 
/////  ::=  *  |                                                                          /////
 
/////             /  |                                                                          /////
 
/////                                                                                                 /////
 
/////                                                                                                         /////
 
/////  ::=    |                                                                               /////
 
/////              (  )  |                                                                               /////
 
/////              -  |                                                                               /////
 
/////                                                                                                 /////
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
expression
expression
                :
                :
                expression ADD term
                expression ADD term
                {
                {
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        gExtraDestModifications = 0;
                        gExtraDestModifications = 0;
                        I.SetCode( EOPERATION_ADD );
                        I.SetCode( EOPERATION_ADD );
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        PopulateSourceRegisters( $1, $3, I, mInstructions );
                        PopulateSourceRegisters( $1, $3, I, mInstructions );
                        mInstructions.push_back(I);
                        mInstructions.push_back(I);
                        gInsertedInstructions++;
                        gInsertedInstructions++;
                        I.Clear();
                        I.Clear();
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << "R" << TempRegIndex << " OFFSET ";
                        ss << "R" << TempRegIndex << " OFFSET ";
                        $$ = ss.str();
                        $$ = ss.str();
                }
                }
                |
                |
                expression MINUS term
                expression MINUS term
                {
                {
                        gExtraDestModifications = 0;
                        gExtraDestModifications = 0;
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        I.SetCode( EOPERATION_ADD );
                        I.SetCode( EOPERATION_ADD );
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetSrc0SignX( true );
                        I.SetSrc0SignX( true );
                        I.SetSrc0SignY( true );
                        I.SetSrc0SignY( true );
                        I.SetSrc0SignZ( true );
                        I.SetSrc0SignZ( true );
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
                        mInstructions.push_back(I);
                        mInstructions.push_back(I);
                        gInsertedInstructions++;
                        gInsertedInstructions++;
                        I.Clear();
                        I.Clear();
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << "R" << TempRegIndex << " OFFSET ";
                        ss << "R" << TempRegIndex << " OFFSET ";
                        $$ = ss.str();
                        $$ = ss.str();
                }
                }
                |
                |
                expression BITWISE_OR term
                expression BITWISE_OR term
                {
                {
                        gExtraDestModifications = 0;
                        gExtraDestModifications = 0;
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetCode( EOPERATION_LOGIC );
                        I.SetCode( EOPERATION_LOGIC );
                        I.SetLogicOperation( ELOGIC_OR );
                        I.SetLogicOperation( ELOGIC_OR );
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
                        mInstructions.push_back(I);
                        mInstructions.push_back(I);
                        gInsertedInstructions++;
                        gInsertedInstructions++;
                        I.Clear();
                        I.Clear();
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << "R" << TempRegIndex << " OFFSET ";
                        ss << "R" << TempRegIndex << " OFFSET ";
                        $$ = ss.str();
                        $$ = ss.str();
                }
                }
 
                //////////////////////////////////////////////////////////////////////////////
 
                //  This is the "in" operator used as the RHV
 
                //  Example:
 
                //   MyValue = in[ MyAddress ]
 
                //
 
                //  Note that this RHV cannot be combined with other RHV expressions, in other
 
                //  words you can not do thing like this: RHV = in[ addr ] + SomeOtherVariable
 
                //
 
                //////////////////////////////////////////////////////////////////////////////
 
                |
 
                IN OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE
 
                {
 
                        std::string Register;
 
                        if ((Register = GetRegisterFromFunctionParameter($3)) != "NULL")
 
                                $$ = "IN " + Register;
 
                        else
 
                                $$ = "IN " + GetRegisterFromAutoVar( $3, yylloc ) + " OFFSET ";
 
                }
                |
                |
                term
                term
                {
                {
                        $$ = $1;
                        $$ = $1;
                }
                }
                ;
                ;
                term
                term
                :
                :
                term MUL factor
                term MUL factor
                {
                {
                        gExtraDestModifications = 0;
                        gExtraDestModifications = 0;
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetCode( EOPERATION_MUL );
                        I.SetCode( EOPERATION_MUL );
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
                        //If we are using fixed point aritmethic then we need to apply the scale
                        //If we are using fixed point aritmethic then we need to apply the scale
                        //R = A * ( B >> SCALE)
                        //R = A * ( B >> SCALE)
                        if (mGenerateFixedPointArithmetic)
                        if (mGenerateFixedPointArithmetic)
                                I.SetSrc0Rotation( EROT_RESULT_RIGHT );
                                I.SetSrc0Rotation( EROT_RESULT_RIGHT );
                        mInstructions.push_back(I);
                        mInstructions.push_back(I);
                        gInsertedInstructions++;
                        gInsertedInstructions++;
                        I.Clear();
                        I.Clear();
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << "R" << TempRegIndex << " OFFSET ";
                        ss << "R" << TempRegIndex << " OFFSET ";
                        $$ = ss.str();
                        $$ = ss.str();
                }
                }
                |
                |
                term DIV factor
                term DIV factor
                {
                {
                        gExtraDestModifications = 0;
                        gExtraDestModifications = 0;
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetCode( EOPERATION_DIV );
                        I.SetCode( EOPERATION_DIV );
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
                        //If we are using fixed point aritmethic then we need to apply the scale
                        //If we are using fixed point aritmethic then we need to apply the scale
                        // R = (A << N) / B
                        // R = (A << N) / B
                        if (mGenerateFixedPointArithmetic)
                        if (mGenerateFixedPointArithmetic)
                                I.SetSrc1Rotation( EROT_SRC1_LEFT );
                                I.SetSrc1Rotation( EROT_SRC1_LEFT );
                        mInstructions.push_back(I);
                        mInstructions.push_back(I);
                        gInsertedInstructions++;
                        gInsertedInstructions++;
                        I.Clear();
                        I.Clear();
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << "R" << TempRegIndex << " OFFSET ";
                        ss << "R" << TempRegIndex << " OFFSET ";
                        $$ = ss.str();
                        $$ = ss.str();
                }
                }
                |
                |
                term BITWISE_AND factor
                term BITWISE_AND factor
                {
                {
                        gExtraDestModifications = 0;
                        gExtraDestModifications = 0;
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetCode( EOPERATION_LOGIC );
                        I.SetCode( EOPERATION_LOGIC );
                        I.SetLogicOperation( ELOGIC_AND );
                        I.SetLogicOperation( ELOGIC_AND );
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
                        mInstructions.push_back(I);
                        mInstructions.push_back(I);
                        gInsertedInstructions++;
                        gInsertedInstructions++;
                        I.Clear();
                        I.Clear();
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << "R" << TempRegIndex << " OFFSET ";
                        ss << "R" << TempRegIndex << " OFFSET ";
                        $$ = ss.str();
                        $$ = ss.str();
                }
                }
                |
                |
                factor
                factor
                {
                {
                        $$ = $1;
                        $$ = $1;
                }
                }
                ;
                ;
                factor
                factor
                :
                :
                source
                source
                {
                {
                        $$ = $1;
                        $$ = $1;
                }
                }
 
                //////////////////////////////////////////////////////////////////////////////
 
                // this is the square root used as part of RHS
 
                // Example:
 
                //   RHS = sqrt(  )
 
                //////////////////////////////////////////////////////////////////////////////
                |
                |
                SQRT OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE
                SQRT OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE
                {
                {
                        gExtraDestModifications = 0;
                        gExtraDestModifications = 0;
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        unsigned int TempRegIndex  = GetFreeTempRegister();
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestinationAddress( TempRegIndex );
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetDestZero( true ); //Use indexing for DST
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetWriteChannel(ECHANNEL_XYZ);
                        I.SetCode( EOPERATION_SQRT );
                        I.SetCode( EOPERATION_SQRT );
                        I.SetSrc0Address( 0 );
                        I.SetSrc0Address( 0 );
                        PopulateSourceRegisters( $3 ,"R0 . X X X", I, mInstructions);
                        PopulateSourceRegisters( $3 ,"R0 . X X X", I, mInstructions);
                        mInstructions.push_back(I);
                        mInstructions.push_back(I);
                        gInsertedInstructions++;
                        gInsertedInstructions++;
                        I.Clear();
                        I.Clear();
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << "R" << TempRegIndex << " OFFSET ";
                        ss << "R" << TempRegIndex << " OFFSET ";
                        $$ = ss.str();
                        $$ = ss.str();
                }
                }
                |
                |
                OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE
                OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE
                {
                {
                        $$ = $2;
                        $$ = $2;
                }
                }
                ;
                ;
        source
        source
        :
        :
        constant
        constant
        {
        {
                unsigned int ImmediateValue;
                unsigned int ImmediateValue;
                std::string StringHex = $1;
                std::string StringHex = $1;
                std::stringstream ss;
                std::stringstream ss;
                ss << std::hex << StringHex;
                ss << std::hex << StringHex;
                ss >> ImmediateValue;
                ss >> ImmediateValue;
                switch (ImmediateValue)
                switch (ImmediateValue)
                {
                {
                case 0:
                case 0:
                        $$ = "R0 . X X X";
                        $$ = "R0 . X X X";
                break;
                break;
                case 1:
                case 1:
                        $$ = "R0 . Y Y Y";
                        $$ = "R0 . Y Y Y";
                break;
                break;
                case 2:
                case 2:
                        $$ = "R0 . Z Z Z";
                        $$ = "R0 . Z Z Z";
                break;
                break;
                default:
                default:
                        std::string StringHex = $1;
                        std::string StringHex = $1;
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << std::hex << StringHex;
                        ss << std::hex << StringHex;
                        ss >> ImmediateValue;
                        ss >> ImmediateValue;
                        $$ = ss.str();
                        $$ = ss.str();
                        break;
                        break;
                }
                }
        }
        }
        |
        |
        OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE
        OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE
        {
        {
                unsigned int TempRegIndex  = GetFreeTempRegister();
                unsigned int TempRegIndex  = GetFreeTempRegister();
                unsigned int ImmediateValue;
                unsigned int ImmediateValue;
                {
                {
                std::string StringHex = $2;
                std::string StringHex = $2;
                std::stringstream ss;
                std::stringstream ss;
                ss << std::hex << StringHex;
                ss << std::hex << StringHex;
                ss >> ImmediateValue;
                ss >> ImmediateValue;
                I.SetDestinationAddress( TempRegIndex );
                I.SetDestinationAddress( TempRegIndex );
                I.SetImm( ImmediateValue );
                I.SetImm( ImmediateValue );
                I.SetDestZero(true);
                I.SetDestZero(true);
                I.SetSrc0Displace(true);
                I.SetSrc0Displace(true);
                I.SetWriteChannel(ECHANNEL_X);
                I.SetWriteChannel(ECHANNEL_X);
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                mInstructions.push_back(I);
                mInstructions.push_back(I);
                gInsertedInstructions++;
                gInsertedInstructions++;
                I.Clear();
                I.Clear();
                }
                }
                {
                {
                std::string StringHex = $4;
                std::string StringHex = $4;
                std::stringstream ss;
                std::stringstream ss;
                ss << std::hex << StringHex;
                ss << std::hex << StringHex;
                ss >> ImmediateValue;
                ss >> ImmediateValue;
                I.SetDestinationAddress( TempRegIndex );
                I.SetDestinationAddress( TempRegIndex );
                I.SetImm( ImmediateValue );
                I.SetImm( ImmediateValue );
                I.SetDestZero(true);
                I.SetDestZero(true);
                I.SetSrc0Displace(true);
                I.SetSrc0Displace(true);
                I.SetWriteChannel(ECHANNEL_Y);
                I.SetWriteChannel(ECHANNEL_Y);
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                mInstructions.push_back(I);
                mInstructions.push_back(I);
                gInsertedInstructions++;
                gInsertedInstructions++;
                I.Clear();
                I.Clear();
                }
                }
                {
                {
                std::string StringHex = $6;
                std::string StringHex = $6;
                std::stringstream ss;
                std::stringstream ss;
                ss << std::hex << StringHex;
                ss << std::hex << StringHex;
                ss >> ImmediateValue;
                ss >> ImmediateValue;
                I.SetDestinationAddress( TempRegIndex );
                I.SetDestinationAddress( TempRegIndex );
                I.SetImm( ImmediateValue );
                I.SetImm( ImmediateValue );
                I.SetDestZero(true);
                I.SetDestZero(true);
                I.SetSrc0Displace(true);
                I.SetSrc0Displace(true);
                I.SetWriteChannel(ECHANNEL_Z);
                I.SetWriteChannel(ECHANNEL_Z);
                I.SetCode( EOPERATION_ADD );
                I.SetCode( EOPERATION_ADD );
                I.mBisonFlagTrippleConstAssign = true;
                I.mBisonFlagTrippleConstAssign = true;
                mInstructions.push_back(I);
                mInstructions.push_back(I);
                gInsertedInstructions++;
                gInsertedInstructions++;
                I.Clear();
                I.Clear();
                }
                }
                gExtraDestModifications = 2;
                gExtraDestModifications = 2;
                std::stringstream ss2;
                std::stringstream ss2;
                ss2 << "R" << TempRegIndex << " OFFSET ";
                ss2 << "R" << TempRegIndex << " OFFSET ";
                $$ = ss2.str();
                $$ = ss2.str();
        }
        }
        |
        |
        IDENTIFIER array_index
        IDENTIFIER array_index
        {
        {
                std::string Register;
                std::string Register;
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                        $$ = Register;
                        $$ = Register;
                 else
                 else
                        $$ = GetRegisterFromAutoVar( $1, yylloc) + " OFFSET ";
                        $$ = GetRegisterFromAutoVar( $1, yylloc) + " OFFSET ";
                if ($2 != "NULL")
                if ($2 != "NULL")
                {
                {
                        $$ += " array_element " + $2;
                        $$ += " array_element " + $2;
                }
                }
        }
        }
        |
        |
        IDENTIFIER DOT coordinate coordinate coordinate
        IDENTIFIER DOT coordinate coordinate coordinate
        {
        {
                std::string X = $3,Y = $4,Z = $5;
                std::string X = $3,Y = $4,Z = $5;
                std::string Register;
                std::string Register;
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                        $$ = (Register + " . " + " " + X + " " + Y  + " " + Z/* + " OFFSET "*/);
                        $$ = (Register + " . " + " " + X + " " + Y  + " " + Z/* + " OFFSET "*/);
                else
                else
                        $$ = (GetRegisterFromAutoVar( $1, yylloc) + " . " + " " + X + " " + Y  + " " + Z + " OFFSET ");
                        $$ = (GetRegisterFromAutoVar( $1, yylloc) + " . " + " " + X + " " + Y  + " " + Z + " OFFSET ");
        }
        }
        |
        |
        REG
        REG
        {
        {
                std::string R = $1;
                std::string R = $1;
                R.erase(0,1);
                R.erase(0,1);
                $$ = "R" + R;
                $$ = "R" + R;
        }
        }
        |
        |
        SCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE
        SCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE
        {
        {
                std::string R = $1;
                std::string R = $1;
                R.erase(0,1);
                R.erase(0,1);
                $$ = "<
                $$ = "<
        }
        }
        |
        |
        UNSCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE
        UNSCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE
        {
        {
                std::string R = $1;
                std::string R = $1;
                R.erase(0,1);
                R.erase(0,1);
                $$ = ">>R" + R;
                $$ = ">>R" + R;
        }
        }
        |
        |
        REG DOT coordinate coordinate coordinate
        REG DOT coordinate coordinate coordinate
        {
        {
                std::string R = $1;
                std::string R = $1;
                std::string X = $3,Y = $4,Z = $5;
                std::string X = $3,Y = $4,Z = $5;
                R.erase(0,1);
                R.erase(0,1);
                $$ = "R" + R + " . " + " " + X + " " + Y  + " " + Z;
                $$ = "R" + R + " . " + " " + X + " " + Y  + " " + Z;
        }
        }
        ;
        ;
        coordinate
        coordinate
        :
        :
        TK_X
        TK_X
        {
        {
                $$ = "X";
                $$ = "X";
        }
        }
        |
        |
        MINUS TK_X
        MINUS TK_X
        {
        {
                $$ = "-X";
                $$ = "-X";
        }
        }
        |
        |
        TK_Y
        TK_Y
        {
        {
                $$ = "Y";
                $$ = "Y";
        }
        }
        |
        |
        MINUS TK_Y
        MINUS TK_Y
        {
        {
                $$ = "-Y";
                $$ = "-Y";
        }
        }
        |
        |
        TK_Z
        TK_Z
        {
        {
                $$ = "Z";
                $$ = "Z";
        }
        }
        |
        |
        MINUS TK_Z
        MINUS TK_Z
        {
        {
                $$ = "-Z";
                $$ = "-Z";
        }
        }
        ;
        ;
array_index
array_index
        :
        :
        {
        {
                $$ = "NULL";
                $$ = "NULL";
        }
        }
        |
        |
        OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE
        OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE
        {
        {
                /*std::string Register;
                /*std::string Register;
                if ((Register = GetRegisterFromFunctionParameter($2)) != "NULL")
                if ((Register = GetRegisterFromFunctionParameter($2)) != "NULL")
                        $$ = Register;
                        $$ = Register;
                else*/
                else*/
                //Indexes into arrays can only be auto variables!
                //Indexes into arrays can only be auto variables!
                $$ = GetRegisterFromAutoVar( $2, yylloc );
                $$ = GetRegisterFromAutoVar( $2, yylloc );
        }
        }
        ;
        ;
left_hand_side
left_hand_side
        :
        :
        OUT OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE
        OUT OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE
        {
        {
                $$ = "OUT " + $3;
                $$ = "OUT " + $3;
        }
        }
        |
        |
        OUT OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE
        OUT OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE
        {
        {
        /*
 
                std::string Register;
 
                if ((Register = GetRegisterFromFunctionParameter($3)) == "NULL")
 
                        Register = GetRegisterFromAutoVar( $3, yylloc );
 
 
 
                $$ = "OUT INDEX" + Register;
 
                */
 
                std::string Register;
                std::string Register;
                if ((Register = GetRegisterFromFunctionParameter($3)) != "NULL")
                if ((Register = GetRegisterFromFunctionParameter($3)) != "NULL")
                        $$ = "OUT INDEX" + Register;
                        $$ = "OUT INDEX" + Register;
                else
                else
                        $$ = "OUT INDEX" + GetRegisterFromAutoVar( $3, yylloc ) + " OFFSET ";
                        $$ = "OUT INDEX" + GetRegisterFromAutoVar( $3, yylloc ) + " OFFSET ";
        }
        }
        |
        |
        IDENTIFIER array_index
        IDENTIFIER array_index
        {
        {
                std::string Register;
                std::string Register;
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                        $$ = Register + ".xyz";
                        $$ = Register + ".xyz";
                else
                else
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".xyz" + " OFFSET " + (($2 != "NULL")?" INDEX"+$2:"");
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".xyz" + " OFFSET " + (($2 != "NULL")?" INDEX"+$2:"");
        }
        }
        |
        |
        IDENTIFIER DOT TK_X
        IDENTIFIER DOT TK_X
        {
        {
                std::string Register;
                std::string Register;
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                        $$ = Register + ".x";
                        $$ = Register + ".x";
                else
                else
                $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".x" + " OFFSET ";
                $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".x" + " OFFSET ";
        }
        }
        |
        |
        IDENTIFIER DOT TK_Y
        IDENTIFIER DOT TK_Y
        {
        {
                std::string Register;
                std::string Register;
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                        $$ = Register + ".y";
                        $$ = Register + ".y";
                else
                else
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".y" + " OFFSET ";
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".y" + " OFFSET ";
        }
        }
        |
        |
        IDENTIFIER DOT TK_Z
        IDENTIFIER DOT TK_Z
        {
        {
                std::string Register;
                std::string Register;
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
                        $$ = Register + ".z";
                        $$ = Register + ".z";
                else
                else
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".z" + " OFFSET ";
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".z" + " OFFSET ";
        }
        }
        |
        |
        REG
        REG
        {
        {
                std::string R = $1;
                std::string R = $1;
                R.erase(0,1);
                R.erase(0,1);
                $$ = "R" + R + ".xyz";
                $$ = "R" + R + ".xyz";
        }
        }
        |
        |
        REG DOT TK_X
        REG DOT TK_X
        {
        {
                std::string R = $1;
                std::string R = $1;
                R.erase(0,1);
                R.erase(0,1);
                $$ = "R" + R + ".x";
                $$ = "R" + R + ".x";
        }
        }
        |
        |
        REG DOT TK_Y
        REG DOT TK_Y
        {
        {
                std::string R = $1;
                std::string R = $1;
                R.erase(0,1);
                R.erase(0,1);
                $$ = "R" + R + ".y";
                $$ = "R" + R + ".y";
        }
        }
        |
        |
        REG DOT TK_Z
        REG DOT TK_Z
        {
        {
                std::string R = $1;
                std::string R = $1;
                R.erase(0,1);
                R.erase(0,1);
                $$ = "R" + R + ".z";
                $$ = "R" + R + ".z";
        }
        }
        |
        |
        REG DOT TK_X TK_Y TK_N
        REG DOT TK_X TK_Y TK_N
        {
        {
                std::string R = $1;
                std::string R = $1;
                R.erase(0,1);
                R.erase(0,1);
                $$ = "R" + R + ".xy";
                $$ = "R" + R + ".xy";
        }
        }
        |
        |
        REG DOT TK_X TK_N TK_Z
        REG DOT TK_X TK_N TK_Z
        {
        {
                std::string R = $1;
                std::string R = $1;
                R.erase(0,1);
                R.erase(0,1);
                $$ = "R" + R + ".xz";
                $$ = "R" + R + ".xz";
        }
        }
        |
        |
        REG DOT TK_N TK_Y TK_Z
        REG DOT TK_N TK_Y TK_Z
        {
        {
                std::string R = $1;
                std::string R = $1;
                R.erase(0,1);
                R.erase(0,1);
                $$ = "R" + R + ".yz";
                $$ = "R" + R + ".yz";
        }
        }
        ;
        ;
boolean_expression
boolean_expression
                                :
                                :
                                expression NOT_EQUAL expression
                                expression NOT_EQUAL expression
                                {
                                {
                                        PopulateBoolean(EBRANCH_IF_ZERO, $1, $3, I, mInstructions, yylloc );
                                        PopulateBoolean(EBRANCH_IF_ZERO, $1, $3, I, mInstructions, yylloc );
                                }
                                }
                                |
                                |
                                expression EQUAL expression
                                expression EQUAL expression
                                {
                                {
                                        PopulateBoolean(EBRANCH_IF_NOT_ZERO, $1, $3, I, mInstructions, yylloc );
                                        PopulateBoolean(EBRANCH_IF_NOT_ZERO, $1, $3, I, mInstructions, yylloc );
                                }
                                }
                                |
                                |
                                expression GREATER_THAN expression
                                expression GREATER_THAN expression
                                {
                                {
                                        PopulateBoolean(EBRANCH_IF_ZERO_OR_SIGN, $1, $3, I, mInstructions, yylloc );
                                        PopulateBoolean(EBRANCH_IF_ZERO_OR_SIGN, $1, $3, I, mInstructions, yylloc );
                                }
                                }
                                |
                                |
                                expression LESS_THAN expression
                                expression LESS_THAN expression
                                {
                                {
                                        PopulateBoolean(EBRANCH_IF_ZERO_OR_NOT_SIGN, $1, $3, I, mInstructions, yylloc );
                                        PopulateBoolean(EBRANCH_IF_ZERO_OR_NOT_SIGN, $1, $3, I, mInstructions, yylloc );
                                }
                                }
                                |
                                |
                                expression LESS_OR_EQUAL_THAN expression
                                expression LESS_OR_EQUAL_THAN expression
                                {
                                {
                                        PopulateBoolean(EBRANCH_IF_NOT_SIGN, $1, $3, I, mInstructions, yylloc );
                                        PopulateBoolean(EBRANCH_IF_NOT_SIGN, $1, $3, I, mInstructions, yylloc );
                                }
                                }
                                |
                                |
                                expression GREATER_OR_EQUAL_THAN expression
                                expression GREATER_OR_EQUAL_THAN expression
                                {
                                {
                                        PopulateBoolean(EBRANCH_IF_SIGN, $1, $3, I, mInstructions, yylloc );
                                        PopulateBoolean(EBRANCH_IF_SIGN, $1, $3, I, mInstructions, yylloc );
                                }
                                }
                                ;
                                ;
constant
constant
        :
        :
                DECCONST
                DECCONST
                {
                {
                        // Transform to HEX string
                        // Transform to HEX string
                        unsigned int Val;
                        unsigned int Val;
                        std::string StringDec = $1;
                        std::string StringDec = $1;
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << StringDec;
                        ss << StringDec;
                        ss >> Val;
                        ss >> Val;
                        std::stringstream ss2;
                        std::stringstream ss2;
                        ss2 << std::hex << Val;
                        ss2 << std::hex << Val;
                        $$ = ss2.str();
                        $$ = ss2.str();
                }
                }
                |
                |
                HEXCONST
                HEXCONST
                {
                {
                        std::string StringHex = $1;
                        std::string StringHex = $1;
                        // Get rid of the 0x
                        // Get rid of the 0x
                        StringHex.erase(StringHex.begin(),StringHex.begin()+2);
                        StringHex.erase(StringHex.begin(),StringHex.begin()+2);
                        std::stringstream ss;
                        std::stringstream ss;
                        ss << std::hex << StringHex;
                        ss << std::hex << StringHex;
                        $$ = ss.str();
                        $$ = ss.str();
                }
                }
                |
                |
                BINCONST
                BINCONST
                {
                {
                        // Transform to HEX string
                        // Transform to HEX string
                        std::string StringBin = $1;
                        std::string StringBin = $1;
                        // Get rid of the 0b
                        // Get rid of the 0b
                        StringBin.erase(StringBin.begin(),StringBin.begin()+2);
                        StringBin.erase(StringBin.begin(),StringBin.begin()+2);
                        std::bitset<32> Bitset( StringBin );
                        std::bitset<32> Bitset( StringBin );
                        std::stringstream ss2;
                        std::stringstream ss2;
                        ss2 << std::hex <<  Bitset.to_ulong();
                        ss2 << std::hex <<  Bitset.to_ulong();
                        $$ = ss2.str();
                        $$ = ss2.str();
                }
                }
        ;
        ;
auto_var_list
auto_var_list
                        :
                        :
                        IDENTIFIER array_size COMMA auto_var_list
                        IDENTIFIER array_size COMMA auto_var_list
                        {
                        {
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
                                {
                                {
                                        std::ostringstream ret;
                                        std::ostringstream ret;
                                        ret << "Duplicated symbol '" << $1 << "'\n";
                                        ret << "Duplicated symbol '" << $1 << "'\n";
                                        throw ret.str();
                                        throw ret.str();
                                }
                                }
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << $2;
                                ss << $2;
                                unsigned int Size;
                                unsigned int Size;
                                ss >> Size;
                                ss >> Size;
                                gAutoVarMap[ $1 ] = AllocAutoVar(Size);
                                gAutoVarMap[ $1 ] = AllocAutoVar(Size);
                        }
                        }
                        |
                        |
                        IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE COMMA auto_var_list
                        IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE COMMA auto_var_list
                        {
                        {
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
                                {
                                {
                                std::ostringstream ret;
                                std::ostringstream ret;
                                ret << "Duplicated symbol " << $1 << "'\n";
                                ret << "Duplicated symbol " << $1 << "'\n";
                                throw ret.str();
                                throw ret.str();
                                }
                                }
                                gAutoVarMap[ $1 ] = AllocAutoVar();
                                gAutoVarMap[ $1 ] = AllocAutoVar();
                                unsigned int Destination = gAutoVarMap[ $1 ];
                                unsigned int Destination = gAutoVarMap[ $1 ];
                                I.ClearWriteChannel();
                                I.ClearWriteChannel();
                                unsigned int ImmediateValue;
                                unsigned int ImmediateValue;
                                {
                                {
                                I.SetDestinationAddress( Destination );
                                I.SetDestinationAddress( Destination );
                                I.SetWriteChannel(ECHANNEL_X);
                                I.SetWriteChannel(ECHANNEL_X);
                                std::string StringHex = $4;
                                std::string StringHex = $4;
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << std::hex << StringHex;
                                ss << std::hex << StringHex;
                                ss >> ImmediateValue;
                                ss >> ImmediateValue;
                                I.SetImm( ImmediateValue );
                                I.SetImm( ImmediateValue );
                                I.SetDestZero( true );
                                I.SetDestZero( true );
                                I.SetSrc1Displace( false );
                                I.SetSrc1Displace( false );
                                I.SetSrc0Displace( true );
                                I.SetSrc0Displace( true );
                                I.SetCode( EOPERATION_ADD );
                                I.SetCode( EOPERATION_ADD );
                                I.mSourceLine = GetCurrentLineNumber( yylloc );
                                I.mSourceLine = GetCurrentLineNumber( yylloc );
                                mInstructions.push_back(I);
                                mInstructions.push_back(I);
                                I.Clear();
                                I.Clear();
                                }
                                }
                                {
                                {
                                I.SetDestinationAddress( Destination );
                                I.SetDestinationAddress( Destination );
                                I.SetWriteChannel(ECHANNEL_Y);
                                I.SetWriteChannel(ECHANNEL_Y);
                                std::string StringHex = $6;
                                std::string StringHex = $6;
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << std::hex << StringHex;
                                ss << std::hex << StringHex;
                                ss >> ImmediateValue;
                                ss >> ImmediateValue;
                                I.SetImm( ImmediateValue );
                                I.SetImm( ImmediateValue );
                                I.SetDestZero( true );
                                I.SetDestZero( true );
                                I.SetSrc1Displace( false );
                                I.SetSrc1Displace( false );
                                I.SetSrc0Displace( true );
                                I.SetSrc0Displace( true );
                                I.SetCode( EOPERATION_ADD );
                                I.SetCode( EOPERATION_ADD );
                                mInstructions.push_back(I);
                                mInstructions.push_back(I);
                                I.Clear();
                                I.Clear();
                                }
                                }
                                {
                                {
                                I.SetDestinationAddress( Destination );
                                I.SetDestinationAddress( Destination );
                                I.SetWriteChannel(ECHANNEL_Z);
                                I.SetWriteChannel(ECHANNEL_Z);
                                std::string StringHex = $8;
                                std::string StringHex = $8;
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << std::hex << StringHex;
                                ss << std::hex << StringHex;
                                ss >> ImmediateValue;
                                ss >> ImmediateValue;
                                I.SetImm( ImmediateValue );
                                I.SetImm( ImmediateValue );
                                I.SetDestZero( true );
                                I.SetDestZero( true );
                                I.SetSrc1Displace( false );
                                I.SetSrc1Displace( false );
                                I.SetSrc0Displace( true );
                                I.SetSrc0Displace( true );
                                I.SetCode( EOPERATION_ADD );
                                I.SetCode( EOPERATION_ADD );
                                mInstructions.push_back(I);
                                mInstructions.push_back(I);
                                I.Clear();
                                I.Clear();
                                }
                                }
                        }
                        }
                        |
                        |
                        IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE
                        IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE
                        {
                        {
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
                                {
                                {
                                std::ostringstream ret;
                                std::ostringstream ret;
                                ret << "Duplicated symbol " << $1 << "'\n";
                                ret << "Duplicated symbol " << $1 << "'\n";
                                throw ret.str();
                                throw ret.str();
                                }
                                }
                                gAutoVarMap[ $1 ] = AllocAutoVar();
                                gAutoVarMap[ $1 ] = AllocAutoVar();
                                unsigned int Destination = gAutoVarMap[ $1 ];
                                unsigned int Destination = gAutoVarMap[ $1 ];
                                I.SetDestZero( true );
                                I.SetDestZero( true );
                                I.SetSrc1Displace( false );
                                I.SetSrc1Displace( false );
                                I.SetSrc0Displace( true );
                                I.SetSrc0Displace( true );
                                I.ClearWriteChannel();
                                I.ClearWriteChannel();
                                unsigned int ImmediateValue;
                                unsigned int ImmediateValue;
                                {
                                {
                                I.SetDestinationAddress( Destination );
                                I.SetDestinationAddress( Destination );
                                I.SetWriteChannel(ECHANNEL_X);
                                I.SetWriteChannel(ECHANNEL_X);
                                std::string StringHex = $4;
                                std::string StringHex = $4;
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << std::hex << StringHex;
                                ss << std::hex << StringHex;
                                ss >> ImmediateValue;
                                ss >> ImmediateValue;
                                I.SetImm( ImmediateValue );
                                I.SetImm( ImmediateValue );
                                I.SetDestZero( true );
                                I.SetDestZero( true );
                                I.SetSrc1Displace( false );
                                I.SetSrc1Displace( false );
                                I.SetSrc0Displace( true );
                                I.SetSrc0Displace( true );
                                I.SetCode( EOPERATION_ADD );
                                I.SetCode( EOPERATION_ADD );
                                I.mSourceLine = GetCurrentLineNumber( yylloc );
                                I.mSourceLine = GetCurrentLineNumber( yylloc );
                                mInstructions.push_back(I);
                                mInstructions.push_back(I);
                                I.Clear();
                                I.Clear();
                                }
                                }
                                {
                                {
                                I.SetDestinationAddress( Destination );
                                I.SetDestinationAddress( Destination );
                                I.SetWriteChannel(ECHANNEL_Y);
                                I.SetWriteChannel(ECHANNEL_Y);
                                std::string StringHex = $6;
                                std::string StringHex = $6;
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << std::hex << StringHex;
                                ss << std::hex << StringHex;
                                ss >> ImmediateValue;
                                ss >> ImmediateValue;
                                I.SetImm( ImmediateValue );
                                I.SetImm( ImmediateValue );
                                I.SetDestZero( true );
                                I.SetDestZero( true );
                                I.SetSrc1Displace( false );
                                I.SetSrc1Displace( false );
                                I.SetSrc0Displace( true );
                                I.SetSrc0Displace( true );
                                I.SetCode( EOPERATION_ADD );
                                I.SetCode( EOPERATION_ADD );
                                mInstructions.push_back(I);
                                mInstructions.push_back(I);
                                I.Clear();
                                I.Clear();
                                }
                                }
                                {
                                {
                                I.SetDestinationAddress( Destination );
                                I.SetDestinationAddress( Destination );
                                I.SetWriteChannel(ECHANNEL_Z);
                                I.SetWriteChannel(ECHANNEL_Z);
                                std::string StringHex = $8;
                                std::string StringHex = $8;
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << std::hex << StringHex;
                                ss << std::hex << StringHex;
                                ss >> ImmediateValue;
                                ss >> ImmediateValue;
                                I.SetImm( ImmediateValue );
                                I.SetImm( ImmediateValue );
                                I.SetDestZero( true );
                                I.SetDestZero( true );
                                I.SetSrc1Displace( false );
                                I.SetSrc1Displace( false );
                                I.SetSrc0Displace( true );
                                I.SetSrc0Displace( true );
                                I.SetCode( EOPERATION_ADD );
                                I.SetCode( EOPERATION_ADD );
                                mInstructions.push_back(I);
                                mInstructions.push_back(I);
                                I.Clear();
                                I.Clear();
                                }
                                }
                        }
                        }
                        |
                        |
                        IDENTIFIER array_size
                        IDENTIFIER array_size
                        {
                        {
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
                                {
                                {
                                        std::ostringstream ret;
                                        std::ostringstream ret;
                                        ret << "Duplicated symbol " << $1 << "'\n";
                                        ret << "Duplicated symbol " << $1 << "'\n";
                                        throw ret.str();
                                        throw ret.str();
                                }
                                }
                                std::stringstream ss;
                                std::stringstream ss;
                                ss << std::hex << $2;
                                ss << std::hex << $2;
                                unsigned int Size;
                                unsigned int Size;
                                ss >> Size;
                                ss >> Size;
                                ////std::cout  << "Array Size is " << Size << " " << $2 << "\n";
                                ////std::cout  << "Array Size is " << Size << " " << $2 << "\n";
                                gAutoVarMap[ $1 ] = AllocAutoVar(Size);
                                gAutoVarMap[ $1 ] = AllocAutoVar(Size);
                        }
                        }
                        ;
                        ;
array_size
array_size
                 :
                 :
                 {
                 {
                 $$ = "1";
                 $$ = "1";
                 }
                 }
                 |
                 |
                 OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE
                 OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE
                 {
                 {
                 $$ = $2;
                 $$ = $2;
                 }
                 }
                 ;
                 ;
%%
%%
// Error function throws an exception (std::string) with the location and error message
// Error function throws an exception (std::string) with the location and error message
void Theia::Parser::error(const Theia::Parser::location_type &loc,
void Theia::Parser::error(const Theia::Parser::location_type &loc,
                                          const std::string &msg) {
                                          const std::string &msg) {
        std::ostringstream ret;
        std::ostringstream ret;
        ret << "Parser Error at " << loc << ": "  << msg;
        ret << "Parser Error at " << loc << ": "  << msg;
        throw ret.str();
        throw ret.str();
}
}
// Now that we have the Parser declared, we can declare the Scanner and implement
// Now that we have the Parser declared, we can declare the Scanner and implement
// the yylex function
// the yylex function
#include "Scanner.h"
#include "Scanner.h"
static int yylex(Theia::Parser::semantic_type * yylval,
static int yylex(Theia::Parser::semantic_type * yylval,
                 Theia::Parser::location_type * yylloc,
                 Theia::Parser::location_type * yylloc,
                 Theia::Scanner &scanner) {
                 Theia::Scanner &scanner) {
        return scanner.yylex(yylval, yylloc);
        return scanner.yylex(yylval, yylloc);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.