|
|
/**********************************************************************************
|
/**********************************************************************************
|
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";
|
//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.SetSrc1SwizzleY(SWY_Y);
|
|
I.SetSrc1SwizzleZ(SWZ_Z);
|
|
I.SetSrc0Address(0);
|
|
I.SetSrc0SwizzleX(SWX_X);
|
|
I.SetSrc0SwizzleY(SWY_X);
|
|
I.SetSrc0SwizzleZ(SWZ_X);
|
|
aInstructions.push_back( I );
|
|
I.Clear();
|
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
|
%%
|
%%
|
|
|
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 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_OUT);
|
$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 );
|
|
|
|
|
//I.SetImm( 0 );
|
//I.SetImm( 0 );
|
I.SetCode( EOPERATION_OUT );
|
I.SetCode( EOPERATION_OUT );
|
std::string Source0 = $3;
|
std::string Source0 = $3;
|
DCOUT << "!!!!!!!!!!!!!!!!!Source0 '" << Source0 << "'\n";
|
DCOUT << "!!!!!!!!!!!!!!!!!Source0 '" << Source0 << "'\n";
|
/* 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));*/
|
|
|
/* 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();
|
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
|
| 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
|
{
|
{
|
|
|
//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";
|
////std::cout << "else\n";
|
|
|
}
|
}
|
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
|
//Now push the JMP
|
|
|
////std::cout << "END elseif\n";
|
////std::cout << "END elseif\n";
|
}
|
}
|
|
|
|
|
//NOW the if statement
|
//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 ( [ , ... , ]) /////
|
|
///// { /////
|
|
///// /////
|
|
///// /////
|
|
///// } /////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
FUNCTION IDENTIFIER OPEN_ROUND_BRACE function_argument_list CLOSE_ROUND_BRACE
|
FUNCTION IDENTIFIER OPEN_ROUND_BRACE function_argument_list CLOSE_ROUND_BRACE
|
{
|
{
|
////std::cout << "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 ( ) /////
|
|
///// { /////
|
|
///// /////
|
|
///// /////
|
|
///// } /////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//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 ( ); /////
|
|
///// /////
|
|
///// /////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
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 /////
|
|
///// /////
|
|
///// = ( [ , ... , ]); /////
|
|
///// /////
|
|
///// /////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
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
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///// /////
|
|
///// 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 do the branch
|
|
|
//Now assign the destination of the branch (our function virtual address)
|
if (mSymbolMap.find($1) == mSymbolMap.end())
|
if (mSymbolMap.find($1) == mSymbolMap.end())
|
{
|
{
|
// ////std::cout << "Error in line : " << $1 <<" undelcared IDENTIFIER\n";
|
//The destination is not yet declared
|
|
//so leave it as a symbol so that it can latter
|
|
//resolved by the linker
|
I.SetDestinationSymbol( "@"+$1 );
|
I.SetDestinationSymbol( "@"+$1 );
|
// exit(1);
|
|
} else {
|
} else {
|
|
//The destination symbol has already been declared
|
|
//so assign it right away
|
I.SetDestinationAddress( mSymbolMap[ $1 ] );
|
I.SetDestinationAddress( mSymbolMap[ $1 ] );
|
}
|
}
|
|
|
|
//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 | ... |
|
// ::= x | y | ... |
|
// ( ) |
|
// ( ) |
|
// - |
|
// - |
|
//
|
//
|
|
|
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();
|
}
|
}
|
|
|
|
|
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;
|
}
|
}
|
|
|
|
|
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;
|
std::string Register;
|
if ((Register = GetRegisterFromFunctionParameter($3)) == "NULL")
|
if ((Register = GetRegisterFromFunctionParameter($3)) == "NULL")
|
Register = GetRegisterFromAutoVar( $3, yylloc );
|
Register = GetRegisterFromAutoVar( $3, yylloc );
|
|
|
$$ = "OUT INDEX" + Register;
|
$$ = "OUT INDEX" + Register;
|
|
*/
|
|
std::string Register;
|
|
if ((Register = GetRegisterFromFunctionParameter($3)) != "NULL")
|
|
$$ = "OUT INDEX" + Register;
|
|
else
|
|
$$ = "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);
|
}
|
}
|
|
|
|
|