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] - Rev 216
Go to most recent revision | Compare with Previous | Blame | View Log
/**********************************************************************************Theia, Ray Cast Programable graphic Processing Unit.Copyright (C) 2012 Diego Valverde (diego.valverde.g@gmail.com)This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.***********************************************************************************/%require "2.4.1"%skeleton "lalr1.cc"%defines%error-verbose%locations%define namespace "Theia"%define parser_class_name "Parser"%parse-param { Theia::Scanner &scanner }%parse-param { std::map<std::string,unsigned int> & mSymbolMap }%parse-param { std::vector< Instruction > &mInstructions }%parse-param { bool &mGenerateFixedPointArithmetic }%lex-param { Theia::Scanner &scanner }%code requires {#include <string>#include <sstream>#include <iomanip>#include <bitset>#include <map>#include "Instruction.h"#include <vector>// We want to return a string#define YYSTYPE std::stringnamespace Theia{// Forward-declare the Scanner class; the Parser needs to be assigned a// Scanner, but the Scanner can't be declared without the Parserclass Scanner;// We use a map to store the INI datatypedef std::map<std::string, std::map<std::string, std::string> > mapData;}}%code{#include "Instruction.h"#include <vector>Instruction I,tmpI;std::vector< unsigned int > gBranchStack;static int gInsertedInstructions = 0;static int gWhileLoopAddress = 0;#define FUNCTION_PARAM_START_REGION 4#define FUNCTION_PARAM_LAST_REGION 10std::map<std::string, unsigned int> gFunctionParameters;std::map<std::string, unsigned int> gAutoVarMap;std::map<std::string, unsigned int> gThreadMap; //Key: Symbol, value: start code addrbool gThreadScope = false;#define AUTOVAR_START_REGION 9#define THREAD_OFFSET 128unsigned int gExtraDestModifications = 0;unsigned int gAutoVarIndex = AUTOVAR_START_REGION;unsigned int gThreadAutoVarIndex = THREAD_OFFSET;unsigned int gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;//----------------------------------------------------------unsigned int GetNextFunctionParamRegister(){unsigned Ret = gFunctionParameterIndex++;return Ret;}//----------------------------------------------------------void AddFunctionParameter( std::string aVar, Theia::Parser::location_type yylloc){////std::cout << "Adding " << aVar << "\n";if (gFunctionParameterIndex+1 > FUNCTION_PARAM_LAST_REGION){std::ostringstream ret;ret << "Cannot allocate more parameters '" << aVar << "' at line " << yylloc << " \n";throw ret.str();}if (gFunctionParameters.find(aVar) != gFunctionParameters.end()){std::ostringstream ret;ret << "Parameter '" << aVar << "' at line " << yylloc << " is already defined\n";throw ret.str();}gFunctionParameters[ aVar ] = gFunctionParameterIndex++;}//----------------------------------------------------------std::string GetRegisterFromFunctionParameter( std::string aVar ){////std::cout << "Looking for " << aVar << "\n";if (gFunctionParameters.find(aVar) == gFunctionParameters.end())return "NULL";std::ostringstream ss;ss << gFunctionParameters[ aVar ];return ("R" + ss.str());}//----------------------------------------------------------unsigned int GetCurretAutoVarFrameSize(){return gAutoVarMap.size();}//----------------------------------------------------------std::string GetRegisterFromAutoVar( std::string aVar, Theia::Parser::location_type yylloc ){if (gAutoVarMap.find(aVar) == gAutoVarMap.end()){std::ostringstream ret;ret << "Undefined variable '" << aVar << "' at line " << yylloc << " \n";throw ret.str();}std::ostringstream ss;ss << gAutoVarMap[ aVar ];return ("R" + ss.str());}//----------------------------------------------------------int GetCurrentLineNumber( const Theia::Parser::location_type &loc ){int ret = -1;std::stringstream ss2;std::string where;ss2 << loc;ss2 >> where;where.erase(where.find_first_of("."));std::stringstream ss3;ss3 << where;ss3 >> ret;return ret;}//----------------------------------------------------------unsigned int AllocAutoVar( unsigned int aSize = 1){if (!gThreadScope){gAutoVarIndex += aSize;return gAutoVarIndex - (aSize-1);}else{gThreadAutoVarIndex += aSize;return (gThreadAutoVarIndex - (aSize-1));}}//----------------------------------------------------------void ClearFunctionParameterMap(){gFunctionParameters.clear();gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;}//----------------------------------------------------------void ClearAutoVarMap(){gAutoVarMap.clear();gAutoVarIndex = AUTOVAR_START_REGION;}//----------------------------------------------------------unsigned int gTempRegisterIndex = 1;unsigned int GetFreeTempRegister( ){if (!gThreadScope)return gAutoVarIndex + (gTempRegisterIndex++);elsereturn gThreadAutoVarIndex + (gTempRegisterIndex++);}//----------------------------------------------------------void ResetTempRegisterIndex( void ){gTempRegisterIndex = 1;}//----------------------------------------------------------bool IsSwizzled( std::string aSource){if (aSource.find(".") != std::string::npos)return true;elsereturn false;}//----------------------------------------------------------void SetSwizzleAndSign( unsigned int aSourceIndex, std::string aSwizzle, Instruction & I ){std::string Reg,X,Y,Z, junk;std::stringstream ss( aSwizzle );ss >> Reg >> junk >> X >> Y >> Z;if (aSourceIndex == 1){if (X == "X") { I.SetSrc1SwizzleX(SWX_X); }if (X == "Y") { I.SetSrc1SwizzleX(SWX_Y); }if (X == "Z") { I.SetSrc1SwizzleX(SWX_Z); }if (X == "-X") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_X); }if (X == "-Y") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Y); }if (X == "-Z") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Z); }if (Y == "X") { I.SetSrc1SwizzleY(SWY_X); }if (Y == "Y") { I.SetSrc1SwizzleY(SWY_Y); }if (Y == "Z") { I.SetSrc1SwizzleY(SWY_Z); }if (Y == "-X") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_X); }if (Y == "-Y") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Y); }if (Y == "-Z") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Z); }if (Z == "X") { I.SetSrc1SwizzleZ(SWZ_X); }if (Z == "Y") { I.SetSrc1SwizzleZ(SWZ_Y); }if (Z == "Z") { I.SetSrc1SwizzleZ(SWZ_Z); }if (Z == "-X") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_X); }if (Z == "-Y") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Y); }if (Z == "-Z") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Z); }} else {if (X == "X") { I.SetSrc0SwizzleX(SWX_X); }if (X == "Y") { I.SetSrc0SwizzleX(SWX_Y); }if (X == "Z") { I.SetSrc0SwizzleX(SWX_Z); }if (X == "-X") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_X); }if (X == "-Y") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Y); }if (X == "-Z") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Z); }if (Y == "X") { I.SetSrc0SwizzleY(SWY_X); }if (Y == "Y") { I.SetSrc0SwizzleY(SWY_Y); }if (Y == "Z") { I.SetSrc0SwizzleY(SWY_Z); }if (Y == "-X") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_X); }if (Y == "-Y") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Y); }if (Y == "-Z") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Z); }if (Z == "X") { I.SetSrc0SwizzleZ(SWZ_X); }if (Z == "Y") { I.SetSrc0SwizzleZ(SWZ_Y); }if (Z == "Z") { I.SetSrc0SwizzleZ(SWZ_Z); }if (Z == "-X") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_X); }if (Z == "-Y") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Y); }if (Z == "-Z") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Z); }}}//----------------------------------------------------------void StoreReturnAddress( std::vector<Instruction> & aInstructions, Theia::Parser::location_type & yylloc ){I.SetCode( EOPERATION_ADD );I.mComment = "store return address**";I.SetImm( aInstructions.size()+4 );I.SetWriteChannel(ECHANNEL_X);I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );I.SetDestZero( true );I.mSourceLine = GetCurrentLineNumber( yylloc );aInstructions.push_back( I );I.Clear();}//----------------------------------------------------------void SavePreviousFramePointer( std::vector<Instruction> & aInstructions ){I.SetCode( EOPERATION_ADD );I.mComment = "store current frame offset";I.SetWriteChannel(ECHANNEL_Y);I.SetDestinationAddress( SPR_CONTROL_REGISTER );I.SetSrc1Address(SPR_CONTROL_REGISTER);I.SetSrc1SwizzleX(SWX_X);I.SetSrc1SwizzleY(SWY_X);I.SetSrc1SwizzleZ(SWZ_X);I.SetSrc0Address(0);I.SetSrc0SwizzleX(SWX_X);I.SetSrc0SwizzleY(SWY_X);I.SetSrc0SwizzleZ(SWZ_X);aInstructions.push_back( I );I.Clear();}//----------------------------------------------------------void SetIndexRegister( unsigned int aIndex, std::vector<Instruction> & aInstructions ){Instruction Tmp;Tmp.SetCode( EOPERATION_ADD );Tmp.mComment = "store array index register";Tmp.SetWriteChannel(ECHANNEL_Z);Tmp.SetDestinationAddress( SPR_CONTROL_REGISTER );Tmp.SetSrc1Address( aIndex );Tmp.SetSrc1Displace( true );Tmp.SetSrc1SwizzleX(SWX_X);Tmp.SetSrc1SwizzleY(SWY_X);Tmp.SetSrc1SwizzleZ(SWZ_X);Tmp.SetSrc0Address(0);Tmp.SetSrc0SwizzleX(SWX_X);Tmp.SetSrc0SwizzleY(SWY_X);Tmp.SetSrc0SwizzleZ(SWZ_X);//Tmp.SetImm( aIndex );//Tmp.SetDestZero( true );aInstructions.push_back( Tmp );}//----------------------------------------------------------void UpdateFramePointer( std::vector<Instruction> & aInstructions ){I.SetCode( EOPERATION_ADD );I.mComment = "displace next frame offset by the number of auto variables in current frame";I.SetWriteChannel(ECHANNEL_X);I.SetDestinationAddress( SPR_CONTROL_REGISTER );I.SetImm( GetCurretAutoVarFrameSize() );I.SetDestZero( false );aInstructions.push_back( I );I.Clear();}//----------------------------------------------------------void CallFunction( std::string aFunctionName, std::vector<Instruction> & aInstructions, std::map<std::string,unsigned int> & aSymbolMap){I.SetCode( EOPERATION_ADD );I.mComment = "call the function";I.SetBranchFlag( true );I.SetBranchType( EBRANCH_ALWAYS );//Now do the branchif (aSymbolMap.find(aFunctionName) == aSymbolMap.end())I.SetDestinationSymbol( "@"+aFunctionName );elseI.SetDestinationAddress( aSymbolMap[ aFunctionName ] );aInstructions.push_back( I );I.Clear();}//----------------------------------------------------------void SetDestinationFromRegister( std::string aDestination, Instruction & aInst, bool Imm ){//Look for displament addressing modeif (aDestination.find("OFFSET") != std::string::npos){aDestination.erase(aDestination.find("OFFSET"));////std::cout << "^_^ left_hand_side " << Destination << "\n";if (Imm == true)aInst.SetSrc0Displace( true ); //When Imm == 0, then setting this makes offsetelseaInst.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset}if (aDestination.find(".") != std::string::npos){aInst.ClearWriteChannel();if (aDestination.find("x") != std::string::npos)aInst.SetWriteChannel(ECHANNEL_X);if (aDestination.find("y") != std::string::npos)aInst.SetWriteChannel(ECHANNEL_Y);if (aDestination.find("z") != std::string::npos)aInst.SetWriteChannel(ECHANNEL_Z);aDestination.erase(aDestination.find("."));}aInst.SetDestinationAddress( atoi(aDestination.c_str()+1) );}//----------------------------------------------------------void PopulateSourceRegisters( std::string a1, std::string a2, Instruction & I, std::vector<Instruction> & aInstructions ){if ( a1.find("R") == std::string::npos ){//This is for constantsunsigned int ImmediateValue;std::string StringHex = a1;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetImm( ImmediateValue );} else {if (a1.find("array_element") != std::string::npos){std::string Index = a1.substr(a1.find("array_element"));////std::cout << "XXXXX " << Index << "\n\n\n";Index = Index.substr(Index.find_first_not_of("array_element R"));////std::cout << "XXXXX " << Index << "\n\n\n";SetIndexRegister( atoi(Index.c_str()), aInstructions );a1.erase(a1.find("array_element"));I.SetSrc0Displace( true );I.SetSrc1Displace( true );I.SetImmBit( true );}//Look for displament addressing modeelse if (a1.find("OFFSET") != std::string::npos){a1.erase(a1.find("OFFSET"));////std::cout << "^_^ a1" << a1 << "\n";I.SetSrc1Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset}std::string Src1 = a1;if (IsSwizzled( Src1 )){SetSwizzleAndSign( 1, Src1, I );Src1.erase(Src1.find("."));}I.SetSrc1Address( atoi( Src1.c_str()+1 ) );}if ( a2.find("R") == std::string::npos){} else {//Look for displament addressing modeif (a2.find("OFFSET") != std::string::npos){a2.erase(a2.find("OFFSET"));////std::cout << "^_^ a2 " << a2 << "\n";I.SetSrc0Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset}std::string Src0 = a2;if (IsSwizzled( Src0 )){SetSwizzleAndSign( 0, Src0, I );Src0.erase(Src0.find("."));}I.SetSrc0Address( atoi( Src0.c_str()+1 ) );}}//----------------------------------------------------------void ClearNextFunctionParamRegister(){gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;}//----------------------------------------------------------void AddFunctionInputList( std::string aVar, std::vector<Instruction> & aInstructions,Theia::Parser::location_type yylloc){//Get the value from the variable//Copy the value into function parameter registerunsigned FunctionParamReg = GetNextFunctionParamRegister();I.Clear();I.SetCode( EOPERATION_ADD );I.mComment = "copy the value into function parameter register";I.SetWriteChannel(ECHANNEL_XYZ);//I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offsetI.SetDestinationAddress( FunctionParamReg );if (aVar.find("R") != std::string::npos){if (aVar.find("OFFSET") != std::string::npos){I.SetSrc1Displace( true );aVar.erase(aVar.find("OFFSET"));}I.SetSrc1Address(atoi(aVar.c_str()+1));return;}std::string Reg = GetRegisterFromFunctionParameter( aVar );if (Reg == "NULL"){Reg = GetRegisterFromAutoVar( aVar, yylloc );I.SetSrc1Address(atoi(Reg.c_str()+1));I.SetSrc1Displace( true );} else {I.SetSrc1Address(atoi(Reg.c_str()+1));I.SetSrc1Displace( false );}I.SetSrc1SwizzleX(SWX_X);I.SetSrc1SwizzleY(SWY_Y);I.SetSrc1SwizzleZ(SWZ_Z);I.SetSrc0Address(0);I.SetSrc0SwizzleX(SWX_X);I.SetSrc0SwizzleY(SWY_X);I.SetSrc0SwizzleZ(SWZ_X);aInstructions.push_back( I );I.Clear();}//----------------------------------------------------------void SetExpressionDestination( std::string aStringDestination, Instruction & I ){std::string Destination = aStringDestination;//Look for indirect addressingif (Destination.find("INDEX") != std::string::npos){std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);Destination.erase(Destination.find("INDEX"));I.SetImm( 0 );I.SetCode( EOPERATION_ADD );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("."));}I.SetDestinationAddress( atoi(Destination.c_str()+1) );} else {//Look for displament addressing modeif (Destination.find("OFFSET") != std::string::npos){Destination.erase(Destination.find("OFFSET"));I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset}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("."));}I.SetDestinationAddress( atoi(Destination.c_str()+1) );}}//----------------------------------------------------------bool SourceNull( std::string aSource ){if (aSource == "NULL")return true;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){bool DestinationHasOffset = false;bool DetinationHasIndex = false;bool Source0HasOffset = false;bool Source1HasOffset = false;bool Source1HasIndex = false;bool Source0HasIndex = false;if (aDestination.find("INDEX") != std::string::npos){std::string ArrayIndex = aDestination.substr(aDestination.find("INDEX")+5);aSource1 = ArrayIndex;DetinationHasIndex = true;}if (aSource1.find("INDEX") != std::string::npos)Source1HasIndex = true;if (aSource0.find("INDEX") != std::string::npos)Source0HasIndex = true;if (aDestination.find("OFFSET") != std::string::npos)DestinationHasOffset = true;if (aSource0.find("OFFSET") != std::string::npos)Source0HasOffset = true;if (aSource1.find("OFFSET") != std::string::npos)Source1HasOffset = true;if (IsSwizzled( aSource1 ))SetSwizzleAndSign( 1, aSource1, I );I.SetSrc1Address( atoi( aSource1.c_str()+1 ) );if (IsSwizzled( aSource0 ))SetSwizzleAndSign( 0, aSource0, I );I.SetSrc0Address( atoi( aSource0.c_str()+1 ) );//Fisrt take care of the destination write channelif (aDestination.find(".") != std::string::npos){I.ClearWriteChannel();if (aDestination.find("x") != std::string::npos)I.SetWriteChannel(ECHANNEL_X);if (aDestination.find("y") != std::string::npos)I.SetWriteChannel(ECHANNEL_Y);if (aDestination.find("z") != std::string::npos)I.SetWriteChannel(ECHANNEL_Z);aDestination.erase(aDestination.find("."));} else {I.SetWriteChannel(ECHANNEL_XYZ);}//Now set the destination IndexI.SetDestinationAddress( atoi(aDestination.c_str()+1) );//Now determine the addressing mode//Simple addressing modesif (!aHasLiteral && !DetinationHasIndex && !Source0HasIndex && !Source1HasIndex){I.SetAddressingMode( DestinationHasOffset,Source1HasOffset,Source0HasOffset);return;}I.SetImmBit( true ); //This is to set the IMM bit = 1, may be overwritten latter//Complex addressing modesif(aHasLiteral &&!SourceNull( aSource0 ) &&!Source0HasOffset &&!Source1HasOffset &&!DestinationHasOffset){I.SetAddressingMode( false,false,false);I.SetImm( aLiteral );}elseif(aHasLiteral &&!SourceNull( aSource0 ) &&Source0HasOffset &&!Source0HasIndex &&DestinationHasOffset){I.SetAddressingMode( false,false,true);I.SetImm( aLiteral );}elseif(!aHasLiteral &&!SourceNull( aSource1 ) &&!Source1HasOffset &&!SourceNull( aSource0 ) &&Source0HasOffset &&Source0HasIndex &&DestinationHasOffset){I.SetAddressingMode( false,true,false);}elseif(!aHasLiteral &&!Source1HasOffset &&!SourceNull( aSource0 ) &&Source0HasOffset &&!Source0HasIndex &&DestinationHasOffset &&DetinationHasIndex){I.SetAddressingMode( false,true,true);}elseif(aHasLiteral &&SourceNull( aSource0 ) &&!DestinationHasOffset &&!DetinationHasIndex){I.SetAddressingMode( true,false,false);I.SetImm( aLiteral );}elseif(aHasLiteral &&SourceNull( aSource0 ) &&DestinationHasOffset &&!DetinationHasIndex){I.SetAddressingMode( true,false,true);I.SetImm( aLiteral );}elseif(!aHasLiteral &&Source1HasOffset &&Source1HasIndex &&SourceNull( aSource0 ) &&DestinationHasOffset &&!DetinationHasIndex){I.SetAddressingMode( true,true,false);}elseif(!aHasLiteral &&Source1HasOffset &&Source1HasIndex &&Source0HasOffset &&!Source0HasIndex &&DestinationHasOffset &&!DetinationHasIndex){I.SetAddressingMode( true,true,true);} else {std::ostringstream ret;ret << "Could not determine addressing mode at line " << yylloc << " \n";throw ret.str();}}//-------------------------------------------------------------void PopulateBoolean(EBRANCHTYPE aBranchType, std::string Source1, std::string Source0, Instruction & I, std::vector<Instruction> & aInstructions, Theia::Parser::location_type & yylloc ){if (Source0.find("R") == std::string::npos){I.mSourceLine = GetCurrentLineNumber( yylloc );I.SetCode( EOPERATION_ADD );unsigned int TempRegIndex = GetFreeTempRegister();I.SetDestinationAddress( TempRegIndex );unsigned int ImmediateValue;std::string StringHex = Source0;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetImm( ImmediateValue );I.SetDestZero( true );I.SetSrc0Displace( true );I.SetWriteChannel(ECHANNEL_X);I.SetWriteChannel(ECHANNEL_Y);I.SetWriteChannel(ECHANNEL_Z);aInstructions.push_back(I);I.Clear();std::stringstream ss2;ss2 << "R" << TempRegIndex;ss2 >> Source0;Source0 += " OFFSET ";}elseI.mSourceLine = GetCurrentLineNumber( yylloc );I.SetCode( EOPERATION_ADD );I.SetSrc0SignX( true );I.SetSrc0SignY( true );I.SetSrc0SignZ( true );I.SetBranchFlag( true );I.ClearWriteChannel();I.SetBranchType( aBranchType );PopulateSourceRegisters( Source1, Source0, I, aInstructions);aInstructions.push_back(I);I.Clear();////std::cout << "pushing code at position " << (mInstructions.size() - 1) << "\n";gBranchStack.push_back(aInstructions.size() - 1);ResetTempRegisterIndex();}//-------------------------------------------------------------// Prototype for the yylex functionstatic int yylex(Theia::Parser::semantic_type * yylval,Theia::Parser::location_type * yylloc,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 IDENTIFIER SQRT SCALE UNSCALE USING FIXED_POINT COMMA OPEN_SQUARE_BRACE CLOSE_SQUARE_BRACE WHILE ADD_EQ THREAD START BITWISE_AND BITWISE_OR OUT%%statement_list: //empty|statement_list statement|statement;statement:AUTO auto_var_list EOS|USING FIXED_POINT EOS{mGenerateFixedPointArithmetic = true;}|EXIT EOS{//Insert a stupid NOP before the exit... is a bug but easier to just patch like this...I.Clear();I.mComment = "NOP";I.SetCode( EOPERATION_NOP );mInstructions.push_back(I);I.Clear();I.SetEofFlag(true);I.mComment = "Set the Exit bit";I.SetCode( EOPERATION_ADD );mInstructions.push_back(I);I.Clear();}|RETURN expression EOS{//////////////////////////////////////////////////////////////////////////////// This means this that the expression was just a constant.// No operations were inserted//////////////////////////////////////////////////////////////////////////////if (gInsertedInstructions == 0){I.Clear();I.SetCode(EOPERATION_ADD);I.mComment ="Set the return value";if ($3.find("R") != std::string::npos){PopulateInstruction( "R1", $2,"R0 . X X X",I,yylloc);}else{unsigned int ImmediateValue = 0;std::string StringHex = $3;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;PopulateInstruction( "R1", $3,"NULL",I, yylloc, true, ImmediateValue);}mInstructions.push_back(I);I.Clear();} else {mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc);gInsertedInstructions = 0;mInstructions.back().mComment ="Assigning return value";mInstructions.back().SetDestinationAddress( RETURN_VALUE_REGISTER );}ResetTempRegisterIndex();I.SetCode( EOPERATION_ADD );I.mComment = "Restore previous function frame offset";I.ClearWriteChannel();I.SetWriteChannel(ECHANNEL_X);I.SetDestinationAddress( SPR_CONTROL_REGISTER );I.SetSrc1Address(SPR_CONTROL_REGISTER);I.SetSrc1SwizzleX(SWX_Y);I.SetSrc1SwizzleY(SWY_Y);I.SetSrc1SwizzleZ(SWZ_Y);I.SetSrc0Address(0);I.SetSrc0SwizzleX(SWX_X);I.SetSrc0SwizzleY(SWY_X);I.SetSrc0SwizzleZ(SWZ_X);mInstructions.push_back( I );I.Clear();//Now returnI.SetImm( 0 );I.SetCode( EOPERATION_ADD );I.mComment = "return from function";I.SetBranchFlag( true );I.SetBranchType( EBRANCH_ALWAYS );I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );mInstructions.push_back(I);I.Clear();}|RETURN EOS{I.SetCode( EOPERATION_ADD );I.mComment = "Restore previous function frame offset";I.SetWriteChannel(ECHANNEL_X);I.SetDestinationAddress( SPR_CONTROL_REGISTER );I.SetSrc1Address(SPR_CONTROL_REGISTER);I.SetSrc1SwizzleX(SWX_Y);I.SetSrc1SwizzleY(SWY_Y);I.SetSrc1SwizzleZ(SWZ_Y);I.SetSrc0Address(0);I.SetSrc0SwizzleX(SWX_X);I.SetSrc0SwizzleY(SWY_X);I.SetSrc0SwizzleZ(SWZ_X);mInstructions.push_back( I );I.Clear();I.SetImm( 0 );I.SetCode( EOPERATION_ADD );I.mComment = "return from function";I.SetBranchFlag( true );I.SetBranchType( EBRANCH_ALWAYS );I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );mInstructions.push_back(I);I.Clear();}|left_hand_side ADD_EQ constant EOS{I.mSourceLine = GetCurrentLineNumber( yylloc );I.SetCode( EOPERATION_ADD );SetDestinationFromRegister( $1, I , true);unsigned int ImmediateValue;std::string StringHex = $3;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetImm( ImmediateValue );I.SetDestZero( false );mInstructions.push_back( I );I.Clear();}|left_hand_side MINUS MINUS EOS{I.mSourceLine = GetCurrentLineNumber( yylloc );I.SetCode( EOPERATION_ADD );SetDestinationFromRegister( $1, I, false );I.SetSrc0SignX( true );I.SetSrc0SignY( true );I.SetSrc0SignZ( true );std::string Destination = $1;if (Destination.find("OFFSET") != std::string::npos){I.SetSrc1Displace( true );Destination.erase(Destination.find("OFFSET"));}if (Destination.find(".") != std::string::npos)Destination.erase(Destination.find("."));I.SetSrc1Address(atoi(Destination.c_str()+1));I.SetSrc0Address(0);I.SetSrc0SwizzleX(SWX_Y);I.SetSrc0SwizzleY(SWY_Y);I.SetSrc0SwizzleZ(SWZ_Y);mInstructions.push_back( I );I.Clear();}|left_hand_side ADD ADD EOS{I.mSourceLine = GetCurrentLineNumber( yylloc );I.SetCode( EOPERATION_ADD );SetDestinationFromRegister( $1, I, false );std::string Destination = $1;if (Destination.find("OFFSET") != std::string::npos){I.SetSrc1Displace( true );Destination.erase(Destination.find("OFFSET"));}if (Destination.find(".") != std::string::npos)Destination.erase(Destination.find("."));I.SetSrc1Address(atoi(Destination.c_str()+1));I.SetSrc0Address(0);I.SetSrc0SwizzleX(SWX_Y);I.SetSrc0SwizzleY(SWY_Y);I.SetSrc0SwizzleZ(SWZ_Y);mInstructions.push_back( I );I.Clear();}|left_hand_side ASSIGN expression EOS{//////////////////////////////////////////////////////////////////////////////// This means this that the expression will write into the output memory// constant index//////////////////////////////////////////////////////////////////////////////if ($1.find("OUT") != std::string::npos && $1.find("INDEX") == std::string::npos ){//PopulateInstruction( "R0", "R0 . X X X",$3,I,yylloc);I.SetCode(EOPERATION_OUT);$1.erase($1.find("OUT"),3);unsigned int ImmediateValue;std::stringstream ss;ss << std::hex << $1;ss >> ImmediateValue;PopulateInstruction( $3, "R0 OFFSET", "R0 OFFSET", I, yylloc, true, ImmediateValue );#ifdef DEBUGI.PrintFields();#endifmInstructions.push_back(I);I.Clear();ResetTempRegisterIndex();goto LABEL_EXPRESSION_DONE;}//////////////////////////////////////////////////////////////////////////////// This means this that the expression will write into the output memory// variable index//////////////////////////////////////////////////////////////////////////////if ($1.find("OUT") != std::string::npos && $1.find("INDEX") != std::string::npos ){std::string Destination = $1;DCOUT << "!!!!!!!!!!!!!!!!!Destination " << Destination << "\n";std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);Destination.erase(Destination.find("INDEX"));I.SetDestZero( true ); //Use indexing for DSTI.SetWriteChannel(ECHANNEL_XYZ);PopulateSourceRegisters( IndexRegister + " OFFSET ", $3, I, mInstructions );//I.SetImm( 0 );I.SetCode( EOPERATION_OUT );std::string Source0 = $3;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;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));// 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 );I.Clear();ResetTempRegisterIndex();goto LABEL_EXPRESSION_DONE;}//////////////////////////////////////////////////////////////////////////////// This means this that the expression was just a constant.// No operations were inserted//////////////////////////////////////////////////////////////////////////////if (gInsertedInstructions == 0){I.Clear();I.SetCode(EOPERATION_ADD);I.mSourceLine = GetCurrentLineNumber(yylloc);if ($3.find("R") != std::string::npos){// case 1:// foo = 0; //$$ = R0 . X X X/* SetDestinationFromRegister( $1, I, false );PopulateSourceRegisters( $3, "R0 . X X X", I, mInstructions);*/PopulateInstruction( $1, "R0 . X X X",$3,I,yylloc);} else {// case 2:// foo = 0xcafe; //$$ = 0xcafeSetDestinationFromRegister( $1, I, true );unsigned int ImmediateValue = 0;std::string StringHex = $3;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;PopulateInstruction( $1, $3,"NULL",I, yylloc, true, ImmediateValue);}std::string strConstant = $3;mInstructions.push_back(I);I.Clear();ResetTempRegisterIndex();goto LABEL_EXPRESSION_DONE;}//////////////////////////////////////////////////////////////////////////////// This means that the last instruction which was inserted was a tripple// constant assignement, like foo = (1,2,3)//////////////////////////////////////////////////////////////////////////////if (mInstructions.back().mBisonFlagTrippleConstAssign){unsigned int LastIndex = mInstructions.size() - 1;mInstructions[LastIndex].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].mSourceLine = GetCurrentLineNumber( yylloc );if($1.find("OFFSET") == std::string::npos){mInstructions[LastIndex].SetAddressingMode(true,false,false);mInstructions[LastIndex-1].SetAddressingMode(true,false,false);mInstructions[LastIndex-2].SetAddressingMode(true,false,false);}ResetTempRegisterIndex();goto LABEL_EXPRESSION_DONE;}//////////////////////////////////////////////////////////////////////////////// Handle the case where the destination is an array of vector// ej: R = v1[ i ] + V2//////////////////////////////////////////////////////////////////////////////if (I.GetOperation() == 0 && $3.find("array_element") != std::string::npos){//No operation meaning the the expression only has a single variable//See if the expression returned is an array_elementif ($3.find("array_element") != std::string::npos){////std::cout << "expression is an array element\n\n";std::string Index = $3.substr($3.find("array_element"));Index = Index.substr(Index.find_first_not_of("array_element R"));SetIndexRegister( atoi(Index.c_str()), mInstructions );$3.erase($3.find("array_element"));SetExpressionDestination( $1, I );I.SetCode(EOPERATION_ADD);I.SetImmBit( true );I.SetDestZero( true );I.SetSrc1Displace( true );I.SetSrc0Displace( false );I.mSourceLine = GetCurrentLineNumber(yylloc);if ($3.find("OFFSET") != std::string::npos)$3.erase($3.find("OFFSET"));I.SetSrc1Address(atoi($3.c_str()+1));I.SetSrc0Address(0);mInstructions.push_back(I);I.Clear();}}else{mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc);gInsertedInstructions = 0;std::string Destination = $1;//std::cout << "DST " << Destination << " \n";//Look for indirect addressingif (Destination.find("INDEX") != std::string::npos){std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);Destination.erase(Destination.find("INDEX"));I.SetImm( 0 );I.SetCode( EOPERATION_ADD );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;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));// 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 );I.Clear();} else {if (mInstructions.back().GetImm()){//Look for displament addressing modeunsigned int AddressingMode = mInstructions.back().GetAddressingMode();if (Destination.find("OFFSET") != std::string::npos){//This means AddressMode is '101', so leave the way it ismInstructions.back().ClearWriteChannel();mInstructions.back().SetWriteChannel(ECHANNEL_Z);Destination.erase(Destination.find("OFFSET"));} else {//This is not supposed to have index, so change addressing mode to '100'mInstructions.back().SetDestZero( true );mInstructions.back().SetSrc1Displace( false );mInstructions.back().SetSrc0Displace( false );mInstructions.back().ClearWriteChannel();mInstructions.back().SetWriteChannel(ECHANNEL_Z);}} else {mInstructions.back().SetDestZero( false ); //First assume no offset was used//Look for displament addressing modeif (Destination.find("OFFSET") != std::string::npos){Destination.erase(Destination.find("OFFSET"));mInstructions.back().SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset}}if (Destination.find(".") != std::string::npos){mInstructions.back().ClearWriteChannel();if (Destination.find("x") != std::string::npos)mInstructions.back().SetWriteChannel(ECHANNEL_X);if (Destination.find("y") != std::string::npos)mInstructions.back().SetWriteChannel(ECHANNEL_Y);if (Destination.find("z") != std::string::npos)mInstructions.back().SetWriteChannel(ECHANNEL_Z);Destination.erase(Destination.find("."));}mInstructions.back().SetDestinationAddress( atoi($1.c_str()+1) );for (int i = 1; i <= gExtraDestModifications; i++ ){int idx = (mInstructions.size()-1)-i;mInstructions[idx].SetDestinationAddress( atoi($1.c_str()+1) );if (mInstructions[idx].GetImm()){//This is not supposed to have index, so change addressing mode to '100'mInstructions[idx].SetDestZero( true );mInstructions[idx].SetSrc1Displace( false );mInstructions[idx].SetSrc0Displace( false );}}gExtraDestModifications = 0;}ResetTempRegisterIndex();}LABEL_EXPRESSION_DONE:gInsertedInstructions = 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{mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()+1);gBranchStack.pop_back();//Now I need to put a GOTO so that the while gets evaluated again...//jump out of the ifI.Clear();I.SetCode( EOPERATION_ADD );I.mComment = "while loop goto re-eval boolean";I.SetDestinationAddress( gWhileLoopAddress );I.SetBranchFlag( true );I.SetBranchType( EBRANCH_ALWAYS );mInstructions.push_back(I);I.Clear();}| IFOPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACEOPEN_BRACE statement_list CLOSE_BRACEELSE{//jump out of the ifI.Clear();I.SetCode( EOPERATION_ADD );I.SetBranchFlag( true );I.SetBranchType( EBRANCH_ALWAYS );mInstructions.push_back(I);I.Clear();//Take care of the destination addr of the if statement.mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());gBranchStack.pop_back();//push the inconditional jump into the stackgBranchStack.push_back(mInstructions.size() - 1);////std::cout << "else\n";}OPEN_BRACE statement_list CLOSE_BRACE{mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());gBranchStack.pop_back();//Now push the JMP////std::cout << "END elseif\n";}|//NOW the if statementIF OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE OPEN_BRACE statement_list CLOSE_BRACE{mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());//mInstructions[gBranchStack.back()].mSourceLine = GetCurrentLineNumber(yylloc);gBranchStack.pop_back();////std::cout << "if closing at " << mInstructions.size() << "\n";}|FUNCTION IDENTIFIER OPEN_ROUND_BRACE function_argument_list CLOSE_ROUND_BRACE{////std::cout << "Function declaration for " << $2 << " at " << mInstructions.size() << "\n" ;mSymbolMap[ $2 ] = mInstructions.size();} OPEN_BRACE statement_list CLOSE_BRACE{//Clear the auto var index now that we leave the function scopeClearAutoVarMap();ClearFunctionParameterMap();//Now uddate the current SPR_CONTROL_REGISTER.x = SPR_CONTROL_REGISTER.yI.SetCode( EOPERATION_ADD );I.mComment = "Restore previous function frame offset";I.SetWriteChannel(ECHANNEL_X);I.SetDestinationAddress( SPR_CONTROL_REGISTER );I.SetSrc1Address(SPR_CONTROL_REGISTER);I.SetSrc1SwizzleX(SWX_Y);I.SetSrc1SwizzleY(SWY_Y);I.SetSrc1SwizzleZ(SWZ_Y);I.SetSrc0Address(0);I.SetSrc0SwizzleX(SWX_X);I.SetSrc0SwizzleY(SWY_X);I.SetSrc0SwizzleZ(SWZ_X);mInstructions.push_back( I );I.Clear();}|//Thread declarationTHREAD IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE{gThreadMap[ $2 ] = mInstructions.size();gThreadScope = true;}OPEN_BRACE statement_list CLOSE_BRACE{////std::cout << "Defining thread" << "\n";gThreadScope = false;ClearAutoVarMap();//Since the thread is done, then disable threadingI.SetCode( EOPERATION_ADD );I.mComment = "Disable multi-threading";I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );unsigned int Value = 0;I.SetImm( Value );I.SetDestZero( true );I.SetWriteChannel(ECHANNEL_Z);mInstructions.push_back( I );I.Clear();}|START IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE EOS{unsigned int ThreadCodeOffset = 0;////std::cout << "Starting thread" << "\n";if (gThreadMap.find($2) == gThreadMap.end()){std::ostringstream ret;ret << "Undefined thread '" << $2 << "' at line " << yylloc << " \n";ret << "Current version of the compiler needs thread defintion prior of thread instantiation\n";throw ret.str();} else {ThreadCodeOffset = gThreadMap[$2];//Now enable the multithreading and set instruction offsetI.SetCode( EOPERATION_ADD );std::ostringstream ss;ss << "Set thread instruction offset to 8'd" << ThreadCodeOffset;I.mComment = ss.str();I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );unsigned int Value = (ThreadCodeOffset << 1);I.SetImm( Value );I.SetDestZero( true );I.SetWriteChannel(ECHANNEL_Z);mInstructions.push_back( I );I.Clear();I.SetCode( EOPERATION_ADD );I.mComment = "Enable multi-threading";I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );Value = (ThreadCodeOffset << 1 | 1);I.SetImm( Value );I.SetDestZero( true );I.SetWriteChannel(ECHANNEL_Z);mInstructions.push_back( I );I.Clear();}}|left_hand_side ASSIGN IDENTIFIER OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS{////std::cout << "Function call returning to var\n";StoreReturnAddress( mInstructions, yylloc );SavePreviousFramePointer( mInstructions );UpdateFramePointer( mInstructions );CallFunction( $3, mInstructions, mSymbolMap );//Return value comes in R1, so let's store this in our variableI.SetCode( EOPERATION_ADD );SetDestinationFromRegister( $1, I, false );I.mComment = "grab the return value from the function";I.SetSrc1Address( RETURN_VALUE_REGISTER);I.SetSrc0Address(0);I.SetSrc0SwizzleX(SWX_X);I.SetSrc0SwizzleY(SWY_X);I.SetSrc0SwizzleZ(SWZ_X);mInstructions.push_back( I );I.Clear();ClearNextFunctionParamRegister();}|//Function callIDENTIFIER OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS{//Store the return addressStoreReturnAddress( mInstructions, yylloc );//Store the current SPR_CONTROL_REGISTER.x into the previous SPR_CONTROL_REGISTER.y//SPR_CONTROL_REGISTER.y = SPR_CONTROL_REGISTER.xxx + 0;I.SetCode( EOPERATION_ADD );I.mComment = "store current frame offset";I.SetWriteChannel(ECHANNEL_Y);I.SetDestinationAddress( SPR_CONTROL_REGISTER );I.SetSrc1Address(SPR_CONTROL_REGISTER);I.SetSrc1SwizzleX(SWX_X);I.SetSrc1SwizzleY(SWY_X);I.SetSrc1SwizzleZ(SWZ_X);I.SetSrc0Address(0);I.SetSrc0SwizzleX(SWX_X);I.SetSrc0SwizzleY(SWY_X);I.SetSrc0SwizzleZ(SWZ_X);mInstructions.push_back( I );I.Clear();//Now uddate the current SPR_CONTROL_REGISTER.x += number of auto variablesI.SetCode( EOPERATION_ADD );I.mComment = "displace next frame offset by the number of auto variables in current frame";I.SetWriteChannel(ECHANNEL_X);I.SetDestinationAddress( SPR_CONTROL_REGISTER );I.SetImm( GetCurretAutoVarFrameSize() );I.SetDestZero( false );mInstructions.push_back( I );I.Clear();//Call the function with a JMPI.SetCode( EOPERATION_ADD );I.mComment = "call the function";I.SetBranchFlag( true );I.SetBranchType( EBRANCH_ALWAYS );//Now do the branchif (mSymbolMap.find($1) == mSymbolMap.end()){// ////std::cout << "Error in line : " << $1 <<" undelcared IDENTIFIER\n";I.SetDestinationSymbol( "@"+$1 );// exit(1);} else {I.SetDestinationAddress( mSymbolMap[ $1 ] );}mInstructions.push_back( I );I.Clear();};function_input_list:|//emptyexpression COMMA function_input_list{AddFunctionInputList( $1, mInstructions,yylloc );}|expression{AddFunctionInputList( $1,mInstructions, yylloc );};function_argument_list:| //emptyIDENTIFIER COMMA function_argument_list{AddFunctionParameter( $1, yylloc );}|IDENTIFIER{AddFunctionParameter( $1, yylloc );};// <Exp> ::= <Exp> + <Term> |// <Exp> - <Term> |// <Term>// <Term> ::= <Term> * <Factor> |// <Term> / <Factor> |// <Factor>// <Factor> ::= x | y | ... |// ( <Exp> ) |// - <Factor> |// <Number>expression:expression ADD term{unsigned int TempRegIndex = GetFreeTempRegister();gExtraDestModifications = 0;I.SetCode( EOPERATION_ADD );I.SetDestinationAddress( TempRegIndex );I.SetDestZero( true ); //Use indexing for DSTI.SetWriteChannel(ECHANNEL_XYZ);PopulateSourceRegisters( $1, $3, I, mInstructions );mInstructions.push_back(I);gInsertedInstructions++;I.Clear();std::stringstream ss;ss << "R" << TempRegIndex << " OFFSET ";$$ = ss.str();}|expression MINUS term{gExtraDestModifications = 0;unsigned int TempRegIndex = GetFreeTempRegister();I.SetCode( EOPERATION_ADD );I.SetDestinationAddress( TempRegIndex );I.SetDestZero( true ); //Use indexing for DSTI.SetWriteChannel(ECHANNEL_XYZ);I.SetSrc0SignX( true );I.SetSrc0SignY( true );I.SetSrc0SignZ( true );PopulateSourceRegisters( $1, $3, I, mInstructions);mInstructions.push_back(I);gInsertedInstructions++;I.Clear();std::stringstream ss;ss << "R" << TempRegIndex << " OFFSET ";$$ = ss.str();}|expression BITWISE_OR term{gExtraDestModifications = 0;unsigned int TempRegIndex = GetFreeTempRegister();I.SetDestinationAddress( TempRegIndex );I.SetDestZero( true ); //Use indexing for DSTI.SetWriteChannel(ECHANNEL_XYZ);I.SetCode( EOPERATION_LOGIC );I.SetLogicOperation( ELOGIC_OR );PopulateSourceRegisters( $1, $3, I, mInstructions);mInstructions.push_back(I);gInsertedInstructions++;I.Clear();std::stringstream ss;ss << "R" << TempRegIndex << " OFFSET ";$$ = ss.str();}|term{$$ = $1;};term:term MUL factor{gExtraDestModifications = 0;unsigned int TempRegIndex = GetFreeTempRegister();I.SetDestinationAddress( TempRegIndex );I.SetDestZero( true ); //Use indexing for DSTI.SetWriteChannel(ECHANNEL_XYZ);I.SetCode( EOPERATION_MUL );PopulateSourceRegisters( $1, $3, I, mInstructions);//If we are using fixed point aritmethic then we need to apply the scale//R = A * ( B >> SCALE)if (mGenerateFixedPointArithmetic)I.SetSrc0Rotation( EROT_RESULT_RIGHT );mInstructions.push_back(I);gInsertedInstructions++;I.Clear();std::stringstream ss;ss << "R" << TempRegIndex << " OFFSET ";$$ = ss.str();}|term DIV factor{gExtraDestModifications = 0;unsigned int TempRegIndex = GetFreeTempRegister();I.SetDestinationAddress( TempRegIndex );I.SetDestZero( true ); //Use indexing for DSTI.SetWriteChannel(ECHANNEL_XYZ);I.SetCode( EOPERATION_DIV );PopulateSourceRegisters( $1, $3, I, mInstructions);//If we are using fixed point aritmethic then we need to apply the scale// R = (A << N) / Bif (mGenerateFixedPointArithmetic)I.SetSrc1Rotation( EROT_SRC1_LEFT );mInstructions.push_back(I);gInsertedInstructions++;I.Clear();std::stringstream ss;ss << "R" << TempRegIndex << " OFFSET ";$$ = ss.str();}|term BITWISE_AND factor{gExtraDestModifications = 0;unsigned int TempRegIndex = GetFreeTempRegister();I.SetDestinationAddress( TempRegIndex );I.SetDestZero( true ); //Use indexing for DSTI.SetWriteChannel(ECHANNEL_XYZ);I.SetCode( EOPERATION_LOGIC );I.SetLogicOperation( ELOGIC_AND );PopulateSourceRegisters( $1, $3, I, mInstructions);mInstructions.push_back(I);gInsertedInstructions++;I.Clear();std::stringstream ss;ss << "R" << TempRegIndex << " OFFSET ";$$ = ss.str();}|factor{$$ = $1;};factor:source{$$ = $1;}|SQRT OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE{gExtraDestModifications = 0;unsigned int TempRegIndex = GetFreeTempRegister();I.SetDestinationAddress( TempRegIndex );I.SetDestZero( true ); //Use indexing for DSTI.SetWriteChannel(ECHANNEL_XYZ);I.SetCode( EOPERATION_SQRT );I.SetSrc0Address( 0 );PopulateSourceRegisters( $3 ,"R0 . X X X", I, mInstructions);mInstructions.push_back(I);gInsertedInstructions++;I.Clear();std::stringstream ss;ss << "R" << TempRegIndex << " OFFSET ";$$ = ss.str();}|OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE{$$ = $2;};source:constant{unsigned int ImmediateValue;std::string StringHex = $1;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;switch (ImmediateValue){case 0:$$ = "R0 . X X X";break;case 1:$$ = "R0 . Y Y Y";break;case 2:$$ = "R0 . Z Z Z";break;default:std::string StringHex = $1;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;$$ = ss.str();break;}}|OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE{unsigned int TempRegIndex = GetFreeTempRegister();unsigned int ImmediateValue;{std::string StringHex = $2;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetDestinationAddress( TempRegIndex );I.SetImm( ImmediateValue );I.SetDestZero(true);I.SetSrc0Displace(true);I.SetWriteChannel(ECHANNEL_X);I.SetCode( EOPERATION_ADD );mInstructions.push_back(I);gInsertedInstructions++;I.Clear();}{std::string StringHex = $4;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetDestinationAddress( TempRegIndex );I.SetImm( ImmediateValue );I.SetDestZero(true);I.SetSrc0Displace(true);I.SetWriteChannel(ECHANNEL_Y);I.SetCode( EOPERATION_ADD );mInstructions.push_back(I);gInsertedInstructions++;I.Clear();}{std::string StringHex = $6;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetDestinationAddress( TempRegIndex );I.SetImm( ImmediateValue );I.SetDestZero(true);I.SetSrc0Displace(true);I.SetWriteChannel(ECHANNEL_Z);I.SetCode( EOPERATION_ADD );I.mBisonFlagTrippleConstAssign = true;mInstructions.push_back(I);gInsertedInstructions++;I.Clear();}gExtraDestModifications = 2;std::stringstream ss2;ss2 << "R" << TempRegIndex << " OFFSET ";$$ = ss2.str();}|IDENTIFIER array_index{std::string Register;if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")$$ = Register;else$$ = GetRegisterFromAutoVar( $1, yylloc) + " OFFSET ";if ($2 != "NULL"){$$ += " array_element " + $2;}}|IDENTIFIER DOT coordinate coordinate coordinate{std::string X = $3,Y = $4,Z = $5;std::string Register;if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")$$ = (Register + " . " + " " + X + " " + Y + " " + Z + " OFFSET ");else$$ = (GetRegisterFromAutoVar( $1, yylloc) + " . " + " " + X + " " + Y + " " + Z + " OFFSET ");}|REG{std::string R = $1;R.erase(0,1);$$ = "R" + R;}|SCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE{std::string R = $1;R.erase(0,1);$$ = "<<R" + R;}|UNSCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE{std::string R = $1;R.erase(0,1);$$ = ">>R" + R;}|REG DOT coordinate coordinate coordinate{std::string R = $1;std::string X = $3,Y = $4,Z = $5;R.erase(0,1);$$ = "R" + R + " . " + " " + X + " " + Y + " " + Z;};coordinate:TK_X{$$ = "X";}|MINUS TK_X{$$ = "-X";}|TK_Y{$$ = "Y";}|MINUS TK_Y{$$ = "-Y";}|TK_Z{$$ = "Z";}|MINUS TK_Z{$$ = "-Z";};array_index:{$$ = "NULL";}|OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE{/*std::string Register;if ((Register = GetRegisterFromFunctionParameter($2)) != "NULL")$$ = Register;else*///Indexes into arrays can only be auto variables!$$ = GetRegisterFromAutoVar( $2, yylloc );};left_hand_side:OUT OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE{$$ = "OUT " + $3;}|OUT OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE{std::string Register;if ((Register = GetRegisterFromFunctionParameter($3)) == "NULL")Register = GetRegisterFromAutoVar( $3, yylloc );$$ = "OUT INDEX" + Register;}|IDENTIFIER array_index{std::string Register;if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")$$ = Register + ".xyz";else$$ = GetRegisterFromAutoVar( $1, yylloc ) + ".xyz" + " OFFSET " + (($2 != "NULL")?" INDEX"+$2:"");}|IDENTIFIER DOT TK_X{std::string Register;if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")$$ = Register + ".x";else$$ = GetRegisterFromAutoVar( $1, yylloc ) + ".x" + " OFFSET ";}|IDENTIFIER DOT TK_Y{std::string Register;if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")$$ = Register + ".y";else$$ = GetRegisterFromAutoVar( $1, yylloc ) + ".y" + " OFFSET ";}|IDENTIFIER DOT TK_Z{std::string Register;if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")$$ = Register + ".z";else$$ = GetRegisterFromAutoVar( $1, yylloc ) + ".z" + " OFFSET ";}|REG{std::string R = $1;R.erase(0,1);$$ = "R" + R + ".xyz";}|REG DOT TK_X{std::string R = $1;R.erase(0,1);$$ = "R" + R + ".x";}|REG DOT TK_Y{std::string R = $1;R.erase(0,1);$$ = "R" + R + ".y";}|REG DOT TK_Z{std::string R = $1;R.erase(0,1);$$ = "R" + R + ".z";}|REG DOT TK_X TK_Y TK_N{std::string R = $1;R.erase(0,1);$$ = "R" + R + ".xy";}|REG DOT TK_X TK_N TK_Z{std::string R = $1;R.erase(0,1);$$ = "R" + R + ".xz";}|REG DOT TK_N TK_Y TK_Z{std::string R = $1;R.erase(0,1);$$ = "R" + R + ".yz";};boolean_expression:expression NOT_EQUAL expression{PopulateBoolean(EBRANCH_IF_ZERO, $1, $3, I, mInstructions, yylloc );}|expression EQUAL expression{PopulateBoolean(EBRANCH_IF_NOT_ZERO, $1, $3, I, mInstructions, yylloc );}|expression GREATER_THAN expression{PopulateBoolean(EBRANCH_IF_ZERO_OR_SIGN, $1, $3, I, mInstructions, yylloc );}|expression LESS_THAN expression{PopulateBoolean(EBRANCH_IF_ZERO_OR_NOT_SIGN, $1, $3, I, mInstructions, yylloc );}|expression LESS_OR_EQUAL_THAN expression{PopulateBoolean(EBRANCH_IF_NOT_SIGN, $1, $3, I, mInstructions, yylloc );}|expression GREATER_OR_EQUAL_THAN expression{PopulateBoolean(EBRANCH_IF_SIGN, $1, $3, I, mInstructions, yylloc );};constant:DECCONST{// Transform to HEX stringunsigned int Val;std::string StringDec = $1;std::stringstream ss;ss << StringDec;ss >> Val;std::stringstream ss2;ss2 << std::hex << Val;$$ = ss2.str();}|HEXCONST{std::string StringHex = $1;// Get rid of the 0xStringHex.erase(StringHex.begin(),StringHex.begin()+2);std::stringstream ss;ss << std::hex << StringHex;$$ = ss.str();}|BINCONST{// Transform to HEX stringstd::string StringBin = $1;// Get rid of the 0bStringBin.erase(StringBin.begin(),StringBin.begin()+2);std::bitset<32> Bitset( StringBin );std::stringstream ss2;ss2 << std::hex << Bitset.to_ulong();$$ = ss2.str();};auto_var_list:IDENTIFIER array_size COMMA auto_var_list{if (gAutoVarMap.find($1) != gAutoVarMap.end()){std::ostringstream ret;ret << "Duplicated symbol '" << $1 << "'\n";throw ret.str();}std::stringstream ss;ss << $2;unsigned int Size;ss >> Size;gAutoVarMap[ $1 ] = AllocAutoVar(Size);}|IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE COMMA auto_var_list{if (gAutoVarMap.find($1) != gAutoVarMap.end()){std::ostringstream ret;ret << "Duplicated symbol " << $1 << "'\n";throw ret.str();}gAutoVarMap[ $1 ] = AllocAutoVar();unsigned int Destination = gAutoVarMap[ $1 ];I.ClearWriteChannel();unsigned int ImmediateValue;{I.SetDestinationAddress( Destination );I.SetWriteChannel(ECHANNEL_X);std::string StringHex = $4;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetImm( ImmediateValue );I.SetDestZero( true );I.SetSrc1Displace( false );I.SetSrc0Displace( true );I.SetCode( EOPERATION_ADD );I.mSourceLine = GetCurrentLineNumber( yylloc );mInstructions.push_back(I);I.Clear();}{I.SetDestinationAddress( Destination );I.SetWriteChannel(ECHANNEL_Y);std::string StringHex = $6;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetImm( ImmediateValue );I.SetDestZero( true );I.SetSrc1Displace( false );I.SetSrc0Displace( true );I.SetCode( EOPERATION_ADD );mInstructions.push_back(I);I.Clear();}{I.SetDestinationAddress( Destination );I.SetWriteChannel(ECHANNEL_Z);std::string StringHex = $8;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetImm( ImmediateValue );I.SetDestZero( true );I.SetSrc1Displace( false );I.SetSrc0Displace( true );I.SetCode( EOPERATION_ADD );mInstructions.push_back(I);I.Clear();}}|IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE{if (gAutoVarMap.find($1) != gAutoVarMap.end()){std::ostringstream ret;ret << "Duplicated symbol " << $1 << "'\n";throw ret.str();}gAutoVarMap[ $1 ] = AllocAutoVar();unsigned int Destination = gAutoVarMap[ $1 ];I.SetDestZero( true );I.SetSrc1Displace( false );I.SetSrc0Displace( true );I.ClearWriteChannel();unsigned int ImmediateValue;{I.SetDestinationAddress( Destination );I.SetWriteChannel(ECHANNEL_X);std::string StringHex = $4;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetImm( ImmediateValue );I.SetDestZero( true );I.SetSrc1Displace( false );I.SetSrc0Displace( true );I.SetCode( EOPERATION_ADD );I.mSourceLine = GetCurrentLineNumber( yylloc );mInstructions.push_back(I);I.Clear();}{I.SetDestinationAddress( Destination );I.SetWriteChannel(ECHANNEL_Y);std::string StringHex = $6;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetImm( ImmediateValue );I.SetDestZero( true );I.SetSrc1Displace( false );I.SetSrc0Displace( true );I.SetCode( EOPERATION_ADD );mInstructions.push_back(I);I.Clear();}{I.SetDestinationAddress( Destination );I.SetWriteChannel(ECHANNEL_Z);std::string StringHex = $8;std::stringstream ss;ss << std::hex << StringHex;ss >> ImmediateValue;I.SetImm( ImmediateValue );I.SetDestZero( true );I.SetSrc1Displace( false );I.SetSrc0Displace( true );I.SetCode( EOPERATION_ADD );mInstructions.push_back(I);I.Clear();}}|IDENTIFIER array_size{if (gAutoVarMap.find($1) != gAutoVarMap.end()){std::ostringstream ret;ret << "Duplicated symbol " << $1 << "'\n";throw ret.str();}std::stringstream ss;ss << std::hex << $2;unsigned int Size;ss >> Size;////std::cout << "Array Size is " << Size << " " << $2 << "\n";gAutoVarMap[ $1 ] = AllocAutoVar(Size);};array_size:{$$ = "1";}|OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE{$$ = $2;};%%// Error function throws an exception (std::string) with the location and error messagevoid Theia::Parser::error(const Theia::Parser::location_type &loc,const std::string &msg) {std::ostringstream ret;ret << "Parser Error at " << loc << ": " << msg;throw ret.str();}// Now that we have the Parser declared, we can declare the Scanner and implement// the yylex function#include "Scanner.h"static int yylex(Theia::Parser::semantic_type * yylval,Theia::Parser::location_type * yylloc,Theia::Scanner &scanner) {return scanner.yylex(yylval, yylloc);}
Go to most recent revision | Compare with Previous | Blame | View Log
