/**********************************************************************************
/**********************************************************************************
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);
}
}