URL
https://opencores.org/ocsvn/theia_gpu/theia_gpu/trunk
Subversion Repositories theia_gpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/theia_gpu
- from Rev 215 to Rev 216
- ↔ Reverse comparison
Rev 215 → Rev 216
/branches/beta_2.0/compiler/src/vp_compiler/Scanner.h
0,0 → 1,66
/* This program is free software. It comes without any warranty, to |
* the extent permitted by applicable law. You can redistribute it |
* and/or modify it under the terms of the Do What The Fuck You Want |
* To Public License, Version 2, as published by Sam Hocevar. See |
* http://sam.zoy.org/wtfpl/COPYING for more details. */ |
|
#pragma once |
|
// Only include FlexLexer.h if it hasn't been already included |
#if ! defined(yyFlexLexerOnce) |
#include <FlexLexer.h> |
#endif |
|
// Override the interface for yylex since we namespaced it |
#undef YY_DECL |
#define YY_DECL int Theia::Scanner::yylex() |
|
// Include Bison for types / tokens |
#include "parser.tab.h" |
|
|
|
namespace Theia |
{ |
class Scanner : public yyFlexLexer |
{ |
public: |
// constructor accepts the input and output streams |
// 0 means std equivilant (stdin, stdout) |
Scanner(std::istream * in = 0, std::ostream * out = 0) : yyFlexLexer(in, out) { } |
|
// overloaded version of yylex - we need a pointer to yylval and yylloc |
inline int yylex(Parser::semantic_type * lval, |
Parser::location_type * lloc); |
|
private: |
// Scanning function created by Flex; make this private to force usage |
// of the overloaded method so we can get a pointer to Bison's yylval |
int yylex(); |
|
// point to yylval (provided by Bison in overloaded yylex) |
Parser::semantic_type * yylval; |
|
// pointer to yylloc (provided by Bison in overloaded yylex) |
Parser::location_type * yylloc; |
|
// block default constructor |
Scanner(); |
// block default copy constructor |
Scanner(Scanner const &rhs); |
// block default assignment operator |
Scanner &operator=(Scanner const &rhs); |
}; |
|
// all our overloaded version does is save yylval and yylloc to member variables |
// and invoke the generated scanner |
int Scanner::yylex(Parser::semantic_type * lval, |
Parser::location_type * lloc) { |
yylval = lval; |
yylloc = lloc; |
return yylex(); |
} |
|
} |
//} |
|
/branches/beta_2.0/compiler/src/vp_compiler/instructions.mem
0,0 → 1,79
|
80019000 00000000 |
80018800 00000001 |
80018400 00000002 |
80018408 00000000 |
80019C0C 00000000 |
8001B038 00000005 |
8001A838 00000005 |
8001A438 00000005 |
0001BC34 1400000E |
8001B030 00000002 |
8001A830 00000002 |
8001A430 00000002 |
0001FC3C 001C000D |
0003FC40 0018000E |
0001DC44 00202100 |
03417C48 001FC011 |
00000000 00000000 |
04010000 00000000 |
8001B03C 00000003 |
8001A83C 00000003 |
8001A43C 00000003 |
0001FC40 0018000F |
02417C64 001BC010 |
00000000 00000000 |
04010000 00000000 |
8001B040 00000007 |
8001A840 00000007 |
8001A440 00000007 |
0003DC44 001C1400 |
0001FC48 00200011 |
8001B04C 00000003 |
8001A84C 00000003 |
8001A44C 00000003 |
0001FC3C 00240013 |
8001BC40 00000014 |
0241609C 001FC010 |
80019D08 0000DEAD |
00000000 00000000 |
04010000 00000000 |
80019D08 0000ACED |
00000000 00000000 |
04010000 00000000 |
0001100C 42060A00 |
00039C28 00100007 |
00019C2C 000A0004 |
0003BC30 000C000B |
0001FC04 0015C00C |
0001100C 42060A00 |
82010008 00000000 |
0001100C 42060A00 |
80019000 00000000 |
80018800 00000001 |
80018400 00000002 |
80018408 00000000 |
80019C0C 00000000 |
8001BC2C 00060000 |
8001BC34 00080000 |
8001BC38 00080000 |
00019C28 14002100 |
8001BC30 0000000A |
00019C3C 14000A00 |
03816064 141FCA0C |
02814048 1415E100 |
1002FC40 001C000B |
0001FC34 001BC010 |
00019C28 14000A00 |
0001DC2C 00161400 |
02010058 00000000 |
1002FC40 001C000B |
0001FC34 001A0010 |
00019C28 14002100 |
0001DC2C 00161400 |
0001DC3C 001E2100 |
00013D08 1400000D |
0201002C 00000000 |
00000000 00000000 |
04010000 00000000 |
0001100C 42060A00 |
/branches/beta_2.0/compiler/src/vp_compiler/parser.tab.c
0,0 → 1,3613
|
/* A Bison parser, made by GNU Bison 2.4.1. */ |
|
/* Skeleton implementation for Bison LALR(1) parsers in C++ |
|
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software |
Foundation, Inc. |
|
This program is free software: you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation, either version 3 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
/* As a special exception, you may create a larger work that contains |
part or all of the Bison parser skeleton and distribute that work |
under terms of your choice, so long as that work isn't itself a |
parser generator using the skeleton or a modified version thereof |
as a parser skeleton. Alternatively, if you modify or redistribute |
the parser skeleton itself, you may (at your option) remove this |
special exception, which will cause the skeleton and the resulting |
Bison output files to be licensed under the GNU General Public |
License without this special exception. |
|
This special exception was added by the Free Software Foundation in |
version 2.2 of Bison. */ |
|
|
/* First part of user declarations. */ |
|
|
/* Line 311 of lalr1.cc */ |
#line 41 "parser.tab.c" |
|
|
#include "parser.tab.h" |
|
/* User implementation prologue. */ |
|
|
/* Line 317 of lalr1.cc */ |
#line 50 "parser.tab.c" |
/* Unqualified %code blocks. */ |
|
/* Line 318 of lalr1.cc */ |
#line 68 "parser.y" |
|
#include "Instruction.h" |
#include <vector> |
Instruction I,tmpI; |
|
std::vector< unsigned int > gBranchStack; |
static int gInsertedInstructions = 0; |
static int gWhileLoopAddress = 0; |
#define FUNCTION_PARAM_START_REGION 4 |
#define FUNCTION_PARAM_LAST_REGION 10 |
std::map<std::string, unsigned int> gFunctionParameters; |
std::map<std::string, unsigned int> gAutoVarMap; |
std::map<std::string, unsigned int> gThreadMap; //Key: Symbol, value: start code addr |
bool gThreadScope = false; |
#define AUTOVAR_START_REGION 9 |
#define THREAD_OFFSET 128 |
unsigned int gExtraDestModifications = 0; |
unsigned int gAutoVarIndex = AUTOVAR_START_REGION; |
unsigned int gThreadAutoVarIndex = THREAD_OFFSET; |
unsigned int gFunctionParameterIndex = FUNCTION_PARAM_START_REGION; |
//---------------------------------------------------------- |
unsigned int GetNextFunctionParamRegister() |
{ |
unsigned Ret = gFunctionParameterIndex++; |
return Ret; |
} |
|
//---------------------------------------------------------- |
void AddFunctionParameter( std::string aVar, Theia::Parser::location_type yylloc) |
{ |
////std::cout << "Adding " << aVar << "\n"; |
if (gFunctionParameterIndex+1 > FUNCTION_PARAM_LAST_REGION) |
{ |
std::ostringstream ret; |
ret << "Cannot allocate more parameters '" << aVar << "' at line " << yylloc << " \n"; |
throw ret.str(); |
} |
if (gFunctionParameters.find(aVar) != gFunctionParameters.end()) |
{ |
std::ostringstream ret; |
ret << "Parameter '" << aVar << "' at line " << yylloc << " is already defined\n"; |
throw ret.str(); |
} |
|
gFunctionParameters[ aVar ] = gFunctionParameterIndex++; |
|
} |
//---------------------------------------------------------- |
std::string GetRegisterFromFunctionParameter( std::string aVar ) |
{ |
////std::cout << "Looking for " << aVar << "\n"; |
if (gFunctionParameters.find(aVar) == gFunctionParameters.end()) |
return "NULL"; |
|
std::ostringstream ss; |
ss << gFunctionParameters[ aVar ]; |
return ("R" + ss.str()); |
} |
//---------------------------------------------------------- |
unsigned int GetCurretAutoVarFrameSize() |
{ |
|
return gAutoVarMap.size(); |
|
} |
//---------------------------------------------------------- |
std::string GetRegisterFromAutoVar( std::string aVar, Theia::Parser::location_type yylloc ) |
{ |
if (gAutoVarMap.find(aVar) == gAutoVarMap.end()) |
{ |
std::ostringstream ret; |
ret << "Undefined variable '" << aVar << "' at line " << yylloc << " \n"; |
throw ret.str(); |
} |
|
std::ostringstream ss; |
ss << gAutoVarMap[ aVar ]; |
return ("R" + ss.str()); |
} |
//---------------------------------------------------------- |
int GetCurrentLineNumber( const Theia::Parser::location_type &loc ) |
{ |
int ret = -1; |
std::stringstream ss2; |
std::string where; |
ss2 << loc; |
ss2 >> where; |
where.erase(where.find_first_of(".")); |
std::stringstream ss3; |
ss3 << where; |
ss3 >> ret; |
return ret; |
} |
//---------------------------------------------------------- |
unsigned int AllocAutoVar( unsigned int aSize = 1) |
{ |
|
if (!gThreadScope) |
{ |
gAutoVarIndex += aSize; |
return gAutoVarIndex - (aSize-1); |
}else{ |
gThreadAutoVarIndex += aSize; |
return (gThreadAutoVarIndex - (aSize-1)); |
} |
} |
//---------------------------------------------------------- |
void ClearFunctionParameterMap() |
{ |
gFunctionParameters.clear(); |
gFunctionParameterIndex = FUNCTION_PARAM_START_REGION; |
} |
//---------------------------------------------------------- |
void ClearAutoVarMap() |
{ |
gAutoVarMap.clear(); |
gAutoVarIndex = AUTOVAR_START_REGION; |
} |
//---------------------------------------------------------- |
unsigned int gTempRegisterIndex = 1; |
unsigned int GetFreeTempRegister( ) |
{ |
if (!gThreadScope) |
return gAutoVarIndex + (gTempRegisterIndex++); |
else |
return gThreadAutoVarIndex + (gTempRegisterIndex++); |
|
} |
//---------------------------------------------------------- |
void ResetTempRegisterIndex( void ) |
{ |
|
gTempRegisterIndex = 1; |
} |
//---------------------------------------------------------- |
bool IsSwizzled( std::string aSource) |
{ |
if (aSource.find(".") != std::string::npos) |
return true; |
else |
return false; |
} |
|
//---------------------------------------------------------- |
void SetSwizzleAndSign( unsigned int aSourceIndex, std::string aSwizzle, Instruction & I ) |
{ |
std::string Reg,X,Y,Z, junk; |
std::stringstream ss( aSwizzle ); |
ss >> Reg >> junk >> X >> Y >> Z; |
|
|
if (aSourceIndex == 1) |
{ |
if (X == "X") { I.SetSrc1SwizzleX(SWX_X); } |
if (X == "Y") { I.SetSrc1SwizzleX(SWX_Y); } |
if (X == "Z") { I.SetSrc1SwizzleX(SWX_Z); } |
if (X == "-X") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_X); } |
if (X == "-Y") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Y); } |
if (X == "-Z") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Z); } |
|
if (Y == "X") { I.SetSrc1SwizzleY(SWY_X); } |
if (Y == "Y") { I.SetSrc1SwizzleY(SWY_Y); } |
if (Y == "Z") { I.SetSrc1SwizzleY(SWY_Z); } |
if (Y == "-X") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_X); } |
if (Y == "-Y") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Y); } |
if (Y == "-Z") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Z); } |
|
if (Z == "X") { I.SetSrc1SwizzleZ(SWZ_X); } |
if (Z == "Y") { I.SetSrc1SwizzleZ(SWZ_Y); } |
if (Z == "Z") { I.SetSrc1SwizzleZ(SWZ_Z); } |
if (Z == "-X") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_X); } |
if (Z == "-Y") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Y); } |
if (Z == "-Z") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Z); } |
} else { |
if (X == "X") { I.SetSrc0SwizzleX(SWX_X); } |
if (X == "Y") { I.SetSrc0SwizzleX(SWX_Y); } |
if (X == "Z") { I.SetSrc0SwizzleX(SWX_Z); } |
if (X == "-X") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_X); } |
if (X == "-Y") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Y); } |
if (X == "-Z") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Z); } |
|
if (Y == "X") { I.SetSrc0SwizzleY(SWY_X); } |
if (Y == "Y") { I.SetSrc0SwizzleY(SWY_Y); } |
if (Y == "Z") { I.SetSrc0SwizzleY(SWY_Z); } |
if (Y == "-X") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_X); } |
if (Y == "-Y") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Y); } |
if (Y == "-Z") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Z); } |
|
if (Z == "X") { I.SetSrc0SwizzleZ(SWZ_X); } |
if (Z == "Y") { I.SetSrc0SwizzleZ(SWZ_Y); } |
if (Z == "Z") { I.SetSrc0SwizzleZ(SWZ_Z); } |
if (Z == "-X") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_X); } |
if (Z == "-Y") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Y); } |
if (Z == "-Z") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Z); } |
} |
} |
//---------------------------------------------------------- |
void StoreReturnAddress( std::vector<Instruction> & aInstructions, Theia::Parser::location_type & yylloc ) |
{ |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "store return address**"; |
I.SetImm( aInstructions.size()+4 ); |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( RETURN_ADDRESS_REGISTER ); |
I.SetDestZero( true ); |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
aInstructions.push_back( I ); |
I.Clear(); |
} |
//---------------------------------------------------------- |
void SavePreviousFramePointer( std::vector<Instruction> & aInstructions ) |
{ |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "store current frame offset"; |
I.SetWriteChannel(ECHANNEL_Y); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetSrc1Address(SPR_CONTROL_REGISTER); |
I.SetSrc1SwizzleX(SWX_X); |
I.SetSrc1SwizzleY(SWY_X); |
I.SetSrc1SwizzleZ(SWZ_X); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
aInstructions.push_back( I ); |
I.Clear(); |
} |
//---------------------------------------------------------- |
void SetIndexRegister( unsigned int aIndex, std::vector<Instruction> & aInstructions ) |
{ |
Instruction Tmp; |
Tmp.SetCode( EOPERATION_ADD ); |
Tmp.mComment = "store array index register"; |
Tmp.SetWriteChannel(ECHANNEL_Z); |
Tmp.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
Tmp.SetSrc1Address( aIndex ); |
Tmp.SetSrc1Displace( true ); |
Tmp.SetSrc1SwizzleX(SWX_X); |
Tmp.SetSrc1SwizzleY(SWY_X); |
Tmp.SetSrc1SwizzleZ(SWZ_X); |
Tmp.SetSrc0Address(0); |
Tmp.SetSrc0SwizzleX(SWX_X); |
Tmp.SetSrc0SwizzleY(SWY_X); |
Tmp.SetSrc0SwizzleZ(SWZ_X); |
//Tmp.SetImm( aIndex ); |
//Tmp.SetDestZero( true ); |
aInstructions.push_back( Tmp ); |
|
} |
//---------------------------------------------------------- |
void UpdateFramePointer( std::vector<Instruction> & aInstructions ) |
{ |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "displace next frame offset by the number of auto variables in current frame"; |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetImm( GetCurretAutoVarFrameSize() ); |
I.SetDestZero( false ); |
aInstructions.push_back( I ); |
I.Clear(); |
} |
//---------------------------------------------------------- |
void CallFunction( std::string aFunctionName, std::vector<Instruction> & aInstructions, std::map<std::string,unsigned int> & aSymbolMap) |
{ |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "call the function"; |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
//Now do the branch |
if (aSymbolMap.find(aFunctionName) == aSymbolMap.end()) |
I.SetDestinationSymbol( "@"+aFunctionName ); |
else |
I.SetDestinationAddress( aSymbolMap[ aFunctionName ] ); |
|
aInstructions.push_back( I ); |
I.Clear(); |
} |
//---------------------------------------------------------- |
void SetDestinationFromRegister( std::string aDestination, Instruction & aInst, bool Imm ) |
{ |
//Look for displament addressing mode |
|
if (aDestination.find("OFFSET") != std::string::npos) |
{ |
aDestination.erase(aDestination.find("OFFSET")); |
////std::cout << "^_^ left_hand_side " << Destination << "\n"; |
if (Imm == true) |
aInst.SetSrc0Displace( true ); //When Imm == 0, then setting this makes offset |
else |
aInst.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
} |
if (aDestination.find(".") != std::string::npos) |
{ |
aInst.ClearWriteChannel(); |
if (aDestination.find("x") != std::string::npos) |
aInst.SetWriteChannel(ECHANNEL_X); |
if (aDestination.find("y") != std::string::npos) |
aInst.SetWriteChannel(ECHANNEL_Y); |
if (aDestination.find("z") != std::string::npos) |
aInst.SetWriteChannel(ECHANNEL_Z); |
|
aDestination.erase(aDestination.find(".")); |
|
} |
aInst.SetDestinationAddress( atoi(aDestination.c_str()+1) ); |
} |
//---------------------------------------------------------- |
void PopulateSourceRegisters( std::string a1, std::string a2, Instruction & I, std::vector<Instruction> & aInstructions ) |
{ |
|
|
if ( a1.find("R") == std::string::npos ) |
{ |
//This is for constants |
unsigned int ImmediateValue; |
std::string StringHex = a1; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
} else { |
|
|
|
if (a1.find("array_element") != std::string::npos) |
{ |
|
|
std::string Index = a1.substr(a1.find("array_element")); |
////std::cout << "XXXXX " << Index << "\n\n\n"; |
Index = Index.substr(Index.find_first_not_of("array_element R")); |
////std::cout << "XXXXX " << Index << "\n\n\n"; |
SetIndexRegister( atoi(Index.c_str()), aInstructions ); |
a1.erase(a1.find("array_element")); |
I.SetSrc0Displace( true ); |
I.SetSrc1Displace( true ); |
I.SetImmBit( true ); |
} |
//Look for displament addressing mode |
else if (a1.find("OFFSET") != std::string::npos) |
{ |
a1.erase(a1.find("OFFSET")); |
////std::cout << "^_^ a1" << a1 << "\n"; |
I.SetSrc1Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
} |
|
std::string Src1 = a1; |
if (IsSwizzled( Src1 )) |
{ |
SetSwizzleAndSign( 1, Src1, I ); |
Src1.erase(Src1.find(".")); |
} |
I.SetSrc1Address( atoi( Src1.c_str()+1 ) ); |
} |
|
if ( a2.find("R") == std::string::npos) |
{ |
} else { |
|
|
|
//Look for displament addressing mode |
if (a2.find("OFFSET") != std::string::npos) |
{ |
a2.erase(a2.find("OFFSET")); |
////std::cout << "^_^ a2 " << a2 << "\n"; |
I.SetSrc0Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
} |
|
std::string Src0 = a2; |
if (IsSwizzled( Src0 )) |
{ |
SetSwizzleAndSign( 0, Src0, I ); |
Src0.erase(Src0.find(".")); |
} |
I.SetSrc0Address( atoi( Src0.c_str()+1 ) ); |
} |
} |
//---------------------------------------------------------- |
void ClearNextFunctionParamRegister() |
{ |
gFunctionParameterIndex = FUNCTION_PARAM_START_REGION; |
} |
//---------------------------------------------------------- |
void AddFunctionInputList( std::string aVar, std::vector<Instruction> & aInstructions,Theia::Parser::location_type yylloc) |
{ |
//Get the value from the variable |
|
//Copy the value into function parameter register |
unsigned FunctionParamReg = GetNextFunctionParamRegister(); |
I.Clear(); |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "copy the value into function parameter register"; |
I.SetWriteChannel(ECHANNEL_XYZ); |
//I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
I.SetDestinationAddress( FunctionParamReg ); |
|
if (aVar.find("R") != std::string::npos) |
{ |
if (aVar.find("OFFSET") != std::string::npos) |
{ |
I.SetSrc1Displace( true ); |
aVar.erase(aVar.find("OFFSET")); |
} |
I.SetSrc1Address(atoi(aVar.c_str()+1)); |
return; |
} |
std::string Reg = GetRegisterFromFunctionParameter( aVar ); |
if (Reg == "NULL") |
{ |
Reg = GetRegisterFromAutoVar( aVar, yylloc ); |
I.SetSrc1Address(atoi(Reg.c_str()+1)); |
I.SetSrc1Displace( true ); |
} else { |
I.SetSrc1Address(atoi(Reg.c_str()+1)); |
I.SetSrc1Displace( false ); |
} |
|
|
|
I.SetSrc1SwizzleX(SWX_X); |
I.SetSrc1SwizzleY(SWY_Y); |
I.SetSrc1SwizzleZ(SWZ_Z); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
aInstructions.push_back( I ); |
I.Clear(); |
} |
//---------------------------------------------------------- |
void SetExpressionDestination( std::string aStringDestination, Instruction & I ) |
{ |
std::string Destination = aStringDestination; |
|
//Look for indirect addressing |
if (Destination.find("INDEX") != std::string::npos) |
{ |
|
std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5); |
Destination.erase(Destination.find("INDEX")); |
I.SetImm( 0 ); |
I.SetCode( EOPERATION_ADD ); |
|
if (Destination.find(".") != std::string::npos) |
{ |
I.ClearWriteChannel(); |
if (Destination.find("x") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_X); |
if (Destination.find("y") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Y); |
if (Destination.find("z") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Z); |
Destination.erase(Destination.find(".")); |
|
} |
|
I.SetDestinationAddress( atoi(Destination.c_str()+1) ); |
|
} else { |
|
//Look for displament addressing mode |
if (Destination.find("OFFSET") != std::string::npos) |
{ |
Destination.erase(Destination.find("OFFSET")); |
I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
} |
if (Destination.find(".") != std::string::npos) |
{ |
I.ClearWriteChannel(); |
if (Destination.find("x") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_X); |
if (Destination.find("y") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Y); |
if (Destination.find("z") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Z); |
|
Destination.erase(Destination.find(".")); |
|
} |
I.SetDestinationAddress( atoi(Destination.c_str()+1) ); |
|
|
|
} |
} |
|
//---------------------------------------------------------- |
bool SourceNull( std::string aSource ) |
{ |
if (aSource == "NULL") |
return true; |
|
return false; |
} |
//---------------------------------------------------------- |
|
void PopulateInstruction( std::string aDestination, std::string aSource1, std::string aSource0, Instruction & I, Theia::Parser::location_type yylloc, bool aHasLiteral = false, unsigned int aLiteral = 0) |
{ |
|
|
bool DestinationHasOffset = false; |
bool DetinationHasIndex = false; |
bool Source0HasOffset = false; |
bool Source1HasOffset = false; |
bool Source1HasIndex = false; |
bool Source0HasIndex = false; |
|
|
if (aDestination.find("INDEX") != std::string::npos) |
{ |
std::string ArrayIndex = aDestination.substr(aDestination.find("INDEX")+5); |
aSource1 = ArrayIndex; |
DetinationHasIndex = true; |
|
} |
|
if (aSource1.find("INDEX") != std::string::npos) |
Source1HasIndex = true; |
|
if (aSource0.find("INDEX") != std::string::npos) |
Source0HasIndex = true; |
|
if (aDestination.find("OFFSET") != std::string::npos) |
DestinationHasOffset = true; |
|
if (aSource0.find("OFFSET") != std::string::npos) |
Source0HasOffset = true; |
|
if (aSource1.find("OFFSET") != std::string::npos) |
Source1HasOffset = true; |
|
if (IsSwizzled( aSource1 )) |
SetSwizzleAndSign( 1, aSource1, I ); |
I.SetSrc1Address( atoi( aSource1.c_str()+1 ) ); |
|
if (IsSwizzled( aSource0 )) |
SetSwizzleAndSign( 0, aSource0, I ); |
I.SetSrc0Address( atoi( aSource0.c_str()+1 ) ); |
|
|
|
//Fisrt take care of the destination write channel |
if (aDestination.find(".") != std::string::npos) |
{ |
I.ClearWriteChannel(); |
if (aDestination.find("x") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_X); |
if (aDestination.find("y") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Y); |
if (aDestination.find("z") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Z); |
aDestination.erase(aDestination.find(".")); |
} else { |
I.SetWriteChannel(ECHANNEL_XYZ); |
} |
//Now set the destination Index |
I.SetDestinationAddress( atoi(aDestination.c_str()+1) ); |
|
|
//Now determine the addressing mode |
//Simple addressing modes |
if (!aHasLiteral && !DetinationHasIndex && !Source0HasIndex && !Source1HasIndex) |
{ |
|
I.SetAddressingMode( DestinationHasOffset,Source1HasOffset,Source0HasOffset); |
return; |
} |
|
|
I.SetImmBit( true ); //This is to set the IMM bit = 1, may be overwritten latter |
//Complex addressing modes |
if |
( |
aHasLiteral && |
!SourceNull( aSource0 ) && |
!Source0HasOffset && |
!Source1HasOffset && |
!DestinationHasOffset |
) |
{ |
I.SetAddressingMode( false,false,false); |
I.SetImm( aLiteral ); |
|
} |
else |
if |
( |
aHasLiteral && |
!SourceNull( aSource0 ) && |
Source0HasOffset && |
!Source0HasIndex && |
DestinationHasOffset |
|
) |
{ |
|
I.SetAddressingMode( false,false,true); |
I.SetImm( aLiteral ); |
|
|
} |
else |
if |
( |
!aHasLiteral && |
!SourceNull( aSource1 ) && |
!Source1HasOffset && |
!SourceNull( aSource0 ) && |
Source0HasOffset && |
Source0HasIndex && |
DestinationHasOffset |
|
) |
{ |
I.SetAddressingMode( false,true,false); |
|
} |
else |
if |
( |
!aHasLiteral && |
!Source1HasOffset && |
!SourceNull( aSource0 ) && |
Source0HasOffset && |
!Source0HasIndex && |
DestinationHasOffset && |
DetinationHasIndex |
|
) |
{ |
I.SetAddressingMode( false,true,true); |
|
} |
else |
if |
( |
aHasLiteral && |
SourceNull( aSource0 ) && |
!DestinationHasOffset && |
!DetinationHasIndex |
|
) |
{ |
|
|
I.SetAddressingMode( true,false,false); |
I.SetImm( aLiteral ); |
} |
else |
if |
( |
aHasLiteral && |
SourceNull( aSource0 ) && |
DestinationHasOffset && |
!DetinationHasIndex |
|
) |
{ |
|
I.SetAddressingMode( true,false,true); |
I.SetImm( aLiteral ); |
} |
else |
if |
( |
!aHasLiteral && |
Source1HasOffset && |
Source1HasIndex && |
SourceNull( aSource0 ) && |
DestinationHasOffset && |
!DetinationHasIndex |
|
) |
{ |
|
I.SetAddressingMode( true,true,false); |
} |
else |
if |
( |
!aHasLiteral && |
Source1HasOffset && |
Source1HasIndex && |
Source0HasOffset && |
!Source0HasIndex && |
DestinationHasOffset && |
!DetinationHasIndex |
|
) |
{ |
|
I.SetAddressingMode( true,true,true); |
} else { |
std::ostringstream ret; |
ret << "Could not determine addressing mode at line " << yylloc << " \n"; |
throw ret.str(); |
} |
|
|
} |
|
//------------------------------------------------------------- |
void PopulateBoolean(EBRANCHTYPE aBranchType, std::string Source1, std::string Source0, Instruction & I, std::vector<Instruction> & aInstructions, Theia::Parser::location_type & yylloc ) |
{ |
|
if (Source0.find("R") == std::string::npos) |
{ |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetCode( EOPERATION_ADD ); |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
unsigned int ImmediateValue; |
std::string StringHex = Source0; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc0Displace( true ); |
I.SetWriteChannel(ECHANNEL_X); |
I.SetWriteChannel(ECHANNEL_Y); |
I.SetWriteChannel(ECHANNEL_Z); |
aInstructions.push_back(I); |
I.Clear(); |
|
std::stringstream ss2; |
ss2 << "R" << TempRegIndex; |
ss2 >> Source0; |
Source0 += " OFFSET "; |
|
} |
else |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
|
I.SetCode( EOPERATION_ADD ); |
I.SetSrc0SignX( true ); |
I.SetSrc0SignY( true ); |
I.SetSrc0SignZ( true ); |
I.SetBranchFlag( true ); |
I.ClearWriteChannel(); |
I.SetBranchType( aBranchType ); |
|
PopulateSourceRegisters( Source1, Source0, I, aInstructions); |
aInstructions.push_back(I); |
I.Clear(); |
////std::cout << "pushing code at position " << (mInstructions.size() - 1) << "\n"; |
gBranchStack.push_back(aInstructions.size() - 1); |
ResetTempRegisterIndex(); |
} |
|
//------------------------------------------------------------- |
// Prototype for the yylex function |
static int yylex(Theia::Parser::semantic_type * yylval, |
Theia::Parser::location_type * yylloc, |
Theia::Scanner &scanner); |
|
|
|
/* Line 318 of lalr1.cc */ |
#line 815 "parser.tab.c" |
|
#ifndef YY_ |
# if YYENABLE_NLS |
# if ENABLE_NLS |
# include <libintl.h> /* FIXME: INFRINGES ON USER NAME SPACE */ |
# define YY_(msgid) dgettext ("bison-runtime", msgid) |
# endif |
# endif |
# ifndef YY_ |
# define YY_(msgid) msgid |
# endif |
#endif |
|
/* Suppress unused-variable warnings by "using" E. */ |
#define YYUSE(e) ((void) (e)) |
|
/* Enable debugging if requested. */ |
#if YYDEBUG |
|
/* A pseudo ostream that takes yydebug_ into account. */ |
# define YYCDEBUG if (yydebug_) (*yycdebug_) |
|
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ |
do { \ |
if (yydebug_) \ |
{ \ |
*yycdebug_ << Title << ' '; \ |
yy_symbol_print_ ((Type), (Value), (Location)); \ |
*yycdebug_ << std::endl; \ |
} \ |
} while (false) |
|
# define YY_REDUCE_PRINT(Rule) \ |
do { \ |
if (yydebug_) \ |
yy_reduce_print_ (Rule); \ |
} while (false) |
|
# define YY_STACK_PRINT() \ |
do { \ |
if (yydebug_) \ |
yystack_print_ (); \ |
} while (false) |
|
#else /* !YYDEBUG */ |
|
# define YYCDEBUG if (false) std::cerr |
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) |
# define YY_REDUCE_PRINT(Rule) |
# define YY_STACK_PRINT() |
|
#endif /* !YYDEBUG */ |
|
#define yyerrok (yyerrstatus_ = 0) |
#define yyclearin (yychar = yyempty_) |
|
#define YYACCEPT goto yyacceptlab |
#define YYABORT goto yyabortlab |
#define YYERROR goto yyerrorlab |
#define YYRECOVERING() (!!yyerrstatus_) |
|
|
/* Line 380 of lalr1.cc */ |
#line 28 "parser.y" |
namespace Theia { |
|
/* Line 380 of lalr1.cc */ |
#line 883 "parser.tab.c" |
#if YYERROR_VERBOSE |
|
/* Return YYSTR after stripping away unnecessary quotes and |
backslashes, so that it's suitable for yyerror. The heuristic is |
that double-quoting is unnecessary unless the string contains an |
apostrophe, a comma, or backslash (other than backslash-backslash). |
YYSTR is taken from yytname. */ |
std::string |
Parser::yytnamerr_ (const char *yystr) |
{ |
if (*yystr == '"') |
{ |
std::string yyr = ""; |
char const *yyp = yystr; |
|
for (;;) |
switch (*++yyp) |
{ |
case '\'': |
case ',': |
goto do_not_strip_quotes; |
|
case '\\': |
if (*++yyp != '\\') |
goto do_not_strip_quotes; |
/* Fall through. */ |
default: |
yyr += *yyp; |
break; |
|
case '"': |
return yyr; |
} |
do_not_strip_quotes: ; |
} |
|
return yystr; |
} |
|
#endif |
|
/// Build a parser object. |
Parser::Parser (Theia::Scanner &scanner_yyarg, std::map<std::string,unsigned int> & mSymbolMap_yyarg, std::vector< Instruction > &mInstructions_yyarg, bool &mGenerateFixedPointArithmetic_yyarg) |
: |
#if YYDEBUG |
yydebug_ (false), |
yycdebug_ (&std::cerr), |
#endif |
scanner (scanner_yyarg), |
mSymbolMap (mSymbolMap_yyarg), |
mInstructions (mInstructions_yyarg), |
mGenerateFixedPointArithmetic (mGenerateFixedPointArithmetic_yyarg) |
{ |
} |
|
Parser::~Parser () |
{ |
} |
|
#if YYDEBUG |
/*--------------------------------. |
| Print this symbol on YYOUTPUT. | |
`--------------------------------*/ |
|
inline void |
Parser::yy_symbol_value_print_ (int yytype, |
const semantic_type* yyvaluep, const location_type* yylocationp) |
{ |
YYUSE (yylocationp); |
YYUSE (yyvaluep); |
switch (yytype) |
{ |
default: |
break; |
} |
} |
|
|
void |
Parser::yy_symbol_print_ (int yytype, |
const semantic_type* yyvaluep, const location_type* yylocationp) |
{ |
*yycdebug_ << (yytype < yyntokens_ ? "token" : "nterm") |
<< ' ' << yytname_[yytype] << " (" |
<< *yylocationp << ": "; |
yy_symbol_value_print_ (yytype, yyvaluep, yylocationp); |
*yycdebug_ << ')'; |
} |
#endif |
|
void |
Parser::yydestruct_ (const char* yymsg, |
int yytype, semantic_type* yyvaluep, location_type* yylocationp) |
{ |
YYUSE (yylocationp); |
YYUSE (yymsg); |
YYUSE (yyvaluep); |
|
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); |
|
switch (yytype) |
{ |
|
default: |
break; |
} |
} |
|
void |
Parser::yypop_ (unsigned int n) |
{ |
yystate_stack_.pop (n); |
yysemantic_stack_.pop (n); |
yylocation_stack_.pop (n); |
} |
|
#if YYDEBUG |
std::ostream& |
Parser::debug_stream () const |
{ |
return *yycdebug_; |
} |
|
void |
Parser::set_debug_stream (std::ostream& o) |
{ |
yycdebug_ = &o; |
} |
|
|
Parser::debug_level_type |
Parser::debug_level () const |
{ |
return yydebug_; |
} |
|
void |
Parser::set_debug_level (debug_level_type l) |
{ |
yydebug_ = l; |
} |
#endif |
|
int |
Parser::parse () |
{ |
/// Lookahead and lookahead in internal form. |
int yychar = yyempty_; |
int yytoken = 0; |
|
/* State. */ |
int yyn; |
int yylen = 0; |
int yystate = 0; |
|
/* Error handling. */ |
int yynerrs_ = 0; |
int yyerrstatus_ = 0; |
|
/// Semantic value of the lookahead. |
semantic_type yylval; |
/// Location of the lookahead. |
location_type yylloc; |
/// The locations where the error started and ended. |
location_type yyerror_range[2]; |
|
/// $$. |
semantic_type yyval; |
/// @$. |
location_type yyloc; |
|
int yyresult; |
|
YYCDEBUG << "Starting parse" << std::endl; |
|
|
/* Initialize the stacks. The initial state will be pushed in |
yynewstate, since the latter expects the semantical and the |
location values to have been already stored, initialize these |
stacks with a primary value. */ |
yystate_stack_ = state_stack_type (0); |
yysemantic_stack_ = semantic_stack_type (0); |
yylocation_stack_ = location_stack_type (0); |
yysemantic_stack_.push (yylval); |
yylocation_stack_.push (yylloc); |
|
/* New state. */ |
yynewstate: |
yystate_stack_.push (yystate); |
YYCDEBUG << "Entering state " << yystate << std::endl; |
|
/* Accept? */ |
if (yystate == yyfinal_) |
goto yyacceptlab; |
|
goto yybackup; |
|
/* Backup. */ |
yybackup: |
|
/* Try to take a decision without lookahead. */ |
yyn = yypact_[yystate]; |
if (yyn == yypact_ninf_) |
goto yydefault; |
|
/* Read a lookahead token. */ |
if (yychar == yyempty_) |
{ |
YYCDEBUG << "Reading a token: "; |
yychar = yylex (&yylval, &yylloc, scanner); |
} |
|
|
/* Convert token to internal form. */ |
if (yychar <= yyeof_) |
{ |
yychar = yytoken = yyeof_; |
YYCDEBUG << "Now at end of input." << std::endl; |
} |
else |
{ |
yytoken = yytranslate_ (yychar); |
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); |
} |
|
/* If the proper action on seeing token YYTOKEN is to reduce or to |
detect an error, take that action. */ |
yyn += yytoken; |
if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) |
goto yydefault; |
|
/* Reduce or error. */ |
yyn = yytable_[yyn]; |
if (yyn <= 0) |
{ |
if (yyn == 0 || yyn == yytable_ninf_) |
goto yyerrlab; |
yyn = -yyn; |
goto yyreduce; |
} |
|
/* Shift the lookahead token. */ |
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); |
|
/* Discard the token being shifted. */ |
yychar = yyempty_; |
|
yysemantic_stack_.push (yylval); |
yylocation_stack_.push (yylloc); |
|
/* Count tokens shifted since error; after three, turn off error |
status. */ |
if (yyerrstatus_) |
--yyerrstatus_; |
|
yystate = yyn; |
goto yynewstate; |
|
/*-----------------------------------------------------------. |
| yydefault -- do the default action for the current state. | |
`-----------------------------------------------------------*/ |
yydefault: |
yyn = yydefact_[yystate]; |
if (yyn == 0) |
goto yyerrlab; |
goto yyreduce; |
|
/*-----------------------------. |
| yyreduce -- Do a reduction. | |
`-----------------------------*/ |
yyreduce: |
yylen = yyr2_[yyn]; |
/* If YYLEN is nonzero, implement the default value of the action: |
`$$ = $1'. Otherwise, use the top of the stack. |
|
Otherwise, the following line sets YYVAL to garbage. |
This behavior is undocumented and Bison |
users should not rely upon it. */ |
if (yylen) |
yyval = yysemantic_stack_[yylen - 1]; |
else |
yyval = yysemantic_stack_[0]; |
|
{ |
slice<location_type, location_stack_type> slice (yylocation_stack_, yylen); |
YYLLOC_DEFAULT (yyloc, slice, yylen); |
} |
YY_REDUCE_PRINT (yyn); |
switch (yyn) |
{ |
case 6: |
|
/* Line 678 of lalr1.cc */ |
#line 842 "parser.y" |
{ |
mGenerateFixedPointArithmetic = true; |
} |
break; |
|
case 7: |
|
/* Line 678 of lalr1.cc */ |
#line 847 "parser.y" |
{ |
//Insert a stupid NOP before the exit... is a bug but easier to just patch like this... |
|
I.Clear(); |
I.mComment = "NOP"; |
I.SetCode( EOPERATION_NOP ); |
mInstructions.push_back(I); |
I.Clear(); |
|
I.SetEofFlag(true); |
I.mComment = "Set the Exit bit"; |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
break; |
|
case 8: |
|
/* Line 678 of lalr1.cc */ |
#line 864 "parser.y" |
{ |
|
////////////////////////////////////////////////////////////////////////////// |
// This means this that the expression was just a constant. |
// No operations were inserted |
////////////////////////////////////////////////////////////////////////////// |
if (gInsertedInstructions == 0) |
{ |
I.Clear(); |
I.SetCode(EOPERATION_ADD); |
I.mComment ="Set the return value"; |
if ((yysemantic_stack_[(3) - (3)]).find("R") != std::string::npos) |
{ |
PopulateInstruction( "R1", (yysemantic_stack_[(3) - (2)]),"R0 . X X X",I,yylloc); |
} |
else |
{ |
unsigned int ImmediateValue = 0; |
std::string StringHex = (yysemantic_stack_[(3) - (3)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
PopulateInstruction( "R1", (yysemantic_stack_[(3) - (3)]),"NULL",I, yylloc, true, ImmediateValue); |
} |
mInstructions.push_back(I); |
I.Clear(); |
} else { |
|
mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc); |
gInsertedInstructions = 0; |
mInstructions.back().mComment ="Assigning return value"; |
mInstructions.back().SetDestinationAddress( RETURN_VALUE_REGISTER ); |
|
} |
ResetTempRegisterIndex(); |
|
I.SetCode( EOPERATION_ADD ); |
I.mComment = "Restore previous function frame offset"; |
I.ClearWriteChannel(); |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetSrc1Address(SPR_CONTROL_REGISTER); |
I.SetSrc1SwizzleX(SWX_Y); |
I.SetSrc1SwizzleY(SWY_Y); |
I.SetSrc1SwizzleZ(SWZ_Y); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
mInstructions.push_back( I ); |
I.Clear(); |
|
//Now return |
I.SetImm( 0 ); |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "return from function"; |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
I.SetDestinationAddress( RETURN_ADDRESS_REGISTER ); |
mInstructions.push_back(I); |
I.Clear(); |
|
|
|
} |
break; |
|
case 9: |
|
/* Line 678 of lalr1.cc */ |
#line 931 "parser.y" |
{ |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "Restore previous function frame offset"; |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetSrc1Address(SPR_CONTROL_REGISTER); |
I.SetSrc1SwizzleX(SWX_Y); |
I.SetSrc1SwizzleY(SWY_Y); |
I.SetSrc1SwizzleZ(SWZ_Y); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
mInstructions.push_back( I ); |
I.Clear(); |
|
I.SetImm( 0 ); |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "return from function"; |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
I.SetDestinationAddress( RETURN_ADDRESS_REGISTER ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
break; |
|
case 10: |
|
/* Line 678 of lalr1.cc */ |
#line 959 "parser.y" |
{ |
|
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetCode( EOPERATION_ADD ); |
SetDestinationFromRegister( (yysemantic_stack_[(4) - (1)]), I , true); |
unsigned int ImmediateValue; |
std::string StringHex = (yysemantic_stack_[(4) - (3)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( false ); |
|
mInstructions.push_back( I ); |
I.Clear(); |
} |
break; |
|
case 11: |
|
/* Line 678 of lalr1.cc */ |
#line 977 "parser.y" |
{ |
|
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetCode( EOPERATION_ADD ); |
SetDestinationFromRegister( (yysemantic_stack_[(4) - (1)]), I, false ); |
I.SetSrc0SignX( true ); |
I.SetSrc0SignY( true ); |
I.SetSrc0SignZ( true ); |
std::string Destination = (yysemantic_stack_[(4) - (1)]); |
if (Destination.find("OFFSET") != std::string::npos) |
{ |
I.SetSrc1Displace( true ); |
Destination.erase(Destination.find("OFFSET")); |
} |
|
if (Destination.find(".") != std::string::npos) |
Destination.erase(Destination.find(".")); |
|
|
I.SetSrc1Address(atoi(Destination.c_str()+1)); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_Y); |
I.SetSrc0SwizzleY(SWY_Y); |
I.SetSrc0SwizzleZ(SWZ_Y); |
mInstructions.push_back( I ); |
I.Clear(); |
} |
break; |
|
case 12: |
|
/* Line 678 of lalr1.cc */ |
#line 1006 "parser.y" |
{ |
|
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetCode( EOPERATION_ADD ); |
SetDestinationFromRegister( (yysemantic_stack_[(4) - (1)]), I, false ); |
std::string Destination = (yysemantic_stack_[(4) - (1)]); |
if (Destination.find("OFFSET") != std::string::npos) |
{ |
I.SetSrc1Displace( true ); |
Destination.erase(Destination.find("OFFSET")); |
} |
|
if (Destination.find(".") != std::string::npos) |
Destination.erase(Destination.find(".")); |
|
I.SetSrc1Address(atoi(Destination.c_str()+1)); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_Y); |
I.SetSrc0SwizzleY(SWY_Y); |
I.SetSrc0SwizzleZ(SWZ_Y); |
mInstructions.push_back( I ); |
I.Clear(); |
} |
break; |
|
case 13: |
|
/* Line 678 of lalr1.cc */ |
#line 1031 "parser.y" |
{ |
|
////////////////////////////////////////////////////////////////////////////// |
// This means this that the expression will write into the output memory |
// constant index |
////////////////////////////////////////////////////////////////////////////// |
|
if ((yysemantic_stack_[(4) - (1)]).find("OUT") != std::string::npos && (yysemantic_stack_[(4) - (1)]).find("INDEX") == std::string::npos ) |
{ |
//PopulateInstruction( "R0", "R0 . X X X",$3,I,yylloc); |
|
I.SetCode(EOPERATION_OUT); |
(yysemantic_stack_[(4) - (1)]).erase((yysemantic_stack_[(4) - (1)]).find("OUT"),3); |
|
unsigned int ImmediateValue; |
std::stringstream ss; |
ss << std::hex << (yysemantic_stack_[(4) - (1)]); |
ss >> ImmediateValue; |
PopulateInstruction( (yysemantic_stack_[(4) - (3)]), "R0 OFFSET", "R0 OFFSET", I, yylloc, true, ImmediateValue ); |
#ifdef DEBUG |
I.PrintFields(); |
#endif |
mInstructions.push_back(I); |
I.Clear(); |
ResetTempRegisterIndex(); |
goto LABEL_EXPRESSION_DONE; |
} |
////////////////////////////////////////////////////////////////////////////// |
// This means this that the expression will write into the output memory |
// variable index |
////////////////////////////////////////////////////////////////////////////// |
|
if ((yysemantic_stack_[(4) - (1)]).find("OUT") != std::string::npos && (yysemantic_stack_[(4) - (1)]).find("INDEX") != std::string::npos ) |
{ |
std::string Destination = (yysemantic_stack_[(4) - (1)]); |
DCOUT << "!!!!!!!!!!!!!!!!!Destination " << Destination << "\n"; |
std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5); |
Destination.erase(Destination.find("INDEX")); |
|
|
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
|
PopulateSourceRegisters( IndexRegister + " OFFSET ", (yysemantic_stack_[(4) - (3)]), I, mInstructions ); |
|
|
//I.SetImm( 0 ); |
I.SetCode( EOPERATION_OUT ); |
std::string Source0 = (yysemantic_stack_[(4) - (3)]); |
DCOUT << "!!!!!!!!!!!!!!!!!Source0 '" << Source0 << "'\n"; |
/* if (Source0.find("OFFSET") != std::string::npos) |
{ |
Source0.erase(Source0.find("OFFSET")); |
I.SetSrc0Displace(1); |
} |
I.SetSrc1Address(atoi(IndexRegister.c_str()+1)); |
I.SetSrc0Address(atoi(Source0.c_str()+1));*/ |
|
/* if (Destination.find(".") != std::string::npos) |
{ |
I.ClearWriteChannel(); |
if (Destination.find("x") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_X); |
if (Destination.find("y") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Y); |
if (Destination.find("z") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Z); |
|
Destination.erase(Destination.find(".")); |
|
} |
|
std::string Source0 = $3; |
if (Source0.find("OFFSET") != std::string::npos) |
{ |
Source0.erase(Source0.find("OFFSET")); |
I.SetSrc0Displace(1); |
} |
I.SetSrc1Address(atoi(IndexRegister.c_str()+1)); |
I.SetSrc0Address(atoi(Source0.c_str()+1)); |
|
|
// I.SetSrc0Address(mInstructions.back().GetDestinationAddress()); |
I.SetDestZero(0); |
I.SetSrc1Displace(1); |
I.SetSrc0Displace(1); |
I.SetDestinationAddress( atoi(Destination.c_str()+1) );*/ |
mInstructions.push_back( I ); |
I.Clear(); |
ResetTempRegisterIndex(); |
goto LABEL_EXPRESSION_DONE; |
} |
////////////////////////////////////////////////////////////////////////////// |
// This means this that the expression was just a constant. |
// No operations were inserted |
////////////////////////////////////////////////////////////////////////////// |
if (gInsertedInstructions == 0) |
{ |
|
I.Clear(); |
|
I.SetCode(EOPERATION_ADD); |
I.mSourceLine = GetCurrentLineNumber(yylloc); |
if ((yysemantic_stack_[(4) - (3)]).find("R") != std::string::npos) |
{ |
// case 1: |
// foo = 0; //$$ = R0 . X X X |
/* SetDestinationFromRegister( $1, I, false ); |
PopulateSourceRegisters( $3, "R0 . X X X", I, mInstructions);*/ |
|
PopulateInstruction( (yysemantic_stack_[(4) - (1)]), "R0 . X X X",(yysemantic_stack_[(4) - (3)]),I,yylloc); |
|
} else { |
// case 2: |
// foo = 0xcafe; //$$ = 0xcafe |
SetDestinationFromRegister( (yysemantic_stack_[(4) - (1)]), I, true ); |
unsigned int ImmediateValue = 0; |
std::string StringHex = (yysemantic_stack_[(4) - (3)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
PopulateInstruction( (yysemantic_stack_[(4) - (1)]), (yysemantic_stack_[(4) - (3)]),"NULL",I, yylloc, true, ImmediateValue); |
} |
std::string strConstant = (yysemantic_stack_[(4) - (3)]); |
|
mInstructions.push_back(I); |
I.Clear(); |
ResetTempRegisterIndex(); |
goto LABEL_EXPRESSION_DONE; |
} |
|
////////////////////////////////////////////////////////////////////////////// |
// This means that the last instruction which was inserted was a tripple |
// constant assignement, like foo = (1,2,3) |
////////////////////////////////////////////////////////////////////////////// |
if (mInstructions.back().mBisonFlagTrippleConstAssign) |
{ |
unsigned int LastIndex = mInstructions.size() - 1; |
mInstructions[LastIndex].SetDestinationAddress(atoi((yysemantic_stack_[(4) - (1)]).c_str()+1)); |
mInstructions[LastIndex-1].SetDestinationAddress(atoi((yysemantic_stack_[(4) - (1)]).c_str()+1)); |
mInstructions[LastIndex-2].SetDestinationAddress(atoi((yysemantic_stack_[(4) - (1)]).c_str()+1)); |
mInstructions[LastIndex-2].mSourceLine = GetCurrentLineNumber( yylloc ); |
if((yysemantic_stack_[(4) - (1)]).find("OFFSET") == std::string::npos) |
{ |
mInstructions[LastIndex].SetAddressingMode(true,false,false); |
mInstructions[LastIndex-1].SetAddressingMode(true,false,false); |
mInstructions[LastIndex-2].SetAddressingMode(true,false,false); |
} |
|
ResetTempRegisterIndex(); |
goto LABEL_EXPRESSION_DONE; |
} |
////////////////////////////////////////////////////////////////////////////// |
// Handle the case where the destination is an array of vector |
// ej: R = v1[ i ] + V2 |
////////////////////////////////////////////////////////////////////////////// |
if (I.GetOperation() == 0 && (yysemantic_stack_[(4) - (3)]).find("array_element") != std::string::npos) |
{ |
//No operation meaning the the expression only has a single variable |
//See if the expression returned is an array_element |
if ((yysemantic_stack_[(4) - (3)]).find("array_element") != std::string::npos) |
{ |
////std::cout << "expression is an array element\n\n"; |
std::string Index = (yysemantic_stack_[(4) - (3)]).substr((yysemantic_stack_[(4) - (3)]).find("array_element")); |
Index = Index.substr(Index.find_first_not_of("array_element R")); |
SetIndexRegister( atoi(Index.c_str()), mInstructions ); |
(yysemantic_stack_[(4) - (3)]).erase((yysemantic_stack_[(4) - (3)]).find("array_element")); |
SetExpressionDestination( (yysemantic_stack_[(4) - (1)]), I ); |
I.SetCode(EOPERATION_ADD); |
I.SetImmBit( true ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( true ); |
I.SetSrc0Displace( false ); |
I.mSourceLine = GetCurrentLineNumber(yylloc); |
|
if ((yysemantic_stack_[(4) - (3)]).find("OFFSET") != std::string::npos) |
(yysemantic_stack_[(4) - (3)]).erase((yysemantic_stack_[(4) - (3)]).find("OFFSET")); |
|
I.SetSrc1Address(atoi((yysemantic_stack_[(4) - (3)]).c_str()+1)); |
I.SetSrc0Address(0); |
mInstructions.push_back(I); |
I.Clear(); |
} |
} |
else |
{ |
|
mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc); |
gInsertedInstructions = 0; |
std::string Destination = (yysemantic_stack_[(4) - (1)]); |
//std::cout << "DST " << Destination << " \n"; |
//Look for indirect addressing |
if (Destination.find("INDEX") != std::string::npos) |
{ |
|
std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5); |
|
Destination.erase(Destination.find("INDEX")); |
|
I.SetImm( 0 ); |
I.SetCode( EOPERATION_ADD ); |
|
if (Destination.find(".") != std::string::npos) |
{ |
I.ClearWriteChannel(); |
if (Destination.find("x") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_X); |
if (Destination.find("y") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Y); |
if (Destination.find("z") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Z); |
|
Destination.erase(Destination.find(".")); |
|
} |
|
std::string Source0 = (yysemantic_stack_[(4) - (3)]); |
if (Source0.find("OFFSET") != std::string::npos) |
{ |
Source0.erase(Source0.find("OFFSET")); |
I.SetSrc0Displace(1); |
} |
I.SetSrc1Address(atoi(IndexRegister.c_str()+1)); |
I.SetSrc0Address(atoi(Source0.c_str()+1)); |
|
|
// I.SetSrc0Address(mInstructions.back().GetDestinationAddress()); |
I.SetDestZero(0); |
I.SetSrc1Displace(1); |
I.SetSrc0Displace(1); |
I.SetDestinationAddress( atoi(Destination.c_str()+1) ); |
mInstructions.push_back( I ); |
I.Clear(); |
} else { |
|
if (mInstructions.back().GetImm()) |
{ |
//Look for displament addressing mode |
unsigned int AddressingMode = mInstructions.back().GetAddressingMode(); |
if (Destination.find("OFFSET") != std::string::npos) |
{ |
//This means AddressMode is '101', so leave the way it is |
mInstructions.back().ClearWriteChannel(); |
mInstructions.back().SetWriteChannel(ECHANNEL_Z); |
Destination.erase(Destination.find("OFFSET")); |
} else { |
//This is not supposed to have index, so change addressing mode to '100' |
|
mInstructions.back().SetDestZero( true ); |
mInstructions.back().SetSrc1Displace( false ); |
mInstructions.back().SetSrc0Displace( false ); |
mInstructions.back().ClearWriteChannel(); |
mInstructions.back().SetWriteChannel(ECHANNEL_Z); |
} |
|
} else { |
mInstructions.back().SetDestZero( false ); //First assume no offset was used |
|
|
|
//Look for displament addressing mode |
if (Destination.find("OFFSET") != std::string::npos) |
{ |
Destination.erase(Destination.find("OFFSET")); |
mInstructions.back().SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
} |
} |
if (Destination.find(".") != std::string::npos) |
{ |
mInstructions.back().ClearWriteChannel(); |
if (Destination.find("x") != std::string::npos) |
mInstructions.back().SetWriteChannel(ECHANNEL_X); |
if (Destination.find("y") != std::string::npos) |
mInstructions.back().SetWriteChannel(ECHANNEL_Y); |
if (Destination.find("z") != std::string::npos) |
mInstructions.back().SetWriteChannel(ECHANNEL_Z); |
|
Destination.erase(Destination.find(".")); |
|
} |
mInstructions.back().SetDestinationAddress( atoi((yysemantic_stack_[(4) - (1)]).c_str()+1) ); |
for (int i = 1; i <= gExtraDestModifications; i++ ) |
{ |
int idx = (mInstructions.size()-1)-i; |
mInstructions[idx].SetDestinationAddress( atoi((yysemantic_stack_[(4) - (1)]).c_str()+1) ); |
if (mInstructions[idx].GetImm()) |
{ |
|
//This is not supposed to have index, so change addressing mode to '100' |
mInstructions[idx].SetDestZero( true ); |
mInstructions[idx].SetSrc1Displace( false ); |
mInstructions[idx].SetSrc0Displace( false ); |
|
|
} |
|
} |
gExtraDestModifications = 0; |
|
|
|
} |
ResetTempRegisterIndex(); |
} |
|
LABEL_EXPRESSION_DONE: |
gInsertedInstructions = 0; |
while(0); |
|
} |
break; |
|
case 14: |
|
/* Line 678 of lalr1.cc */ |
#line 1343 "parser.y" |
{ /*Middle rule here, get me the loop address*/ ;gWhileLoopAddress = (mInstructions.size());} |
break; |
|
case 15: |
|
/* Line 678 of lalr1.cc */ |
#line 1344 "parser.y" |
{ |
mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()+1); |
gBranchStack.pop_back(); |
//Now I need to put a GOTO so that the while gets evaluated again... |
//jump out of the if |
I.Clear(); |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "while loop goto re-eval boolean"; |
I.SetDestinationAddress( gWhileLoopAddress ); |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
mInstructions.push_back(I); |
I.Clear(); |
|
} |
break; |
|
case 16: |
|
/* Line 678 of lalr1.cc */ |
#line 1363 "parser.y" |
{ |
|
//jump out of the if |
I.Clear(); |
I.SetCode( EOPERATION_ADD ); |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
mInstructions.push_back(I); |
I.Clear(); |
//Take care of the destination addr of the if statement. |
mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()); |
gBranchStack.pop_back(); |
//push the inconditional jump into the stack |
gBranchStack.push_back(mInstructions.size() - 1); |
////std::cout << "else\n"; |
|
} |
break; |
|
case 17: |
|
/* Line 678 of lalr1.cc */ |
#line 1381 "parser.y" |
{ |
|
mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()); |
gBranchStack.pop_back(); |
//Now push the JMP |
|
////std::cout << "END elseif\n"; |
} |
break; |
|
case 18: |
|
/* Line 678 of lalr1.cc */ |
#line 1392 "parser.y" |
{ |
mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()); |
//mInstructions[gBranchStack.back()].mSourceLine = GetCurrentLineNumber(yylloc); |
|
gBranchStack.pop_back(); |
////std::cout << "if closing at " << mInstructions.size() << "\n"; |
|
} |
break; |
|
case 19: |
|
/* Line 678 of lalr1.cc */ |
#line 1402 "parser.y" |
{ |
////std::cout << "Function declaration for " << $2 << " at " << mInstructions.size() << "\n" ; |
mSymbolMap[ (yysemantic_stack_[(5) - (2)]) ] = mInstructions.size(); |
} |
break; |
|
case 20: |
|
/* Line 678 of lalr1.cc */ |
#line 1406 "parser.y" |
{ |
//Clear the auto var index now that we leave the function scope |
ClearAutoVarMap(); |
ClearFunctionParameterMap(); |
|
//Now uddate the current SPR_CONTROL_REGISTER.x = SPR_CONTROL_REGISTER.y |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "Restore previous function frame offset"; |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetSrc1Address(SPR_CONTROL_REGISTER); |
I.SetSrc1SwizzleX(SWX_Y); |
I.SetSrc1SwizzleY(SWY_Y); |
I.SetSrc1SwizzleZ(SWZ_Y); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
|
mInstructions.push_back( I ); |
I.Clear(); |
} |
break; |
|
case 21: |
|
/* Line 678 of lalr1.cc */ |
#line 1431 "parser.y" |
{ |
gThreadMap[ (yysemantic_stack_[(4) - (2)]) ] = mInstructions.size(); |
gThreadScope = true; |
} |
break; |
|
case 22: |
|
/* Line 678 of lalr1.cc */ |
#line 1436 "parser.y" |
{ |
////std::cout << "Defining thread" << "\n"; |
gThreadScope = false; |
ClearAutoVarMap(); |
//Since the thread is done, then disable threading |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "Disable multi-threading"; |
I.SetDestinationAddress( SPR_CONTROL_REGISTER0 ); |
unsigned int Value = 0; |
I.SetImm( Value ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_Z); |
mInstructions.push_back( I ); |
I.Clear(); |
|
} |
break; |
|
case 23: |
|
/* Line 678 of lalr1.cc */ |
#line 1454 "parser.y" |
{ |
unsigned int ThreadCodeOffset = 0; |
////std::cout << "Starting thread" << "\n"; |
if (gThreadMap.find((yysemantic_stack_[(5) - (2)])) == gThreadMap.end()) |
{ |
|
std::ostringstream ret; |
ret << "Undefined thread '" << (yysemantic_stack_[(5) - (2)]) << "' at line " << yylloc << " \n"; |
ret << "Current version of the compiler needs thread defintion prior of thread instantiation\n"; |
throw ret.str(); |
} else { |
ThreadCodeOffset = gThreadMap[(yysemantic_stack_[(5) - (2)])]; |
//Now enable the multithreading and set instruction offset |
I.SetCode( EOPERATION_ADD ); |
std::ostringstream ss; |
ss << "Set thread instruction offset to 8'd" << ThreadCodeOffset; |
I.mComment = ss.str(); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER0 ); |
unsigned int Value = (ThreadCodeOffset << 1); |
I.SetImm( Value ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_Z); |
mInstructions.push_back( I ); |
I.Clear(); |
|
|
I.SetCode( EOPERATION_ADD ); |
I.mComment = "Enable multi-threading"; |
I.SetDestinationAddress( SPR_CONTROL_REGISTER0 ); |
Value = (ThreadCodeOffset << 1 | 1); |
I.SetImm( Value ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_Z); |
mInstructions.push_back( I ); |
I.Clear(); |
|
} |
|
} |
break; |
|
case 24: |
|
/* Line 678 of lalr1.cc */ |
#line 1495 "parser.y" |
{ |
////std::cout << "Function call returning to var\n"; |
StoreReturnAddress( mInstructions, yylloc ); |
SavePreviousFramePointer( mInstructions ); |
UpdateFramePointer( mInstructions ); |
CallFunction( (yysemantic_stack_[(7) - (3)]), mInstructions, mSymbolMap ); |
|
|
//Return value comes in R1, so let's store this in our variable |
I.SetCode( EOPERATION_ADD ); |
SetDestinationFromRegister( (yysemantic_stack_[(7) - (1)]), I, false ); |
I.mComment = "grab the return value from the function"; |
I.SetSrc1Address( RETURN_VALUE_REGISTER); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
mInstructions.push_back( I ); |
I.Clear(); |
ClearNextFunctionParamRegister(); |
} |
break; |
|
case 25: |
|
/* Line 678 of lalr1.cc */ |
#line 1519 "parser.y" |
{ |
|
//Store the return address |
StoreReturnAddress( mInstructions, yylloc ); |
|
|
//Store the current SPR_CONTROL_REGISTER.x into the previous SPR_CONTROL_REGISTER.y |
//SPR_CONTROL_REGISTER.y = SPR_CONTROL_REGISTER.xxx + 0; |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "store current frame offset"; |
I.SetWriteChannel(ECHANNEL_Y); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetSrc1Address(SPR_CONTROL_REGISTER); |
I.SetSrc1SwizzleX(SWX_X); |
I.SetSrc1SwizzleY(SWY_X); |
I.SetSrc1SwizzleZ(SWZ_X); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
mInstructions.push_back( I ); |
I.Clear(); |
//Now uddate the current SPR_CONTROL_REGISTER.x += number of auto variables |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "displace next frame offset by the number of auto variables in current frame"; |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetImm( GetCurretAutoVarFrameSize() ); |
I.SetDestZero( false ); |
mInstructions.push_back( I ); |
I.Clear(); |
//Call the function with a JMP |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "call the function"; |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
//Now do the branch |
if (mSymbolMap.find((yysemantic_stack_[(5) - (1)])) == mSymbolMap.end()) |
{ |
// ////std::cout << "Error in line : " << $1 <<" undelcared IDENTIFIER\n"; |
I.SetDestinationSymbol( "@"+(yysemantic_stack_[(5) - (1)]) ); |
// exit(1); |
} else { |
I.SetDestinationAddress( mSymbolMap[ (yysemantic_stack_[(5) - (1)]) ] ); |
} |
|
|
mInstructions.push_back( I ); |
I.Clear(); |
|
} |
break; |
|
case 27: |
|
/* Line 678 of lalr1.cc */ |
#line 1578 "parser.y" |
{ |
AddFunctionInputList( (yysemantic_stack_[(3) - (1)]), mInstructions,yylloc ); |
} |
break; |
|
case 28: |
|
/* Line 678 of lalr1.cc */ |
#line 1583 "parser.y" |
{ |
AddFunctionInputList( (yysemantic_stack_[(1) - (1)]),mInstructions, yylloc ); |
} |
break; |
|
case 30: |
|
/* Line 678 of lalr1.cc */ |
#line 1592 "parser.y" |
{ |
AddFunctionParameter( (yysemantic_stack_[(3) - (1)]), yylloc ); |
} |
break; |
|
case 31: |
|
/* Line 678 of lalr1.cc */ |
#line 1597 "parser.y" |
{ |
AddFunctionParameter( (yysemantic_stack_[(1) - (1)]), yylloc ); |
} |
break; |
|
case 32: |
|
/* Line 678 of lalr1.cc */ |
#line 1618 "parser.y" |
{ |
unsigned int TempRegIndex = GetFreeTempRegister(); |
gExtraDestModifications = 0; |
|
I.SetCode( EOPERATION_ADD ); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
|
PopulateSourceRegisters( (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions ); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
(yyval) = ss.str(); |
|
} |
break; |
|
case 33: |
|
/* Line 678 of lalr1.cc */ |
#line 1639 "parser.y" |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetCode( EOPERATION_ADD ); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetSrc0SignX( true ); |
I.SetSrc0SignY( true ); |
I.SetSrc0SignZ( true ); |
|
PopulateSourceRegisters( (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
(yyval) = ss.str(); |
} |
break; |
|
case 34: |
|
/* Line 678 of lalr1.cc */ |
#line 1661 "parser.y" |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetCode( EOPERATION_LOGIC ); |
I.SetLogicOperation( ELOGIC_OR ); |
PopulateSourceRegisters( (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions); |
|
|
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
(yyval) = ss.str(); |
} |
break; |
|
case 35: |
|
/* Line 678 of lalr1.cc */ |
#line 1682 "parser.y" |
{ |
(yyval) = (yysemantic_stack_[(1) - (1)]); |
} |
break; |
|
case 36: |
|
/* Line 678 of lalr1.cc */ |
#line 1690 "parser.y" |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetCode( EOPERATION_MUL ); |
|
PopulateSourceRegisters( (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions); |
|
//If we are using fixed point aritmethic then we need to apply the scale |
//R = A * ( B >> SCALE) |
if (mGenerateFixedPointArithmetic) |
I.SetSrc0Rotation( EROT_RESULT_RIGHT ); |
|
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
(yyval) = ss.str(); |
} |
break; |
|
case 37: |
|
/* Line 678 of lalr1.cc */ |
#line 1715 "parser.y" |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetCode( EOPERATION_DIV ); |
|
PopulateSourceRegisters( (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions); |
|
//If we are using fixed point aritmethic then we need to apply the scale |
// R = (A << N) / B |
if (mGenerateFixedPointArithmetic) |
I.SetSrc1Rotation( EROT_SRC1_LEFT ); |
|
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
(yyval) = ss.str(); |
} |
break; |
|
case 38: |
|
/* Line 678 of lalr1.cc */ |
#line 1740 "parser.y" |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetCode( EOPERATION_LOGIC ); |
I.SetLogicOperation( ELOGIC_AND ); |
PopulateSourceRegisters( (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions); |
|
|
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
(yyval) = ss.str(); |
} |
break; |
|
case 39: |
|
/* Line 678 of lalr1.cc */ |
#line 1761 "parser.y" |
{ |
(yyval) = (yysemantic_stack_[(1) - (1)]); |
} |
break; |
|
case 40: |
|
/* Line 678 of lalr1.cc */ |
#line 1769 "parser.y" |
{ |
(yyval) = (yysemantic_stack_[(1) - (1)]); |
} |
break; |
|
case 41: |
|
/* Line 678 of lalr1.cc */ |
#line 1774 "parser.y" |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetCode( EOPERATION_SQRT ); |
I.SetSrc0Address( 0 ); |
PopulateSourceRegisters( (yysemantic_stack_[(4) - (3)]) ,"R0 . X X X", I, mInstructions); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
(yyval) = ss.str(); |
} |
break; |
|
case 42: |
|
/* Line 678 of lalr1.cc */ |
#line 1793 "parser.y" |
{ |
(yyval) = (yysemantic_stack_[(3) - (2)]); |
} |
break; |
|
case 43: |
|
/* Line 678 of lalr1.cc */ |
#line 1803 "parser.y" |
{ |
|
unsigned int ImmediateValue; |
std::string StringHex = (yysemantic_stack_[(1) - (1)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
switch (ImmediateValue) |
{ |
case 0: |
(yyval) = "R0 . X X X"; |
break; |
case 1: |
(yyval) = "R0 . Y Y Y"; |
break; |
case 2: |
(yyval) = "R0 . Z Z Z"; |
break; |
default: |
std::string StringHex = (yysemantic_stack_[(1) - (1)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
(yyval) = ss.str(); |
break; |
} |
} |
break; |
|
case 44: |
|
/* Line 678 of lalr1.cc */ |
#line 1833 "parser.y" |
{ |
unsigned int TempRegIndex = GetFreeTempRegister(); |
unsigned int ImmediateValue; |
|
{ |
|
std::string StringHex = (yysemantic_stack_[(7) - (2)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
|
I.SetDestinationAddress( TempRegIndex ); |
I.SetImm( ImmediateValue ); |
I.SetDestZero(true); |
I.SetSrc0Displace(true); |
I.SetWriteChannel(ECHANNEL_X); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
} |
|
{ |
std::string StringHex = (yysemantic_stack_[(7) - (4)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
I.SetDestinationAddress( TempRegIndex ); |
I.SetImm( ImmediateValue ); |
I.SetDestZero(true); |
I.SetSrc0Displace(true); |
I.SetWriteChannel(ECHANNEL_Y); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
} |
|
{ |
std::string StringHex = (yysemantic_stack_[(7) - (6)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
I.SetDestinationAddress( TempRegIndex ); |
I.SetImm( ImmediateValue ); |
I.SetDestZero(true); |
I.SetSrc0Displace(true); |
I.SetWriteChannel(ECHANNEL_Z); |
I.SetCode( EOPERATION_ADD ); |
I.mBisonFlagTrippleConstAssign = true; |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
} |
|
gExtraDestModifications = 2; |
std::stringstream ss2; |
ss2 << "R" << TempRegIndex << " OFFSET "; |
(yyval) = ss2.str(); |
} |
break; |
|
case 45: |
|
/* Line 678 of lalr1.cc */ |
#line 1898 "parser.y" |
{ |
|
|
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter((yysemantic_stack_[(2) - (1)]))) != "NULL") |
(yyval) = Register; |
else |
(yyval) = GetRegisterFromAutoVar( (yysemantic_stack_[(2) - (1)]), yylloc) + " OFFSET "; |
|
if ((yysemantic_stack_[(2) - (2)]) != "NULL") |
{ |
|
(yyval) += " array_element " + (yysemantic_stack_[(2) - (2)]); |
|
} |
} |
break; |
|
case 46: |
|
/* Line 678 of lalr1.cc */ |
#line 1916 "parser.y" |
{ |
|
std::string X = (yysemantic_stack_[(5) - (3)]),Y = (yysemantic_stack_[(5) - (4)]),Z = (yysemantic_stack_[(5) - (5)]); |
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter((yysemantic_stack_[(5) - (1)]))) != "NULL") |
(yyval) = (Register + " . " + " " + X + " " + Y + " " + Z + " OFFSET "); |
else |
(yyval) = (GetRegisterFromAutoVar( (yysemantic_stack_[(5) - (1)]), yylloc) + " . " + " " + X + " " + Y + " " + Z + " OFFSET "); |
} |
break; |
|
case 47: |
|
/* Line 678 of lalr1.cc */ |
#line 1927 "parser.y" |
{ |
|
std::string R = (yysemantic_stack_[(1) - (1)]); |
R.erase(0,1); |
(yyval) = "R" + R; |
|
} |
break; |
|
case 48: |
|
/* Line 678 of lalr1.cc */ |
#line 1936 "parser.y" |
{ |
|
std::string R = (yysemantic_stack_[(4) - (1)]); |
R.erase(0,1); |
(yyval) = "<<R" + R; |
} |
break; |
|
case 49: |
|
/* Line 678 of lalr1.cc */ |
#line 1944 "parser.y" |
{ |
|
std::string R = (yysemantic_stack_[(4) - (1)]); |
R.erase(0,1); |
(yyval) = ">>R" + R; |
} |
break; |
|
case 50: |
|
/* Line 678 of lalr1.cc */ |
#line 1952 "parser.y" |
{ |
std::string R = (yysemantic_stack_[(5) - (1)]); |
std::string X = (yysemantic_stack_[(5) - (3)]),Y = (yysemantic_stack_[(5) - (4)]),Z = (yysemantic_stack_[(5) - (5)]); |
R.erase(0,1); |
(yyval) = "R" + R + " . " + " " + X + " " + Y + " " + Z; |
|
} |
break; |
|
case 51: |
|
/* Line 678 of lalr1.cc */ |
#line 1965 "parser.y" |
{ |
(yyval) = "X"; |
} |
break; |
|
case 52: |
|
/* Line 678 of lalr1.cc */ |
#line 1970 "parser.y" |
{ |
(yyval) = "-X"; |
} |
break; |
|
case 53: |
|
/* Line 678 of lalr1.cc */ |
#line 1975 "parser.y" |
{ |
(yyval) = "Y"; |
} |
break; |
|
case 54: |
|
/* Line 678 of lalr1.cc */ |
#line 1980 "parser.y" |
{ |
(yyval) = "-Y"; |
} |
break; |
|
case 55: |
|
/* Line 678 of lalr1.cc */ |
#line 1985 "parser.y" |
{ |
(yyval) = "Z"; |
} |
break; |
|
case 56: |
|
/* Line 678 of lalr1.cc */ |
#line 1990 "parser.y" |
{ |
(yyval) = "-Z"; |
} |
break; |
|
case 57: |
|
/* Line 678 of lalr1.cc */ |
#line 1998 "parser.y" |
{ |
(yyval) = "NULL"; |
} |
break; |
|
case 58: |
|
/* Line 678 of lalr1.cc */ |
#line 2003 "parser.y" |
{ |
/*std::string Register; |
if ((Register = GetRegisterFromFunctionParameter($2)) != "NULL") |
$$ = Register; |
else*/ |
//Indexes into arrays can only be auto variables! |
(yyval) = GetRegisterFromAutoVar( (yysemantic_stack_[(3) - (2)]), yylloc ); |
} |
break; |
|
case 59: |
|
/* Line 678 of lalr1.cc */ |
#line 2016 "parser.y" |
{ |
|
(yyval) = "OUT " + (yysemantic_stack_[(4) - (3)]); |
} |
break; |
|
case 60: |
|
/* Line 678 of lalr1.cc */ |
#line 2022 "parser.y" |
{ |
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter((yysemantic_stack_[(4) - (3)]))) == "NULL") |
Register = GetRegisterFromAutoVar( (yysemantic_stack_[(4) - (3)]), yylloc ); |
|
(yyval) = "OUT INDEX" + Register; |
} |
break; |
|
case 61: |
|
/* Line 678 of lalr1.cc */ |
#line 2031 "parser.y" |
{ |
|
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter((yysemantic_stack_[(2) - (1)]))) != "NULL") |
(yyval) = Register + ".xyz"; |
else |
(yyval) = GetRegisterFromAutoVar( (yysemantic_stack_[(2) - (1)]), yylloc ) + ".xyz" + " OFFSET " + (((yysemantic_stack_[(2) - (2)]) != "NULL")?" INDEX"+(yysemantic_stack_[(2) - (2)]):""); |
|
} |
break; |
|
case 62: |
|
/* Line 678 of lalr1.cc */ |
#line 2042 "parser.y" |
{ |
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter((yysemantic_stack_[(3) - (1)]))) != "NULL") |
(yyval) = Register + ".x"; |
else |
(yyval) = GetRegisterFromAutoVar( (yysemantic_stack_[(3) - (1)]), yylloc ) + ".x" + " OFFSET "; |
} |
break; |
|
case 63: |
|
/* Line 678 of lalr1.cc */ |
#line 2051 "parser.y" |
{ |
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter((yysemantic_stack_[(3) - (1)]))) != "NULL") |
(yyval) = Register + ".y"; |
else |
(yyval) = GetRegisterFromAutoVar( (yysemantic_stack_[(3) - (1)]), yylloc ) + ".y" + " OFFSET "; |
} |
break; |
|
case 64: |
|
/* Line 678 of lalr1.cc */ |
#line 2060 "parser.y" |
{ |
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter((yysemantic_stack_[(3) - (1)]))) != "NULL") |
(yyval) = Register + ".z"; |
else |
(yyval) = GetRegisterFromAutoVar( (yysemantic_stack_[(3) - (1)]), yylloc ) + ".z" + " OFFSET "; |
} |
break; |
|
case 65: |
|
/* Line 678 of lalr1.cc */ |
#line 2069 "parser.y" |
{ |
std::string R = (yysemantic_stack_[(1) - (1)]); |
R.erase(0,1); |
(yyval) = "R" + R + ".xyz"; |
} |
break; |
|
case 66: |
|
/* Line 678 of lalr1.cc */ |
#line 2076 "parser.y" |
{ |
std::string R = (yysemantic_stack_[(3) - (1)]); |
R.erase(0,1); |
(yyval) = "R" + R + ".x"; |
} |
break; |
|
case 67: |
|
/* Line 678 of lalr1.cc */ |
#line 2083 "parser.y" |
{ |
std::string R = (yysemantic_stack_[(3) - (1)]); |
R.erase(0,1); |
(yyval) = "R" + R + ".y"; |
} |
break; |
|
case 68: |
|
/* Line 678 of lalr1.cc */ |
#line 2090 "parser.y" |
{ |
|
std::string R = (yysemantic_stack_[(3) - (1)]); |
R.erase(0,1); |
(yyval) = "R" + R + ".z"; |
} |
break; |
|
case 69: |
|
/* Line 678 of lalr1.cc */ |
#line 2098 "parser.y" |
{ |
std::string R = (yysemantic_stack_[(5) - (1)]); |
R.erase(0,1); |
(yyval) = "R" + R + ".xy"; |
} |
break; |
|
case 70: |
|
/* Line 678 of lalr1.cc */ |
#line 2105 "parser.y" |
{ |
std::string R = (yysemantic_stack_[(5) - (1)]); |
R.erase(0,1); |
(yyval) = "R" + R + ".xz"; |
} |
break; |
|
case 71: |
|
/* Line 678 of lalr1.cc */ |
#line 2112 "parser.y" |
{ |
std::string R = (yysemantic_stack_[(5) - (1)]); |
R.erase(0,1); |
(yyval) = "R" + R + ".yz"; |
} |
break; |
|
case 72: |
|
/* Line 678 of lalr1.cc */ |
#line 2123 "parser.y" |
{ |
PopulateBoolean(EBRANCH_IF_ZERO, (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions, yylloc ); |
|
} |
break; |
|
case 73: |
|
/* Line 678 of lalr1.cc */ |
#line 2129 "parser.y" |
{ |
PopulateBoolean(EBRANCH_IF_NOT_ZERO, (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions, yylloc ); |
|
} |
break; |
|
case 74: |
|
/* Line 678 of lalr1.cc */ |
#line 2135 "parser.y" |
{ |
PopulateBoolean(EBRANCH_IF_ZERO_OR_SIGN, (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions, yylloc ); |
|
} |
break; |
|
case 75: |
|
/* Line 678 of lalr1.cc */ |
#line 2142 "parser.y" |
{ |
PopulateBoolean(EBRANCH_IF_ZERO_OR_NOT_SIGN, (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions, yylloc ); |
|
} |
break; |
|
case 76: |
|
/* Line 678 of lalr1.cc */ |
#line 2148 "parser.y" |
{ |
PopulateBoolean(EBRANCH_IF_NOT_SIGN, (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions, yylloc ); |
|
} |
break; |
|
case 77: |
|
/* Line 678 of lalr1.cc */ |
#line 2154 "parser.y" |
{ |
PopulateBoolean(EBRANCH_IF_SIGN, (yysemantic_stack_[(3) - (1)]), (yysemantic_stack_[(3) - (3)]), I, mInstructions, yylloc ); |
|
} |
break; |
|
case 78: |
|
/* Line 678 of lalr1.cc */ |
#line 2163 "parser.y" |
{ |
// Transform to HEX string |
unsigned int Val; |
std::string StringDec = (yysemantic_stack_[(1) - (1)]); |
std::stringstream ss; |
ss << StringDec; |
ss >> Val; |
std::stringstream ss2; |
ss2 << std::hex << Val; |
(yyval) = ss2.str(); |
} |
break; |
|
case 79: |
|
/* Line 678 of lalr1.cc */ |
#line 2176 "parser.y" |
{ |
std::string StringHex = (yysemantic_stack_[(1) - (1)]); |
// Get rid of the 0x |
StringHex.erase(StringHex.begin(),StringHex.begin()+2); |
std::stringstream ss; |
ss << std::hex << StringHex; |
|
(yyval) = ss.str(); |
} |
break; |
|
case 80: |
|
/* Line 678 of lalr1.cc */ |
#line 2187 "parser.y" |
{ |
// Transform to HEX string |
std::string StringBin = (yysemantic_stack_[(1) - (1)]); |
// Get rid of the 0b |
StringBin.erase(StringBin.begin(),StringBin.begin()+2); |
std::bitset<32> Bitset( StringBin ); |
std::stringstream ss2; |
ss2 << std::hex << Bitset.to_ulong(); |
(yyval) = ss2.str(); |
} |
break; |
|
case 81: |
|
/* Line 678 of lalr1.cc */ |
#line 2201 "parser.y" |
{ |
if (gAutoVarMap.find((yysemantic_stack_[(4) - (1)])) != gAutoVarMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol '" << (yysemantic_stack_[(4) - (1)]) << "'\n"; |
throw ret.str(); |
} |
|
std::stringstream ss; |
ss << (yysemantic_stack_[(4) - (2)]); |
unsigned int Size; |
ss >> Size; |
gAutoVarMap[ (yysemantic_stack_[(4) - (1)]) ] = AllocAutoVar(Size); |
} |
break; |
|
case 82: |
|
/* Line 678 of lalr1.cc */ |
#line 2217 "parser.y" |
{ |
if (gAutoVarMap.find((yysemantic_stack_[(11) - (1)])) != gAutoVarMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol " << (yysemantic_stack_[(11) - (1)]) << "'\n"; |
throw ret.str(); |
} |
gAutoVarMap[ (yysemantic_stack_[(11) - (1)]) ] = AllocAutoVar(); |
|
unsigned int Destination = gAutoVarMap[ (yysemantic_stack_[(11) - (1)]) ]; |
|
|
|
I.ClearWriteChannel(); |
unsigned int ImmediateValue; |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_X); |
std::string StringHex = (yysemantic_stack_[(11) - (4)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_Y); |
std::string StringHex = (yysemantic_stack_[(11) - (6)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_Z); |
std::string StringHex = (yysemantic_stack_[(11) - (8)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
} |
break; |
|
case 83: |
|
/* Line 678 of lalr1.cc */ |
#line 2281 "parser.y" |
{ |
if (gAutoVarMap.find((yysemantic_stack_[(9) - (1)])) != gAutoVarMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol " << (yysemantic_stack_[(9) - (1)]) << "'\n"; |
throw ret.str(); |
} |
gAutoVarMap[ (yysemantic_stack_[(9) - (1)]) ] = AllocAutoVar(); |
|
unsigned int Destination = gAutoVarMap[ (yysemantic_stack_[(9) - (1)]) ]; |
|
|
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
|
|
I.ClearWriteChannel(); |
unsigned int ImmediateValue; |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_X); |
std::string StringHex = (yysemantic_stack_[(9) - (4)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_Y); |
std::string StringHex = (yysemantic_stack_[(9) - (6)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_Z); |
std::string StringHex = (yysemantic_stack_[(9) - (8)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
} |
break; |
|
case 84: |
|
/* Line 678 of lalr1.cc */ |
#line 2349 "parser.y" |
{ |
|
if (gAutoVarMap.find((yysemantic_stack_[(2) - (1)])) != gAutoVarMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol " << (yysemantic_stack_[(2) - (1)]) << "'\n"; |
throw ret.str(); |
} |
std::stringstream ss; |
ss << std::hex << (yysemantic_stack_[(2) - (2)]); |
unsigned int Size; |
ss >> Size; |
////std::cout << "Array Size is " << Size << " " << $2 << "\n"; |
gAutoVarMap[ (yysemantic_stack_[(2) - (1)]) ] = AllocAutoVar(Size); |
} |
break; |
|
case 85: |
|
/* Line 678 of lalr1.cc */ |
#line 2368 "parser.y" |
{ |
(yyval) = "1"; |
} |
break; |
|
case 86: |
|
/* Line 678 of lalr1.cc */ |
#line 2373 "parser.y" |
{ |
|
(yyval) = (yysemantic_stack_[(3) - (2)]); |
} |
break; |
|
|
|
/* Line 678 of lalr1.cc */ |
#line 2972 "parser.tab.c" |
default: |
break; |
} |
YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc); |
|
yypop_ (yylen); |
yylen = 0; |
YY_STACK_PRINT (); |
|
yysemantic_stack_.push (yyval); |
yylocation_stack_.push (yyloc); |
|
/* Shift the result of the reduction. */ |
yyn = yyr1_[yyn]; |
yystate = yypgoto_[yyn - yyntokens_] + yystate_stack_[0]; |
if (0 <= yystate && yystate <= yylast_ |
&& yycheck_[yystate] == yystate_stack_[0]) |
yystate = yytable_[yystate]; |
else |
yystate = yydefgoto_[yyn - yyntokens_]; |
goto yynewstate; |
|
/*------------------------------------. |
| yyerrlab -- here on detecting error | |
`------------------------------------*/ |
yyerrlab: |
/* If not already recovering from an error, report this error. */ |
if (!yyerrstatus_) |
{ |
++yynerrs_; |
error (yylloc, yysyntax_error_ (yystate, yytoken)); |
} |
|
yyerror_range[0] = yylloc; |
if (yyerrstatus_ == 3) |
{ |
/* If just tried and failed to reuse lookahead token after an |
error, discard it. */ |
|
if (yychar <= yyeof_) |
{ |
/* Return failure if at end of input. */ |
if (yychar == yyeof_) |
YYABORT; |
} |
else |
{ |
yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc); |
yychar = yyempty_; |
} |
} |
|
/* Else will try to reuse lookahead token after shifting the error |
token. */ |
goto yyerrlab1; |
|
|
/*---------------------------------------------------. |
| yyerrorlab -- error raised explicitly by YYERROR. | |
`---------------------------------------------------*/ |
yyerrorlab: |
|
/* Pacify compilers like GCC when the user code never invokes |
YYERROR and the label yyerrorlab therefore never appears in user |
code. */ |
if (false) |
goto yyerrorlab; |
|
yyerror_range[0] = yylocation_stack_[yylen - 1]; |
/* Do not reclaim the symbols of the rule which action triggered |
this YYERROR. */ |
yypop_ (yylen); |
yylen = 0; |
yystate = yystate_stack_[0]; |
goto yyerrlab1; |
|
/*-------------------------------------------------------------. |
| yyerrlab1 -- common code for both syntax error and YYERROR. | |
`-------------------------------------------------------------*/ |
yyerrlab1: |
yyerrstatus_ = 3; /* Each real token shifted decrements this. */ |
|
for (;;) |
{ |
yyn = yypact_[yystate]; |
if (yyn != yypact_ninf_) |
{ |
yyn += yyterror_; |
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) |
{ |
yyn = yytable_[yyn]; |
if (0 < yyn) |
break; |
} |
} |
|
/* Pop the current state because it cannot handle the error token. */ |
if (yystate_stack_.height () == 1) |
YYABORT; |
|
yyerror_range[0] = yylocation_stack_[0]; |
yydestruct_ ("Error: popping", |
yystos_[yystate], |
&yysemantic_stack_[0], &yylocation_stack_[0]); |
yypop_ (); |
yystate = yystate_stack_[0]; |
YY_STACK_PRINT (); |
} |
|
yyerror_range[1] = yylloc; |
// Using YYLLOC is tempting, but would change the location of |
// the lookahead. YYLOC is available though. |
YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); |
yysemantic_stack_.push (yylval); |
yylocation_stack_.push (yyloc); |
|
/* Shift the error token. */ |
YY_SYMBOL_PRINT ("Shifting", yystos_[yyn], |
&yysemantic_stack_[0], &yylocation_stack_[0]); |
|
yystate = yyn; |
goto yynewstate; |
|
/* Accept. */ |
yyacceptlab: |
yyresult = 0; |
goto yyreturn; |
|
/* Abort. */ |
yyabortlab: |
yyresult = 1; |
goto yyreturn; |
|
yyreturn: |
if (yychar != yyempty_) |
yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); |
|
/* Do not reclaim the symbols of the rule which action triggered |
this YYABORT or YYACCEPT. */ |
yypop_ (yylen); |
while (yystate_stack_.height () != 1) |
{ |
yydestruct_ ("Cleanup: popping", |
yystos_[yystate_stack_[0]], |
&yysemantic_stack_[0], |
&yylocation_stack_[0]); |
yypop_ (); |
} |
|
return yyresult; |
} |
|
// Generate an error message. |
std::string |
Parser::yysyntax_error_ (int yystate, int tok) |
{ |
std::string res; |
YYUSE (yystate); |
#if YYERROR_VERBOSE |
int yyn = yypact_[yystate]; |
if (yypact_ninf_ < yyn && yyn <= yylast_) |
{ |
/* Start YYX at -YYN if negative to avoid negative indexes in |
YYCHECK. */ |
int yyxbegin = yyn < 0 ? -yyn : 0; |
|
/* Stay within bounds of both yycheck and yytname. */ |
int yychecklim = yylast_ - yyn + 1; |
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; |
int count = 0; |
for (int x = yyxbegin; x < yyxend; ++x) |
if (yycheck_[x + yyn] == x && x != yyterror_) |
++count; |
|
// FIXME: This method of building the message is not compatible |
// with internationalization. It should work like yacc.c does it. |
// That is, first build a string that looks like this: |
// "syntax error, unexpected %s or %s or %s" |
// Then, invoke YY_ on this string. |
// Finally, use the string as a format to output |
// yytname_[tok], etc. |
// Until this gets fixed, this message appears in English only. |
res = "syntax error, unexpected "; |
res += yytnamerr_ (yytname_[tok]); |
if (count < 5) |
{ |
count = 0; |
for (int x = yyxbegin; x < yyxend; ++x) |
if (yycheck_[x + yyn] == x && x != yyterror_) |
{ |
res += (!count++) ? ", expecting " : " or "; |
res += yytnamerr_ (yytname_[x]); |
} |
} |
} |
else |
#endif |
res = YY_("syntax error"); |
return res; |
} |
|
|
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing |
STATE-NUM. */ |
const signed char Parser::yypact_ninf_ = -121; |
const short int |
Parser::yypact_[] = |
{ |
216, -26, 243, -19, -14, 3, 19, -11, 27, -121, |
20, 33, 29, 7, -121, 50, 68, 45, 248, -121, |
-121, -121, -121, 48, -22, 59, 71, 75, 54, 8, |
-121, -121, -121, 108, -121, 248, 184, 248, 153, 81, |
-121, 104, 117, 122, 126, 134, -121, -121, 271, 121, |
123, 173, 135, 173, 114, -121, 15, 115, 195, 195, |
-121, 248, 127, 133, 248, -121, 248, 248, 248, 248, |
248, 138, 14, 157, 103, -121, -121, 148, 164, 100, |
-121, -121, -121, 145, -121, 248, 174, 175, 151, 158, |
24, 57, 182, 183, 185, 173, 179, -26, -121, 173, |
205, -121, -121, -121, 195, 195, 16, 211, 212, 8, |
8, 8, -121, -121, -121, 190, 215, 248, 248, 248, |
248, 248, 248, 224, 214, 220, 221, 217, 248, -121, |
231, -121, 227, -121, -121, 248, -121, -121, -121, -121, |
230, -121, -121, 234, -121, -121, -121, 195, 195, -121, |
-121, -121, 138, -121, 86, 86, 86, 86, 86, 86, |
216, -121, -121, -121, -121, -121, 238, 239, -121, 241, |
173, 173, -121, -121, -121, 247, 55, 216, 216, 249, |
250, 244, 216, 273, 93, 143, -121, 173, -121, 161, |
-121, -121, -121, 272, -121, 274, 252, 216, -26, 199, |
-121, -121 |
}; |
|
/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE |
doesn't specify something else to do. Zero means the default is an |
error. */ |
const unsigned char |
Parser::yydefact_[] = |
{ |
2, 0, 0, 0, 0, 0, 65, 57, 0, 14, |
0, 0, 0, 0, 4, 0, 85, 0, 0, 78, |
79, 80, 9, 47, 57, 0, 0, 0, 0, 35, |
39, 40, 43, 0, 7, 0, 0, 26, 0, 0, |
61, 0, 0, 0, 0, 0, 1, 3, 0, 0, |
0, 0, 0, 0, 84, 5, 0, 43, 0, 0, |
45, 0, 0, 0, 0, 8, 0, 0, 0, 0, |
0, 29, 0, 0, 66, 67, 68, 0, 0, 28, |
62, 63, 64, 0, 6, 0, 0, 0, 0, 0, |
57, 0, 0, 0, 0, 0, 0, 0, 42, 0, |
0, 51, 53, 55, 0, 0, 0, 0, 0, 32, |
33, 34, 37, 36, 38, 31, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, 26, 58, |
0, 21, 0, 60, 59, 26, 13, 12, 11, 10, |
0, 86, 81, 0, 52, 54, 56, 0, 0, 41, |
48, 49, 29, 19, 73, 72, 74, 75, 76, 77, |
2, 69, 70, 71, 25, 27, 0, 0, 23, 0, |
0, 0, 50, 46, 30, 0, 0, 2, 2, 0, |
0, 0, 2, 18, 0, 0, 24, 0, 44, 0, |
16, 15, 22, 0, 20, 0, 83, 2, 0, 0, |
82, 17 |
}; |
|
/* YYPGOTO[NTERM-NUM]. */ |
const short int |
Parser::yypgoto_[] = |
{ |
-121, -52, -13, -121, -121, -121, -121, -120, 142, 0, |
47, 171, -121, -55, 283, -121, 213, -17, -94, -121 |
}; |
|
/* YYDEFGOTO[NTERM-NUM]. */ |
const short int |
Parser::yydefgoto_[] = |
{ |
-1, 13, 14, 42, 195, 175, 167, 78, 116, 79, |
29, 30, 31, 104, 60, 15, 73, 32, 17, 54 |
}; |
|
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If |
positive, shift that token. If negative, reduce the rule which |
number is the opposite. If zero, do what YYDEFACT says. */ |
const signed char Parser::yytable_ninf_ = -1; |
const unsigned char |
Parser::yytable_[] = |
{ |
47, 57, 28, 142, 105, 37, 59, 46, 165, 16, |
1, 2, 3, 34, 4, 169, 33, 38, 56, 35, |
39, 5, 117, 118, 119, 120, 121, 122, 89, 68, |
69, 39, 98, 149, 94, 72, 96, 64, 64, 64, |
135, 6, 7, 66, 66, 66, 8, 36, 91, 147, |
148, 9, 59, 10, 11, 43, 70, 12, 1, 2, |
3, 106, 4, 67, 67, 67, 39, 41, 44, 5, |
48, 45, 55, 49, 183, 61, 58, 64, 140, 50, |
64, 65, 143, 66, 136, 72, 66, 62, 52, 6, |
7, 63, 172, 173, 8, 51, 1, 2, 3, 9, |
4, 10, 11, 67, 200, 12, 67, 5, 176, 64, |
53, 109, 191, 110, 111, 66, 83, 154, 155, 156, |
157, 158, 159, 64, 71, 184, 185, 6, 7, 66, |
189, 84, 8, 85, 124, 67, 125, 9, 86, 10, |
11, 128, 87, 12, 92, 199, 1, 2, 3, 67, |
4, 95, 93, 180, 181, 97, 99, 5, 19, 20, |
21, 107, 192, 47, 1, 2, 3, 108, 4, 88, |
193, 47, 47, 115, 123, 5, 47, 6, 7, 126, |
194, 127, 8, 80, 81, 82, 47, 9, 129, 10, |
11, 131, 132, 12, 133, 6, 7, 19, 20, 21, |
8, 134, 1, 2, 3, 9, 4, 10, 11, 137, |
138, 12, 139, 5, 74, 75, 76, 77, 201, 1, |
2, 3, 141, 4, 100, 101, 102, 103, 150, 151, |
5, 152, 153, 6, 7, 144, 145, 146, 8, 112, |
113, 114, 160, 9, 164, 10, 11, 161, 166, 12, |
6, 7, 162, 163, 168, 8, 177, 178, 179, 18, |
9, 188, 10, 11, 18, 182, 12, 19, 20, 21, |
22, 170, 19, 20, 21, 171, 186, 23, 24, 25, |
26, 27, 23, 24, 25, 26, 27, 18, 190, 196, |
40, 187, 197, 198, 174, 19, 20, 21, 130, 0, |
0, 0, 0, 0, 0, 23, 90, 25, 26, 27 |
}; |
|
/* YYCHECK. */ |
const short int |
Parser::yycheck_[] = |
{ |
13, 18, 2, 97, 59, 16, 28, 0, 128, 35, |
3, 4, 5, 27, 7, 135, 35, 28, 18, 16, |
42, 14, 8, 9, 10, 11, 12, 13, 45, 21, |
22, 42, 17, 17, 51, 35, 53, 23, 23, 23, |
16, 34, 35, 29, 29, 29, 39, 28, 48, 104, |
105, 44, 28, 46, 47, 35, 48, 50, 3, 4, |
5, 61, 7, 49, 49, 49, 42, 40, 35, 14, |
20, 42, 27, 23, 19, 16, 28, 23, 95, 29, |
23, 27, 99, 29, 27, 85, 29, 16, 20, 34, |
35, 16, 147, 148, 39, 45, 3, 4, 5, 44, |
7, 46, 47, 49, 198, 50, 49, 14, 160, 23, |
42, 64, 19, 66, 67, 29, 35, 117, 118, 119, |
120, 121, 122, 23, 16, 177, 178, 34, 35, 29, |
182, 27, 39, 16, 31, 49, 33, 44, 16, 46, |
47, 41, 16, 50, 23, 197, 3, 4, 5, 49, |
7, 16, 29, 170, 171, 41, 41, 14, 24, 25, |
26, 34, 19, 176, 3, 4, 5, 34, 7, 35, |
187, 184, 185, 35, 17, 14, 189, 34, 35, 31, |
19, 17, 39, 30, 31, 32, 199, 44, 43, 46, |
47, 17, 17, 50, 43, 34, 35, 24, 25, 26, |
39, 43, 3, 4, 5, 44, 7, 46, 47, 27, |
27, 50, 27, 14, 30, 31, 32, 33, 19, 3, |
4, 5, 43, 7, 29, 30, 31, 32, 17, 17, |
14, 41, 17, 34, 35, 30, 31, 32, 39, 68, |
69, 70, 18, 44, 27, 46, 47, 33, 17, 50, |
34, 35, 32, 32, 27, 39, 18, 18, 17, 16, |
44, 17, 46, 47, 16, 18, 50, 24, 25, 26, |
27, 41, 24, 25, 26, 41, 27, 34, 35, 36, |
37, 38, 34, 35, 36, 37, 38, 16, 15, 17, |
7, 41, 18, 41, 152, 24, 25, 26, 85, -1, |
-1, -1, -1, -1, -1, 34, 35, 36, 37, 38 |
}; |
|
/* STOS_[STATE-NUM] -- The (internal number of the) accessing |
symbol of state STATE-NUM. */ |
const unsigned char |
Parser::yystos_[] = |
{ |
0, 3, 4, 5, 7, 14, 34, 35, 39, 44, |
46, 47, 50, 52, 53, 66, 35, 69, 16, 24, |
25, 26, 27, 34, 35, 36, 37, 38, 60, 61, |
62, 63, 68, 35, 27, 16, 28, 16, 28, 42, |
65, 40, 54, 35, 35, 42, 0, 53, 20, 23, |
29, 45, 20, 42, 70, 27, 60, 68, 28, 28, |
65, 16, 16, 16, 23, 27, 29, 49, 21, 22, |
48, 16, 60, 67, 30, 31, 32, 33, 58, 60, |
30, 31, 32, 35, 27, 16, 16, 16, 35, 68, |
35, 60, 23, 29, 68, 16, 68, 41, 17, 41, |
29, 30, 31, 32, 64, 64, 60, 34, 34, 61, |
61, 61, 62, 62, 62, 35, 59, 8, 9, 10, |
11, 12, 13, 17, 31, 33, 31, 17, 41, 43, |
67, 17, 17, 43, 43, 16, 27, 27, 27, 27, |
68, 43, 69, 68, 30, 31, 32, 64, 64, 17, |
17, 17, 41, 17, 60, 60, 60, 60, 60, 60, |
18, 33, 32, 32, 27, 58, 17, 57, 27, 58, |
41, 41, 64, 64, 59, 56, 52, 18, 18, 17, |
68, 68, 18, 19, 52, 52, 27, 41, 17, 52, |
15, 19, 19, 68, 19, 55, 17, 18, 41, 52, |
69, 19 |
}; |
|
#if YYDEBUG |
/* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding |
to YYLEX-NUM. */ |
const unsigned short int |
Parser::yytoken_number_[] = |
{ |
0, 256, 257, 258, 259, 260, 261, 262, 263, 264, |
265, 266, 267, 268, 269, 270, 271, 272, 273, 274, |
275, 276, 277, 278, 279, 280, 281, 282, 283, 284, |
285, 286, 287, 288, 289, 290, 291, 292, 293, 294, |
295, 296, 297, 298, 299, 300, 301, 302, 303, 304, |
305 |
}; |
#endif |
|
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ |
const unsigned char |
Parser::yyr1_[] = |
{ |
0, 51, 52, 52, 52, 53, 53, 53, 53, 53, |
53, 53, 53, 53, 54, 53, 55, 53, 53, 56, |
53, 57, 53, 53, 53, 53, 58, 58, 58, 59, |
59, 59, 60, 60, 60, 60, 61, 61, 61, 61, |
62, 62, 62, 63, 63, 63, 63, 63, 63, 63, |
63, 64, 64, 64, 64, 64, 64, 65, 65, 66, |
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, |
66, 66, 67, 67, 67, 67, 67, 67, 68, 68, |
68, 69, 69, 69, 69, 70, 70 |
}; |
|
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ |
const unsigned char |
Parser::yyr2_[] = |
{ |
0, 2, 0, 2, 1, 3, 3, 2, 3, 2, |
4, 4, 4, 4, 0, 8, 0, 12, 7, 0, |
9, 0, 8, 5, 7, 5, 0, 3, 1, 0, |
3, 1, 3, 3, 3, 1, 3, 3, 3, 1, |
1, 4, 3, 1, 7, 2, 5, 1, 4, 4, |
5, 1, 2, 1, 2, 1, 2, 0, 3, 4, |
4, 2, 3, 3, 3, 1, 3, 3, 3, 5, |
5, 5, 3, 3, 3, 3, 3, 3, 1, 1, |
1, 4, 11, 9, 2, 0, 3 |
}; |
|
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE |
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. |
First, the terminals, then, starting at \a yyntokens_, nonterminals. */ |
const char* |
const Parser::yytname_[] = |
{ |
"$end", "error", "$undefined", "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", "IDENTIFIER", |
"SQRT", "SCALE", "UNSCALE", "USING", "FIXED_POINT", "COMMA", |
"OPEN_SQUARE_BRACE", "CLOSE_SQUARE_BRACE", "WHILE", "ADD_EQ", "THREAD", |
"START", "BITWISE_AND", "BITWISE_OR", "OUT", "$accept", "statement_list", |
"statement", "$@1", "$@2", "$@3", "$@4", "function_input_list", |
"function_argument_list", "expression", "term", "factor", "source", |
"coordinate", "array_index", "left_hand_side", "boolean_expression", |
"constant", "auto_var_list", "array_size", 0 |
}; |
#endif |
|
#if YYDEBUG |
/* YYRHS -- A `-1'-separated list of the rules' RHS. */ |
const Parser::rhs_number_type |
Parser::yyrhs_[] = |
{ |
52, 0, -1, -1, 52, 53, -1, 53, -1, 3, |
69, 27, -1, 39, 40, 27, -1, 7, 27, -1, |
4, 60, 27, -1, 4, 27, -1, 66, 45, 68, |
27, -1, 66, 29, 29, 27, -1, 66, 23, 23, |
27, -1, 66, 20, 60, 27, -1, -1, 44, 54, |
16, 67, 17, 18, 52, 19, -1, -1, 14, 16, |
67, 17, 18, 52, 19, 15, 55, 18, 52, 19, |
-1, 14, 16, 67, 17, 18, 52, 19, -1, -1, |
5, 35, 16, 59, 17, 56, 18, 52, 19, -1, |
-1, 46, 35, 16, 17, 57, 18, 52, 19, -1, |
47, 35, 16, 17, 27, -1, 66, 20, 35, 16, |
58, 17, 27, -1, 35, 16, 58, 17, 27, -1, |
-1, 60, 41, 58, -1, 60, -1, -1, 35, 41, |
59, -1, 35, -1, 60, 23, 61, -1, 60, 29, |
61, -1, 60, 49, 61, -1, 61, -1, 61, 22, |
62, -1, 61, 21, 62, -1, 61, 48, 62, -1, |
62, -1, 63, -1, 36, 16, 60, 17, -1, 16, |
60, 17, -1, 68, -1, 16, 68, 41, 68, 41, |
68, 17, -1, 35, 65, -1, 35, 28, 64, 64, |
64, -1, 34, -1, 37, 16, 34, 17, -1, 38, |
16, 34, 17, -1, 34, 28, 64, 64, 64, -1, |
30, -1, 29, 30, -1, 31, -1, 29, 31, -1, |
32, -1, 29, 32, -1, -1, 42, 35, 43, -1, |
50, 42, 68, 43, -1, 50, 42, 35, 43, -1, |
35, 65, -1, 35, 28, 30, -1, 35, 28, 31, |
-1, 35, 28, 32, -1, 34, -1, 34, 28, 30, |
-1, 34, 28, 31, -1, 34, 28, 32, -1, 34, |
28, 30, 31, 33, -1, 34, 28, 30, 33, 32, |
-1, 34, 28, 33, 31, 32, -1, 60, 9, 60, |
-1, 60, 8, 60, -1, 60, 10, 60, -1, 60, |
11, 60, -1, 60, 12, 60, -1, 60, 13, 60, |
-1, 24, -1, 25, -1, 26, -1, 35, 70, 41, |
69, -1, 35, 20, 16, 68, 41, 68, 41, 68, |
17, 41, 69, -1, 35, 20, 16, 68, 41, 68, |
41, 68, 17, -1, 35, 70, -1, -1, 42, 68, |
43, -1 |
}; |
|
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in |
YYRHS. */ |
const unsigned short int |
Parser::yyprhs_[] = |
{ |
0, 0, 3, 4, 7, 9, 13, 17, 20, 24, |
27, 32, 37, 42, 47, 48, 57, 58, 71, 79, |
80, 90, 91, 100, 106, 114, 120, 121, 125, 127, |
128, 132, 134, 138, 142, 146, 148, 152, 156, 160, |
162, 164, 169, 173, 175, 183, 186, 192, 194, 199, |
204, 210, 212, 215, 217, 220, 222, 225, 226, 230, |
235, 240, 243, 247, 251, 255, 257, 261, 265, 269, |
275, 281, 287, 291, 295, 299, 303, 307, 311, 313, |
315, 317, 322, 334, 344, 347, 348 |
}; |
|
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ |
const unsigned short int |
Parser::yyrline_[] = |
{ |
0, 830, 830, 832, 834, 839, 841, 846, 863, 930, |
958, 976, 1005, 1030, 1343, 1343, 1363, 1359, 1391, 1402, |
1401, 1431, 1430, 1453, 1494, 1518, 1574, 1577, 1582, 1588, |
1591, 1596, 1617, 1638, 1660, 1681, 1689, 1714, 1739, 1760, |
1768, 1773, 1792, 1802, 1832, 1897, 1915, 1926, 1935, 1943, |
1951, 1964, 1969, 1974, 1979, 1984, 1989, 1998, 2002, 2015, |
2021, 2030, 2041, 2050, 2059, 2068, 2075, 2082, 2089, 2097, |
2104, 2111, 2122, 2128, 2134, 2141, 2147, 2153, 2162, 2175, |
2186, 2200, 2216, 2280, 2348, 2368, 2372 |
}; |
|
// Print the state stack on the debug stream. |
void |
Parser::yystack_print_ () |
{ |
*yycdebug_ << "Stack now"; |
for (state_stack_type::const_iterator i = yystate_stack_.begin (); |
i != yystate_stack_.end (); ++i) |
*yycdebug_ << ' ' << *i; |
*yycdebug_ << std::endl; |
} |
|
// Report on the debug stream that the rule \a yyrule is going to be reduced. |
void |
Parser::yy_reduce_print_ (int yyrule) |
{ |
unsigned int yylno = yyrline_[yyrule]; |
int yynrhs = yyr2_[yyrule]; |
/* Print the symbols being reduced, and their result. */ |
*yycdebug_ << "Reducing stack by rule " << yyrule - 1 |
<< " (line " << yylno << "):" << std::endl; |
/* The symbols being reduced. */ |
for (int yyi = 0; yyi < yynrhs; yyi++) |
YY_SYMBOL_PRINT (" $" << yyi + 1 << " =", |
yyrhs_[yyprhs_[yyrule] + yyi], |
&(yysemantic_stack_[(yynrhs) - (yyi + 1)]), |
&(yylocation_stack_[(yynrhs) - (yyi + 1)])); |
} |
#endif // YYDEBUG |
|
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ |
Parser::token_number_type |
Parser::yytranslate_ (int t) |
{ |
static |
const token_number_type |
translate_table[] = |
{ |
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 1, 2, 3, 4, |
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, |
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, |
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, |
45, 46, 47, 48, 49, 50 |
}; |
if ((unsigned int) t <= yyuser_token_number_max_) |
return translate_table[t]; |
else |
return yyundef_token_; |
} |
|
const int Parser::yyeof_ = 0; |
const int Parser::yylast_ = 309; |
const int Parser::yynnts_ = 20; |
const int Parser::yyempty_ = -2; |
const int Parser::yyfinal_ = 46; |
const int Parser::yyterror_ = 1; |
const int Parser::yyerrcode_ = 256; |
const int Parser::yyntokens_ = 51; |
|
const unsigned int Parser::yyuser_token_number_max_ = 305; |
const Parser::token_number_type Parser::yyundef_token_ = 2; |
|
|
/* Line 1054 of lalr1.cc */ |
#line 28 "parser.y" |
} // Theia |
|
/* Line 1054 of lalr1.cc */ |
#line 3588 "parser.tab.c" |
|
|
/* Line 1056 of lalr1.cc */ |
#line 2378 "parser.y" |
|
|
|
|
// Error function throws an exception (std::string) with the location and error message |
void Theia::Parser::error(const Theia::Parser::location_type &loc, |
const std::string &msg) { |
std::ostringstream ret; |
ret << "Parser Error at " << loc << ": " << msg; |
throw ret.str(); |
} |
|
// Now that we have the Parser declared, we can declare the Scanner and implement |
// the yylex function |
#include "Scanner.h" |
static int yylex(Theia::Parser::semantic_type * yylval, |
Theia::Parser::location_type * yylloc, |
Theia::Scanner &scanner) { |
return scanner.yylex(yylval, yylloc); |
} |
|
|
/branches/beta_2.0/compiler/src/vp_compiler/scanner.l
0,0 → 1,105
%{ |
|
/********************************************************************************** |
Theia, Ray Cast Programable graphic Processing Unit. |
Copyright (C) 2012 Diego Valverde (diego.valverde.g@gmail.com) |
|
This program is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
of the License, or (at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
***********************************************************************************/ |
|
#include "Scanner.h" |
// used to keep track of location |
#define YY_USER_ACTION yylloc->columns(yyleng); |
int LineNumber = 1; |
%} |
|
%option nodefault yyclass="Scanner" noyywrap c++ |
|
comment "//"(.*)*\n |
separator ([ \t""])+ |
character [a-zA-Z] |
hexchar [a-fA-F] |
digit [0-9] |
decconstant {digit}({digit})* |
hexconstant 0x({digit}|{hexchar})+ |
binconstant 0b(1|0)+ |
registry (r|R)({digit})+ |
identifier ([a-wA-Z])({character}|{digit}|_)* |
|
|
%% |
|
%{ |
yylloc->step(); |
%} |
|
{comment} {yylloc->lines(); ;LineNumber++; ;} |
"\n" {yylloc->lines(); ;LineNumber++;} |
{separator} {/* do nothing */} |
{decconstant} { *yylval = yytext; return Theia::Parser::token::DECCONST; } |
{hexconstant} { *yylval = yytext; return Theia::Parser::token::HEXCONST; } |
{binconstant} { *yylval = yytext; return Theia::Parser::token::BINCONST; } |
"sqrt" {return Theia::Parser::token::SQRT;} |
"if" {return Theia::Parser::token::IF;} |
"else" {return Theia::Parser::token::ELSE;} |
"while" {return Theia::Parser::token::WHILE;} |
"&" {return Theia::Parser::token::BITWISE_AND;} |
"|" {return Theia::Parser::token::BITWISE_OR;} |
"function" {return Theia::Parser::token::FUNCTION;} |
"jmp" {return Theia::Parser::token::JMP;} |
"return" {return Theia::Parser::token::RETURN;} |
"exit" {return Theia::Parser::token::EXIT;} |
"vector" {return Theia::Parser::token::AUTO;} |
"thread" {return Theia::Parser::token::THREAD;} |
"start" {return Theia::Parser::token::START;} |
"(" {return Theia::Parser::token::OPEN_ROUND_BRACE;} |
")" {return Theia::Parser::token::CLOSE_ROUND_BRACE;} |
"{" {return Theia::Parser::token::OPEN_BRACE;} |
"}" {return Theia::Parser::token::CLOSE_BRACE;} |
"-" {*yylval = yytext;return Theia::Parser::token::MINUS; } |
"==" {return Theia::Parser::token::EQUAL; } |
"!=" {return Theia::Parser::token::NOT_EQUAL; } |
"scale" {return Theia::Parser::token::SCALE; } |
"unscale" {return Theia::Parser::token::UNSCALE; } |
"using" {return Theia::Parser::token::USING; } |
"out" {return Theia::Parser::token::OUT; } |
"fixed_point_arithmetic" {return Theia::Parser::token::FIXED_POINT; } |
"<=" {return Theia::Parser::token::LESS_OR_EQUAL_THAN; } |
">=" {return Theia::Parser::token::GREATER_OR_EQUAL_THAN; } |
"=" {return Theia::Parser::token::ASSIGN; } |
">" {return Theia::Parser::token::GREATER_THAN; } |
"<" {return Theia::Parser::token::LESS_THAN; } |
"[" {return Theia::Parser::token::OPEN_SQUARE_BRACE; } |
"]" {return Theia::Parser::token::CLOSE_SQUARE_BRACE; } |
"*" {return Theia::Parser::token::MUL; } |
"/" {return Theia::Parser::token::DIV; } |
"+=" {return Theia::Parser::token::ADD_EQ; } |
"+" {return Theia::Parser::token::ADD; } |
";" {return Theia::Parser::token::EOS; } |
"," {return Theia::Parser::token::COMMA; } |
"." {return Theia::Parser::token::DOT; } |
x {*yylval = yytext;return Theia::Parser::token::TK_X; } |
y {*yylval = yytext;return Theia::Parser::token::TK_Y; } |
z {*yylval = yytext;return Theia::Parser::token::TK_Z; } |
"n" {*yylval = yytext;return Theia::Parser::token::TK_N; } |
{registry} { *yylval = yytext; return Theia::Parser::token::REG;} |
{identifier} {*yylval = yytext; return Theia::Parser::token::IDENTIFIER;} |
. { |
std::ostringstream ret; |
ret << "Unknown Indetifier at line " << LineNumber << " '" << yytext << "'\n"; |
throw ret.str(); |
}; |
%% |
/branches/beta_2.0/compiler/src/vp_compiler/parser.tab.h
0,0 → 1,395
|
/* A Bison parser, made by GNU Bison 2.4.1. */ |
|
/* Skeleton interface for Bison LALR(1) parsers in C++ |
|
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software |
Foundation, Inc. |
|
This program is free software: you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation, either version 3 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
/* As a special exception, you may create a larger work that contains |
part or all of the Bison parser skeleton and distribute that work |
under terms of your choice, so long as that work isn't itself a |
parser generator using the skeleton or a modified version thereof |
as a parser skeleton. Alternatively, if you modify or redistribute |
the parser skeleton itself, you may (at your option) remove this |
special exception, which will cause the skeleton and the resulting |
Bison output files to be licensed under the GNU General Public |
License without this special exception. |
|
This special exception was added by the Free Software Foundation in |
version 2.2 of Bison. */ |
|
/* C++ LALR(1) parser skeleton written by Akim Demaille. */ |
|
#ifndef PARSER_HEADER_H |
# define PARSER_HEADER_H |
|
/* "%code requires" blocks. */ |
|
/* Line 35 of lalr1.cc */ |
#line 36 "parser.y" |
|
#include <string> |
#include <sstream> |
#include <iomanip> |
#include <bitset> |
#include <map> |
#include "Instruction.h" |
#include <vector> |
|
|
// We want to return a string |
#define YYSTYPE std::string |
|
|
namespace Theia |
{ |
// Forward-declare the Scanner class; the Parser needs to be assigned a |
// Scanner, but the Scanner can't be declared without the Parser |
class Scanner; |
|
// We use a map to store the INI data |
typedef std::map<std::string, std::map<std::string, std::string> > mapData; |
|
|
|
|
|
} |
|
|
|
|
/* Line 35 of lalr1.cc */ |
#line 78 "parser.tab.h" |
|
|
#include <string> |
#include <iostream> |
#include "stack.hh" |
|
|
/* Line 35 of lalr1.cc */ |
#line 28 "parser.y" |
namespace Theia { |
|
/* Line 35 of lalr1.cc */ |
#line 91 "parser.tab.h" |
class position; |
class location; |
|
/* Line 35 of lalr1.cc */ |
#line 28 "parser.y" |
} // Theia |
|
/* Line 35 of lalr1.cc */ |
#line 100 "parser.tab.h" |
|
#include "location.hh" |
|
/* Enabling traces. */ |
#ifndef YYDEBUG |
# define YYDEBUG 0 |
#endif |
|
/* Enabling verbose error messages. */ |
#ifdef YYERROR_VERBOSE |
# undef YYERROR_VERBOSE |
# define YYERROR_VERBOSE 1 |
#else |
# define YYERROR_VERBOSE 1 |
#endif |
|
/* Enabling the token table. */ |
#ifndef YYTOKEN_TABLE |
# define YYTOKEN_TABLE 0 |
#endif |
|
/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. |
If N is 0, then set CURRENT to the empty location which ends |
the previous symbol: RHS[0] (always defined). */ |
|
#ifndef YYLLOC_DEFAULT |
# define YYLLOC_DEFAULT(Current, Rhs, N) \ |
do { \ |
if (N) \ |
{ \ |
(Current).begin = (Rhs)[1].begin; \ |
(Current).end = (Rhs)[N].end; \ |
} \ |
else \ |
{ \ |
(Current).begin = (Current).end = (Rhs)[0].end; \ |
} \ |
} while (false) |
#endif |
|
|
/* Line 35 of lalr1.cc */ |
#line 28 "parser.y" |
namespace Theia { |
|
/* Line 35 of lalr1.cc */ |
#line 147 "parser.tab.h" |
|
/// A Bison parser. |
class Parser |
{ |
public: |
/// Symbol semantic values. |
#ifndef YYSTYPE |
typedef int semantic_type; |
#else |
typedef YYSTYPE semantic_type; |
#endif |
/// Symbol locations. |
typedef location location_type; |
/// Tokens. |
struct token |
{ |
/* Tokens. */ |
enum yytokentype { |
AUTO = 258, |
RETURN = 259, |
FUNCTION = 260, |
JMP = 261, |
EXIT = 262, |
EQUAL = 263, |
NOT_EQUAL = 264, |
GREATER_THAN = 265, |
LESS_THAN = 266, |
LESS_OR_EQUAL_THAN = 267, |
GREATER_OR_EQUAL_THAN = 268, |
IF = 269, |
ELSE = 270, |
OPEN_ROUND_BRACE = 271, |
CLOSE_ROUND_BRACE = 272, |
OPEN_BRACE = 273, |
CLOSE_BRACE = 274, |
ASSIGN = 275, |
DIV = 276, |
MUL = 277, |
ADD = 278, |
DECCONST = 279, |
HEXCONST = 280, |
BINCONST = 281, |
EOS = 282, |
DOT = 283, |
MINUS = 284, |
TK_X = 285, |
TK_Y = 286, |
TK_Z = 287, |
TK_N = 288, |
REG = 289, |
IDENTIFIER = 290, |
SQRT = 291, |
SCALE = 292, |
UNSCALE = 293, |
USING = 294, |
FIXED_POINT = 295, |
COMMA = 296, |
OPEN_SQUARE_BRACE = 297, |
CLOSE_SQUARE_BRACE = 298, |
WHILE = 299, |
ADD_EQ = 300, |
THREAD = 301, |
START = 302, |
BITWISE_AND = 303, |
BITWISE_OR = 304, |
OUT = 305 |
}; |
|
}; |
/// Token type. |
typedef token::yytokentype token_type; |
|
/// Build a parser object. |
Parser (Theia::Scanner &scanner_yyarg, std::map<std::string,unsigned int> & mSymbolMap_yyarg, std::vector< Instruction > &mInstructions_yyarg, bool &mGenerateFixedPointArithmetic_yyarg); |
virtual ~Parser (); |
|
/// Parse. |
/// \returns 0 iff parsing succeeded. |
virtual int parse (); |
|
#if YYDEBUG |
/// The current debugging stream. |
std::ostream& debug_stream () const; |
/// Set the current debugging stream. |
void set_debug_stream (std::ostream &); |
|
/// Type for debugging levels. |
typedef int debug_level_type; |
/// The current debugging level. |
debug_level_type debug_level () const; |
/// Set the current debugging level. |
void set_debug_level (debug_level_type l); |
#endif |
|
private: |
/// Report a syntax error. |
/// \param loc where the syntax error is found. |
/// \param msg a description of the syntax error. |
virtual void error (const location_type& loc, const std::string& msg); |
|
/// Generate an error message. |
/// \param state the state where the error occurred. |
/// \param tok the lookahead token. |
virtual std::string yysyntax_error_ (int yystate, int tok); |
|
#if YYDEBUG |
/// \brief Report a symbol value on the debug stream. |
/// \param yytype The token type. |
/// \param yyvaluep Its semantic value. |
/// \param yylocationp Its location. |
virtual void yy_symbol_value_print_ (int yytype, |
const semantic_type* yyvaluep, |
const location_type* yylocationp); |
/// \brief Report a symbol on the debug stream. |
/// \param yytype The token type. |
/// \param yyvaluep Its semantic value. |
/// \param yylocationp Its location. |
virtual void yy_symbol_print_ (int yytype, |
const semantic_type* yyvaluep, |
const location_type* yylocationp); |
#endif |
|
|
/// State numbers. |
typedef int state_type; |
/// State stack type. |
typedef stack<state_type> state_stack_type; |
/// Semantic value stack type. |
typedef stack<semantic_type> semantic_stack_type; |
/// location stack type. |
typedef stack<location_type> location_stack_type; |
|
/// The state stack. |
state_stack_type yystate_stack_; |
/// The semantic value stack. |
semantic_stack_type yysemantic_stack_; |
/// The location stack. |
location_stack_type yylocation_stack_; |
|
/// Internal symbol numbers. |
typedef unsigned char token_number_type; |
/* Tables. */ |
/// For a state, the index in \a yytable_ of its portion. |
static const short int yypact_[]; |
static const signed char yypact_ninf_; |
|
/// For a state, default rule to reduce. |
/// Unless\a yytable_ specifies something else to do. |
/// Zero means the default is an error. |
static const unsigned char yydefact_[]; |
|
static const short int yypgoto_[]; |
static const short int yydefgoto_[]; |
|
/// What to do in a state. |
/// \a yytable_[yypact_[s]]: what to do in state \a s. |
/// - if positive, shift that token. |
/// - if negative, reduce the rule which number is the opposite. |
/// - if zero, do what YYDEFACT says. |
static const unsigned char yytable_[]; |
static const signed char yytable_ninf_; |
|
static const short int yycheck_[]; |
|
/// For a state, its accessing symbol. |
static const unsigned char yystos_[]; |
|
/// For a rule, its LHS. |
static const unsigned char yyr1_[]; |
/// For a rule, its RHS length. |
static const unsigned char yyr2_[]; |
|
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE |
/// For a symbol, its name in clear. |
static const char* const yytname_[]; |
#endif |
|
#if YYERROR_VERBOSE |
/// Convert the symbol name \a n to a form suitable for a diagnostic. |
virtual std::string yytnamerr_ (const char *n); |
#endif |
|
#if YYDEBUG |
/// A type to store symbol numbers and -1. |
typedef signed char rhs_number_type; |
/// A `-1'-separated list of the rules' RHS. |
static const rhs_number_type yyrhs_[]; |
/// For each rule, the index of the first RHS symbol in \a yyrhs_. |
static const unsigned short int yyprhs_[]; |
/// For each rule, its source line number. |
static const unsigned short int yyrline_[]; |
/// For each scanner token number, its symbol number. |
static const unsigned short int yytoken_number_[]; |
/// Report on the debug stream that the rule \a r is going to be reduced. |
virtual void yy_reduce_print_ (int r); |
/// Print the state stack on the debug stream. |
virtual void yystack_print_ (); |
|
/* Debugging. */ |
int yydebug_; |
std::ostream* yycdebug_; |
#endif |
|
/// Convert a scanner token number \a t to a symbol number. |
token_number_type yytranslate_ (int t); |
|
/// \brief Reclaim the memory associated to a symbol. |
/// \param yymsg Why this token is reclaimed. |
/// \param yytype The symbol type. |
/// \param yyvaluep Its semantic value. |
/// \param yylocationp Its location. |
inline void yydestruct_ (const char* yymsg, |
int yytype, |
semantic_type* yyvaluep, |
location_type* yylocationp); |
|
/// Pop \a n symbols the three stacks. |
inline void yypop_ (unsigned int n = 1); |
|
/* Constants. */ |
static const int yyeof_; |
/* LAST_ -- Last index in TABLE_. */ |
static const int yylast_; |
static const int yynnts_; |
static const int yyempty_; |
static const int yyfinal_; |
static const int yyterror_; |
static const int yyerrcode_; |
static const int yyntokens_; |
static const unsigned int yyuser_token_number_max_; |
static const token_number_type yyundef_token_; |
|
/* User arguments. */ |
Theia::Scanner &scanner; |
std::map<std::string,unsigned int> & mSymbolMap; |
std::vector< Instruction > &mInstructions; |
bool &mGenerateFixedPointArithmetic; |
}; |
|
/* Line 35 of lalr1.cc */ |
#line 28 "parser.y" |
} // Theia |
|
/* Line 35 of lalr1.cc */ |
#line 392 "parser.tab.h" |
|
|
|
#endif /* ! defined PARSER_HEADER_H */ |
/branches/beta_2.0/compiler/src/vp_compiler/Compiler.h
0,0 → 1,239
/* This program is free software. It comes without any warranty, to |
* the extent permitted by applicable law. You can redistribute it |
* and/or modify it under the terms of the Do What The Fuck You Want |
* To Public License, Version 2, as published by Sam Hocevar. See |
* http://sam.zoy.org/wtfpl/COPYING for more details. */ |
|
#pragma once |
|
#include <fstream> |
#include "Scanner.h" |
#include <vector> |
#include "Instruction.h" |
#include <iostream> |
#include <string> |
#include <iterator> |
|
|
class TheiaCompiler |
{ |
public: |
std::vector<std::string> mPreprocessedFile; |
// can instantiate with either a file name or an already open stream |
inline explicit TheiaCompiler(std::string fileName) throw(std::string); |
inline explicit TheiaCompiler(std::string fileName, bool aMode32) throw(std::string); |
inline explicit TheiaCompiler(std::istream &iniStream) throw(std::string); |
|
// Get a value from section and key |
const char * getValue(const char * const section, const char * const key) const; |
//------------------------------------------------------------------------------------- |
void PrependCodeInitialization() |
{ |
|
Instruction I; |
I.mComment ="Make sure R0 has the appropiate values (0,1,2)"; |
I.SetCode( EOPERATION_ADD ); |
I.SetDestinationAddress( 0 ); |
I.SetImm( 0 ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_X); |
mInstructions.push_back( I ); |
I.Clear(); |
|
|
I.SetCode( EOPERATION_ADD ); |
I.SetDestinationAddress( 0 ); |
I.SetImm( 1 ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_Y); |
mInstructions.push_back( I ); |
I.Clear(); |
|
|
I.SetCode( EOPERATION_ADD ); |
I.SetDestinationAddress( 0 ); |
I.SetImm( 2 ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_Z); |
mInstructions.push_back( I ); |
I.Clear(); |
|
I.mComment = "Disable multi-threading by default"; |
I.SetCode( EOPERATION_ADD ); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER0 ); |
I.SetImm( 0 ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_Z); |
mInstructions.push_back( I ); |
I.Clear(); |
|
I.mComment = "Make sure R3 (Frame Offset) is initialized to zero"; |
I.SetCode( EOPERATION_ADD ); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetImm( 0 ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_XYZ); |
mInstructions.push_back( I ); |
I.Clear(); |
} |
//------------------------------------------------------------------------------------- |
std::string GetHexCodeDump(void) |
{ |
std::ostringstream oss; |
//Add the header |
oss << "//List file created by theia_compile\n"; |
|
|
for ( int i = 0; i < mInstructions.size(); i++) |
{ |
|
oss << GetLineSymbolDefintion( i ); |
|
if (mInstructions[i].mSourceLine > 0) |
oss << "//" << mPreprocessedFile[ mInstructions[i].mSourceLine -1 ] << "\n"; |
|
if (mInstructions[i].mComment.size()) |
oss << "//" << mInstructions[i].mComment<< "\n"; |
|
oss << std::dec << i ; |
//oss << std::hex << " (0x" << i << ") " ; |
oss << ":\t" << mInstructions[i].PrintAssembly() << "\n"; |
} |
|
return oss.str(); |
} |
//------------------------------------------------------------------------------------- |
std::string GetLineSymbolDefintion( unsigned int aLine ) |
{ |
|
std::map<std::string, unsigned int>::const_iterator it; |
for (it = mSymbolMap.begin(); it != mSymbolMap.end(); ++it) |
{ |
if (it->second == aLine) |
return "\n//" + it->first + "\n"; |
|
} |
return std::string(""); |
} |
//------------------------------------------------------------------------------------- |
void Print(void) |
{ |
for (int i = 0; i < mInstructions.size(); i++) |
{ |
//std::cout << "EA : " << i << "\n"; |
//std::cout << mInstructions[i].PrintHex() << "\n"; |
//mInstructions[i].PrintFields(); |
//std::cout << "\n"; |
} |
} |
//-------------------------------------------------------------------------------------------------- |
std::string PostProcess( std::string fileName ) |
{ |
std::string Result; |
std::ifstream ifs(fileName.c_str()); |
if (!ifs.good()) |
throw std::string("Unable to open file "+ fileName); |
|
unsigned int CodeSize = 0; |
while (!ifs.eof()) |
{ |
char Buffer[1024]; |
ifs.getline( Buffer,1024 ); |
std::string Line = Buffer; |
|
//Ignore comments |
if (Line.find("//") != std::string::npos) |
Line.erase(Line.find("//"),Line.length()); |
|
while (Line.find("\t") != std::string::npos) |
Line.replace(Line.find("\t"),1," "); |
//Ignore blank lines |
if (Line.length() == 0) |
continue; |
|
std::stringstream ss; |
ss << Line; |
std::string LineNumber,DestinationSymbol; |
unsigned int Operation,Destination,Src1,Src0; |
if (Line.find("@") != std::string::npos) |
{ |
ss >> std::hex>> LineNumber >> Operation >> DestinationSymbol >> Src1 >> Src0; |
DestinationSymbol.erase(0,1); |
//std::cout << "XXXX DestinationSymbol " << DestinationSymbol << "\n"; |
std::ostringstream oss; |
Destination = mSymbolMap[ DestinationSymbol ]; |
//std::cout << "XXXX Destination " << Destination << "\n"; |
} |
else |
ss >> std::hex>> LineNumber >> Operation >> Destination >> Src1 >> Src0; |
|
//std::cout << "'" << Line << "'" << std::hex << LineNumber << "," << Operation << "," << Destination << "," << Src1 << "," << Src0 << "\n"; |
Instruction I; |
I.SetFields(Operation,Destination,Src1,Src0); |
CodeSize++; |
if (m32BitMode) |
Result += I.PrintHex32() + "\n"; |
else |
Result += I.PrintHex() + "\n"; |
} |
std::cout << "CodeBlockSize: " << CodeSize << "\n"; |
return Result; |
} |
|
//-------------------------------------------------------------------------------------------------- |
|
private: |
// supress default constructor |
TheiaCompiler(); |
// supress default copy constructor |
TheiaCompiler(TheiaCompiler const &rhs); |
// supress default assignment operator |
TheiaCompiler &operator=(TheiaCompiler const &rhs); |
|
std::vector< Instruction > mInstructions; |
std::map<std::string,unsigned int> mSymbolMap; |
bool mGenerateFixedPointArithmetic; |
bool m32BitMode; |
}; |
|
//------------------------------------------------------------------------------------------------------- |
TheiaCompiler::TheiaCompiler(std::string fileName, bool aMode32 = false) throw(std::string) |
{ |
m32BitMode = aMode32; |
mGenerateFixedPointArithmetic = false; |
|
std::ifstream inFile(fileName.c_str()); |
if (!inFile.good()) |
throw std::string("Unable to open file "+ fileName); |
|
//First get me a local copy of the file into a vector |
std::string Line; //int i = 1; |
while( std::getline(inFile, Line) ) |
{ |
mPreprocessedFile.push_back( Line ); |
////std::cout << i++ << " " << Line << "\n"; |
} |
|
inFile.close(); |
inFile.open(fileName.c_str()); |
if (!inFile.good()) |
throw std::string("Unable to open file "+ fileName); |
|
PrependCodeInitialization(); |
|
Theia::Scanner scanner(&inFile); |
Theia::Parser parser(scanner, mSymbolMap , mInstructions, mGenerateFixedPointArithmetic); |
std::cout << "parsing file\n"; |
parser.parse(); |
} |
//------------------------------------------------------------------------------------------------------- |
|
TheiaCompiler::TheiaCompiler(std::istream &iniStream) throw(std::string) |
{ |
mGenerateFixedPointArithmetic = false; |
Theia::Scanner scanner(&iniStream); |
Theia::Parser parser(scanner, mSymbolMap, mInstructions, mGenerateFixedPointArithmetic); |
parser.parse(); |
} |
|
//------------------------------------------------------------------------------------------------------- |
/branches/beta_2.0/compiler/src/vp_compiler/position.hh
0,0 → 1,165
|
/* A Bison parser, made by GNU Bison 2.4.1. */ |
|
/* Positions for Bison parsers in C++ |
|
Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. |
|
This program is free software: you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation, either version 3 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
/* As a special exception, you may create a larger work that contains |
part or all of the Bison parser skeleton and distribute that work |
under terms of your choice, so long as that work isn't itself a |
parser generator using the skeleton or a modified version thereof |
as a parser skeleton. Alternatively, if you modify or redistribute |
the parser skeleton itself, you may (at your option) remove this |
special exception, which will cause the skeleton and the resulting |
Bison output files to be licensed under the GNU General Public |
License without this special exception. |
|
This special exception was added by the Free Software Foundation in |
version 2.2 of Bison. */ |
|
/** |
** \file position.hh |
** Define the Theia::position class. |
*/ |
|
#ifndef BISON_POSITION_HH |
# define BISON_POSITION_HH |
|
# include <iostream> |
# include <string> |
# include <algorithm> |
|
|
/* Line 38 of location.cc */ |
#line 28 "parser.y" |
namespace Theia { |
|
/* Line 38 of location.cc */ |
#line 53 "position.hh" |
/// Abstract a position. |
class position |
{ |
public: |
|
/// Construct a position. |
position () |
: filename (0), line (1), column (1) |
{ |
} |
|
|
/// Initialization. |
inline void initialize (std::string* fn) |
{ |
filename = fn; |
line = 1; |
column = 1; |
} |
|
/** \name Line and Column related manipulators |
** \{ */ |
public: |
/// (line related) Advance to the COUNT next lines. |
inline void lines (int count = 1) |
{ |
column = 1; |
line += count; |
} |
|
/// (column related) Advance to the COUNT next columns. |
inline void columns (int count = 1) |
{ |
column = std::max (1u, column + count); |
} |
/** \} */ |
|
public: |
/// File name to which this position refers. |
std::string* filename; |
/// Current line number. |
unsigned int line; |
/// Current column number. |
unsigned int column; |
}; |
|
/// Add and assign a position. |
inline const position& |
operator+= (position& res, const int width) |
{ |
res.columns (width); |
return res; |
} |
|
/// Add two position objects. |
inline const position |
operator+ (const position& begin, const int width) |
{ |
position res = begin; |
return res += width; |
} |
|
/// Add and assign a position. |
inline const position& |
operator-= (position& res, const int width) |
{ |
return res += -width; |
} |
|
/// Add two position objects. |
inline const position |
operator- (const position& begin, const int width) |
{ |
return begin + -width; |
} |
|
/// Compare two position objects. |
inline bool |
operator== (const position& pos1, const position& pos2) |
{ |
return |
(pos1.filename == pos2.filename |
|| pos1.filename && pos2.filename && *pos1.filename == *pos2.filename) |
&& pos1.line == pos2.line && pos1.column == pos2.column; |
} |
|
/// Compare two position objects. |
inline bool |
operator!= (const position& pos1, const position& pos2) |
{ |
return !(pos1 == pos2); |
} |
|
/** \brief Intercept output stream redirection. |
** \param ostr the destination output stream |
** \param pos a reference to the position to redirect |
*/ |
inline std::ostream& |
operator<< (std::ostream& ostr, const position& pos) |
{ |
if (pos.filename) |
ostr << *pos.filename << ':'; |
return ostr << pos.line << '.' << pos.column; |
} |
|
|
/* Line 144 of location.cc */ |
#line 28 "parser.y" |
} // Theia |
|
/* Line 144 of location.cc */ |
#line 165 "position.hh" |
#endif // not BISON_POSITION_HH |
/branches/beta_2.0/compiler/src/vp_compiler/Instruction.cpp
0,0 → 1,784
|
/********************************************************************************** |
Theia, Ray Cast Programable graphic Processing Unit. |
Copyright (C) 2012 Diego Valverde (diego.valverde.g@gmail.com) |
|
This program is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
of the License, or (at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
***********************************************************************************/ |
|
|
#include "Instruction.h" |
#include <sstream> |
#include <iostream> |
#include <iomanip> |
//---------------------------------------------------------------- |
#define OP_SIZE 16 |
|
#define OP_RNG 63,48 |
#define OP_BIT_IMM 15 |
#define OP_SCALE_RNG 14,11 |
#define OP_EOF 10 |
#define OP_BRANCH 9 |
#define OP_BTYPE_RNG 8,6 |
|
#define OP_CODE_RNG 2,0 |
|
#define DST_ADDR 7,0 |
#define DST_WE_RNG 10,8 |
#define DST_WE_Z 8 |
#define DST_WE_Y 9 |
#define DST_WE_X 10 |
|
#define DST_ZERO 13 |
#define SRC1_DISPLACED 12 |
#define SRC0_DISPLACED 11 |
#define ADDRMODE_RNG 13,11 |
|
#define DST_RNG 47,34 |
#define SCR1_RNG 33,17 |
#define SRC0_RNG 16,0 |
// Source0 structure |
#define SRC0_SIZE 17 |
#define SRC0_RNG 16,0 |
#define SRC0_ADDR_SIZE 8 |
#define SRC0_SIGN_RNG 16,14 |
#define SRC0_SIGN_X 16 |
#define SRC0_SIGN_Y 15 |
#define SRC0_SIGN_Z 14 |
#define SRC0_SWZX_RNG 13,8 |
#define SRC0_SWZ_X 13,12 |
#define SRC0_SWZ_Y 11,10 |
#define SRC0_SWZ_Z 9,8 |
#define SRC0_ADDR_RNG 7,0 |
// Source1 structure |
#define SRC1_SIZE 17 |
#define SRC1_RNG 33,17 |
#define SRC1_ADDR_SIZE 8 |
#define SRC1_SIGN_RNG 16,14 |
#define SRC1_SIGN_X 16 |
#define SRC1_SIGN_Y 15 |
#define SRC1_SIGN_Z 14 |
#define SRC1_SWZX_RNG 13,8 |
#define SRC1_SWZ_X 13,12 |
#define SRC1_SWZ_Y 11,10 |
#define SRC1_SWZ_Z 9,8 |
#define SRC1_ADDR_RNG 7,0 |
|
|
std::string gOperationStrings[] = |
{ |
"NOP", |
"ADD", |
"DIV", |
"MUL", |
"SQRT", |
"LOGIC", |
"OUT" |
}; |
|
std::string gBranchTypeStrings[] = |
{ |
"ALWAYS", |
"ZERO", |
"NOT_ZERO", |
"SIGN", |
"NOT_SIGN", |
"ZERO_OR_SIGN", |
"ZERO_OR_NOT_SIGN" |
}; |
|
std::string gSwizzleXTypeStrings[] = |
{ |
"x", |
"z", |
"y" |
}; |
|
std::string gSwizzleYTypeStrings[] = |
{ |
"y", |
"z", |
"x" |
}; |
|
std::string gSwizzleZTypeStrings[] = |
{ |
"z", |
"y", |
"x" |
}; |
|
//-------------------------------------------------------------- |
template <std::size_t N > |
inline void SetbitRange( std::bitset<N> & aBitset , unsigned int aEnd, unsigned int aStart, unsigned int aValue) |
{ |
unsigned long mask = 1; |
unsigned long result = 0; |
for (int i = aStart; i <= aEnd; ++i) |
{ |
aBitset[i] = ( mask & aValue ); |
mask <<= 1; |
} |
|
} |
//-------------------------------------------------------------- |
template <std::size_t N > |
inline unsigned int GetbitRange( std::bitset<N> & aBitset , unsigned int aEnd, unsigned int aStart) |
{ |
|
unsigned long Result = 0; |
int j = 0; |
for (int i = aStart; i <= aEnd; ++i) |
{ |
Result |= ( aBitset[i] << j++); |
|
} |
|
return Result; |
|
} |
//-------------------------------------------------------------- |
const char lookuparrbin2hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; |
|
char convert_bin2hex(std::string bits) |
{ |
unsigned int result = 0; |
unsigned int shifter0 = 0; |
unsigned int shifter1 = 1; |
|
for(int n=0; n < bits.length(); n++) |
{ |
result <<= 1; //shift result to the left by 1 |
if(bits[n] == '1') result = (result | shifter1); |
else result = (result | shifter0); |
} |
return lookuparrbin2hex[result]; |
} |
//-------------------------------------------------------------- |
|
std::string BinStringToHexString(std::string aBinString ) |
{ |
std::string endresult = ""; |
for(int i = 0; i < aBinString.length(); i = i+4) |
{ |
endresult += convert_bin2hex(aBinString.substr(i,4)); |
} |
return endresult; |
} |
|
//-------------------------------------------------------------- |
Instruction::Instruction() |
{ |
mDestinationIsSymbol = false; |
mBisonFlagTrippleConstAssign = false; |
mSourceLine = -1; |
} |
//-------------------------------------------------------------- |
Instruction::~Instruction() |
{ |
|
} |
//-------------------------------------------------------------- |
void Instruction::SetFields( unsigned int aOperation, unsigned int aDestination, unsigned int aSrc1, unsigned int aSrc0 ) |
{ |
SetbitRange<16>(mOperation,16,0,aOperation); |
SetbitRange<14>(mDestination,14,0,aDestination); |
SetbitRange<17>(mSource1,17,0,aSrc1); |
SetbitRange<17>(mSource0,17,0,aSrc0); |
} |
//-------------------------------------------------------------- |
void Instruction::Clear() |
{ |
mOperation.reset(); |
mDestination.reset(); |
mSource1.reset(); |
mSource0.reset(); |
mComment.clear(); |
mDestinationIsSymbol = false; |
mBisonFlagTrippleConstAssign = false; |
mSourceLine = -1; |
} |
//-------------------------------------------------------------- |
|
std::string Instruction::PrintHex32() |
{ |
std::string Bits = PrintBin(); |
|
|
std::bitset<32> BitsetH(Bits.substr(0,32)); |
std::bitset<32> BitsetL(Bits.substr(32,32)); |
|
//std::cout << "!!! F" << Bits << " \n"; |
//std::cout << "!!! H" << BitsetH.to_string() << BitsetL.to_string() << " \n"; |
|
|
return BinStringToHexString( BitsetH.to_string() ) + " " + BinStringToHexString( BitsetL.to_string() ) ; |
|
} |
|
//-------------------------------------------------------------- |
std::string Instruction::PrintHex() |
{ |
std::string I; |
if (mDestinationIsSymbol) |
{ |
std::ostringstream oss; |
oss << std::hex << mOperation.to_ulong() << " "; |
oss << mDestinationSymbol; |
oss << " " << mSource1.to_ulong() << " " << mSource0.to_ulong(); |
return oss.str(); |
} |
I = BinStringToHexString( PrintBin() ); |
|
return I; |
|
} |
//-------------------------------------------------------------- |
unsigned int Instruction::GetOperation() |
{ |
|
return GetbitRange<16>(mOperation,OP_CODE_RNG); |
} |
//-------------------------------------------------------------- |
bool Instruction::GetImm( void) |
{ |
return mOperation[OP_BIT_IMM]; |
} |
//-------------------------------------------------------------- |
unsigned int Instruction::GetAddressingMode( void ) |
{ |
|
return GetbitRange<14>(mDestination,ADDRMODE_RNG); |
} |
//-------------------------------------------------------------- |
std::string Instruction::PrintAssembly() |
{ |
|
unsigned int Scale = GetbitRange<16>(mOperation,OP_SCALE_RNG); |
std::bitset<4> bScale( Scale ); |
|
std::ostringstream oss,oss2; |
#if 1 |
oss << std::hex << mOperation.to_ulong() << " "; |
if (mDestinationIsSymbol) |
oss << mDestinationSymbol; |
else |
oss << mDestination.to_ulong(); |
|
oss << " " << mSource1.to_ulong() << " " << mSource0.to_ulong(); |
|
#else |
oss << PrintHex(); |
|
#endif |
|
std::string tmpString = oss.str(); |
while (tmpString.size() < 50) tmpString.push_back(' '); |
oss2 << tmpString << "//\t" << PrintHex() << "\t"; |
|
oss2 << mOperationString << " "; |
if (mOperation[OP_BRANCH]) |
{ |
|
oss2 << "<BRANCH." << gBranchTypeStrings[ GetbitRange<16>(mOperation,OP_BTYPE_RNG) ] << "> "; |
} |
|
if (mDestinationIsSymbol) |
oss2 << mDestinationSymbol; |
else |
{ |
if (bScale[2] && bScale[3]) |
oss2 << "(unscaled) "; |
else if (bScale[2]) |
oss2 << "(scaled) "; |
|
if (mOperation[OP_BIT_IMM]) |
{ |
unsigned int AddressingMode = GetbitRange<14>(mDestination,ADDRMODE_RNG); |
unsigned int DestinationIndex = GetbitRange<14>(mDestination,DST_ADDR); |
std::string Reg = ((mOperation[OP_BRANCH])?"@*R[":"R["); |
switch ( AddressingMode ) |
{ |
case 0: oss2 << Reg << DestinationIndex << "]";break; |
case 1: oss2 << Reg << DestinationIndex << " + offset ]"; break; |
case 2: oss2 << Reg << DestinationIndex << " + offset ]"; break; |
case 3: oss2 << Reg << DestinationIndex << "+ R[" << mSource1.to_ulong() << " + offset] + offset ]";break; |
case 4: oss2 << Reg << DestinationIndex << "]"; break; |
case 5: oss2 << Reg << DestinationIndex << " + offset ]"; break; |
case 6: oss2 << Reg << DestinationIndex << " + offset ]";break; |
case 7: oss2 << Reg << DestinationIndex << " + offset ]";break; |
default: oss2 << "??"; |
} |
|
/* |
if (mDestination[SRC0_DISPLACED]) |
{ |
oss2 << ((mOperation[OP_BRANCH])?"@*R[":"R[") << GetbitRange<14>(mDestination,DST_ADDR) << "+ offset"; |
|
if (mDestination[SRC1_DISPLACED]) |
oss2 << " + R[" << mSource1.to_ulong() << " + offset]"; |
oss2 << "]"; |
} else |
oss2 << ((mOperation[OP_BRANCH])?"@*R":"R") << GetbitRange<14>(mDestination,DST_ADDR); |
*/ |
} |
else |
{ |
if (mDestination[DST_ZERO]) |
oss2 << ((mOperation[OP_BRANCH])?"@[":"R[") << GetbitRange<14>(mDestination,DST_ADDR) << "+ offset]"; |
else |
oss2 << ((mOperation[OP_BRANCH])?"@":"R") << GetbitRange<14>(mDestination,DST_ADDR); |
} |
} |
//Now print the write channels |
oss2 << "."; |
if (mDestination[DST_WE_X]) |
oss2 << "x"; |
else |
oss2 << "_"; |
|
if (mDestination[DST_WE_Y]) |
oss2 << "y"; |
else |
oss2 << "_"; |
|
if (mDestination[DST_WE_Z]) |
oss2 << "z"; |
else |
oss2 << "_"; |
|
oss2 << " "; |
|
if (mOperation[OP_BIT_IMM]) |
{ |
unsigned int AddressingMode = GetbitRange<14>(mDestination,ADDRMODE_RNG); |
unsigned int ImmediateValue = (mSource0.to_ulong() + (mSource1.to_ulong() << 17)); |
switch (AddressingMode) |
{ |
case 0: oss2 << std::hex << "I(" << ImmediateValue << ") R[DST]" ; break; |
case 1: oss2 << std::hex << "I(" << ImmediateValue << ") R[DST+offset]" << " *** " << mSource1.to_ulong() << " , " << mSource1.to_ulong();break; |
case 2: oss2 << "??????";break; |
case 3: oss2 << std::dec << "0 R[" << mSource0.to_ulong() << " + offset]"; break; |
case 4: oss2 << std::hex << "I(" << ImmediateValue << ") 0" ;break; |
case 5: oss2 << std::hex << "I(" << ImmediateValue << ") 0" ;break; |
case 6: oss2 << std::dec << " R[" << mSource1.to_ulong() << " + offset + index] 0";break; |
case 7: oss2 << std::dec << " R[" << mSource1.to_ulong() << " + offset + index] R[" << mSource0.to_ulong() << " + offset]"; break; |
default: |
oss2 << "??"; |
} |
/*if (mDestination[SRC1_DISPLACED] && mDestination[SRC0_DISPLACED] && !mDestination[DST_ZERO]) |
{ |
oss2 << std::dec << " R[" << mSource0.to_ulong() << " + offset] 0"; |
} else if (mDestination[SRC1_DISPLACED] && mDestination[SRC0_DISPLACED] && mDestination[DST_ZERO]) |
{ |
oss2 << std::dec << " R[" << mSource0.to_ulong() << " + offset + index] R[" << mSource0.to_ulong() << " + offset]"; |
} |
else |
{ |
oss2 << std::hex << "I(" << (mSource0.to_ulong() + (mSource1.to_ulong() << 17)) << ") "; |
|
if (mDestination[DST_ZERO]) |
oss2 << "0"; |
else |
oss2 << "R[DST]"; |
}*/ |
} else { |
|
|
if (bScale[0] && bScale[3]) |
oss2 << "(unscaled) "; |
else if (bScale[0]) |
oss2 << "(scaled) "; |
|
|
oss2 << "R"; |
if (mDestination[SRC1_DISPLACED]) |
oss2 << "[" << GetbitRange<17>(mSource1,SRC1_ADDR_RNG) << " + offset]"; |
else |
oss2 << GetbitRange<17>(mSource1,SRC1_ADDR_RNG); |
|
oss2 << "." |
|
<< ((mSource1[SRC1_SIGN_X]) ? "-":"") << gSwizzleXTypeStrings[ GetbitRange<17>(mSource1,SRC1_SWZ_X) ] |
<< ((mSource1[SRC1_SIGN_Y]) ? "-":"") <<gSwizzleYTypeStrings[ GetbitRange<17>(mSource1,SRC1_SWZ_Y) ] |
<< ((mSource1[SRC1_SIGN_Z]) ? "-":"") <<gSwizzleZTypeStrings[ GetbitRange<17>(mSource1,SRC1_SWZ_Z) ] << " "; |
|
|
if (bScale[1] && bScale[3]) |
oss2 << "(unscaled) "; |
else if (bScale[1]) |
oss2 << "(scaled) "; |
|
oss2 << "R"; |
if (mDestination[SRC0_DISPLACED]) |
oss2 << "[" << GetbitRange<17>(mSource0,SRC0_ADDR_RNG) << " + offset]"; |
else |
oss2 << GetbitRange<17>(mSource0,SRC0_ADDR_RNG); |
|
oss2 << "." |
|
<< ((mSource0[SRC0_SIGN_X]) ? "-":"") << gSwizzleXTypeStrings[ GetbitRange<17>(mSource0,SRC0_SWZ_X) ] |
<< ((mSource0[SRC0_SIGN_Y]) ? "-":"") << gSwizzleYTypeStrings[ GetbitRange<17>(mSource0,SRC0_SWZ_Y) ] |
<< ((mSource0[SRC0_SIGN_Z]) ? "-":"") << gSwizzleZTypeStrings[ GetbitRange<17>(mSource0,SRC0_SWZ_Z) ]; |
} |
|
|
return oss2.str(); |
} |
//-------------------------------------------------------------- |
unsigned int Instruction::GetDestinationAddress() |
{ |
return GetbitRange<14>(mDestination,DST_ADDR); |
} |
//-------------------------------------------------------------- |
void Instruction::SetImmBit( bool aImm ) |
{ |
mOperation[OP_BIT_IMM] = aImm; |
} |
//-------------------------------------------------------------- |
void Instruction::PrintFields() |
{ |
if (mOperation[OP_BRANCH]) |
{ |
std::cout << "BRANCH to " << mDestination.to_ulong() << "\n"; |
} |
std::cout << "Imm :" << mOperation[OP_BIT_IMM] << "\n"; |
std::cout << "Branch :" << mOperation[OP_BRANCH] << "\n"; |
std::cout << "WE.x :" << mDestination[DST_WE_X] << "\n"; |
std::cout << "WE.y :" << mDestination[DST_WE_Y] << "\n"; |
std::cout << "WE.z :" << mDestination[DST_WE_Z] << "\n"; |
std::cout << "EOF :" << mOperation[OP_EOF] << "\n"; |
|
std::cout << "OP :" << mOperation.to_string() << "\n"; |
if (mDestinationIsSymbol) |
std::cout << "DST :" << mDestinationSymbol << "\n"; |
else |
std::cout << "DST :" << mDestination.to_string() << "\n"; |
std::cout << "DSTZERO :" << mDestination[DST_ZERO] << "\n"; |
std::cout << "SRC1 :" << mSource1.to_string() << " (" << mSource1.to_ulong() << ")\n"; |
std::cout << "SRC0 :" << mSource0.to_string() << " (" << mSource0.to_ulong() << ")\n"; |
} |
//-------------------------------------------------------------- |
std::string Instruction::PrintBin() |
{ |
|
std::bitset<64> Bitset; |
|
|
SetbitRange<64>(Bitset,OP_RNG,mOperation.to_ulong()); |
SetbitRange<64>(Bitset,DST_RNG,mDestination.to_ulong()); |
SetbitRange<64>(Bitset,SRC1_RNG,mSource1.to_ulong()); |
SetbitRange<64>(Bitset,SRC0_RNG,mSource0.to_ulong()); |
return Bitset.to_string(); |
|
} |
//-------------------------------------------------------------- |
void Instruction::SetEofFlag( bool aEof ) |
{ |
mOperation[ OP_EOF ] = aEof; |
} |
//-------------------------------------------------------------- |
void Instruction::SetCode( EOPERATION aCode ) |
{ |
SetbitRange<16>(mOperation,OP_CODE_RNG,aCode); |
mOperationString = gOperationStrings[aCode]; |
} |
//-------------------------------------------------------------- |
void Instruction::SetImm( unsigned int aLiteral ) |
{ |
|
|
mOperation[OP_BIT_IMM] = true; |
mSource0 = aLiteral; |
mSource1 = (aLiteral >> SOURCE0_SIZE); |
} |
//-------------------------------------------------------------- |
void Instruction::SetAddressingMode( bool aDstZero, bool aSrc1Dsp , bool aSrc0Dsp) |
{ |
SetDestZero( aDstZero ); |
SetSrc1Displace( aSrc1Dsp ); |
SetSrc0Displace( aSrc0Dsp ); |
} |
//-------------------------------------------------------------- |
/*void SetAddressingMode( EADDRESSINGTYPE aAddressMode ) |
{ |
std::bitset<4> AddressingMode( aAddressMode ); |
AddressingMode[3] = mOperation[OP_BIT_IMM] ; |
|
switch ( AddressingMode ) |
{ |
case EDIRECT_ADDRESSING: |
SetDestZero( false ); |
SetSrc1Displace( false ); |
SetSrc0Displace( false ); |
break; |
case EDIRECT_DISP_SRC0: |
SetDestZero( false ); |
SetSrc1Displace( false ); |
SetSrc0Displace( true ); |
break; |
EDIRECT_DISP_SRC1: |
SetDestZero( false ); |
SetSrc1Displace( true ); |
SetSrc0Displace( false ); |
break; |
EDIRECT_DISP_SRC1_SRC0: |
SetDestZero( false ); |
SetSrc1Displace( true ); |
SetSrc0Displace( true ); |
break; |
EDIRECT_DISP_DST: |
SetDestZero( true ); |
SetSrc1Displace( false ); |
SetSrc0Displace( false ); |
break; |
EDIRECT_DISP_DST_SRC0: |
SetDestZero( true ); |
SetSrc1Displace( false ); |
SetSrc0Displace( true ); |
break; |
case EDIRECT_DISP_DST_SRC1: |
SetDestZero( true ); |
SetSrc1Displace( true ); |
SetSrc0Displace( false ); |
break; |
case EDIRECT_DISP_DST_SRC1_SRC0: |
SetDestZero( true ); |
SetSrc1Displace( true ); |
SetSrc0Displace( true ); |
break; |
EDIRECT_IMM: //R[DSTINDEX ] = IMMV op R[DSTINDEX] |
SetDestZero( false ); |
SetSrc1Displace( false ); |
SetSrc0Displace( false ); |
break; |
EDIRECT_IMM_ZERO: //R[DSTINDEX ] = IMMV op 32'b0 |
SetDestZero( true ); |
SetSrc1Displace( false ); |
SetSrc0Displace( false ); |
break; |
EDIRECT_IMM_DISPALCE: //R[DSTINDEX + offset] = IMMV op R[DSTINDEX] |
SetDestZero( false ); |
SetSrc1Displace( false ); |
SetSrc0Displace( true ); |
break; |
EDIRECT_IMM_DISPALCE_ZERO: //R[DSTINDEX + offset] = IMMV op 32'b0 |
SetDestZero( true ); |
SetSrc1Displace( false ); |
SetSrc0Displace( true ); |
break; |
EINDIRECT_IMM_DISP: // DST = R[ DSTINDEX ] + OFFSET |
SetDestZero( false ); |
SetSrc1Displace( false ); |
SetSrc0Displace( false ); |
break; |
break; |
EINDIRECT_IMM_DISP_ZERO: |
break; |
EINDIRECT_NO_IMM: |
break; |
EINDIRECT_NO_IMM_DISP: |
break; |
} |
}*/ |
//-------------------------------------------------------------- |
void Instruction::SetDestZero( bool aZero ) |
{ |
mDestination[DST_ZERO] = aZero; |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc0Displace( bool aDisplace ) |
{ |
mDestination[SRC0_DISPLACED] = aDisplace; |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc1Displace( bool aDisplace ) |
{ |
mDestination[SRC1_DISPLACED] = aDisplace; |
} |
//-------------------------------------------------------------- |
void Instruction::SetBranchFlag( bool aBranch ) |
{ |
mOperation[OP_BRANCH] = aBranch; |
} |
//-------------------------------------------------------------- |
void Instruction::SetBranchType( EBRANCHTYPE aBranchType ) |
{ |
SetbitRange<16>(mOperation,OP_BTYPE_RNG,aBranchType); |
} |
//-------------------------------------------------------------- |
void Instruction::ClearWriteChannel() |
{ |
|
mDestination[DST_WE_X] = false; |
mDestination[DST_WE_Y] = false; |
mDestination[DST_WE_Z] = false; |
} |
//-------------------------------------------------------------- |
void Instruction::SetWriteChannel( ECHANNEL aChannel ) |
{ |
|
if (aChannel == ECHANNEL_XYZ) |
{ |
mDestination[DST_WE_X] = true; |
mDestination[DST_WE_Y] = true; |
mDestination[DST_WE_Z] = true; |
return; |
} |
|
switch ( aChannel ) |
{ |
case ECHANNEL_X: |
mDestination[DST_WE_X] = true; |
break; |
case ECHANNEL_Y: |
mDestination[DST_WE_Y] = true; |
break; |
case ECHANNEL_Z: |
mDestination[DST_WE_Z] = true; |
break; |
} |
|
} |
//-------------------------------------------------------------- |
void Instruction::SetDestinationAddress( unsigned int aAddress ) |
{ |
|
SetbitRange<14>(mDestination,DST_ADDR,aAddress); |
|
} |
//-------------------------------------------------------------- |
void Instruction::SetDestinationSymbol( std::string aSymbol ) |
{ |
mDestinationIsSymbol = true; |
mDestinationSymbol = aSymbol; |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc1SignX( bool aSign ) |
{ |
mSource1[SRC1_SIGN_X] = aSign; |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc1SignY( bool aSign ) |
{ |
mSource1[SRC1_SIGN_Y] = aSign; |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc1SignZ( bool aSign ) |
{ |
mSource1[SRC1_SIGN_Z] = aSign; |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc1SwizzleX(ESWIZZLE_X aChannel) |
{ |
SetbitRange<17>(mSource1,SRC1_SWZ_X,aChannel); |
|
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc1SwizzleY(ESWIZZLE_Y aChannel) |
{ |
SetbitRange<17>(mSource1,SRC1_SWZ_Y,aChannel); |
|
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc1SwizzleZ(ESWIZZLE_Z aChannel) |
{ |
SetbitRange<17>(mSource1,SRC1_SWZ_Z,aChannel); |
|
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc1Address(unsigned int aAddress ) |
{ |
SetbitRange<17>(mSource1,SRC1_ADDR_RNG,aAddress); |
} |
//-------------------------------------------------------------- |
void Instruction::SetLogicOperation(ELOGIC_OPERATION aOperation ) |
{ |
SetbitRange<16>(mOperation,OP_SCALE_RNG,aOperation); |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc1Rotation( EROTATION aRotation ) |
{ |
unsigned int OldVal = GetbitRange<16>(mOperation,OP_SCALE_RNG); |
|
SetbitRange<16>(mOperation,OP_SCALE_RNG,(OldVal | aRotation) ); |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc0Rotation( EROTATION aRotation ) |
{ |
unsigned int OldVal = GetbitRange<16>(mOperation,OP_SCALE_RNG); |
|
SetbitRange<16>(mOperation,OP_SCALE_RNG,(OldVal | aRotation ) ); |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc0SignX( bool aSign ) |
{ |
mSource0[SRC0_SIGN_X] = aSign; |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc0SignY( bool aSign ) |
{ |
mSource0[SRC0_SIGN_Y] = aSign; |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc0SignZ( bool aSign ) |
{ |
mSource0[SRC0_SIGN_Z] = aSign; |
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc0SwizzleX(ESWIZZLE_X aChannel) |
{ |
SetbitRange<17>(mSource0,SRC0_SWZ_X,aChannel); |
|
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc0SwizzleY(ESWIZZLE_Y aChannel) |
{ |
SetbitRange<17>(mSource0,SRC0_SWZ_Y,aChannel); |
|
|
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc0SwizzleZ(ESWIZZLE_Z aChannel) |
{ |
SetbitRange<17>(mSource0,SRC0_SWZ_Z,aChannel); |
|
} |
//-------------------------------------------------------------- |
void Instruction::SetSrc0Address(unsigned int aAddress ) |
{ |
SetbitRange<17>(mSource0,SRC0_ADDR_RNG,aAddress); |
} |
//-------------------------------------------------------------- |
std::bitset<DESTINATION_SIZE> Instruction::GetDestination( ) |
{ |
return mDestination; |
} |
//-------------------------------------------------------------- |
ECHANNEL Instruction::GetWriteChannel( ) |
{ |
//std::cout << "Ecahhhannel " << GetbitRange<DESTINATION_SIZE>(mDestination,DST_WE_RNG) << "\n"; |
|
return ((ECHANNEL)GetbitRange<DESTINATION_SIZE>(mDestination,DST_WE_RNG)); |
} |
//-------------------------------------------------------------- |
/* |
void Instruction::SetDestination( std::bitset<DESTINATION_SIZE> aDestination ) |
{ |
mDestination = aDestination; |
} |
*/ |
//-------------------------------------------------------------- |
/branches/beta_2.0/compiler/src/vp_compiler/parser.y
0,0 → 1,2398
|
/********************************************************************************** |
Theia, Ray Cast Programable graphic Processing Unit. |
Copyright (C) 2012 Diego Valverde (diego.valverde.g@gmail.com) |
|
This program is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
of the License, or (at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
***********************************************************************************/ |
|
|
%require "2.4.1" |
%skeleton "lalr1.cc" |
%defines |
%error-verbose |
%locations |
%define namespace "Theia" |
%define parser_class_name "Parser" |
%parse-param { Theia::Scanner &scanner } |
%parse-param { std::map<std::string,unsigned int> & mSymbolMap } |
%parse-param { std::vector< Instruction > &mInstructions } |
%parse-param { bool &mGenerateFixedPointArithmetic } |
%lex-param { Theia::Scanner &scanner } |
|
%code requires { |
#include <string> |
#include <sstream> |
#include <iomanip> |
#include <bitset> |
#include <map> |
#include "Instruction.h" |
#include <vector> |
|
|
// We want to return a string |
#define YYSTYPE std::string |
|
|
namespace Theia |
{ |
// Forward-declare the Scanner class; the Parser needs to be assigned a |
// Scanner, but the Scanner can't be declared without the Parser |
class Scanner; |
|
// We use a map to store the INI data |
typedef std::map<std::string, std::map<std::string, std::string> > mapData; |
|
|
|
|
|
} |
|
} |
|
%code |
{ |
#include "Instruction.h" |
#include <vector> |
Instruction I,tmpI; |
|
std::vector< unsigned int > gBranchStack; |
static int gInsertedInstructions = 0; |
static int gWhileLoopAddress = 0; |
#define FUNCTION_PARAM_START_REGION 4 |
#define FUNCTION_PARAM_LAST_REGION 10 |
std::map<std::string, unsigned int> gFunctionParameters; |
std::map<std::string, unsigned int> gAutoVarMap; |
std::map<std::string, unsigned int> gThreadMap; //Key: Symbol, value: start code addr |
bool gThreadScope = false; |
#define AUTOVAR_START_REGION 9 |
#define THREAD_OFFSET 128 |
unsigned int gExtraDestModifications = 0; |
unsigned int gAutoVarIndex = AUTOVAR_START_REGION; |
unsigned int gThreadAutoVarIndex = THREAD_OFFSET; |
unsigned int gFunctionParameterIndex = FUNCTION_PARAM_START_REGION; |
//---------------------------------------------------------- |
unsigned int GetNextFunctionParamRegister() |
{ |
unsigned Ret = gFunctionParameterIndex++; |
return Ret; |
} |
|
//---------------------------------------------------------- |
void AddFunctionParameter( std::string aVar, Theia::Parser::location_type yylloc) |
{ |
////std::cout << "Adding " << aVar << "\n"; |
if (gFunctionParameterIndex+1 > FUNCTION_PARAM_LAST_REGION) |
{ |
std::ostringstream ret; |
ret << "Cannot allocate more parameters '" << aVar << "' at line " << yylloc << " \n"; |
throw ret.str(); |
} |
if (gFunctionParameters.find(aVar) != gFunctionParameters.end()) |
{ |
std::ostringstream ret; |
ret << "Parameter '" << aVar << "' at line " << yylloc << " is already defined\n"; |
throw ret.str(); |
} |
|
gFunctionParameters[ aVar ] = gFunctionParameterIndex++; |
|
} |
//---------------------------------------------------------- |
std::string GetRegisterFromFunctionParameter( std::string aVar ) |
{ |
////std::cout << "Looking for " << aVar << "\n"; |
if (gFunctionParameters.find(aVar) == gFunctionParameters.end()) |
return "NULL"; |
|
std::ostringstream ss; |
ss << gFunctionParameters[ aVar ]; |
return ("R" + ss.str()); |
} |
//---------------------------------------------------------- |
unsigned int GetCurretAutoVarFrameSize() |
{ |
|
return gAutoVarMap.size(); |
|
} |
//---------------------------------------------------------- |
std::string GetRegisterFromAutoVar( std::string aVar, Theia::Parser::location_type yylloc ) |
{ |
if (gAutoVarMap.find(aVar) == gAutoVarMap.end()) |
{ |
std::ostringstream ret; |
ret << "Undefined variable '" << aVar << "' at line " << yylloc << " \n"; |
throw ret.str(); |
} |
|
std::ostringstream ss; |
ss << gAutoVarMap[ aVar ]; |
return ("R" + ss.str()); |
} |
//---------------------------------------------------------- |
int GetCurrentLineNumber( const Theia::Parser::location_type &loc ) |
{ |
int ret = -1; |
std::stringstream ss2; |
std::string where; |
ss2 << loc; |
ss2 >> where; |
where.erase(where.find_first_of(".")); |
std::stringstream ss3; |
ss3 << where; |
ss3 >> ret; |
return ret; |
} |
//---------------------------------------------------------- |
unsigned int AllocAutoVar( unsigned int aSize = 1) |
{ |
|
if (!gThreadScope) |
{ |
gAutoVarIndex += aSize; |
return gAutoVarIndex - (aSize-1); |
}else{ |
gThreadAutoVarIndex += aSize; |
return (gThreadAutoVarIndex - (aSize-1)); |
} |
} |
//---------------------------------------------------------- |
void ClearFunctionParameterMap() |
{ |
gFunctionParameters.clear(); |
gFunctionParameterIndex = FUNCTION_PARAM_START_REGION; |
} |
//---------------------------------------------------------- |
void ClearAutoVarMap() |
{ |
gAutoVarMap.clear(); |
gAutoVarIndex = AUTOVAR_START_REGION; |
} |
//---------------------------------------------------------- |
unsigned int gTempRegisterIndex = 1; |
unsigned int GetFreeTempRegister( ) |
{ |
if (!gThreadScope) |
return gAutoVarIndex + (gTempRegisterIndex++); |
else |
return gThreadAutoVarIndex + (gTempRegisterIndex++); |
|
} |
//---------------------------------------------------------- |
void ResetTempRegisterIndex( void ) |
{ |
|
gTempRegisterIndex = 1; |
} |
//---------------------------------------------------------- |
bool IsSwizzled( std::string aSource) |
{ |
if (aSource.find(".") != std::string::npos) |
return true; |
else |
return false; |
} |
|
//---------------------------------------------------------- |
void SetSwizzleAndSign( unsigned int aSourceIndex, std::string aSwizzle, Instruction & I ) |
{ |
std::string Reg,X,Y,Z, junk; |
std::stringstream ss( aSwizzle ); |
ss >> Reg >> junk >> X >> Y >> Z; |
|
|
if (aSourceIndex == 1) |
{ |
if (X == "X") { I.SetSrc1SwizzleX(SWX_X); } |
if (X == "Y") { I.SetSrc1SwizzleX(SWX_Y); } |
if (X == "Z") { I.SetSrc1SwizzleX(SWX_Z); } |
if (X == "-X") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_X); } |
if (X == "-Y") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Y); } |
if (X == "-Z") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Z); } |
|
if (Y == "X") { I.SetSrc1SwizzleY(SWY_X); } |
if (Y == "Y") { I.SetSrc1SwizzleY(SWY_Y); } |
if (Y == "Z") { I.SetSrc1SwizzleY(SWY_Z); } |
if (Y == "-X") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_X); } |
if (Y == "-Y") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Y); } |
if (Y == "-Z") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Z); } |
|
if (Z == "X") { I.SetSrc1SwizzleZ(SWZ_X); } |
if (Z == "Y") { I.SetSrc1SwizzleZ(SWZ_Y); } |
if (Z == "Z") { I.SetSrc1SwizzleZ(SWZ_Z); } |
if (Z == "-X") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_X); } |
if (Z == "-Y") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Y); } |
if (Z == "-Z") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Z); } |
} else { |
if (X == "X") { I.SetSrc0SwizzleX(SWX_X); } |
if (X == "Y") { I.SetSrc0SwizzleX(SWX_Y); } |
if (X == "Z") { I.SetSrc0SwizzleX(SWX_Z); } |
if (X == "-X") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_X); } |
if (X == "-Y") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Y); } |
if (X == "-Z") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Z); } |
|
if (Y == "X") { I.SetSrc0SwizzleY(SWY_X); } |
if (Y == "Y") { I.SetSrc0SwizzleY(SWY_Y); } |
if (Y == "Z") { I.SetSrc0SwizzleY(SWY_Z); } |
if (Y == "-X") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_X); } |
if (Y == "-Y") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Y); } |
if (Y == "-Z") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Z); } |
|
if (Z == "X") { I.SetSrc0SwizzleZ(SWZ_X); } |
if (Z == "Y") { I.SetSrc0SwizzleZ(SWZ_Y); } |
if (Z == "Z") { I.SetSrc0SwizzleZ(SWZ_Z); } |
if (Z == "-X") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_X); } |
if (Z == "-Y") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Y); } |
if (Z == "-Z") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Z); } |
} |
} |
//---------------------------------------------------------- |
void StoreReturnAddress( std::vector<Instruction> & aInstructions, Theia::Parser::location_type & yylloc ) |
{ |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "store return address**"; |
I.SetImm( aInstructions.size()+4 ); |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( RETURN_ADDRESS_REGISTER ); |
I.SetDestZero( true ); |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
aInstructions.push_back( I ); |
I.Clear(); |
} |
//---------------------------------------------------------- |
void SavePreviousFramePointer( std::vector<Instruction> & aInstructions ) |
{ |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "store current frame offset"; |
I.SetWriteChannel(ECHANNEL_Y); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetSrc1Address(SPR_CONTROL_REGISTER); |
I.SetSrc1SwizzleX(SWX_X); |
I.SetSrc1SwizzleY(SWY_X); |
I.SetSrc1SwizzleZ(SWZ_X); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
aInstructions.push_back( I ); |
I.Clear(); |
} |
//---------------------------------------------------------- |
void SetIndexRegister( unsigned int aIndex, std::vector<Instruction> & aInstructions ) |
{ |
Instruction Tmp; |
Tmp.SetCode( EOPERATION_ADD ); |
Tmp.mComment = "store array index register"; |
Tmp.SetWriteChannel(ECHANNEL_Z); |
Tmp.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
Tmp.SetSrc1Address( aIndex ); |
Tmp.SetSrc1Displace( true ); |
Tmp.SetSrc1SwizzleX(SWX_X); |
Tmp.SetSrc1SwizzleY(SWY_X); |
Tmp.SetSrc1SwizzleZ(SWZ_X); |
Tmp.SetSrc0Address(0); |
Tmp.SetSrc0SwizzleX(SWX_X); |
Tmp.SetSrc0SwizzleY(SWY_X); |
Tmp.SetSrc0SwizzleZ(SWZ_X); |
//Tmp.SetImm( aIndex ); |
//Tmp.SetDestZero( true ); |
aInstructions.push_back( Tmp ); |
|
} |
//---------------------------------------------------------- |
void UpdateFramePointer( std::vector<Instruction> & aInstructions ) |
{ |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "displace next frame offset by the number of auto variables in current frame"; |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetImm( GetCurretAutoVarFrameSize() ); |
I.SetDestZero( false ); |
aInstructions.push_back( I ); |
I.Clear(); |
} |
//---------------------------------------------------------- |
void CallFunction( std::string aFunctionName, std::vector<Instruction> & aInstructions, std::map<std::string,unsigned int> & aSymbolMap) |
{ |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "call the function"; |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
//Now do the branch |
if (aSymbolMap.find(aFunctionName) == aSymbolMap.end()) |
I.SetDestinationSymbol( "@"+aFunctionName ); |
else |
I.SetDestinationAddress( aSymbolMap[ aFunctionName ] ); |
|
aInstructions.push_back( I ); |
I.Clear(); |
} |
//---------------------------------------------------------- |
void SetDestinationFromRegister( std::string aDestination, Instruction & aInst, bool Imm ) |
{ |
//Look for displament addressing mode |
|
if (aDestination.find("OFFSET") != std::string::npos) |
{ |
aDestination.erase(aDestination.find("OFFSET")); |
////std::cout << "^_^ left_hand_side " << Destination << "\n"; |
if (Imm == true) |
aInst.SetSrc0Displace( true ); //When Imm == 0, then setting this makes offset |
else |
aInst.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
} |
if (aDestination.find(".") != std::string::npos) |
{ |
aInst.ClearWriteChannel(); |
if (aDestination.find("x") != std::string::npos) |
aInst.SetWriteChannel(ECHANNEL_X); |
if (aDestination.find("y") != std::string::npos) |
aInst.SetWriteChannel(ECHANNEL_Y); |
if (aDestination.find("z") != std::string::npos) |
aInst.SetWriteChannel(ECHANNEL_Z); |
|
aDestination.erase(aDestination.find(".")); |
|
} |
aInst.SetDestinationAddress( atoi(aDestination.c_str()+1) ); |
} |
//---------------------------------------------------------- |
void PopulateSourceRegisters( std::string a1, std::string a2, Instruction & I, std::vector<Instruction> & aInstructions ) |
{ |
|
|
if ( a1.find("R") == std::string::npos ) |
{ |
//This is for constants |
unsigned int ImmediateValue; |
std::string StringHex = a1; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
} else { |
|
|
|
if (a1.find("array_element") != std::string::npos) |
{ |
|
|
std::string Index = a1.substr(a1.find("array_element")); |
////std::cout << "XXXXX " << Index << "\n\n\n"; |
Index = Index.substr(Index.find_first_not_of("array_element R")); |
////std::cout << "XXXXX " << Index << "\n\n\n"; |
SetIndexRegister( atoi(Index.c_str()), aInstructions ); |
a1.erase(a1.find("array_element")); |
I.SetSrc0Displace( true ); |
I.SetSrc1Displace( true ); |
I.SetImmBit( true ); |
} |
//Look for displament addressing mode |
else if (a1.find("OFFSET") != std::string::npos) |
{ |
a1.erase(a1.find("OFFSET")); |
////std::cout << "^_^ a1" << a1 << "\n"; |
I.SetSrc1Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
} |
|
std::string Src1 = a1; |
if (IsSwizzled( Src1 )) |
{ |
SetSwizzleAndSign( 1, Src1, I ); |
Src1.erase(Src1.find(".")); |
} |
I.SetSrc1Address( atoi( Src1.c_str()+1 ) ); |
} |
|
if ( a2.find("R") == std::string::npos) |
{ |
} else { |
|
|
|
//Look for displament addressing mode |
if (a2.find("OFFSET") != std::string::npos) |
{ |
a2.erase(a2.find("OFFSET")); |
////std::cout << "^_^ a2 " << a2 << "\n"; |
I.SetSrc0Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
} |
|
std::string Src0 = a2; |
if (IsSwizzled( Src0 )) |
{ |
SetSwizzleAndSign( 0, Src0, I ); |
Src0.erase(Src0.find(".")); |
} |
I.SetSrc0Address( atoi( Src0.c_str()+1 ) ); |
} |
} |
//---------------------------------------------------------- |
void ClearNextFunctionParamRegister() |
{ |
gFunctionParameterIndex = FUNCTION_PARAM_START_REGION; |
} |
//---------------------------------------------------------- |
void AddFunctionInputList( std::string aVar, std::vector<Instruction> & aInstructions,Theia::Parser::location_type yylloc) |
{ |
//Get the value from the variable |
|
//Copy the value into function parameter register |
unsigned FunctionParamReg = GetNextFunctionParamRegister(); |
I.Clear(); |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "copy the value into function parameter register"; |
I.SetWriteChannel(ECHANNEL_XYZ); |
//I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
I.SetDestinationAddress( FunctionParamReg ); |
|
if (aVar.find("R") != std::string::npos) |
{ |
if (aVar.find("OFFSET") != std::string::npos) |
{ |
I.SetSrc1Displace( true ); |
aVar.erase(aVar.find("OFFSET")); |
} |
I.SetSrc1Address(atoi(aVar.c_str()+1)); |
return; |
} |
std::string Reg = GetRegisterFromFunctionParameter( aVar ); |
if (Reg == "NULL") |
{ |
Reg = GetRegisterFromAutoVar( aVar, yylloc ); |
I.SetSrc1Address(atoi(Reg.c_str()+1)); |
I.SetSrc1Displace( true ); |
} else { |
I.SetSrc1Address(atoi(Reg.c_str()+1)); |
I.SetSrc1Displace( false ); |
} |
|
|
|
I.SetSrc1SwizzleX(SWX_X); |
I.SetSrc1SwizzleY(SWY_Y); |
I.SetSrc1SwizzleZ(SWZ_Z); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
aInstructions.push_back( I ); |
I.Clear(); |
} |
//---------------------------------------------------------- |
void SetExpressionDestination( std::string aStringDestination, Instruction & I ) |
{ |
std::string Destination = aStringDestination; |
|
//Look for indirect addressing |
if (Destination.find("INDEX") != std::string::npos) |
{ |
|
std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5); |
Destination.erase(Destination.find("INDEX")); |
I.SetImm( 0 ); |
I.SetCode( EOPERATION_ADD ); |
|
if (Destination.find(".") != std::string::npos) |
{ |
I.ClearWriteChannel(); |
if (Destination.find("x") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_X); |
if (Destination.find("y") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Y); |
if (Destination.find("z") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Z); |
Destination.erase(Destination.find(".")); |
|
} |
|
I.SetDestinationAddress( atoi(Destination.c_str()+1) ); |
|
} else { |
|
//Look for displament addressing mode |
if (Destination.find("OFFSET") != std::string::npos) |
{ |
Destination.erase(Destination.find("OFFSET")); |
I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
} |
if (Destination.find(".") != std::string::npos) |
{ |
I.ClearWriteChannel(); |
if (Destination.find("x") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_X); |
if (Destination.find("y") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Y); |
if (Destination.find("z") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Z); |
|
Destination.erase(Destination.find(".")); |
|
} |
I.SetDestinationAddress( atoi(Destination.c_str()+1) ); |
|
|
|
} |
} |
|
//---------------------------------------------------------- |
bool SourceNull( std::string aSource ) |
{ |
if (aSource == "NULL") |
return true; |
|
return false; |
} |
//---------------------------------------------------------- |
|
void PopulateInstruction( std::string aDestination, std::string aSource1, std::string aSource0, Instruction & I, Theia::Parser::location_type yylloc, bool aHasLiteral = false, unsigned int aLiteral = 0) |
{ |
|
|
bool DestinationHasOffset = false; |
bool DetinationHasIndex = false; |
bool Source0HasOffset = false; |
bool Source1HasOffset = false; |
bool Source1HasIndex = false; |
bool Source0HasIndex = false; |
|
|
if (aDestination.find("INDEX") != std::string::npos) |
{ |
std::string ArrayIndex = aDestination.substr(aDestination.find("INDEX")+5); |
aSource1 = ArrayIndex; |
DetinationHasIndex = true; |
|
} |
|
if (aSource1.find("INDEX") != std::string::npos) |
Source1HasIndex = true; |
|
if (aSource0.find("INDEX") != std::string::npos) |
Source0HasIndex = true; |
|
if (aDestination.find("OFFSET") != std::string::npos) |
DestinationHasOffset = true; |
|
if (aSource0.find("OFFSET") != std::string::npos) |
Source0HasOffset = true; |
|
if (aSource1.find("OFFSET") != std::string::npos) |
Source1HasOffset = true; |
|
if (IsSwizzled( aSource1 )) |
SetSwizzleAndSign( 1, aSource1, I ); |
I.SetSrc1Address( atoi( aSource1.c_str()+1 ) ); |
|
if (IsSwizzled( aSource0 )) |
SetSwizzleAndSign( 0, aSource0, I ); |
I.SetSrc0Address( atoi( aSource0.c_str()+1 ) ); |
|
|
|
//Fisrt take care of the destination write channel |
if (aDestination.find(".") != std::string::npos) |
{ |
I.ClearWriteChannel(); |
if (aDestination.find("x") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_X); |
if (aDestination.find("y") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Y); |
if (aDestination.find("z") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Z); |
aDestination.erase(aDestination.find(".")); |
} else { |
I.SetWriteChannel(ECHANNEL_XYZ); |
} |
//Now set the destination Index |
I.SetDestinationAddress( atoi(aDestination.c_str()+1) ); |
|
|
//Now determine the addressing mode |
//Simple addressing modes |
if (!aHasLiteral && !DetinationHasIndex && !Source0HasIndex && !Source1HasIndex) |
{ |
|
I.SetAddressingMode( DestinationHasOffset,Source1HasOffset,Source0HasOffset); |
return; |
} |
|
|
I.SetImmBit( true ); //This is to set the IMM bit = 1, may be overwritten latter |
//Complex addressing modes |
if |
( |
aHasLiteral && |
!SourceNull( aSource0 ) && |
!Source0HasOffset && |
!Source1HasOffset && |
!DestinationHasOffset |
) |
{ |
I.SetAddressingMode( false,false,false); |
I.SetImm( aLiteral ); |
|
} |
else |
if |
( |
aHasLiteral && |
!SourceNull( aSource0 ) && |
Source0HasOffset && |
!Source0HasIndex && |
DestinationHasOffset |
|
) |
{ |
|
I.SetAddressingMode( false,false,true); |
I.SetImm( aLiteral ); |
|
|
} |
else |
if |
( |
!aHasLiteral && |
!SourceNull( aSource1 ) && |
!Source1HasOffset && |
!SourceNull( aSource0 ) && |
Source0HasOffset && |
Source0HasIndex && |
DestinationHasOffset |
|
) |
{ |
I.SetAddressingMode( false,true,false); |
|
} |
else |
if |
( |
!aHasLiteral && |
!Source1HasOffset && |
!SourceNull( aSource0 ) && |
Source0HasOffset && |
!Source0HasIndex && |
DestinationHasOffset && |
DetinationHasIndex |
|
) |
{ |
I.SetAddressingMode( false,true,true); |
|
} |
else |
if |
( |
aHasLiteral && |
SourceNull( aSource0 ) && |
!DestinationHasOffset && |
!DetinationHasIndex |
|
) |
{ |
|
|
I.SetAddressingMode( true,false,false); |
I.SetImm( aLiteral ); |
} |
else |
if |
( |
aHasLiteral && |
SourceNull( aSource0 ) && |
DestinationHasOffset && |
!DetinationHasIndex |
|
) |
{ |
|
I.SetAddressingMode( true,false,true); |
I.SetImm( aLiteral ); |
} |
else |
if |
( |
!aHasLiteral && |
Source1HasOffset && |
Source1HasIndex && |
SourceNull( aSource0 ) && |
DestinationHasOffset && |
!DetinationHasIndex |
|
) |
{ |
|
I.SetAddressingMode( true,true,false); |
} |
else |
if |
( |
!aHasLiteral && |
Source1HasOffset && |
Source1HasIndex && |
Source0HasOffset && |
!Source0HasIndex && |
DestinationHasOffset && |
!DetinationHasIndex |
|
) |
{ |
|
I.SetAddressingMode( true,true,true); |
} else { |
std::ostringstream ret; |
ret << "Could not determine addressing mode at line " << yylloc << " \n"; |
throw ret.str(); |
} |
|
|
} |
|
//------------------------------------------------------------- |
void PopulateBoolean(EBRANCHTYPE aBranchType, std::string Source1, std::string Source0, Instruction & I, std::vector<Instruction> & aInstructions, Theia::Parser::location_type & yylloc ) |
{ |
|
if (Source0.find("R") == std::string::npos) |
{ |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetCode( EOPERATION_ADD ); |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
unsigned int ImmediateValue; |
std::string StringHex = Source0; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc0Displace( true ); |
I.SetWriteChannel(ECHANNEL_X); |
I.SetWriteChannel(ECHANNEL_Y); |
I.SetWriteChannel(ECHANNEL_Z); |
aInstructions.push_back(I); |
I.Clear(); |
|
std::stringstream ss2; |
ss2 << "R" << TempRegIndex; |
ss2 >> Source0; |
Source0 += " OFFSET "; |
|
} |
else |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
|
I.SetCode( EOPERATION_ADD ); |
I.SetSrc0SignX( true ); |
I.SetSrc0SignY( true ); |
I.SetSrc0SignZ( true ); |
I.SetBranchFlag( true ); |
I.ClearWriteChannel(); |
I.SetBranchType( aBranchType ); |
|
PopulateSourceRegisters( Source1, Source0, I, aInstructions); |
aInstructions.push_back(I); |
I.Clear(); |
////std::cout << "pushing code at position " << (mInstructions.size() - 1) << "\n"; |
gBranchStack.push_back(aInstructions.size() - 1); |
ResetTempRegisterIndex(); |
} |
|
//------------------------------------------------------------- |
// Prototype for the yylex function |
static int yylex(Theia::Parser::semantic_type * yylval, |
Theia::Parser::location_type * yylloc, |
Theia::Scanner &scanner); |
} |
|
%token AUTO RETURN FUNCTION JMP EXIT EQUAL NOT_EQUAL GREATER_THAN LESS_THAN LESS_OR_EQUAL_THAN GREATER_OR_EQUAL_THAN IF ELSE OPEN_ROUND_BRACE CLOSE_ROUND_BRACE OPEN_BRACE CLOSE_BRACE ASSIGN DIV MUL ADD DECCONST HEXCONST BINCONST EOS DOT MINUS TK_X TK_Y TK_Z TK_N REG |
%token IDENTIFIER SQRT SCALE UNSCALE USING FIXED_POINT COMMA OPEN_SQUARE_BRACE CLOSE_SQUARE_BRACE WHILE ADD_EQ THREAD START BITWISE_AND BITWISE_OR OUT |
%% |
|
statement_list: //empty |
| |
statement_list statement |
| |
statement |
; |
|
statement |
: |
AUTO auto_var_list EOS |
| |
USING FIXED_POINT EOS |
{ |
mGenerateFixedPointArithmetic = true; |
} |
| |
EXIT EOS |
{ |
//Insert a stupid NOP before the exit... is a bug but easier to just patch like this... |
|
I.Clear(); |
I.mComment = "NOP"; |
I.SetCode( EOPERATION_NOP ); |
mInstructions.push_back(I); |
I.Clear(); |
|
I.SetEofFlag(true); |
I.mComment = "Set the Exit bit"; |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
| |
RETURN expression EOS |
{ |
|
////////////////////////////////////////////////////////////////////////////// |
// This means this that the expression was just a constant. |
// No operations were inserted |
////////////////////////////////////////////////////////////////////////////// |
if (gInsertedInstructions == 0) |
{ |
I.Clear(); |
I.SetCode(EOPERATION_ADD); |
I.mComment ="Set the return value"; |
if ($3.find("R") != std::string::npos) |
{ |
PopulateInstruction( "R1", $2,"R0 . X X X",I,yylloc); |
} |
else |
{ |
unsigned int ImmediateValue = 0; |
std::string StringHex = $3; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
PopulateInstruction( "R1", $3,"NULL",I, yylloc, true, ImmediateValue); |
} |
mInstructions.push_back(I); |
I.Clear(); |
} else { |
|
mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc); |
gInsertedInstructions = 0; |
mInstructions.back().mComment ="Assigning return value"; |
mInstructions.back().SetDestinationAddress( RETURN_VALUE_REGISTER ); |
|
} |
ResetTempRegisterIndex(); |
|
I.SetCode( EOPERATION_ADD ); |
I.mComment = "Restore previous function frame offset"; |
I.ClearWriteChannel(); |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetSrc1Address(SPR_CONTROL_REGISTER); |
I.SetSrc1SwizzleX(SWX_Y); |
I.SetSrc1SwizzleY(SWY_Y); |
I.SetSrc1SwizzleZ(SWZ_Y); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
mInstructions.push_back( I ); |
I.Clear(); |
|
//Now return |
I.SetImm( 0 ); |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "return from function"; |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
I.SetDestinationAddress( RETURN_ADDRESS_REGISTER ); |
mInstructions.push_back(I); |
I.Clear(); |
|
|
|
} |
| |
RETURN EOS |
{ |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "Restore previous function frame offset"; |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetSrc1Address(SPR_CONTROL_REGISTER); |
I.SetSrc1SwizzleX(SWX_Y); |
I.SetSrc1SwizzleY(SWY_Y); |
I.SetSrc1SwizzleZ(SWZ_Y); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
mInstructions.push_back( I ); |
I.Clear(); |
|
I.SetImm( 0 ); |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "return from function"; |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
I.SetDestinationAddress( RETURN_ADDRESS_REGISTER ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
|
| |
left_hand_side ADD_EQ constant EOS |
{ |
|
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetCode( EOPERATION_ADD ); |
SetDestinationFromRegister( $1, I , true); |
unsigned int ImmediateValue; |
std::string StringHex = $3; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( false ); |
|
mInstructions.push_back( I ); |
I.Clear(); |
} |
| |
left_hand_side MINUS MINUS EOS |
{ |
|
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetCode( EOPERATION_ADD ); |
SetDestinationFromRegister( $1, I, false ); |
I.SetSrc0SignX( true ); |
I.SetSrc0SignY( true ); |
I.SetSrc0SignZ( true ); |
std::string Destination = $1; |
if (Destination.find("OFFSET") != std::string::npos) |
{ |
I.SetSrc1Displace( true ); |
Destination.erase(Destination.find("OFFSET")); |
} |
|
if (Destination.find(".") != std::string::npos) |
Destination.erase(Destination.find(".")); |
|
|
I.SetSrc1Address(atoi(Destination.c_str()+1)); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_Y); |
I.SetSrc0SwizzleY(SWY_Y); |
I.SetSrc0SwizzleZ(SWZ_Y); |
mInstructions.push_back( I ); |
I.Clear(); |
} |
| |
left_hand_side ADD ADD EOS |
{ |
|
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetCode( EOPERATION_ADD ); |
SetDestinationFromRegister( $1, I, false ); |
std::string Destination = $1; |
if (Destination.find("OFFSET") != std::string::npos) |
{ |
I.SetSrc1Displace( true ); |
Destination.erase(Destination.find("OFFSET")); |
} |
|
if (Destination.find(".") != std::string::npos) |
Destination.erase(Destination.find(".")); |
|
I.SetSrc1Address(atoi(Destination.c_str()+1)); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_Y); |
I.SetSrc0SwizzleY(SWY_Y); |
I.SetSrc0SwizzleZ(SWZ_Y); |
mInstructions.push_back( I ); |
I.Clear(); |
} |
| |
left_hand_side ASSIGN expression EOS |
{ |
|
////////////////////////////////////////////////////////////////////////////// |
// This means this that the expression will write into the output memory |
// constant index |
////////////////////////////////////////////////////////////////////////////// |
|
if ($1.find("OUT") != std::string::npos && $1.find("INDEX") == std::string::npos ) |
{ |
//PopulateInstruction( "R0", "R0 . X X X",$3,I,yylloc); |
|
I.SetCode(EOPERATION_OUT); |
$1.erase($1.find("OUT"),3); |
|
unsigned int ImmediateValue; |
std::stringstream ss; |
ss << std::hex << $1; |
ss >> ImmediateValue; |
PopulateInstruction( $3, "R0 OFFSET", "R0 OFFSET", I, yylloc, true, ImmediateValue ); |
#ifdef DEBUG |
I.PrintFields(); |
#endif |
mInstructions.push_back(I); |
I.Clear(); |
ResetTempRegisterIndex(); |
goto LABEL_EXPRESSION_DONE; |
} |
////////////////////////////////////////////////////////////////////////////// |
// This means this that the expression will write into the output memory |
// variable index |
////////////////////////////////////////////////////////////////////////////// |
|
if ($1.find("OUT") != std::string::npos && $1.find("INDEX") != std::string::npos ) |
{ |
std::string Destination = $1; |
DCOUT << "!!!!!!!!!!!!!!!!!Destination " << Destination << "\n"; |
std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5); |
Destination.erase(Destination.find("INDEX")); |
|
|
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
|
PopulateSourceRegisters( IndexRegister + " OFFSET ", $3, I, mInstructions ); |
|
|
//I.SetImm( 0 ); |
I.SetCode( EOPERATION_OUT ); |
std::string Source0 = $3; |
DCOUT << "!!!!!!!!!!!!!!!!!Source0 '" << Source0 << "'\n"; |
/* if (Source0.find("OFFSET") != std::string::npos) |
{ |
Source0.erase(Source0.find("OFFSET")); |
I.SetSrc0Displace(1); |
} |
I.SetSrc1Address(atoi(IndexRegister.c_str()+1)); |
I.SetSrc0Address(atoi(Source0.c_str()+1));*/ |
|
/* if (Destination.find(".") != std::string::npos) |
{ |
I.ClearWriteChannel(); |
if (Destination.find("x") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_X); |
if (Destination.find("y") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Y); |
if (Destination.find("z") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Z); |
|
Destination.erase(Destination.find(".")); |
|
} |
|
std::string Source0 = $3; |
if (Source0.find("OFFSET") != std::string::npos) |
{ |
Source0.erase(Source0.find("OFFSET")); |
I.SetSrc0Displace(1); |
} |
I.SetSrc1Address(atoi(IndexRegister.c_str()+1)); |
I.SetSrc0Address(atoi(Source0.c_str()+1)); |
|
|
// I.SetSrc0Address(mInstructions.back().GetDestinationAddress()); |
I.SetDestZero(0); |
I.SetSrc1Displace(1); |
I.SetSrc0Displace(1); |
I.SetDestinationAddress( atoi(Destination.c_str()+1) );*/ |
mInstructions.push_back( I ); |
I.Clear(); |
ResetTempRegisterIndex(); |
goto LABEL_EXPRESSION_DONE; |
} |
////////////////////////////////////////////////////////////////////////////// |
// This means this that the expression was just a constant. |
// No operations were inserted |
////////////////////////////////////////////////////////////////////////////// |
if (gInsertedInstructions == 0) |
{ |
|
I.Clear(); |
|
I.SetCode(EOPERATION_ADD); |
I.mSourceLine = GetCurrentLineNumber(yylloc); |
if ($3.find("R") != std::string::npos) |
{ |
// case 1: |
// foo = 0; //$$ = R0 . X X X |
/* SetDestinationFromRegister( $1, I, false ); |
PopulateSourceRegisters( $3, "R0 . X X X", I, mInstructions);*/ |
|
PopulateInstruction( $1, "R0 . X X X",$3,I,yylloc); |
|
} else { |
// case 2: |
// foo = 0xcafe; //$$ = 0xcafe |
SetDestinationFromRegister( $1, I, true ); |
unsigned int ImmediateValue = 0; |
std::string StringHex = $3; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
PopulateInstruction( $1, $3,"NULL",I, yylloc, true, ImmediateValue); |
} |
std::string strConstant = $3; |
|
mInstructions.push_back(I); |
I.Clear(); |
ResetTempRegisterIndex(); |
goto LABEL_EXPRESSION_DONE; |
} |
|
////////////////////////////////////////////////////////////////////////////// |
// This means that the last instruction which was inserted was a tripple |
// constant assignement, like foo = (1,2,3) |
////////////////////////////////////////////////////////////////////////////// |
if (mInstructions.back().mBisonFlagTrippleConstAssign) |
{ |
unsigned int LastIndex = mInstructions.size() - 1; |
mInstructions[LastIndex].SetDestinationAddress(atoi($1.c_str()+1)); |
mInstructions[LastIndex-1].SetDestinationAddress(atoi($1.c_str()+1)); |
mInstructions[LastIndex-2].SetDestinationAddress(atoi($1.c_str()+1)); |
mInstructions[LastIndex-2].mSourceLine = GetCurrentLineNumber( yylloc ); |
if($1.find("OFFSET") == std::string::npos) |
{ |
mInstructions[LastIndex].SetAddressingMode(true,false,false); |
mInstructions[LastIndex-1].SetAddressingMode(true,false,false); |
mInstructions[LastIndex-2].SetAddressingMode(true,false,false); |
} |
|
ResetTempRegisterIndex(); |
goto LABEL_EXPRESSION_DONE; |
} |
////////////////////////////////////////////////////////////////////////////// |
// Handle the case where the destination is an array of vector |
// ej: R = v1[ i ] + V2 |
////////////////////////////////////////////////////////////////////////////// |
if (I.GetOperation() == 0 && $3.find("array_element") != std::string::npos) |
{ |
//No operation meaning the the expression only has a single variable |
//See if the expression returned is an array_element |
if ($3.find("array_element") != std::string::npos) |
{ |
////std::cout << "expression is an array element\n\n"; |
std::string Index = $3.substr($3.find("array_element")); |
Index = Index.substr(Index.find_first_not_of("array_element R")); |
SetIndexRegister( atoi(Index.c_str()), mInstructions ); |
$3.erase($3.find("array_element")); |
SetExpressionDestination( $1, I ); |
I.SetCode(EOPERATION_ADD); |
I.SetImmBit( true ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( true ); |
I.SetSrc0Displace( false ); |
I.mSourceLine = GetCurrentLineNumber(yylloc); |
|
if ($3.find("OFFSET") != std::string::npos) |
$3.erase($3.find("OFFSET")); |
|
I.SetSrc1Address(atoi($3.c_str()+1)); |
I.SetSrc0Address(0); |
mInstructions.push_back(I); |
I.Clear(); |
} |
} |
else |
{ |
|
mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc); |
gInsertedInstructions = 0; |
std::string Destination = $1; |
//std::cout << "DST " << Destination << " \n"; |
//Look for indirect addressing |
if (Destination.find("INDEX") != std::string::npos) |
{ |
|
std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5); |
|
Destination.erase(Destination.find("INDEX")); |
|
I.SetImm( 0 ); |
I.SetCode( EOPERATION_ADD ); |
|
if (Destination.find(".") != std::string::npos) |
{ |
I.ClearWriteChannel(); |
if (Destination.find("x") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_X); |
if (Destination.find("y") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Y); |
if (Destination.find("z") != std::string::npos) |
I.SetWriteChannel(ECHANNEL_Z); |
|
Destination.erase(Destination.find(".")); |
|
} |
|
std::string Source0 = $3; |
if (Source0.find("OFFSET") != std::string::npos) |
{ |
Source0.erase(Source0.find("OFFSET")); |
I.SetSrc0Displace(1); |
} |
I.SetSrc1Address(atoi(IndexRegister.c_str()+1)); |
I.SetSrc0Address(atoi(Source0.c_str()+1)); |
|
|
// I.SetSrc0Address(mInstructions.back().GetDestinationAddress()); |
I.SetDestZero(0); |
I.SetSrc1Displace(1); |
I.SetSrc0Displace(1); |
I.SetDestinationAddress( atoi(Destination.c_str()+1) ); |
mInstructions.push_back( I ); |
I.Clear(); |
} else { |
|
if (mInstructions.back().GetImm()) |
{ |
//Look for displament addressing mode |
unsigned int AddressingMode = mInstructions.back().GetAddressingMode(); |
if (Destination.find("OFFSET") != std::string::npos) |
{ |
//This means AddressMode is '101', so leave the way it is |
mInstructions.back().ClearWriteChannel(); |
mInstructions.back().SetWriteChannel(ECHANNEL_Z); |
Destination.erase(Destination.find("OFFSET")); |
} else { |
//This is not supposed to have index, so change addressing mode to '100' |
|
mInstructions.back().SetDestZero( true ); |
mInstructions.back().SetSrc1Displace( false ); |
mInstructions.back().SetSrc0Displace( false ); |
mInstructions.back().ClearWriteChannel(); |
mInstructions.back().SetWriteChannel(ECHANNEL_Z); |
} |
|
} else { |
mInstructions.back().SetDestZero( false ); //First assume no offset was used |
|
|
|
//Look for displament addressing mode |
if (Destination.find("OFFSET") != std::string::npos) |
{ |
Destination.erase(Destination.find("OFFSET")); |
mInstructions.back().SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset |
} |
} |
if (Destination.find(".") != std::string::npos) |
{ |
mInstructions.back().ClearWriteChannel(); |
if (Destination.find("x") != std::string::npos) |
mInstructions.back().SetWriteChannel(ECHANNEL_X); |
if (Destination.find("y") != std::string::npos) |
mInstructions.back().SetWriteChannel(ECHANNEL_Y); |
if (Destination.find("z") != std::string::npos) |
mInstructions.back().SetWriteChannel(ECHANNEL_Z); |
|
Destination.erase(Destination.find(".")); |
|
} |
mInstructions.back().SetDestinationAddress( atoi($1.c_str()+1) ); |
for (int i = 1; i <= gExtraDestModifications; i++ ) |
{ |
int idx = (mInstructions.size()-1)-i; |
mInstructions[idx].SetDestinationAddress( atoi($1.c_str()+1) ); |
if (mInstructions[idx].GetImm()) |
{ |
|
//This is not supposed to have index, so change addressing mode to '100' |
mInstructions[idx].SetDestZero( true ); |
mInstructions[idx].SetSrc1Displace( false ); |
mInstructions[idx].SetSrc0Displace( false ); |
|
|
} |
|
} |
gExtraDestModifications = 0; |
|
|
|
} |
ResetTempRegisterIndex(); |
} |
|
LABEL_EXPRESSION_DONE: |
gInsertedInstructions = 0; |
while(0); |
|
} |
| |
WHILE { /*Middle rule here, get me the loop address*/ ;gWhileLoopAddress = (mInstructions.size());}OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE OPEN_BRACE statement_list CLOSE_BRACE |
{ |
mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()+1); |
gBranchStack.pop_back(); |
//Now I need to put a GOTO so that the while gets evaluated again... |
//jump out of the if |
I.Clear(); |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "while loop goto re-eval boolean"; |
I.SetDestinationAddress( gWhileLoopAddress ); |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
mInstructions.push_back(I); |
I.Clear(); |
|
} |
| IF |
OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE |
OPEN_BRACE statement_list CLOSE_BRACE |
ELSE |
{ |
|
//jump out of the if |
I.Clear(); |
I.SetCode( EOPERATION_ADD ); |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
mInstructions.push_back(I); |
I.Clear(); |
//Take care of the destination addr of the if statement. |
mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()); |
gBranchStack.pop_back(); |
//push the inconditional jump into the stack |
gBranchStack.push_back(mInstructions.size() - 1); |
////std::cout << "else\n"; |
|
} |
OPEN_BRACE statement_list CLOSE_BRACE |
{ |
|
mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()); |
gBranchStack.pop_back(); |
//Now push the JMP |
|
////std::cout << "END elseif\n"; |
} |
| |
//NOW the if statement |
IF OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE OPEN_BRACE statement_list CLOSE_BRACE |
{ |
mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()); |
//mInstructions[gBranchStack.back()].mSourceLine = GetCurrentLineNumber(yylloc); |
|
gBranchStack.pop_back(); |
////std::cout << "if closing at " << mInstructions.size() << "\n"; |
|
} |
| |
FUNCTION IDENTIFIER OPEN_ROUND_BRACE function_argument_list CLOSE_ROUND_BRACE |
{ |
////std::cout << "Function declaration for " << $2 << " at " << mInstructions.size() << "\n" ; |
mSymbolMap[ $2 ] = mInstructions.size(); |
} OPEN_BRACE statement_list CLOSE_BRACE |
{ |
//Clear the auto var index now that we leave the function scope |
ClearAutoVarMap(); |
ClearFunctionParameterMap(); |
|
//Now uddate the current SPR_CONTROL_REGISTER.x = SPR_CONTROL_REGISTER.y |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "Restore previous function frame offset"; |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetSrc1Address(SPR_CONTROL_REGISTER); |
I.SetSrc1SwizzleX(SWX_Y); |
I.SetSrc1SwizzleY(SWY_Y); |
I.SetSrc1SwizzleZ(SWZ_Y); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
|
mInstructions.push_back( I ); |
I.Clear(); |
} |
| |
//Thread declaration |
THREAD IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE |
{ |
gThreadMap[ $2 ] = mInstructions.size(); |
gThreadScope = true; |
} |
OPEN_BRACE statement_list CLOSE_BRACE |
{ |
////std::cout << "Defining thread" << "\n"; |
gThreadScope = false; |
ClearAutoVarMap(); |
//Since the thread is done, then disable threading |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "Disable multi-threading"; |
I.SetDestinationAddress( SPR_CONTROL_REGISTER0 ); |
unsigned int Value = 0; |
I.SetImm( Value ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_Z); |
mInstructions.push_back( I ); |
I.Clear(); |
|
} |
| |
START IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE EOS |
{ |
unsigned int ThreadCodeOffset = 0; |
////std::cout << "Starting thread" << "\n"; |
if (gThreadMap.find($2) == gThreadMap.end()) |
{ |
|
std::ostringstream ret; |
ret << "Undefined thread '" << $2 << "' at line " << yylloc << " \n"; |
ret << "Current version of the compiler needs thread defintion prior of thread instantiation\n"; |
throw ret.str(); |
} else { |
ThreadCodeOffset = gThreadMap[$2]; |
//Now enable the multithreading and set instruction offset |
I.SetCode( EOPERATION_ADD ); |
std::ostringstream ss; |
ss << "Set thread instruction offset to 8'd" << ThreadCodeOffset; |
I.mComment = ss.str(); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER0 ); |
unsigned int Value = (ThreadCodeOffset << 1); |
I.SetImm( Value ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_Z); |
mInstructions.push_back( I ); |
I.Clear(); |
|
|
I.SetCode( EOPERATION_ADD ); |
I.mComment = "Enable multi-threading"; |
I.SetDestinationAddress( SPR_CONTROL_REGISTER0 ); |
Value = (ThreadCodeOffset << 1 | 1); |
I.SetImm( Value ); |
I.SetDestZero( true ); |
I.SetWriteChannel(ECHANNEL_Z); |
mInstructions.push_back( I ); |
I.Clear(); |
|
} |
|
} |
| |
left_hand_side ASSIGN IDENTIFIER OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS |
{ |
////std::cout << "Function call returning to var\n"; |
StoreReturnAddress( mInstructions, yylloc ); |
SavePreviousFramePointer( mInstructions ); |
UpdateFramePointer( mInstructions ); |
CallFunction( $3, mInstructions, mSymbolMap ); |
|
|
//Return value comes in R1, so let's store this in our variable |
I.SetCode( EOPERATION_ADD ); |
SetDestinationFromRegister( $1, I, false ); |
I.mComment = "grab the return value from the function"; |
I.SetSrc1Address( RETURN_VALUE_REGISTER); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
mInstructions.push_back( I ); |
I.Clear(); |
ClearNextFunctionParamRegister(); |
} |
| |
//Function call |
IDENTIFIER OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS |
{ |
|
//Store the return address |
StoreReturnAddress( mInstructions, yylloc ); |
|
|
//Store the current SPR_CONTROL_REGISTER.x into the previous SPR_CONTROL_REGISTER.y |
//SPR_CONTROL_REGISTER.y = SPR_CONTROL_REGISTER.xxx + 0; |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "store current frame offset"; |
I.SetWriteChannel(ECHANNEL_Y); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetSrc1Address(SPR_CONTROL_REGISTER); |
I.SetSrc1SwizzleX(SWX_X); |
I.SetSrc1SwizzleY(SWY_X); |
I.SetSrc1SwizzleZ(SWZ_X); |
I.SetSrc0Address(0); |
I.SetSrc0SwizzleX(SWX_X); |
I.SetSrc0SwizzleY(SWY_X); |
I.SetSrc0SwizzleZ(SWZ_X); |
mInstructions.push_back( I ); |
I.Clear(); |
//Now uddate the current SPR_CONTROL_REGISTER.x += number of auto variables |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "displace next frame offset by the number of auto variables in current frame"; |
I.SetWriteChannel(ECHANNEL_X); |
I.SetDestinationAddress( SPR_CONTROL_REGISTER ); |
I.SetImm( GetCurretAutoVarFrameSize() ); |
I.SetDestZero( false ); |
mInstructions.push_back( I ); |
I.Clear(); |
//Call the function with a JMP |
I.SetCode( EOPERATION_ADD ); |
I.mComment = "call the function"; |
I.SetBranchFlag( true ); |
I.SetBranchType( EBRANCH_ALWAYS ); |
//Now do the branch |
if (mSymbolMap.find($1) == mSymbolMap.end()) |
{ |
// ////std::cout << "Error in line : " << $1 <<" undelcared IDENTIFIER\n"; |
I.SetDestinationSymbol( "@"+$1 ); |
// exit(1); |
} else { |
I.SetDestinationAddress( mSymbolMap[ $1 ] ); |
} |
|
|
mInstructions.push_back( I ); |
I.Clear(); |
|
} |
; |
|
|
|
function_input_list |
: |
|//empty |
expression COMMA function_input_list |
{ |
AddFunctionInputList( $1, mInstructions,yylloc ); |
} |
| |
expression |
{ |
AddFunctionInputList( $1,mInstructions, yylloc ); |
} |
; |
|
function_argument_list |
: |
| //empty |
IDENTIFIER COMMA function_argument_list |
{ |
AddFunctionParameter( $1, yylloc ); |
} |
| |
IDENTIFIER |
{ |
AddFunctionParameter( $1, yylloc ); |
} |
; |
|
// <Exp> ::= <Exp> + <Term> | |
// <Exp> - <Term> | |
// <Term> |
|
// <Term> ::= <Term> * <Factor> | |
// <Term> / <Factor> | |
// <Factor> |
|
// <Factor> ::= x | y | ... | |
// ( <Exp> ) | |
// - <Factor> | |
// <Number> |
|
expression |
: |
expression ADD term |
{ |
unsigned int TempRegIndex = GetFreeTempRegister(); |
gExtraDestModifications = 0; |
|
I.SetCode( EOPERATION_ADD ); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
|
PopulateSourceRegisters( $1, $3, I, mInstructions ); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
$$ = ss.str(); |
|
} |
| |
expression MINUS term |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetCode( EOPERATION_ADD ); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetSrc0SignX( true ); |
I.SetSrc0SignY( true ); |
I.SetSrc0SignZ( true ); |
|
PopulateSourceRegisters( $1, $3, I, mInstructions); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
$$ = ss.str(); |
} |
| |
expression BITWISE_OR term |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetCode( EOPERATION_LOGIC ); |
I.SetLogicOperation( ELOGIC_OR ); |
PopulateSourceRegisters( $1, $3, I, mInstructions); |
|
|
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
$$ = ss.str(); |
} |
| |
term |
{ |
$$ = $1; |
} |
; |
|
term |
: |
term MUL factor |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetCode( EOPERATION_MUL ); |
|
PopulateSourceRegisters( $1, $3, I, mInstructions); |
|
//If we are using fixed point aritmethic then we need to apply the scale |
//R = A * ( B >> SCALE) |
if (mGenerateFixedPointArithmetic) |
I.SetSrc0Rotation( EROT_RESULT_RIGHT ); |
|
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
$$ = ss.str(); |
} |
| |
term DIV factor |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetCode( EOPERATION_DIV ); |
|
PopulateSourceRegisters( $1, $3, I, mInstructions); |
|
//If we are using fixed point aritmethic then we need to apply the scale |
// R = (A << N) / B |
if (mGenerateFixedPointArithmetic) |
I.SetSrc1Rotation( EROT_SRC1_LEFT ); |
|
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
$$ = ss.str(); |
} |
| |
term BITWISE_AND factor |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetCode( EOPERATION_LOGIC ); |
I.SetLogicOperation( ELOGIC_AND ); |
PopulateSourceRegisters( $1, $3, I, mInstructions); |
|
|
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
$$ = ss.str(); |
} |
| |
factor |
{ |
$$ = $1; |
} |
; |
|
factor |
: |
source |
{ |
$$ = $1; |
} |
| |
SQRT OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE |
{ |
gExtraDestModifications = 0; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetDestZero( true ); //Use indexing for DST |
I.SetWriteChannel(ECHANNEL_XYZ); |
I.SetCode( EOPERATION_SQRT ); |
I.SetSrc0Address( 0 ); |
PopulateSourceRegisters( $3 ,"R0 . X X X", I, mInstructions); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
|
std::stringstream ss; |
ss << "R" << TempRegIndex << " OFFSET "; |
$$ = ss.str(); |
} |
| |
OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE |
{ |
$$ = $2; |
} |
; |
|
|
|
source |
: |
constant |
{ |
|
unsigned int ImmediateValue; |
std::string StringHex = $1; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
switch (ImmediateValue) |
{ |
case 0: |
$$ = "R0 . X X X"; |
break; |
case 1: |
$$ = "R0 . Y Y Y"; |
break; |
case 2: |
$$ = "R0 . Z Z Z"; |
break; |
default: |
std::string StringHex = $1; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
$$ = ss.str(); |
break; |
} |
} |
| |
OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE |
{ |
unsigned int TempRegIndex = GetFreeTempRegister(); |
unsigned int ImmediateValue; |
|
{ |
|
std::string StringHex = $2; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
|
I.SetDestinationAddress( TempRegIndex ); |
I.SetImm( ImmediateValue ); |
I.SetDestZero(true); |
I.SetSrc0Displace(true); |
I.SetWriteChannel(ECHANNEL_X); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
} |
|
{ |
std::string StringHex = $4; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
I.SetDestinationAddress( TempRegIndex ); |
I.SetImm( ImmediateValue ); |
I.SetDestZero(true); |
I.SetSrc0Displace(true); |
I.SetWriteChannel(ECHANNEL_Y); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
} |
|
{ |
std::string StringHex = $6; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
I.SetDestinationAddress( TempRegIndex ); |
I.SetImm( ImmediateValue ); |
I.SetDestZero(true); |
I.SetSrc0Displace(true); |
I.SetWriteChannel(ECHANNEL_Z); |
I.SetCode( EOPERATION_ADD ); |
I.mBisonFlagTrippleConstAssign = true; |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
} |
|
gExtraDestModifications = 2; |
std::stringstream ss2; |
ss2 << "R" << TempRegIndex << " OFFSET "; |
$$ = ss2.str(); |
} |
| |
IDENTIFIER array_index |
{ |
|
|
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL") |
$$ = Register; |
else |
$$ = GetRegisterFromAutoVar( $1, yylloc) + " OFFSET "; |
|
if ($2 != "NULL") |
{ |
|
$$ += " array_element " + $2; |
|
} |
} |
| |
IDENTIFIER DOT coordinate coordinate coordinate |
{ |
|
std::string X = $3,Y = $4,Z = $5; |
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL") |
$$ = (Register + " . " + " " + X + " " + Y + " " + Z + " OFFSET "); |
else |
$$ = (GetRegisterFromAutoVar( $1, yylloc) + " . " + " " + X + " " + Y + " " + Z + " OFFSET "); |
} |
| |
REG |
{ |
|
std::string R = $1; |
R.erase(0,1); |
$$ = "R" + R; |
|
} |
| |
SCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE |
{ |
|
std::string R = $1; |
R.erase(0,1); |
$$ = "<<R" + R; |
} |
| |
UNSCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE |
{ |
|
std::string R = $1; |
R.erase(0,1); |
$$ = ">>R" + R; |
} |
| |
REG DOT coordinate coordinate coordinate |
{ |
std::string R = $1; |
std::string X = $3,Y = $4,Z = $5; |
R.erase(0,1); |
$$ = "R" + R + " . " + " " + X + " " + Y + " " + Z; |
|
} |
; |
|
|
coordinate |
: |
TK_X |
{ |
$$ = "X"; |
} |
| |
MINUS TK_X |
{ |
$$ = "-X"; |
} |
| |
TK_Y |
{ |
$$ = "Y"; |
} |
| |
MINUS TK_Y |
{ |
$$ = "-Y"; |
} |
| |
TK_Z |
{ |
$$ = "Z"; |
} |
| |
MINUS TK_Z |
{ |
$$ = "-Z"; |
} |
; |
|
|
array_index |
: |
{ |
$$ = "NULL"; |
} |
| |
OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE |
{ |
/*std::string Register; |
if ((Register = GetRegisterFromFunctionParameter($2)) != "NULL") |
$$ = Register; |
else*/ |
//Indexes into arrays can only be auto variables! |
$$ = GetRegisterFromAutoVar( $2, yylloc ); |
} |
; |
|
left_hand_side |
: |
OUT OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE |
{ |
|
$$ = "OUT " + $3; |
} |
| |
OUT OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE |
{ |
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter($3)) == "NULL") |
Register = GetRegisterFromAutoVar( $3, yylloc ); |
|
$$ = "OUT INDEX" + Register; |
} |
| |
IDENTIFIER array_index |
{ |
|
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL") |
$$ = Register + ".xyz"; |
else |
$$ = GetRegisterFromAutoVar( $1, yylloc ) + ".xyz" + " OFFSET " + (($2 != "NULL")?" INDEX"+$2:""); |
|
} |
| |
IDENTIFIER DOT TK_X |
{ |
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL") |
$$ = Register + ".x"; |
else |
$$ = GetRegisterFromAutoVar( $1, yylloc ) + ".x" + " OFFSET "; |
} |
| |
IDENTIFIER DOT TK_Y |
{ |
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL") |
$$ = Register + ".y"; |
else |
$$ = GetRegisterFromAutoVar( $1, yylloc ) + ".y" + " OFFSET "; |
} |
| |
IDENTIFIER DOT TK_Z |
{ |
std::string Register; |
if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL") |
$$ = Register + ".z"; |
else |
$$ = GetRegisterFromAutoVar( $1, yylloc ) + ".z" + " OFFSET "; |
} |
| |
REG |
{ |
std::string R = $1; |
R.erase(0,1); |
$$ = "R" + R + ".xyz"; |
} |
| |
REG DOT TK_X |
{ |
std::string R = $1; |
R.erase(0,1); |
$$ = "R" + R + ".x"; |
} |
| |
REG DOT TK_Y |
{ |
std::string R = $1; |
R.erase(0,1); |
$$ = "R" + R + ".y"; |
} |
| |
REG DOT TK_Z |
{ |
|
std::string R = $1; |
R.erase(0,1); |
$$ = "R" + R + ".z"; |
} |
| |
REG DOT TK_X TK_Y TK_N |
{ |
std::string R = $1; |
R.erase(0,1); |
$$ = "R" + R + ".xy"; |
} |
| |
REG DOT TK_X TK_N TK_Z |
{ |
std::string R = $1; |
R.erase(0,1); |
$$ = "R" + R + ".xz"; |
} |
| |
REG DOT TK_N TK_Y TK_Z |
{ |
std::string R = $1; |
R.erase(0,1); |
$$ = "R" + R + ".yz"; |
} |
; |
|
|
boolean_expression |
: |
expression NOT_EQUAL expression |
{ |
PopulateBoolean(EBRANCH_IF_ZERO, $1, $3, I, mInstructions, yylloc ); |
|
} |
| |
expression EQUAL expression |
{ |
PopulateBoolean(EBRANCH_IF_NOT_ZERO, $1, $3, I, mInstructions, yylloc ); |
|
} |
| |
expression GREATER_THAN expression |
{ |
PopulateBoolean(EBRANCH_IF_ZERO_OR_SIGN, $1, $3, I, mInstructions, yylloc ); |
|
} |
|
| |
expression LESS_THAN expression |
{ |
PopulateBoolean(EBRANCH_IF_ZERO_OR_NOT_SIGN, $1, $3, I, mInstructions, yylloc ); |
|
} |
| |
expression LESS_OR_EQUAL_THAN expression |
{ |
PopulateBoolean(EBRANCH_IF_NOT_SIGN, $1, $3, I, mInstructions, yylloc ); |
|
} |
| |
expression GREATER_OR_EQUAL_THAN expression |
{ |
PopulateBoolean(EBRANCH_IF_SIGN, $1, $3, I, mInstructions, yylloc ); |
|
} |
; |
|
constant |
: |
DECCONST |
{ |
// Transform to HEX string |
unsigned int Val; |
std::string StringDec = $1; |
std::stringstream ss; |
ss << StringDec; |
ss >> Val; |
std::stringstream ss2; |
ss2 << std::hex << Val; |
$$ = ss2.str(); |
} |
| |
HEXCONST |
{ |
std::string StringHex = $1; |
// Get rid of the 0x |
StringHex.erase(StringHex.begin(),StringHex.begin()+2); |
std::stringstream ss; |
ss << std::hex << StringHex; |
|
$$ = ss.str(); |
} |
| |
BINCONST |
{ |
// Transform to HEX string |
std::string StringBin = $1; |
// Get rid of the 0b |
StringBin.erase(StringBin.begin(),StringBin.begin()+2); |
std::bitset<32> Bitset( StringBin ); |
std::stringstream ss2; |
ss2 << std::hex << Bitset.to_ulong(); |
$$ = ss2.str(); |
} |
; |
auto_var_list |
: |
IDENTIFIER array_size COMMA auto_var_list |
{ |
if (gAutoVarMap.find($1) != gAutoVarMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol '" << $1 << "'\n"; |
throw ret.str(); |
} |
|
std::stringstream ss; |
ss << $2; |
unsigned int Size; |
ss >> Size; |
gAutoVarMap[ $1 ] = AllocAutoVar(Size); |
} |
| |
IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE COMMA auto_var_list |
{ |
if (gAutoVarMap.find($1) != gAutoVarMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol " << $1 << "'\n"; |
throw ret.str(); |
} |
gAutoVarMap[ $1 ] = AllocAutoVar(); |
|
unsigned int Destination = gAutoVarMap[ $1 ]; |
|
|
|
I.ClearWriteChannel(); |
unsigned int ImmediateValue; |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_X); |
std::string StringHex = $4; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_Y); |
std::string StringHex = $6; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_Z); |
std::string StringHex = $8; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
} |
| |
IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE |
{ |
if (gAutoVarMap.find($1) != gAutoVarMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol " << $1 << "'\n"; |
throw ret.str(); |
} |
gAutoVarMap[ $1 ] = AllocAutoVar(); |
|
unsigned int Destination = gAutoVarMap[ $1 ]; |
|
|
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
|
|
I.ClearWriteChannel(); |
unsigned int ImmediateValue; |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_X); |
std::string StringHex = $4; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_Y); |
std::string StringHex = $6; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
{ |
I.SetDestinationAddress( Destination ); |
I.SetWriteChannel(ECHANNEL_Z); |
std::string StringHex = $8; |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
I.SetImm( ImmediateValue ); |
I.SetDestZero( true ); |
I.SetSrc1Displace( false ); |
I.SetSrc0Displace( true ); |
I.SetCode( EOPERATION_ADD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
} |
| |
IDENTIFIER array_size |
{ |
|
if (gAutoVarMap.find($1) != gAutoVarMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol " << $1 << "'\n"; |
throw ret.str(); |
} |
std::stringstream ss; |
ss << std::hex << $2; |
unsigned int Size; |
ss >> Size; |
////std::cout << "Array Size is " << Size << " " << $2 << "\n"; |
gAutoVarMap[ $1 ] = AllocAutoVar(Size); |
} |
; |
|
array_size |
: |
{ |
$$ = "1"; |
} |
| |
OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE |
{ |
|
$$ = $2; |
} |
; |
%% |
|
|
|
// Error function throws an exception (std::string) with the location and error message |
void Theia::Parser::error(const Theia::Parser::location_type &loc, |
const std::string &msg) { |
std::ostringstream ret; |
ret << "Parser Error at " << loc << ": " << msg; |
throw ret.str(); |
} |
|
// Now that we have the Parser declared, we can declare the Scanner and implement |
// the yylex function |
#include "Scanner.h" |
static int yylex(Theia::Parser::semantic_type * yylval, |
Theia::Parser::location_type * yylloc, |
Theia::Scanner &scanner) { |
return scanner.yylex(yylval, yylloc); |
} |
|
/branches/beta_2.0/compiler/src/vp_compiler/stack.hh
0,0 → 1,141
|
/* A Bison parser, made by GNU Bison 2.4.1. */ |
|
/* Stack handling for Bison parsers in C++ |
|
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software |
Foundation, Inc. |
|
This program is free software: you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation, either version 3 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
/* As a special exception, you may create a larger work that contains |
part or all of the Bison parser skeleton and distribute that work |
under terms of your choice, so long as that work isn't itself a |
parser generator using the skeleton or a modified version thereof |
as a parser skeleton. Alternatively, if you modify or redistribute |
the parser skeleton itself, you may (at your option) remove this |
special exception, which will cause the skeleton and the resulting |
Bison output files to be licensed under the GNU General Public |
License without this special exception. |
|
This special exception was added by the Free Software Foundation in |
version 2.2 of Bison. */ |
|
#ifndef BISON_STACK_HH |
# define BISON_STACK_HH |
|
#include <deque> |
|
|
/* Line 1067 of lalr1.cc */ |
#line 28 "parser.y" |
namespace Theia { |
|
/* Line 1067 of lalr1.cc */ |
#line 47 "stack.hh" |
template <class T, class S = std::deque<T> > |
class stack |
{ |
public: |
|
// Hide our reversed order. |
typedef typename S::reverse_iterator iterator; |
typedef typename S::const_reverse_iterator const_iterator; |
|
stack () : seq_ () |
{ |
} |
|
stack (unsigned int n) : seq_ (n) |
{ |
} |
|
inline |
T& |
operator [] (unsigned int i) |
{ |
return seq_[i]; |
} |
|
inline |
const T& |
operator [] (unsigned int i) const |
{ |
return seq_[i]; |
} |
|
inline |
void |
push (const T& t) |
{ |
seq_.push_front (t); |
} |
|
inline |
void |
pop (unsigned int n = 1) |
{ |
for (; n; --n) |
seq_.pop_front (); |
} |
|
inline |
unsigned int |
height () const |
{ |
return seq_.size (); |
} |
|
inline const_iterator begin () const { return seq_.rbegin (); } |
inline const_iterator end () const { return seq_.rend (); } |
|
private: |
|
S seq_; |
}; |
|
/// Present a slice of the top of a stack. |
template <class T, class S = stack<T> > |
class slice |
{ |
public: |
|
slice (const S& stack, |
unsigned int range) : stack_ (stack), |
range_ (range) |
{ |
} |
|
inline |
const T& |
operator [] (unsigned int i) const |
{ |
return stack_[range_ - i]; |
} |
|
private: |
|
const S& stack_; |
unsigned int range_; |
}; |
|
/* Line 1153 of lalr1.cc */ |
#line 28 "parser.y" |
} // Theia |
|
/* Line 1153 of lalr1.cc */ |
#line 139 "stack.hh" |
|
#endif // not BISON_STACK_HH[]dnl |
|
/branches/beta_2.0/compiler/src/vp_compiler/Main.cpp
0,0 → 1,121
/* This program is free software. It comes without any warranty, to |
* the extent permitted by applicable law. You can redistribute it |
* and/or modify it under the terms of the Do What The Fuck You Want |
* To Public License, Version 2, as published by Sam Hocevar. See |
* http://sam.zoy.org/wtfpl/COPYING for more details. */ |
|
#include "Compiler.h" |
#include "Preprocessor.h" |
#include <string> |
#include <iostream> |
#include <fstream> |
#include <cstring> |
|
Preprocessor PP; |
|
int main(int argc, char * argv[]) { |
// make sure we received a filename |
if (argc < 2) { |
std::cerr << "Usage: ./theia_compile -i [FILENAME] [-f <hex32|hex64>]" << std::endl; |
return 255; |
} |
|
|
std::cout << "---------------------------------------------------------------\n"; |
std::cout << " \n"; |
std::cout << " _/_/_/_/_/ _/ _/ \n"; |
std::cout << " _/ _/_/_/ _/_/ _/_/_/ \n"; |
std::cout << " _/ _/ _/ _/_/_/_/ _/ _/ _/ \n"; |
std::cout << " _/ _/ _/ _/ _/ _/ _/ \n"; |
std::cout << "_/ _/ _/ _/_/_/ _/ _/_/_/ \n"; |
std::cout << "\n"; |
std::cout << "\n"; |
std::cout << "---------------------------------------------------------------\n"; |
|
char * inputFile, * outputMode; |
TheiaCompiler * Compiler; |
bool OutputMode32 = false; |
bool FilePathDefined = false; |
bool StdIn = false; |
try { |
|
for (int i = 1; i < argc; i++) |
{ |
|
if (!strcmp(argv[i],"-i")) |
{ |
inputFile = argv[i+1]; |
FilePathDefined = true; |
i++; |
} |
else if (!strcmp(argv[i],"-stdin")) |
{ |
StdIn = true; |
} |
else if (!strcmp(argv[i],"-hex32")) |
{ |
OutputMode32 = true; |
|
} |
else |
{ |
std::cout << "Error: Invalid option " << argv[i] << "\n"; |
return 255; |
} |
|
|
|
} |
if (!FilePathDefined) |
{ |
std::cout << "Error: Input file not defined\n "; |
return 255; |
} |
|
if (StdIn) |
{ |
Compiler = new TheiaCompiler(std::cin); |
} else { |
PP.Execute(inputFile); |
Compiler = new TheiaCompiler( std::string(inputFile)+ ".preprocessed",OutputMode32); |
|
|
} |
/* |
// - means stdin, not a file named '-' |
if (strcmp(argv[1], "-") == 0) { |
|
Compiler = new TheiaCompiler(std::cin); |
} else { |
PP.Execute(argv[1]); |
|
Compiler = new TheiaCompiler( std::string(argv[1])+ ".preprocessed"); |
} |
*/ |
} catch (std::string error) { |
std::cerr << "ERROR: " << error << std::endl; |
return 255; |
} |
Compiler->Print(); |
|
std::ofstream ofs; |
ofs.open("code.list"); |
if (!ofs.good()) |
{ |
std::cout << "Error could not open file for write 'code.mem'\n"; |
return 0; |
} |
|
ofs << Compiler->GetHexCodeDump(); |
ofs.close(); |
ofs.open("code.mem"); |
ofs << Compiler->PostProcess("code.list"); |
ofs.close(); |
|
delete Compiler; |
std::string Command = "rm " + std::string(inputFile)+ ".preprocessed"; |
system(Command.c_str()); |
std::cout << "Code successfully compiled!\n"; |
return 0; |
} |
|
/branches/beta_2.0/compiler/src/vp_compiler/location.hh
0,0 → 1,169
|
/* A Bison parser, made by GNU Bison 2.4.1. */ |
|
/* Locations for Bison parsers in C++ |
|
Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. |
|
This program is free software: you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation, either version 3 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
/* As a special exception, you may create a larger work that contains |
part or all of the Bison parser skeleton and distribute that work |
under terms of your choice, so long as that work isn't itself a |
parser generator using the skeleton or a modified version thereof |
as a parser skeleton. Alternatively, if you modify or redistribute |
the parser skeleton itself, you may (at your option) remove this |
special exception, which will cause the skeleton and the resulting |
Bison output files to be licensed under the GNU General Public |
License without this special exception. |
|
This special exception was added by the Free Software Foundation in |
version 2.2 of Bison. */ |
|
/** |
** \file location.hh |
** Define the Theia::location class. |
*/ |
|
#ifndef BISON_LOCATION_HH |
# define BISON_LOCATION_HH |
|
# include <iostream> |
# include <string> |
# include "position.hh" |
|
|
/* Line 162 of location.cc */ |
#line 28 "parser.y" |
namespace Theia { |
|
/* Line 162 of location.cc */ |
#line 53 "location.hh" |
|
/// Abstract a location. |
class location |
{ |
public: |
|
/// Construct a location. |
location () |
: begin (), end () |
{ |
} |
|
|
/// Initialization. |
inline void initialize (std::string* fn) |
{ |
begin.initialize (fn); |
end = begin; |
} |
|
/** \name Line and Column related manipulators |
** \{ */ |
public: |
/// Reset initial location to final location. |
inline void step () |
{ |
begin = end; |
} |
|
/// Extend the current location to the COUNT next columns. |
inline void columns (unsigned int count = 1) |
{ |
end += count; |
} |
|
/// Extend the current location to the COUNT next lines. |
inline void lines (unsigned int count = 1) |
{ |
end.lines (count); |
} |
/** \} */ |
|
|
public: |
/// Beginning of the located region. |
position begin; |
/// End of the located region. |
position end; |
}; |
|
/// Join two location objects to create a location. |
inline const location operator+ (const location& begin, const location& end) |
{ |
location res = begin; |
res.end = end.end; |
return res; |
} |
|
/// Add two location objects. |
inline const location operator+ (const location& begin, unsigned int width) |
{ |
location res = begin; |
res.columns (width); |
return res; |
} |
|
/// Add and assign a location. |
inline location& operator+= (location& res, unsigned int width) |
{ |
res.columns (width); |
return res; |
} |
|
/// Compare two location objects. |
inline bool |
operator== (const location& loc1, const location& loc2) |
{ |
return loc1.begin == loc2.begin && loc1.end == loc2.end; |
} |
|
/// Compare two location objects. |
inline bool |
operator!= (const location& loc1, const location& loc2) |
{ |
return !(loc1 == loc2); |
} |
|
/** \brief Intercept output stream redirection. |
** \param ostr the destination output stream |
** \param loc a reference to the location to redirect |
** |
** Avoid duplicate information. |
*/ |
inline std::ostream& operator<< (std::ostream& ostr, const location& loc) |
{ |
position last = loc.end - 1; |
ostr << loc.begin; |
if (last.filename |
&& (!loc.begin.filename |
|| *loc.begin.filename != *last.filename)) |
ostr << '-' << last; |
else if (loc.begin.line != last.line) |
ostr << '-' << last.line << '.' << last.column; |
else if (loc.begin.column != last.column) |
ostr << '-' << last.column; |
return ostr; |
} |
|
|
/* Line 271 of location.cc */ |
#line 28 "parser.y" |
} // Theia |
|
/* Line 271 of location.cc */ |
#line 168 "location.hh" |
|
#endif // not BISON_LOCATION_HH |
/branches/beta_2.0/compiler/src/vp_compiler/Preprocessor.cpp
0,0 → 1,227
#include "Preprocessor.h" |
#include <iostream> |
#include <fstream> |
#include <map> |
#include <vector> |
using namespace std; |
|
//---------------------------------------------------------------- |
Preprocessor::Preprocessor() |
{ |
} |
//---------------------------------------------------------------- |
Preprocessor::~Preprocessor() |
{ |
} |
//----------------------------------------------------------------------- |
void Tokenize(const string& str, |
vector<string>& tokens, |
const string& delimiters = " ") |
{ |
|
string::size_type lastPos = str.find_first_not_of(delimiters, 0); |
string::size_type pos = str.find_first_of(delimiters, lastPos); |
|
while (string::npos != pos || string::npos != lastPos) |
{ |
|
tokens.push_back(str.substr(lastPos, pos - lastPos)); |
lastPos = str.find_first_not_of(delimiters, pos); |
pos = str.find_first_of(delimiters, lastPos); |
} |
} |
//---------------------------------------------------------------- |
vector<string> Preprocessor::ScanFile( std::ifstream & ifs ) |
{ |
vector<string> NewFile; |
while (!ifs.eof()) |
{ |
char Buffer[1024]; |
ifs.getline( Buffer,1024 ); |
string Line = Buffer; |
|
//replace tabs with spaces |
int pos = 0; |
while ((pos = Line.find("\t")) != string::npos) |
Line.replace(pos,1," "); |
|
if (Line.find("#") == string::npos) |
{ |
NewFile.push_back(Line); |
continue; |
} |
|
if (Line.find("#macro") != string::npos) |
{ |
|
NewFile.push_back("//" + Line); |
PopulateMacroFunction(Line,ifs,NewFile); |
continue; |
} |
|
vector<string> Tokens; |
Tokenize(Line,Tokens," "); |
if (Tokens.size() != 0) |
{ |
|
if (Tokens[0] == "#define") |
mMacros[ Tokens[1] ] = Tokens[2]; |
} |
|
NewFile.push_back("//" + Line); |
|
} |
|
//for( map<string,string>::const_iterator it = mMacros.begin(); it != mMacros.end(); ++it ) |
//cout << "macro " << it->first << " = " << it->second << "\n"; |
//cout << "\n"; |
//for( map<string,TMacroFunction>::iterator it = mMacroFunctions.begin(); it != mMacroFunctions.end(); ++it ) |
//cout << "macro function " << it->first << "\n"; |
|
return NewFile; |
} |
//---------------------------------------------------------------- |
void Preprocessor::SubstitudeMacros( vector<string> & aFile, ofstream & ofs ) |
{ |
//for (int i = 0; i < NewFile.size(); i++) |
int i = 0; |
for ( vector<string>::iterator I = aFile.begin(); (I != aFile.end() && i < aFile.size()); I++, i++) |
{ |
//cout << "Line " << *I << "\n"; |
//Now the macro literals |
for( map<string,string>::const_iterator it = mMacros.begin(); it != mMacros.end(); ++it ) |
{ |
string Key = it->first; |
string Value = it->second; |
string Line = aFile[i]; |
while (Line.find(Key) != string::npos) |
Line.replace(Line.find(Key),Key.length(),Value); |
aFile[i] = Line; |
} |
|
|
//First the macro functions |
for( map<string,TMacroFunction>::iterator it = mMacroFunctions.begin(); it != mMacroFunctions.end(); ++it ) |
{ |
string Key = it->first; |
TMacroFunction MacroFunction = it->second; |
string Line =*I; |
if (Line.find("//") != string::npos) |
Line.erase(Line.find("//"),Line.length()-Line.find("//")); |
//continue; |
|
if (Line.find(Key) != string::npos) |
{ |
int pos = 0; |
while ((pos = Line.find(" ")) != string::npos) |
Line.erase(pos,1); |
vector<string> Tokens; |
Tokenize(Line,Tokens,"="); |
|
MacroFunction.mReturnValue = Tokens[0]; |
vector<string> Tokens2; |
string Tmp = Tokens[1]; |
Tokens.clear(); |
Tokenize(Tmp,Tokens,"("); |
Tmp = Tokens[1]; |
while ((pos = Tmp.find(")")) != string::npos) |
Tmp.erase(pos,1); |
while ((pos = Tmp.find(";")) != string::npos) |
Tmp.erase(pos,1); |
Tokens.clear(); |
Tokenize(Tmp,Tokens,","); |
MacroFunction.mParamterValue = Tokens; |
|
vector<string> MacroString = MacroFunction.GetSubstitudedMacro(); |
aFile[i] = "//" + aFile[i]; |
I = aFile.begin() + i+1; |
aFile.insert(I,MacroString.begin(),MacroString.end()); |
|
I = aFile.begin() + i; |
} |
} |
|
// cout << aFile[i].c_str() << std::endl; |
ofs << aFile[i].c_str() << std::endl; |
} |
} |
//---------------------------------------------------------------- |
void Preprocessor::Execute( string aFile ) |
{ |
ifstream ifs; |
ifs.open(aFile.c_str()); |
if (!ifs.good()) |
std::cout << "Cannot open file" << aFile << "\n"; |
cout << "Scanning file " << aFile << "\n"; |
vector<string> NewFile = ScanFile( ifs ); |
ifs.close(); |
cout << "Preprocessing file " << aFile << "\n"; |
ofstream ofs(string(aFile + ".preprocessed").c_str()); |
SubstitudeMacros( NewFile, ofs ); |
ofs.close(); |
} |
//---------------------------------------------------------------- |
vector<string> TMacroFunction::GetSubstitudedMacro() |
{ |
vector<string> ReturnString; |
for (int i = 0; i < mLines.size(); i++) |
{ |
|
string Line = mLines[i]; |
for (int j = 0; j < mParamterSymbol.size(); j++) |
{ |
while( Line.find(mParamterSymbol[j]) != string::npos ) |
Line.replace(Line.find(mParamterSymbol[j]),mParamterSymbol[j].length(),mParamterValue[j]); |
|
while( Line.find(mReturnSymbol) != string::npos ) |
Line.replace(Line.find(mReturnSymbol),mReturnSymbol.length(),mReturnValue); |
|
} |
|
ReturnString.push_back( Line ); |
} |
return ReturnString; |
} |
//---------------------------------------------------------------- |
void Preprocessor::PopulateMacroFunction(string aSignature, std::ifstream & ifs, vector<string> & aNewFile) |
{ |
|
//Get rid of spaces |
int pos = 0; |
while ((pos = aSignature.find(" ")) != string::npos) |
aSignature.erase(pos,1); |
//Delete the "#macro" string |
aSignature.erase(0,6); |
vector<string> Tokens; |
Tokenize(aSignature,Tokens,"="); |
TMacroFunction M; |
M.mReturnSymbol = Tokens[0]; |
|
string Tmp = Tokens[1]; |
Tokens.clear(); |
Tokenize(Tmp,Tokens,"("); |
M.mName = Tokens[0]; |
Tmp = Tokens[1]; |
while ((pos = Tmp.find(")")) != string::npos) |
Tmp.erase(pos,1); |
Tokens.clear(); |
Tokenize(Tmp,Tokens,","); |
M.mParamterSymbol = Tokens; |
|
int MacroLineCount = 0; |
while (MacroLineCount < MAX_MACRO_FUNCTION_LINE_COUNT) |
{ |
char Buffer[1024]; |
ifs.getline( Buffer,1024 ); |
string Line = Buffer; |
aNewFile.push_back("//" + Line); |
if (Line.find("#endmacro") != string::npos) |
break; |
M.mLines.push_back( Line ); |
MacroLineCount++; |
} |
|
mMacroFunctions[M.mName] = M; |
M.mLines.clear(); |
} |
//---------------------------------------------------------------- |
/branches/beta_2.0/compiler/src/vp_compiler/Instruction.h
0,0 → 1,209
#ifndef INSTRUCTION_H |
#define INSTRUCTION_H |
|
/********************************************************************************** |
Theia, Ray Cast Programable graphic Processing Unit. |
Copyright (C) 2012 Diego Valverde (diego.valverde.g@gmail.com) |
|
This program is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
of the License, or (at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
***********************************************************************************/ |
|
#include <bitset> |
#include <string> |
#include <fstream> |
|
#define OPERATION_SIZE 16 |
#define DESTINATION_SIZE 14 |
#define SOURCE1_SIZE 17 |
#define SOURCE0_SIZE 17 |
#define RETURN_VALUE_REGISTER 1 |
#define RETURN_ADDRESS_REGISTER 2//31 |
#define SPR_CONTROL_REGISTER 3 //30 |
#define SPR_CONTROL_REGISTER0 2 |
|
//---------------------------------------------------------------------------------- |
//#define DEBUG 1 |
//Use this macro instead of std::cout, it is easier to turn off |
class NullStream |
{ |
public: |
NullStream() { } |
template<typename T> NullStream& operator<<(T const&) { return *this; } |
}; |
|
|
#ifdef DEBUG |
#define DCOUT std::cout |
#else |
#define DCOUT NullStream() |
#endif |
//---------------------------------------------------------------------------------- |
|
|
|
typedef enum |
{ |
ECHANNEL_X=4, |
ECHANNEL_Y=2, |
ECHANNEL_Z=1, |
ECHANNEL_XYZ=7 |
|
} ECHANNEL; |
|
typedef enum |
{ |
SWX_X=0, |
SWX_Z, |
SWX_Y |
} ESWIZZLE_X; |
|
typedef enum |
{ |
SWY_Y=0, |
SWY_Z, |
SWY_X |
} ESWIZZLE_Y; |
|
typedef enum |
{ |
SWZ_Z=0, |
SWZ_Y, |
SWZ_X |
} ESWIZZLE_Z; |
|
typedef enum |
{ |
EOPERATION_NOP=0, |
EOPERATION_ADD=1, |
EOPERATION_DIV, |
EOPERATION_MUL, |
EOPERATION_SQRT, |
EOPERATION_LOGIC, |
EOPERATION_OUT |
|
} EOPERATION; |
|
|
typedef enum |
{ |
ELOGIC_AND = 0, |
ELOGIC_OR, |
ELOGIC_NOT, |
ELOGIC_SHL, |
ELOGIC_SHR |
|
} ELOGIC_OPERATION; |
|
typedef enum |
{ |
EROT_NONE = 0, |
EROT_SRC0_LEFT =1, |
EROT_SRC1_LEFT =2, |
EROT_SRC1_SCR0_LEFT = 3, |
EROT_SRC0_RIGHT=9, |
EROT_SRC1_RIGHT=10, |
EROT_SRC1_SRC0_RIGHT=11, |
EROT_RESULT_RIGHT=12 |
} EROTATION; |
|
typedef enum |
{ |
EBRANCH_ALWAYS=0, |
EBRANCH_IF_ZERO, |
EBRANCH_IF_NOT_ZERO, |
EBRANCH_IF_SIGN, |
EBRANCH_IF_NOT_SIGN, |
EBRANCH_IF_ZERO_OR_SIGN, |
EBRANCH_IF_ZERO_OR_NOT_SIGN |
|
} EBRANCHTYPE; |
|
class Instruction |
{ |
public: |
Instruction(); |
~Instruction(); |
public: |
std::string PrintHex(); |
std::string PrintBin(); |
std::string PrintAssembly(); |
void PrintFields(); |
std::string PrintHex32(); |
void Clear( void ); |
bool mBisonFlagTrippleConstAssign; |
|
public: |
void SetFields( unsigned int aOperation, unsigned int aDestination, unsigned int aSrc1, unsigned int aSrc0 ); |
void SetCode( EOPERATION aCode ); |
void SetImm( unsigned int aLiteral ); |
void SetImmBit( bool aImm ); |
void SetDestZero( bool aZero ); |
void SetSrc0Displace( bool aDisplace ); |
void SetSrc1Displace( bool aDisplace ); |
void SetLogicOperation(ELOGIC_OPERATION aOperation ); |
void SetAddressingMode( bool, bool, bool ); |
|
void SetEofFlag( bool aEof ); |
void SetWriteChannel( ECHANNEL aChannel ); |
void ClearWriteChannel(); |
void SetDestinationAddress( unsigned int aDestinationAddress ); |
void SetDestination( std::bitset<DESTINATION_SIZE> aDestination ); |
void SetDestinationSymbol( std::string aSymbol ); |
void SetBranchFlag( bool aBranch ); |
void SetBranchType( EBRANCHTYPE aType ); |
//Source 1 |
void SetSrc1SignX( bool aSign ); |
void SetSrc1SignY( bool aSign ); |
void SetSrc1SignZ( bool aSign ); |
void SetSrc1SwizzleX( ESWIZZLE_X aChannel ); |
void SetSrc1SwizzleY( ESWIZZLE_Y aChannel ); |
void SetSrc1SwizzleZ( ESWIZZLE_Z aChannel ); |
void SetSrc1Address( unsigned int aAddress ); |
void SetSrc1Rotation( EROTATION aRotation ); |
//Source 0 |
void SetSrc0SignX( bool aSign ); |
void SetSrc0SignY( bool aSign ); |
void SetSrc0SignZ( bool aSign ); |
void SetSrc0SwizzleX( ESWIZZLE_X aChannel ); |
void SetSrc0SwizzleY( ESWIZZLE_Y aChannel ); |
void SetSrc0SwizzleZ( ESWIZZLE_Z aChannel ); |
void SetSrc0Address( unsigned int aAddress ); |
void SetSrc0Rotation( EROTATION aRotation ); |
|
std::bitset<DESTINATION_SIZE> GetDestination( void ); |
unsigned int GetOperation( void ); |
unsigned int GetAddressingMode( void ); |
unsigned int GetDestinationAddress( void ); |
bool GetImm( void); |
ECHANNEL GetWriteChannel( void ); |
|
private: |
std::bitset<OPERATION_SIZE> mOperation; |
std::string mOperationString; |
std::bitset<DESTINATION_SIZE> mDestination; |
std::bitset<SOURCE1_SIZE> mSource1; |
std::bitset<SOURCE0_SIZE> mSource0; |
unsigned int mLiteral; |
bool mDestinationIsSymbol; |
std::string mDestinationSymbol; |
public: |
int mSourceLine; |
std::string mComment; |
private: |
//std::ofstream mOutputFile; |
}; |
|
#endif |
/branches/beta_2.0/compiler/src/vp_compiler/Preprocessor.h
0,0 → 1,37
|
#include <string> |
#include <map> |
#include <vector> |
using namespace std; |
//----------------------------------------------------------------------- |
#define MAX_MACRO_FUNCTION_LINE_COUNT 100 |
class TMacroFunction |
{ |
public: |
vector<string> GetSubstitudedMacro( void ); |
string mName; |
string mReturnSymbol; |
string mReturnValue; |
vector<string> mParamterSymbol; |
vector<string> mParamterValue; |
vector<string> mLines; |
} ; |
//-------------------------------------------------------- |
class Preprocessor |
{ |
public: |
Preprocessor(); |
~Preprocessor(); |
public: |
void Execute( string aFile ); |
|
private: |
vector<string> ScanFile( ifstream & ifs ); |
void SubstitudeMacros( vector<string> & aFile, ofstream & ofs ); |
void PopulateMacroFunction(string aSignature, ifstream & ifs, vector<string> & aNewFile); |
|
map<string, TMacroFunction> mMacroFunctions; |
map <string,string> mMacros; |
|
}; |
//-------------------------------------------------------- |
/branches/beta_2.0/compiler/src/vp_compiler/lex.yy.cc
0,0 → 1,1914
|
#line 3 "lex.yy.cc" |
|
#define YY_INT_ALIGNED short int |
|
/* A lexical scanner generated by flex */ |
|
#define FLEX_SCANNER |
#define YY_FLEX_MAJOR_VERSION 2 |
#define YY_FLEX_MINOR_VERSION 5 |
#define YY_FLEX_SUBMINOR_VERSION 35 |
#if YY_FLEX_SUBMINOR_VERSION > 0 |
#define FLEX_BETA |
#endif |
|
/* The c++ scanner is a mess. The FlexLexer.h header file relies on the |
* following macro. This is required in order to pass the c++-multiple-scanners |
* test in the regression suite. We get reports that it breaks inheritance. |
* We will address this in a future release of flex, or omit the C++ scanner |
* altogether. |
*/ |
#define yyFlexLexer yyFlexLexer |
|
/* First, we deal with platform-specific or compiler-specific issues. */ |
|
/* begin standard C headers. */ |
|
/* end standard C headers. */ |
|
/* flex integer type definitions */ |
|
#ifndef FLEXINT_H |
#define FLEXINT_H |
|
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ |
|
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L |
|
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, |
* if you want the limit (max/min) macros for int types. |
*/ |
#ifndef __STDC_LIMIT_MACROS |
#define __STDC_LIMIT_MACROS 1 |
#endif |
|
#include <inttypes.h> |
typedef int8_t flex_int8_t; |
typedef uint8_t flex_uint8_t; |
typedef int16_t flex_int16_t; |
typedef uint16_t flex_uint16_t; |
typedef int32_t flex_int32_t; |
typedef uint32_t flex_uint32_t; |
#else |
typedef signed char flex_int8_t; |
typedef short int flex_int16_t; |
typedef int flex_int32_t; |
typedef unsigned char flex_uint8_t; |
typedef unsigned short int flex_uint16_t; |
typedef unsigned int flex_uint32_t; |
|
/* Limits of integral types. */ |
#ifndef INT8_MIN |
#define INT8_MIN (-128) |
#endif |
#ifndef INT16_MIN |
#define INT16_MIN (-32767-1) |
#endif |
#ifndef INT32_MIN |
#define INT32_MIN (-2147483647-1) |
#endif |
#ifndef INT8_MAX |
#define INT8_MAX (127) |
#endif |
#ifndef INT16_MAX |
#define INT16_MAX (32767) |
#endif |
#ifndef INT32_MAX |
#define INT32_MAX (2147483647) |
#endif |
#ifndef UINT8_MAX |
#define UINT8_MAX (255U) |
#endif |
#ifndef UINT16_MAX |
#define UINT16_MAX (65535U) |
#endif |
#ifndef UINT32_MAX |
#define UINT32_MAX (4294967295U) |
#endif |
|
#endif /* ! C99 */ |
|
#endif /* ! FLEXINT_H */ |
|
/* begin standard C++ headers. */ |
#include <iostream> |
#include <errno.h> |
#include <cstdlib> |
#include <cstdio> |
#include <cstring> |
/* end standard C++ headers. */ |
|
#ifdef __cplusplus |
|
/* The "const" storage-class-modifier is valid. */ |
#define YY_USE_CONST |
|
#else /* ! __cplusplus */ |
|
/* C99 requires __STDC__ to be defined as 1. */ |
#if defined (__STDC__) |
|
#define YY_USE_CONST |
|
#endif /* defined (__STDC__) */ |
#endif /* ! __cplusplus */ |
|
#ifdef YY_USE_CONST |
#define yyconst const |
#else |
#define yyconst |
#endif |
|
/* Returned upon end-of-file. */ |
#define YY_NULL 0 |
|
/* Promotes a possibly negative, possibly signed char to an unsigned |
* integer for use as an array index. If the signed char is negative, |
* we want to instead treat it as an 8-bit unsigned char, hence the |
* double cast. |
*/ |
#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) |
|
/* Enter a start condition. This macro really ought to take a parameter, |
* but we do it the disgusting crufty way forced on us by the ()-less |
* definition of BEGIN. |
*/ |
#define BEGIN (yy_start) = 1 + 2 * |
|
/* Translate the current start state into a value that can be later handed |
* to BEGIN to return to the state. The YYSTATE alias is for lex |
* compatibility. |
*/ |
#define YY_START (((yy_start) - 1) / 2) |
#define YYSTATE YY_START |
|
/* Action number for EOF rule of a given start state. */ |
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) |
|
/* Special action meaning "start processing a new file". */ |
#define YY_NEW_FILE yyrestart( yyin ) |
|
#define YY_END_OF_BUFFER_CHAR 0 |
|
/* Size of default input buffer. */ |
#ifndef YY_BUF_SIZE |
#ifdef __ia64__ |
/* On IA-64, the buffer size is 16k, not 8k. |
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. |
* Ditto for the __ia64__ case accordingly. |
*/ |
#define YY_BUF_SIZE 32768 |
#else |
#define YY_BUF_SIZE 16384 |
#endif /* __ia64__ */ |
#endif |
|
/* The state buf must be large enough to hold one state per character in the main buffer. |
*/ |
#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) |
|
#ifndef YY_TYPEDEF_YY_BUFFER_STATE |
#define YY_TYPEDEF_YY_BUFFER_STATE |
typedef struct yy_buffer_state *YY_BUFFER_STATE; |
#endif |
|
extern int yyleng; |
|
#define EOB_ACT_CONTINUE_SCAN 0 |
#define EOB_ACT_END_OF_FILE 1 |
#define EOB_ACT_LAST_MATCH 2 |
|
#define YY_LESS_LINENO(n) |
|
/* Return all but the first "n" matched characters back to the input stream. */ |
#define yyless(n) \ |
do \ |
{ \ |
/* Undo effects of setting up yytext. */ \ |
int yyless_macro_arg = (n); \ |
YY_LESS_LINENO(yyless_macro_arg);\ |
*yy_cp = (yy_hold_char); \ |
YY_RESTORE_YY_MORE_OFFSET \ |
(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ |
YY_DO_BEFORE_ACTION; /* set up yytext again */ \ |
} \ |
while ( 0 ) |
|
#define unput(c) yyunput( c, (yytext_ptr) ) |
|
#ifndef YY_TYPEDEF_YY_SIZE_T |
#define YY_TYPEDEF_YY_SIZE_T |
typedef size_t yy_size_t; |
#endif |
|
#ifndef YY_STRUCT_YY_BUFFER_STATE |
#define YY_STRUCT_YY_BUFFER_STATE |
struct yy_buffer_state |
{ |
|
std::istream* yy_input_file; |
|
char *yy_ch_buf; /* input buffer */ |
char *yy_buf_pos; /* current position in input buffer */ |
|
/* Size of input buffer in bytes, not including room for EOB |
* characters. |
*/ |
yy_size_t yy_buf_size; |
|
/* Number of characters read into yy_ch_buf, not including EOB |
* characters. |
*/ |
int yy_n_chars; |
|
/* Whether we "own" the buffer - i.e., we know we created it, |
* and can realloc() it to grow it, and should free() it to |
* delete it. |
*/ |
int yy_is_our_buffer; |
|
/* Whether this is an "interactive" input source; if so, and |
* if we're using stdio for input, then we want to use getc() |
* instead of fread(), to make sure we stop fetching input after |
* each newline. |
*/ |
int yy_is_interactive; |
|
/* Whether we're considered to be at the beginning of a line. |
* If so, '^' rules will be active on the next match, otherwise |
* not. |
*/ |
int yy_at_bol; |
|
int yy_bs_lineno; /**< The line count. */ |
int yy_bs_column; /**< The column count. */ |
|
/* Whether to try to fill the input buffer when we reach the |
* end of it. |
*/ |
int yy_fill_buffer; |
|
int yy_buffer_status; |
|
#define YY_BUFFER_NEW 0 |
#define YY_BUFFER_NORMAL 1 |
/* When an EOF's been seen but there's still some text to process |
* then we mark the buffer as YY_EOF_PENDING, to indicate that we |
* shouldn't try reading from the input source any more. We might |
* still have a bunch of tokens to match, though, because of |
* possible backing-up. |
* |
* When we actually see the EOF, we change the status to "new" |
* (via yyrestart()), so that the user can continue scanning by |
* just pointing yyin at a new input file. |
*/ |
#define YY_BUFFER_EOF_PENDING 2 |
|
}; |
#endif /* !YY_STRUCT_YY_BUFFER_STATE */ |
|
/* We provide macros for accessing buffer states in case in the |
* future we want to put the buffer states in a more general |
* "scanner state". |
* |
* Returns the top of the stack, or NULL. |
*/ |
#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ |
? (yy_buffer_stack)[(yy_buffer_stack_top)] \ |
: NULL) |
|
/* Same as previous macro, but useful when we know that the buffer stack is not |
* NULL or when we need an lvalue. For internal use only. |
*/ |
#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] |
|
void *yyalloc (yy_size_t ); |
void *yyrealloc (void *,yy_size_t ); |
void yyfree (void * ); |
|
#define yy_new_buffer yy_create_buffer |
|
#define yy_set_interactive(is_interactive) \ |
{ \ |
if ( ! YY_CURRENT_BUFFER ){ \ |
yyensure_buffer_stack (); \ |
YY_CURRENT_BUFFER_LVALUE = \ |
yy_create_buffer( yyin, YY_BUF_SIZE ); \ |
} \ |
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ |
} |
|
#define yy_set_bol(at_bol) \ |
{ \ |
if ( ! YY_CURRENT_BUFFER ){\ |
yyensure_buffer_stack (); \ |
YY_CURRENT_BUFFER_LVALUE = \ |
yy_create_buffer( yyin, YY_BUF_SIZE ); \ |
} \ |
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ |
} |
|
#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) |
|
/* Begin user sect3 */ |
#define YY_SKIP_YYWRAP |
|
typedef unsigned char YY_CHAR; |
|
#define yytext_ptr yytext |
#define YY_INTERACTIVE |
|
#include <FlexLexer.h> |
|
int yyFlexLexer::yywrap() { return 1; } |
int yyFlexLexer::yylex() |
{ |
LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" ); |
return 0; |
} |
|
#define YY_DECL int Scanner::yylex() |
|
/* Done after the current pattern has been matched and before the |
* corresponding action - sets up yytext. |
*/ |
#define YY_DO_BEFORE_ACTION \ |
(yytext_ptr) = yy_bp; \ |
yyleng = (size_t) (yy_cp - yy_bp); \ |
(yy_hold_char) = *yy_cp; \ |
*yy_cp = '\0'; \ |
(yy_c_buf_p) = yy_cp; |
|
#define YY_NUM_RULES 53 |
#define YY_END_OF_BUFFER 54 |
/* This struct is not used in this scanner, |
but its presence is necessary. */ |
struct yy_trans_info |
{ |
flex_int32_t yy_verify; |
flex_int32_t yy_nxt; |
}; |
static yyconst flex_int16_t yy_accept[141] = |
{ 0, |
0, 0, 54, 52, 3, 2, 52, 11, 20, 21, |
39, 42, 44, 24, 45, 40, 4, 4, 43, 36, |
34, 35, 51, 51, 37, 38, 51, 51, 51, 51, |
49, 51, 51, 51, 51, 51, 51, 51, 46, 47, |
48, 22, 12, 23, 3, 26, 41, 0, 4, 0, |
0, 32, 25, 33, 51, 50, 51, 51, 51, 51, |
8, 51, 51, 51, 51, 51, 51, 51, 51, 51, |
51, 51, 0, 1, 6, 5, 51, 51, 51, 51, |
14, 30, 51, 51, 51, 51, 51, 51, 51, 51, |
51, 9, 16, 51, 51, 51, 51, 7, 51, 51, |
|
51, 51, 51, 51, 51, 51, 51, 27, 19, 51, |
51, 29, 51, 10, 51, 51, 15, 18, 51, 17, |
51, 51, 28, 51, 13, 51, 51, 51, 51, 51, |
51, 51, 51, 51, 51, 51, 51, 51, 31, 0 |
} ; |
|
static yyconst flex_int32_t yy_ec[256] = |
{ 0, |
1, 1, 1, 1, 1, 1, 1, 1, 2, 3, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 2, 4, 2, 1, 1, 1, 5, 1, 6, |
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, |
16, 16, 16, 16, 16, 16, 16, 1, 17, 18, |
19, 20, 1, 1, 21, 21, 21, 21, 21, 21, |
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, |
22, 23, 22, 22, 22, 22, 22, 22, 22, 22, |
24, 1, 25, 1, 26, 1, 27, 28, 29, 30, |
|
31, 32, 33, 34, 35, 36, 22, 37, 38, 39, |
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, |
50, 51, 52, 53, 54, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1 |
} ; |
|
static yyconst flex_int32_t yy_meta[55] = |
{ 0, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 2, 2, 2, 1, 1, 1, 1, |
2, 3, 3, 1, 1, 3, 2, 2, 2, 2, |
2, 2, 3, 3, 3, 3, 3, 3, 3, 3, |
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
3, 1, 1, 1 |
} ; |
|
static yyconst flex_int16_t yy_base[144] = |
{ 0, |
0, 0, 174, 175, 171, 175, 153, 175, 175, 175, |
175, 152, 175, 175, 175, 157, 41, 44, 175, 150, |
149, 148, 0, 47, 175, 175, 27, 31, 134, 127, |
0, 118, 56, 36, 129, 29, 131, 127, 175, 175, |
175, 175, 175, 175, 158, 175, 175, 156, 68, 60, |
0, 175, 175, 175, 0, 77, 114, 122, 107, 116, |
0, 113, 108, 107, 124, 107, 122, 105, 103, 111, |
116, 109, 140, 175, 65, 0, 111, 96, 109, 110, |
0, 0, 92, 100, 91, 92, 103, 104, 93, 86, |
93, 0, 0, 99, 83, 84, 95, 0, 80, 97, |
|
96, 89, 81, 89, 93, 83, 78, 0, 0, 86, |
78, 0, 71, 0, 72, 72, 0, 0, 80, 0, |
70, 70, 0, 73, 0, 68, 61, 79, 77, 60, |
67, 56, 66, 61, 58, 43, 51, 56, 0, 175, |
92, 95, 65 |
} ; |
|
static yyconst flex_int16_t yy_def[144] = |
{ 0, |
140, 1, 140, 140, 140, 140, 140, 140, 140, 140, |
140, 140, 140, 140, 140, 140, 140, 140, 140, 140, |
140, 140, 141, 141, 140, 140, 141, 141, 141, 141, |
141, 141, 141, 141, 141, 141, 141, 141, 140, 140, |
140, 140, 140, 140, 140, 140, 140, 142, 140, 140, |
143, 140, 140, 140, 141, 141, 141, 141, 141, 141, |
141, 141, 141, 141, 141, 141, 141, 141, 141, 141, |
141, 141, 142, 140, 140, 143, 141, 141, 141, 141, |
141, 141, 141, 141, 141, 141, 141, 141, 141, 141, |
141, 141, 141, 141, 141, 141, 141, 141, 141, 141, |
|
141, 141, 141, 141, 141, 141, 141, 141, 141, 141, |
141, 141, 141, 141, 141, 141, 141, 141, 141, 141, |
141, 141, 141, 141, 141, 141, 141, 141, 141, 141, |
141, 141, 141, 141, 141, 141, 141, 141, 141, 0, |
140, 140, 140 |
} ; |
|
static yyconst flex_int16_t yy_nxt[230] = |
{ 0, |
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, |
14, 15, 16, 17, 18, 18, 19, 20, 21, 22, |
23, 23, 24, 25, 26, 4, 23, 23, 23, 23, |
27, 28, 23, 23, 29, 30, 23, 23, 31, 32, |
23, 23, 33, 34, 35, 36, 37, 38, 39, 40, |
41, 42, 43, 44, 49, 49, 49, 49, 49, 49, |
56, 56, 56, 57, 65, 59, 76, 69, 50, 56, |
56, 56, 70, 75, 75, 58, 60, 66, 75, 75, |
67, 49, 49, 49, 139, 138, 64, 137, 136, 51, |
56, 56, 56, 55, 55, 73, 73, 73, 135, 134, |
|
133, 132, 131, 130, 129, 128, 127, 126, 125, 124, |
123, 122, 121, 120, 119, 118, 117, 116, 115, 114, |
113, 112, 111, 110, 109, 108, 107, 106, 105, 104, |
103, 102, 101, 100, 99, 98, 97, 96, 95, 94, |
93, 92, 74, 91, 90, 89, 88, 87, 86, 85, |
84, 83, 82, 81, 80, 79, 78, 77, 74, 45, |
72, 71, 68, 63, 62, 61, 54, 53, 52, 48, |
47, 46, 45, 140, 3, 140, 140, 140, 140, 140, |
140, 140, 140, 140, 140, 140, 140, 140, 140, 140, |
140, 140, 140, 140, 140, 140, 140, 140, 140, 140, |
|
140, 140, 140, 140, 140, 140, 140, 140, 140, 140, |
140, 140, 140, 140, 140, 140, 140, 140, 140, 140, |
140, 140, 140, 140, 140, 140, 140, 140, 140 |
} ; |
|
static yyconst flex_int16_t yy_chk[230] = |
{ 0, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 17, 17, 17, 18, 18, 18, |
24, 24, 24, 27, 34, 28, 143, 36, 17, 33, |
33, 33, 36, 50, 50, 27, 28, 34, 75, 75, |
34, 49, 49, 49, 138, 137, 33, 136, 135, 17, |
56, 56, 56, 141, 141, 142, 142, 142, 134, 133, |
|
132, 131, 130, 129, 128, 127, 126, 124, 122, 121, |
119, 116, 115, 113, 111, 110, 107, 106, 105, 104, |
103, 102, 101, 100, 99, 97, 96, 95, 94, 91, |
90, 89, 88, 87, 86, 85, 84, 83, 80, 79, |
78, 77, 73, 72, 71, 70, 69, 68, 67, 66, |
65, 64, 63, 62, 60, 59, 58, 57, 48, 45, |
38, 37, 35, 32, 30, 29, 22, 21, 20, 16, |
12, 7, 5, 3, 140, 140, 140, 140, 140, 140, |
140, 140, 140, 140, 140, 140, 140, 140, 140, 140, |
140, 140, 140, 140, 140, 140, 140, 140, 140, 140, |
|
140, 140, 140, 140, 140, 140, 140, 140, 140, 140, |
140, 140, 140, 140, 140, 140, 140, 140, 140, 140, |
140, 140, 140, 140, 140, 140, 140, 140, 140 |
} ; |
|
/* The intent behind this definition is that it'll catch |
* any uses of REJECT which flex missed. |
*/ |
#define REJECT reject_used_but_not_detected |
#define yymore() yymore_used_but_not_detected |
#define YY_MORE_ADJ 0 |
#define YY_RESTORE_YY_MORE_OFFSET |
#line 1 "scanner.l" |
#line 2 "scanner.l" |
|
/********************************************************************************** |
Theia, Ray Cast Programable graphic Processing Unit. |
Copyright (C) 2012 Diego Valverde (diego.valverde.g@gmail.com) |
|
This program is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
of the License, or (at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
***********************************************************************************/ |
|
#include "Scanner.h" |
// used to keep track of location |
#define YY_USER_ACTION yylloc->columns(yyleng); |
int LineNumber = 1; |
#line 546 "lex.yy.cc" |
|
#define INITIAL 0 |
|
#ifndef YY_NO_UNISTD_H |
/* Special case for "unistd.h", since it is non-ANSI. We include it way |
* down here because we want the user's section 1 to have been scanned first. |
* The user has a chance to override it with an option. |
*/ |
#include <unistd.h> |
#endif |
|
#ifndef YY_EXTRA_TYPE |
#define YY_EXTRA_TYPE void * |
#endif |
|
#ifndef yytext_ptr |
static void yy_flex_strncpy (char *,yyconst char *,int ); |
#endif |
|
#ifdef YY_NEED_STRLEN |
static int yy_flex_strlen (yyconst char * ); |
#endif |
|
#ifndef YY_NO_INPUT |
|
#endif |
|
/* Amount of stuff to slurp up with each read. */ |
#ifndef YY_READ_BUF_SIZE |
#ifdef __ia64__ |
/* On IA-64, the buffer size is 16k, not 8k */ |
#define YY_READ_BUF_SIZE 16384 |
#else |
#define YY_READ_BUF_SIZE 8192 |
#endif /* __ia64__ */ |
#endif |
|
/* Copy whatever the last rule matched to the standard output. */ |
#ifndef ECHO |
#define ECHO LexerOutput( yytext, yyleng ) |
#endif |
|
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, |
* is returned in "result". |
*/ |
#ifndef YY_INPUT |
#define YY_INPUT(buf,result,max_size) \ |
\ |
if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ |
YY_FATAL_ERROR( "input in flex scanner failed" ); |
|
#endif |
|
/* No semi-colon after return; correct usage is to write "yyterminate();" - |
* we don't want an extra ';' after the "return" because that will cause |
* some compilers to complain about unreachable statements. |
*/ |
#ifndef yyterminate |
#define yyterminate() return YY_NULL |
#endif |
|
/* Number of entries by which start-condition stack grows. */ |
#ifndef YY_START_STACK_INCR |
#define YY_START_STACK_INCR 25 |
#endif |
|
/* Report a fatal error. */ |
#ifndef YY_FATAL_ERROR |
#define YY_FATAL_ERROR(msg) LexerError( msg ) |
#endif |
|
/* end tables serialization structures and prototypes */ |
|
/* Default declaration of generated scanner - a define so the user can |
* easily add parameters. |
*/ |
#ifndef YY_DECL |
#define YY_DECL_IS_OURS 1 |
#define YY_DECL int yyFlexLexer::yylex() |
#endif /* !YY_DECL */ |
|
/* Code executed at the beginning of each rule, after yytext and yyleng |
* have been set up. |
*/ |
#ifndef YY_USER_ACTION |
#define YY_USER_ACTION |
#endif |
|
/* Code executed at the end of each rule. */ |
#ifndef YY_BREAK |
#define YY_BREAK break; |
#endif |
|
#define YY_RULE_SETUP \ |
YY_USER_ACTION |
|
/** The main scanner function which does all the work. |
*/ |
YY_DECL |
{ |
register yy_state_type yy_current_state; |
register char *yy_cp, *yy_bp; |
register int yy_act; |
|
#line 43 "scanner.l" |
|
|
|
yylloc->step(); |
|
|
#line 658 "lex.yy.cc" |
|
if ( !(yy_init) ) |
{ |
(yy_init) = 1; |
|
#ifdef YY_USER_INIT |
YY_USER_INIT; |
#endif |
|
if ( ! (yy_start) ) |
(yy_start) = 1; /* first start state */ |
|
if ( ! yyin ) |
yyin = & std::cin; |
|
if ( ! yyout ) |
yyout = & std::cout; |
|
if ( ! YY_CURRENT_BUFFER ) { |
yyensure_buffer_stack (); |
YY_CURRENT_BUFFER_LVALUE = |
yy_create_buffer( yyin, YY_BUF_SIZE ); |
} |
|
yy_load_buffer_state( ); |
} |
|
while ( 1 ) /* loops until end-of-file is reached */ |
{ |
yy_cp = (yy_c_buf_p); |
|
/* Support of yytext. */ |
*yy_cp = (yy_hold_char); |
|
/* yy_bp points to the position in yy_ch_buf of the start of |
* the current run. |
*/ |
yy_bp = yy_cp; |
|
yy_current_state = (yy_start); |
yy_match: |
do |
{ |
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; |
if ( yy_accept[yy_current_state] ) |
{ |
(yy_last_accepting_state) = yy_current_state; |
(yy_last_accepting_cpos) = yy_cp; |
} |
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) |
{ |
yy_current_state = (int) yy_def[yy_current_state]; |
if ( yy_current_state >= 141 ) |
yy_c = yy_meta[(unsigned int) yy_c]; |
} |
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; |
++yy_cp; |
} |
while ( yy_base[yy_current_state] != 175 ); |
|
yy_find_action: |
yy_act = yy_accept[yy_current_state]; |
if ( yy_act == 0 ) |
{ /* have to back up */ |
yy_cp = (yy_last_accepting_cpos); |
yy_current_state = (yy_last_accepting_state); |
yy_act = yy_accept[yy_current_state]; |
} |
|
YY_DO_BEFORE_ACTION; |
|
do_action: /* This label is used only to access EOF actions. */ |
|
switch ( yy_act ) |
{ /* beginning of action switch */ |
case 0: /* must back up */ |
/* undo the effects of YY_DO_BEFORE_ACTION */ |
*yy_cp = (yy_hold_char); |
yy_cp = (yy_last_accepting_cpos); |
yy_current_state = (yy_last_accepting_state); |
goto yy_find_action; |
|
case 1: |
/* rule 1 can match eol */ |
YY_RULE_SETUP |
#line 49 "scanner.l" |
{yylloc->lines(); ;LineNumber++; ;} |
YY_BREAK |
case 2: |
/* rule 2 can match eol */ |
YY_RULE_SETUP |
#line 50 "scanner.l" |
{yylloc->lines(); ;LineNumber++;} |
YY_BREAK |
case 3: |
YY_RULE_SETUP |
#line 51 "scanner.l" |
{/* do nothing */} |
YY_BREAK |
case 4: |
YY_RULE_SETUP |
#line 52 "scanner.l" |
{ *yylval = yytext; return Theia::Parser::token::DECCONST; } |
YY_BREAK |
case 5: |
YY_RULE_SETUP |
#line 53 "scanner.l" |
{ *yylval = yytext; return Theia::Parser::token::HEXCONST; } |
YY_BREAK |
case 6: |
YY_RULE_SETUP |
#line 54 "scanner.l" |
{ *yylval = yytext; return Theia::Parser::token::BINCONST; } |
YY_BREAK |
case 7: |
YY_RULE_SETUP |
#line 55 "scanner.l" |
{return Theia::Parser::token::SQRT;} |
YY_BREAK |
case 8: |
YY_RULE_SETUP |
#line 56 "scanner.l" |
{return Theia::Parser::token::IF;} |
YY_BREAK |
case 9: |
YY_RULE_SETUP |
#line 57 "scanner.l" |
{return Theia::Parser::token::ELSE;} |
YY_BREAK |
case 10: |
YY_RULE_SETUP |
#line 58 "scanner.l" |
{return Theia::Parser::token::WHILE;} |
YY_BREAK |
case 11: |
YY_RULE_SETUP |
#line 59 "scanner.l" |
{return Theia::Parser::token::BITWISE_AND;} |
YY_BREAK |
case 12: |
YY_RULE_SETUP |
#line 60 "scanner.l" |
{return Theia::Parser::token::BITWISE_OR;} |
YY_BREAK |
case 13: |
YY_RULE_SETUP |
#line 61 "scanner.l" |
{return Theia::Parser::token::FUNCTION;} |
YY_BREAK |
case 14: |
YY_RULE_SETUP |
#line 62 "scanner.l" |
{return Theia::Parser::token::JMP;} |
YY_BREAK |
case 15: |
YY_RULE_SETUP |
#line 63 "scanner.l" |
{return Theia::Parser::token::RETURN;} |
YY_BREAK |
case 16: |
YY_RULE_SETUP |
#line 64 "scanner.l" |
{return Theia::Parser::token::EXIT;} |
YY_BREAK |
case 17: |
YY_RULE_SETUP |
#line 65 "scanner.l" |
{return Theia::Parser::token::AUTO;} |
YY_BREAK |
case 18: |
YY_RULE_SETUP |
#line 66 "scanner.l" |
{return Theia::Parser::token::THREAD;} |
YY_BREAK |
case 19: |
YY_RULE_SETUP |
#line 67 "scanner.l" |
{return Theia::Parser::token::START;} |
YY_BREAK |
case 20: |
YY_RULE_SETUP |
#line 68 "scanner.l" |
{return Theia::Parser::token::OPEN_ROUND_BRACE;} |
YY_BREAK |
case 21: |
YY_RULE_SETUP |
#line 69 "scanner.l" |
{return Theia::Parser::token::CLOSE_ROUND_BRACE;} |
YY_BREAK |
case 22: |
YY_RULE_SETUP |
#line 70 "scanner.l" |
{return Theia::Parser::token::OPEN_BRACE;} |
YY_BREAK |
case 23: |
YY_RULE_SETUP |
#line 71 "scanner.l" |
{return Theia::Parser::token::CLOSE_BRACE;} |
YY_BREAK |
case 24: |
YY_RULE_SETUP |
#line 72 "scanner.l" |
{*yylval = yytext;return Theia::Parser::token::MINUS; } |
YY_BREAK |
case 25: |
YY_RULE_SETUP |
#line 73 "scanner.l" |
{return Theia::Parser::token::EQUAL; } |
YY_BREAK |
case 26: |
YY_RULE_SETUP |
#line 74 "scanner.l" |
{return Theia::Parser::token::NOT_EQUAL; } |
YY_BREAK |
case 27: |
YY_RULE_SETUP |
#line 75 "scanner.l" |
{return Theia::Parser::token::SCALE; } |
YY_BREAK |
case 28: |
YY_RULE_SETUP |
#line 76 "scanner.l" |
{return Theia::Parser::token::UNSCALE; } |
YY_BREAK |
case 29: |
YY_RULE_SETUP |
#line 77 "scanner.l" |
{return Theia::Parser::token::USING; } |
YY_BREAK |
case 30: |
YY_RULE_SETUP |
#line 78 "scanner.l" |
{return Theia::Parser::token::OUT; } |
YY_BREAK |
case 31: |
YY_RULE_SETUP |
#line 79 "scanner.l" |
{return Theia::Parser::token::FIXED_POINT; } |
YY_BREAK |
case 32: |
YY_RULE_SETUP |
#line 80 "scanner.l" |
{return Theia::Parser::token::LESS_OR_EQUAL_THAN; } |
YY_BREAK |
case 33: |
YY_RULE_SETUP |
#line 81 "scanner.l" |
{return Theia::Parser::token::GREATER_OR_EQUAL_THAN; } |
YY_BREAK |
case 34: |
YY_RULE_SETUP |
#line 82 "scanner.l" |
{return Theia::Parser::token::ASSIGN; } |
YY_BREAK |
case 35: |
YY_RULE_SETUP |
#line 83 "scanner.l" |
{return Theia::Parser::token::GREATER_THAN; } |
YY_BREAK |
case 36: |
YY_RULE_SETUP |
#line 84 "scanner.l" |
{return Theia::Parser::token::LESS_THAN; } |
YY_BREAK |
case 37: |
YY_RULE_SETUP |
#line 85 "scanner.l" |
{return Theia::Parser::token::OPEN_SQUARE_BRACE; } |
YY_BREAK |
case 38: |
YY_RULE_SETUP |
#line 86 "scanner.l" |
{return Theia::Parser::token::CLOSE_SQUARE_BRACE; } |
YY_BREAK |
case 39: |
YY_RULE_SETUP |
#line 87 "scanner.l" |
{return Theia::Parser::token::MUL; } |
YY_BREAK |
case 40: |
YY_RULE_SETUP |
#line 88 "scanner.l" |
{return Theia::Parser::token::DIV; } |
YY_BREAK |
case 41: |
YY_RULE_SETUP |
#line 89 "scanner.l" |
{return Theia::Parser::token::ADD_EQ; } |
YY_BREAK |
case 42: |
YY_RULE_SETUP |
#line 90 "scanner.l" |
{return Theia::Parser::token::ADD; } |
YY_BREAK |
case 43: |
YY_RULE_SETUP |
#line 91 "scanner.l" |
{return Theia::Parser::token::EOS; } |
YY_BREAK |
case 44: |
YY_RULE_SETUP |
#line 92 "scanner.l" |
{return Theia::Parser::token::COMMA; } |
YY_BREAK |
case 45: |
YY_RULE_SETUP |
#line 93 "scanner.l" |
{return Theia::Parser::token::DOT; } |
YY_BREAK |
case 46: |
YY_RULE_SETUP |
#line 94 "scanner.l" |
{*yylval = yytext;return Theia::Parser::token::TK_X; } |
YY_BREAK |
case 47: |
YY_RULE_SETUP |
#line 95 "scanner.l" |
{*yylval = yytext;return Theia::Parser::token::TK_Y; } |
YY_BREAK |
case 48: |
YY_RULE_SETUP |
#line 96 "scanner.l" |
{*yylval = yytext;return Theia::Parser::token::TK_Z; } |
YY_BREAK |
case 49: |
YY_RULE_SETUP |
#line 97 "scanner.l" |
{*yylval = yytext;return Theia::Parser::token::TK_N; } |
YY_BREAK |
case 50: |
YY_RULE_SETUP |
#line 98 "scanner.l" |
{ *yylval = yytext; return Theia::Parser::token::REG;} |
YY_BREAK |
case 51: |
YY_RULE_SETUP |
#line 99 "scanner.l" |
{*yylval = yytext; return Theia::Parser::token::IDENTIFIER;} |
YY_BREAK |
case 52: |
YY_RULE_SETUP |
#line 100 "scanner.l" |
{ |
std::ostringstream ret; |
ret << "Unknown Indetifier at line " << LineNumber << " '" << yytext << "'\n"; |
throw ret.str(); |
}; |
YY_BREAK |
case 53: |
YY_RULE_SETUP |
#line 105 "scanner.l" |
YY_FATAL_ERROR( "flex scanner jammed" ); |
YY_BREAK |
#line 1012 "lex.yy.cc" |
case YY_STATE_EOF(INITIAL): |
yyterminate(); |
|
case YY_END_OF_BUFFER: |
{ |
/* Amount of text matched not including the EOB char. */ |
int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; |
|
/* Undo the effects of YY_DO_BEFORE_ACTION. */ |
*yy_cp = (yy_hold_char); |
YY_RESTORE_YY_MORE_OFFSET |
|
if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) |
{ |
/* We're scanning a new file or input source. It's |
* possible that this happened because the user |
* just pointed yyin at a new source and called |
* yylex(). If so, then we have to assure |
* consistency between YY_CURRENT_BUFFER and our |
* globals. Here is the right place to do so, because |
* this is the first action (other than possibly a |
* back-up) that will match for the new input source. |
*/ |
(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; |
YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; |
YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; |
} |
|
/* Note that here we test for yy_c_buf_p "<=" to the position |
* of the first EOB in the buffer, since yy_c_buf_p will |
* already have been incremented past the NUL character |
* (since all states make transitions on EOB to the |
* end-of-buffer state). Contrast this with the test |
* in input(). |
*/ |
if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) |
{ /* This was really a NUL. */ |
yy_state_type yy_next_state; |
|
(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; |
|
yy_current_state = yy_get_previous_state( ); |
|
/* Okay, we're now positioned to make the NUL |
* transition. We couldn't have |
* yy_get_previous_state() go ahead and do it |
* for us because it doesn't know how to deal |
* with the possibility of jamming (and we don't |
* want to build jamming into it because then it |
* will run more slowly). |
*/ |
|
yy_next_state = yy_try_NUL_trans( yy_current_state ); |
|
yy_bp = (yytext_ptr) + YY_MORE_ADJ; |
|
if ( yy_next_state ) |
{ |
/* Consume the NUL. */ |
yy_cp = ++(yy_c_buf_p); |
yy_current_state = yy_next_state; |
goto yy_match; |
} |
|
else |
{ |
yy_cp = (yy_c_buf_p); |
goto yy_find_action; |
} |
} |
|
else switch ( yy_get_next_buffer( ) ) |
{ |
case EOB_ACT_END_OF_FILE: |
{ |
(yy_did_buffer_switch_on_eof) = 0; |
|
if ( yywrap( ) ) |
{ |
/* Note: because we've taken care in |
* yy_get_next_buffer() to have set up |
* yytext, we can now set up |
* yy_c_buf_p so that if some total |
* hoser (like flex itself) wants to |
* call the scanner after we return the |
* YY_NULL, it'll still work - another |
* YY_NULL will get returned. |
*/ |
(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; |
|
yy_act = YY_STATE_EOF(YY_START); |
goto do_action; |
} |
|
else |
{ |
if ( ! (yy_did_buffer_switch_on_eof) ) |
YY_NEW_FILE; |
} |
break; |
} |
|
case EOB_ACT_CONTINUE_SCAN: |
(yy_c_buf_p) = |
(yytext_ptr) + yy_amount_of_matched_text; |
|
yy_current_state = yy_get_previous_state( ); |
|
yy_cp = (yy_c_buf_p); |
yy_bp = (yytext_ptr) + YY_MORE_ADJ; |
goto yy_match; |
|
case EOB_ACT_LAST_MATCH: |
(yy_c_buf_p) = |
&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; |
|
yy_current_state = yy_get_previous_state( ); |
|
yy_cp = (yy_c_buf_p); |
yy_bp = (yytext_ptr) + YY_MORE_ADJ; |
goto yy_find_action; |
} |
break; |
} |
|
default: |
YY_FATAL_ERROR( |
"fatal flex scanner internal error--no action found" ); |
} /* end of action switch */ |
} /* end of scanning one token */ |
} /* end of yylex */ |
|
/* The contents of this function are C++ specific, so the () macro is not used. |
*/ |
yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) |
{ |
yyin = arg_yyin; |
yyout = arg_yyout; |
yy_c_buf_p = 0; |
yy_init = 0; |
yy_start = 0; |
yy_flex_debug = 0; |
yylineno = 1; // this will only get updated if %option yylineno |
|
yy_did_buffer_switch_on_eof = 0; |
|
yy_looking_for_trail_begin = 0; |
yy_more_flag = 0; |
yy_more_len = 0; |
yy_more_offset = yy_prev_more_offset = 0; |
|
yy_start_stack_ptr = yy_start_stack_depth = 0; |
yy_start_stack = NULL; |
|
yy_buffer_stack = 0; |
yy_buffer_stack_top = 0; |
yy_buffer_stack_max = 0; |
|
yy_state_buf = 0; |
|
} |
|
/* The contents of this function are C++ specific, so the () macro is not used. |
*/ |
yyFlexLexer::~yyFlexLexer() |
{ |
delete [] yy_state_buf; |
yyfree(yy_start_stack ); |
yy_delete_buffer( YY_CURRENT_BUFFER ); |
yyfree(yy_buffer_stack ); |
} |
|
/* The contents of this function are C++ specific, so the () macro is not used. |
*/ |
void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) |
{ |
if ( new_in ) |
{ |
yy_delete_buffer( YY_CURRENT_BUFFER ); |
yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); |
} |
|
if ( new_out ) |
yyout = new_out; |
} |
|
#ifdef YY_INTERACTIVE |
int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) |
#else |
int yyFlexLexer::LexerInput( char* buf, int max_size ) |
#endif |
{ |
if ( yyin->eof() || yyin->fail() ) |
return 0; |
|
#ifdef YY_INTERACTIVE |
yyin->get( buf[0] ); |
|
if ( yyin->eof() ) |
return 0; |
|
if ( yyin->bad() ) |
return -1; |
|
return 1; |
|
#else |
(void) yyin->read( buf, max_size ); |
|
if ( yyin->bad() ) |
return -1; |
else |
return yyin->gcount(); |
#endif |
} |
|
void yyFlexLexer::LexerOutput( const char* buf, int size ) |
{ |
(void) yyout->write( buf, size ); |
} |
|
/* yy_get_next_buffer - try to read in a new buffer |
* |
* Returns a code representing an action: |
* EOB_ACT_LAST_MATCH - |
* EOB_ACT_CONTINUE_SCAN - continue scanning from current position |
* EOB_ACT_END_OF_FILE - end of file |
*/ |
int yyFlexLexer::yy_get_next_buffer() |
{ |
register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; |
register char *source = (yytext_ptr); |
register int number_to_move, i; |
int ret_val; |
|
if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) |
YY_FATAL_ERROR( |
"fatal flex scanner internal error--end of buffer missed" ); |
|
if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) |
{ /* Don't try to fill the buffer, so this is an EOF. */ |
if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) |
{ |
/* We matched a single character, the EOB, so |
* treat this as a final EOF. |
*/ |
return EOB_ACT_END_OF_FILE; |
} |
|
else |
{ |
/* We matched some text prior to the EOB, first |
* process it. |
*/ |
return EOB_ACT_LAST_MATCH; |
} |
} |
|
/* Try to read more data. */ |
|
/* First move last chars to start of buffer. */ |
number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; |
|
for ( i = 0; i < number_to_move; ++i ) |
*(dest++) = *(source++); |
|
if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) |
/* don't do the read, it's not guaranteed to return an EOF, |
* just force an EOF |
*/ |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; |
|
else |
{ |
int num_to_read = |
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; |
|
while ( num_to_read <= 0 ) |
{ /* Not enough room in the buffer - grow it. */ |
|
/* just a shorter name for the current buffer */ |
YY_BUFFER_STATE b = YY_CURRENT_BUFFER; |
|
int yy_c_buf_p_offset = |
(int) ((yy_c_buf_p) - b->yy_ch_buf); |
|
if ( b->yy_is_our_buffer ) |
{ |
int new_size = b->yy_buf_size * 2; |
|
if ( new_size <= 0 ) |
b->yy_buf_size += b->yy_buf_size / 8; |
else |
b->yy_buf_size *= 2; |
|
b->yy_ch_buf = (char *) |
/* Include room in for 2 EOB chars. */ |
yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); |
} |
else |
/* Can't grow it, we don't own it. */ |
b->yy_ch_buf = 0; |
|
if ( ! b->yy_ch_buf ) |
YY_FATAL_ERROR( |
"fatal error - scanner input buffer overflow" ); |
|
(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; |
|
num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - |
number_to_move - 1; |
|
} |
|
if ( num_to_read > YY_READ_BUF_SIZE ) |
num_to_read = YY_READ_BUF_SIZE; |
|
/* Read in more data. */ |
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), |
(yy_n_chars), (size_t) num_to_read ); |
|
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); |
} |
|
if ( (yy_n_chars) == 0 ) |
{ |
if ( number_to_move == YY_MORE_ADJ ) |
{ |
ret_val = EOB_ACT_END_OF_FILE; |
yyrestart( yyin ); |
} |
|
else |
{ |
ret_val = EOB_ACT_LAST_MATCH; |
YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = |
YY_BUFFER_EOF_PENDING; |
} |
} |
|
else |
ret_val = EOB_ACT_CONTINUE_SCAN; |
|
if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { |
/* Extend the array by 50%, plus the number we really need. */ |
yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); |
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); |
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) |
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); |
} |
|
(yy_n_chars) += number_to_move; |
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; |
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; |
|
(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; |
|
return ret_val; |
} |
|
/* yy_get_previous_state - get the state just before the EOB char was reached */ |
|
yy_state_type yyFlexLexer::yy_get_previous_state() |
{ |
register yy_state_type yy_current_state; |
register char *yy_cp; |
|
yy_current_state = (yy_start); |
|
for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) |
{ |
register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); |
if ( yy_accept[yy_current_state] ) |
{ |
(yy_last_accepting_state) = yy_current_state; |
(yy_last_accepting_cpos) = yy_cp; |
} |
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) |
{ |
yy_current_state = (int) yy_def[yy_current_state]; |
if ( yy_current_state >= 141 ) |
yy_c = yy_meta[(unsigned int) yy_c]; |
} |
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; |
} |
|
return yy_current_state; |
} |
|
/* yy_try_NUL_trans - try to make a transition on the NUL character |
* |
* synopsis |
* next_state = yy_try_NUL_trans( current_state ); |
*/ |
yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) |
{ |
register int yy_is_jam; |
register char *yy_cp = (yy_c_buf_p); |
|
register YY_CHAR yy_c = 1; |
if ( yy_accept[yy_current_state] ) |
{ |
(yy_last_accepting_state) = yy_current_state; |
(yy_last_accepting_cpos) = yy_cp; |
} |
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) |
{ |
yy_current_state = (int) yy_def[yy_current_state]; |
if ( yy_current_state >= 141 ) |
yy_c = yy_meta[(unsigned int) yy_c]; |
} |
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; |
yy_is_jam = (yy_current_state == 140); |
|
return yy_is_jam ? 0 : yy_current_state; |
} |
|
void yyFlexLexer::yyunput( int c, register char* yy_bp) |
{ |
register char *yy_cp; |
|
yy_cp = (yy_c_buf_p); |
|
/* undo effects of setting up yytext */ |
*yy_cp = (yy_hold_char); |
|
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) |
{ /* need to shift things up to make room */ |
/* +2 for EOB chars. */ |
register int number_to_move = (yy_n_chars) + 2; |
register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ |
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; |
register char *source = |
&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; |
|
while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) |
*--dest = *--source; |
|
yy_cp += (int) (dest - source); |
yy_bp += (int) (dest - source); |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = |
(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; |
|
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) |
YY_FATAL_ERROR( "flex scanner push-back overflow" ); |
} |
|
*--yy_cp = (char) c; |
|
(yytext_ptr) = yy_bp; |
(yy_hold_char) = *yy_cp; |
(yy_c_buf_p) = yy_cp; |
} |
|
int yyFlexLexer::yyinput() |
{ |
int c; |
|
*(yy_c_buf_p) = (yy_hold_char); |
|
if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) |
{ |
/* yy_c_buf_p now points to the character we want to return. |
* If this occurs *before* the EOB characters, then it's a |
* valid NUL; if not, then we've hit the end of the buffer. |
*/ |
if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) |
/* This was really a NUL. */ |
*(yy_c_buf_p) = '\0'; |
|
else |
{ /* need more input */ |
int offset = (yy_c_buf_p) - (yytext_ptr); |
++(yy_c_buf_p); |
|
switch ( yy_get_next_buffer( ) ) |
{ |
case EOB_ACT_LAST_MATCH: |
/* This happens because yy_g_n_b() |
* sees that we've accumulated a |
* token and flags that we need to |
* try matching the token before |
* proceeding. But for input(), |
* there's no matching to consider. |
* So convert the EOB_ACT_LAST_MATCH |
* to EOB_ACT_END_OF_FILE. |
*/ |
|
/* Reset buffer status. */ |
yyrestart( yyin ); |
|
/*FALLTHROUGH*/ |
|
case EOB_ACT_END_OF_FILE: |
{ |
if ( yywrap( ) ) |
return EOF; |
|
if ( ! (yy_did_buffer_switch_on_eof) ) |
YY_NEW_FILE; |
#ifdef __cplusplus |
return yyinput(); |
#else |
return input(); |
#endif |
} |
|
case EOB_ACT_CONTINUE_SCAN: |
(yy_c_buf_p) = (yytext_ptr) + offset; |
break; |
} |
} |
} |
|
c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ |
*(yy_c_buf_p) = '\0'; /* preserve yytext */ |
(yy_hold_char) = *++(yy_c_buf_p); |
|
return c; |
} |
|
/** Immediately switch to a different input stream. |
* @param input_file A readable stream. |
* |
* @note This function does not reset the start condition to @c INITIAL . |
*/ |
void yyFlexLexer::yyrestart( std::istream* input_file ) |
{ |
|
if ( ! YY_CURRENT_BUFFER ){ |
yyensure_buffer_stack (); |
YY_CURRENT_BUFFER_LVALUE = |
yy_create_buffer( yyin, YY_BUF_SIZE ); |
} |
|
yy_init_buffer( YY_CURRENT_BUFFER, input_file ); |
yy_load_buffer_state( ); |
} |
|
/** Switch to a different input buffer. |
* @param new_buffer The new input buffer. |
* |
*/ |
void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) |
{ |
|
/* TODO. We should be able to replace this entire function body |
* with |
* yypop_buffer_state(); |
* yypush_buffer_state(new_buffer); |
*/ |
yyensure_buffer_stack (); |
if ( YY_CURRENT_BUFFER == new_buffer ) |
return; |
|
if ( YY_CURRENT_BUFFER ) |
{ |
/* Flush out information for old buffer. */ |
*(yy_c_buf_p) = (yy_hold_char); |
YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); |
} |
|
YY_CURRENT_BUFFER_LVALUE = new_buffer; |
yy_load_buffer_state( ); |
|
/* We don't actually know whether we did this switch during |
* EOF (yywrap()) processing, but the only time this flag |
* is looked at is after yywrap() is called, so it's safe |
* to go ahead and always set it. |
*/ |
(yy_did_buffer_switch_on_eof) = 1; |
} |
|
void yyFlexLexer::yy_load_buffer_state() |
{ |
(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; |
(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; |
yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; |
(yy_hold_char) = *(yy_c_buf_p); |
} |
|
/** Allocate and initialize an input buffer state. |
* @param file A readable stream. |
* @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. |
* |
* @return the allocated buffer state. |
*/ |
YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) |
{ |
YY_BUFFER_STATE b; |
|
b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); |
if ( ! b ) |
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); |
|
b->yy_buf_size = size; |
|
/* yy_ch_buf has to be 2 characters longer than the size given because |
* we need to put in 2 end-of-buffer characters. |
*/ |
b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); |
if ( ! b->yy_ch_buf ) |
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); |
|
b->yy_is_our_buffer = 1; |
|
yy_init_buffer( b, file ); |
|
return b; |
} |
|
/** Destroy the buffer. |
* @param b a buffer created with yy_create_buffer() |
* |
*/ |
void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) |
{ |
|
if ( ! b ) |
return; |
|
if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ |
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; |
|
if ( b->yy_is_our_buffer ) |
yyfree((void *) b->yy_ch_buf ); |
|
yyfree((void *) b ); |
} |
|
extern "C" int isatty (int ); |
|
/* Initializes or reinitializes a buffer. |
* This function is sometimes called more than once on the same buffer, |
* such as during a yyrestart() or at EOF. |
*/ |
void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) |
|
{ |
int oerrno = errno; |
|
yy_flush_buffer( b ); |
|
b->yy_input_file = file; |
b->yy_fill_buffer = 1; |
|
/* If b is the current buffer, then yy_init_buffer was _probably_ |
* called from yyrestart() or through yy_get_next_buffer. |
* In that case, we don't want to reset the lineno or column. |
*/ |
if (b != YY_CURRENT_BUFFER){ |
b->yy_bs_lineno = 1; |
b->yy_bs_column = 0; |
} |
|
b->yy_is_interactive = 0; |
errno = oerrno; |
} |
|
/** Discard all buffered characters. On the next scan, YY_INPUT will be called. |
* @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. |
* |
*/ |
void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) |
{ |
if ( ! b ) |
return; |
|
b->yy_n_chars = 0; |
|
/* We always need two end-of-buffer characters. The first causes |
* a transition to the end-of-buffer state. The second causes |
* a jam in that state. |
*/ |
b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; |
b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; |
|
b->yy_buf_pos = &b->yy_ch_buf[0]; |
|
b->yy_at_bol = 1; |
b->yy_buffer_status = YY_BUFFER_NEW; |
|
if ( b == YY_CURRENT_BUFFER ) |
yy_load_buffer_state( ); |
} |
|
/** Pushes the new state onto the stack. The new state becomes |
* the current state. This function will allocate the stack |
* if necessary. |
* @param new_buffer The new state. |
* |
*/ |
void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) |
{ |
if (new_buffer == NULL) |
return; |
|
yyensure_buffer_stack(); |
|
/* This block is copied from yy_switch_to_buffer. */ |
if ( YY_CURRENT_BUFFER ) |
{ |
/* Flush out information for old buffer. */ |
*(yy_c_buf_p) = (yy_hold_char); |
YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); |
} |
|
/* Only push if top exists. Otherwise, replace top. */ |
if (YY_CURRENT_BUFFER) |
(yy_buffer_stack_top)++; |
YY_CURRENT_BUFFER_LVALUE = new_buffer; |
|
/* copied from yy_switch_to_buffer. */ |
yy_load_buffer_state( ); |
(yy_did_buffer_switch_on_eof) = 1; |
} |
|
/** Removes and deletes the top of the stack, if present. |
* The next element becomes the new top. |
* |
*/ |
void yyFlexLexer::yypop_buffer_state (void) |
{ |
if (!YY_CURRENT_BUFFER) |
return; |
|
yy_delete_buffer(YY_CURRENT_BUFFER ); |
YY_CURRENT_BUFFER_LVALUE = NULL; |
if ((yy_buffer_stack_top) > 0) |
--(yy_buffer_stack_top); |
|
if (YY_CURRENT_BUFFER) { |
yy_load_buffer_state( ); |
(yy_did_buffer_switch_on_eof) = 1; |
} |
} |
|
/* Allocates the stack if it does not exist. |
* Guarantees space for at least one push. |
*/ |
void yyFlexLexer::yyensure_buffer_stack(void) |
{ |
int num_to_alloc; |
|
if (!(yy_buffer_stack)) { |
|
/* First allocation is just for 2 elements, since we don't know if this |
* scanner will even need a stack. We use 2 instead of 1 to avoid an |
* immediate realloc on the next call. |
*/ |
num_to_alloc = 1; |
(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc |
(num_to_alloc * sizeof(struct yy_buffer_state*) |
); |
if ( ! (yy_buffer_stack) ) |
YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); |
|
memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); |
|
(yy_buffer_stack_max) = num_to_alloc; |
(yy_buffer_stack_top) = 0; |
return; |
} |
|
if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ |
|
/* Increase the buffer to prepare for a possible push. */ |
int grow_size = 8 /* arbitrary grow size */; |
|
num_to_alloc = (yy_buffer_stack_max) + grow_size; |
(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc |
((yy_buffer_stack), |
num_to_alloc * sizeof(struct yy_buffer_state*) |
); |
if ( ! (yy_buffer_stack) ) |
YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); |
|
/* zero only the new slots.*/ |
memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); |
(yy_buffer_stack_max) = num_to_alloc; |
} |
} |
|
void yyFlexLexer::yy_push_state( int new_state ) |
{ |
if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) |
{ |
yy_size_t new_size; |
|
(yy_start_stack_depth) += YY_START_STACK_INCR; |
new_size = (yy_start_stack_depth) * sizeof( int ); |
|
if ( ! (yy_start_stack) ) |
(yy_start_stack) = (int *) yyalloc(new_size ); |
|
else |
(yy_start_stack) = (int *) yyrealloc((void *) (yy_start_stack),new_size ); |
|
if ( ! (yy_start_stack) ) |
YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); |
} |
|
(yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; |
|
BEGIN(new_state); |
} |
|
void yyFlexLexer::yy_pop_state() |
{ |
if ( --(yy_start_stack_ptr) < 0 ) |
YY_FATAL_ERROR( "start-condition stack underflow" ); |
|
BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); |
} |
|
int yyFlexLexer::yy_top_state() |
{ |
return (yy_start_stack)[(yy_start_stack_ptr) - 1]; |
} |
|
#ifndef YY_EXIT_FAILURE |
#define YY_EXIT_FAILURE 2 |
#endif |
|
void yyFlexLexer::LexerError( yyconst char msg[] ) |
{ |
std::cerr << msg << std::endl; |
exit( YY_EXIT_FAILURE ); |
} |
|
/* Redefine yyless() so it works in section 3 code. */ |
|
#undef yyless |
#define yyless(n) \ |
do \ |
{ \ |
/* Undo effects of setting up yytext. */ \ |
int yyless_macro_arg = (n); \ |
YY_LESS_LINENO(yyless_macro_arg);\ |
yytext[yyleng] = (yy_hold_char); \ |
(yy_c_buf_p) = yytext + yyless_macro_arg; \ |
(yy_hold_char) = *(yy_c_buf_p); \ |
*(yy_c_buf_p) = '\0'; \ |
yyleng = yyless_macro_arg; \ |
} \ |
while ( 0 ) |
|
/* Accessor methods (get/set functions) to struct members. */ |
|
/* |
* Internal utility routines. |
*/ |
|
#ifndef yytext_ptr |
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) |
{ |
register int i; |
for ( i = 0; i < n; ++i ) |
s1[i] = s2[i]; |
} |
#endif |
|
#ifdef YY_NEED_STRLEN |
static int yy_flex_strlen (yyconst char * s ) |
{ |
register int n; |
for ( n = 0; s[n]; ++n ) |
; |
|
return n; |
} |
#endif |
|
void *yyalloc (yy_size_t size ) |
{ |
return (void *) malloc( size ); |
} |
|
void *yyrealloc (void * ptr, yy_size_t size ) |
{ |
/* The cast to (char *) in the following accommodates both |
* implementations that use char* generic pointers, and those |
* that use void* generic pointers. It works with the latter |
* because both ANSI C and C++ allow castless assignment from |
* any pointer type to void*, and deal with argument conversions |
* as though doing an assignment. |
*/ |
return (void *) realloc( (char *) ptr, size ); |
} |
|
void yyfree (void * ptr ) |
{ |
free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ |
} |
|
#define YYTABLES_NAME "yytables" |
|
#line 105 "scanner.l" |
|
|
|
/branches/beta_2.0/compiler/src/vp_compiler/Makefile
0,0 → 1,9
all: |
bison parser.y |
flex scanner.l |
g++ -g lex.yy.cc Main.cpp parser.tab.c Preprocessor.cpp Instruction.cpp -o theia_vp_compile |
mv -v theia_vp_compile ../../bin/ |
clean: |
rm -rf parser.tab.c parser.tab.h location.hh position.hh stack.hh |
rm -rf lex.yy.cc |
rm -rf theia_compile |
/branches/beta_2.0/compiler/src/cp_compiler/Scanner.h
0,0 → 1,66
/* This program is free software. It comes without any warranty, to |
* the extent permitted by applicable law. You can redistribute it |
* and/or modify it under the terms of the Do What The Fuck You Want |
* To Public License, Version 2, as published by Sam Hocevar. See |
* http://sam.zoy.org/wtfpl/COPYING for more details. */ |
|
#pragma once |
|
// Only include FlexLexer.h if it hasn't been already included |
#if ! defined(yyFlexLexerOnce) |
#include <FlexLexer.h> |
#endif |
|
// Override the interface for yylex since we namespaced it |
#undef YY_DECL |
#define YY_DECL int Theia::Scanner::yylex() |
|
// Include Bison for types / tokens |
#include "parser.tab.h" |
|
|
|
namespace Theia |
{ |
class Scanner : public yyFlexLexer |
{ |
public: |
// constructor accepts the input and output streams |
// 0 means std equivilant (stdin, stdout) |
Scanner(std::istream * in = 0, std::ostream * out = 0) : yyFlexLexer(in, out) { } |
|
// overloaded version of yylex - we need a pointer to yylval and yylloc |
inline int yylex(Parser::semantic_type * lval, |
Parser::location_type * lloc); |
|
private: |
// Scanning function created by Flex; make this private to force usage |
// of the overloaded method so we can get a pointer to Bison's yylval |
int yylex(); |
|
// point to yylval (provided by Bison in overloaded yylex) |
Parser::semantic_type * yylval; |
|
// pointer to yylloc (provided by Bison in overloaded yylex) |
Parser::location_type * yylloc; |
|
// block default constructor |
Scanner(); |
// block default copy constructor |
Scanner(Scanner const &rhs); |
// block default assignment operator |
Scanner &operator=(Scanner const &rhs); |
}; |
|
// all our overloaded version does is save yylval and yylloc to member variables |
// and invoke the generated scanner |
int Scanner::yylex(Parser::semantic_type * lval, |
Parser::location_type * lloc) { |
yylval = lval; |
yylloc = lloc; |
return yylex(); |
} |
|
} |
//} |
|
/branches/beta_2.0/compiler/src/cp_compiler/parser.tab.c
0,0 → 1,1599
|
/* A Bison parser, made by GNU Bison 2.4.1. */ |
|
/* Skeleton implementation for Bison LALR(1) parsers in C++ |
|
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software |
Foundation, Inc. |
|
This program is free software: you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation, either version 3 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
/* As a special exception, you may create a larger work that contains |
part or all of the Bison parser skeleton and distribute that work |
under terms of your choice, so long as that work isn't itself a |
parser generator using the skeleton or a modified version thereof |
as a parser skeleton. Alternatively, if you modify or redistribute |
the parser skeleton itself, you may (at your option) remove this |
special exception, which will cause the skeleton and the resulting |
Bison output files to be licensed under the GNU General Public |
License without this special exception. |
|
This special exception was added by the Free Software Foundation in |
version 2.2 of Bison. */ |
|
|
/* First part of user declarations. */ |
|
|
/* Line 311 of lalr1.cc */ |
#line 41 "parser.tab.c" |
|
|
#include "parser.tab.h" |
|
/* User implementation prologue. */ |
|
|
/* Line 317 of lalr1.cc */ |
#line 50 "parser.tab.c" |
/* Unqualified %code blocks. */ |
|
/* Line 318 of lalr1.cc */ |
#line 68 "parser.y" |
|
#include "Instruction.h" |
#include <vector> |
CControlInstruction I; |
std::vector< unsigned int > gBranchStack; |
static int gInsertedInstructions = 0; |
static int gWhileLoopAddress = 0; |
#define FUNCTION_PARAM_START_REGION 4 |
#define FUNCTION_PARAM_LAST_REGION 7 |
std::map<std::string, unsigned int> gVaribleMap; |
|
#define AUTOVAR_START_REGION 9 |
#define TEMP_VAR_START_OFFSET 128 |
unsigned int gAutoVarIndex = AUTOVAR_START_REGION; |
|
unsigned int gFunctionParameterIndex = FUNCTION_PARAM_START_REGION; |
//---------------------------------------------------------- |
int GetCurrentLineNumber( const Theia::Parser::location_type &loc ) |
{ |
int ret = -1; |
std::stringstream ss2; |
std::string where; |
ss2 << loc; |
ss2 >> where; |
where.erase(where.find_first_of(".")); |
std::stringstream ss3; |
ss3 << where; |
ss3 >> ret; |
return ret; |
} |
//---------------------------------------------------------- |
unsigned int GetAddressFromIdentifier( std::string aIdentifier, Theia::Parser::location_type yylloc ) |
{ |
if (aIdentifier.find("R") != std::string::npos) |
{ |
return atoi(aIdentifier.c_str()+1); |
} |
if (gVaribleMap.find(aIdentifier) == gVaribleMap.end()) |
{ |
std::ostringstream ret; |
ret << "Undefined variable '" << aIdentifier << "' at line " << yylloc << " \n"; |
throw ret.str(); |
} |
|
return gVaribleMap[ aIdentifier ]; |
|
} |
//---------------------------------------------------------- |
unsigned int gTempRegisterIndex = TEMP_VAR_START_OFFSET; |
//---------------------------------------------------------- |
unsigned int GetFreeTempRegister( void ) |
{ |
|
return gTempRegisterIndex++; |
|
} |
//---------------------------------------------------------- |
void ResetTempRegisterIndex( void ) |
{ |
|
gTempRegisterIndex = TEMP_VAR_START_OFFSET; |
} |
//---------------------------------------------------------- |
unsigned int AllocateVariable( ) |
{ |
gAutoVarIndex++; |
return gAutoVarIndex; |
|
} |
//---------------------------------------------------------- |
// Prototype for the yylex function |
static int yylex(Theia::Parser::semantic_type * yylval, |
Theia::Parser::location_type * yylloc, |
Theia::Scanner &scanner); |
|
|
|
/* Line 318 of lalr1.cc */ |
#line 133 "parser.tab.c" |
|
#ifndef YY_ |
# if YYENABLE_NLS |
# if ENABLE_NLS |
# include <libintl.h> /* FIXME: INFRINGES ON USER NAME SPACE */ |
# define YY_(msgid) dgettext ("bison-runtime", msgid) |
# endif |
# endif |
# ifndef YY_ |
# define YY_(msgid) msgid |
# endif |
#endif |
|
/* Suppress unused-variable warnings by "using" E. */ |
#define YYUSE(e) ((void) (e)) |
|
/* Enable debugging if requested. */ |
#if YYDEBUG |
|
/* A pseudo ostream that takes yydebug_ into account. */ |
# define YYCDEBUG if (yydebug_) (*yycdebug_) |
|
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ |
do { \ |
if (yydebug_) \ |
{ \ |
*yycdebug_ << Title << ' '; \ |
yy_symbol_print_ ((Type), (Value), (Location)); \ |
*yycdebug_ << std::endl; \ |
} \ |
} while (false) |
|
# define YY_REDUCE_PRINT(Rule) \ |
do { \ |
if (yydebug_) \ |
yy_reduce_print_ (Rule); \ |
} while (false) |
|
# define YY_STACK_PRINT() \ |
do { \ |
if (yydebug_) \ |
yystack_print_ (); \ |
} while (false) |
|
#else /* !YYDEBUG */ |
|
# define YYCDEBUG if (false) std::cerr |
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) |
# define YY_REDUCE_PRINT(Rule) |
# define YY_STACK_PRINT() |
|
#endif /* !YYDEBUG */ |
|
#define yyerrok (yyerrstatus_ = 0) |
#define yyclearin (yychar = yyempty_) |
|
#define YYACCEPT goto yyacceptlab |
#define YYABORT goto yyabortlab |
#define YYERROR goto yyerrorlab |
#define YYRECOVERING() (!!yyerrstatus_) |
|
|
/* Line 380 of lalr1.cc */ |
#line 28 "parser.y" |
namespace Theia { |
|
/* Line 380 of lalr1.cc */ |
#line 201 "parser.tab.c" |
#if YYERROR_VERBOSE |
|
/* Return YYSTR after stripping away unnecessary quotes and |
backslashes, so that it's suitable for yyerror. The heuristic is |
that double-quoting is unnecessary unless the string contains an |
apostrophe, a comma, or backslash (other than backslash-backslash). |
YYSTR is taken from yytname. */ |
std::string |
Parser::yytnamerr_ (const char *yystr) |
{ |
if (*yystr == '"') |
{ |
std::string yyr = ""; |
char const *yyp = yystr; |
|
for (;;) |
switch (*++yyp) |
{ |
case '\'': |
case ',': |
goto do_not_strip_quotes; |
|
case '\\': |
if (*++yyp != '\\') |
goto do_not_strip_quotes; |
/* Fall through. */ |
default: |
yyr += *yyp; |
break; |
|
case '"': |
return yyr; |
} |
do_not_strip_quotes: ; |
} |
|
return yystr; |
} |
|
#endif |
|
/// Build a parser object. |
Parser::Parser (Theia::Scanner &scanner_yyarg, std::map<std::string,unsigned int> & mSymbolMap_yyarg, std::vector< CControlInstruction > &mInstructions_yyarg, bool &mGenerateFixedPointArithmetic_yyarg) |
: |
#if YYDEBUG |
yydebug_ (false), |
yycdebug_ (&std::cerr), |
#endif |
scanner (scanner_yyarg), |
mSymbolMap (mSymbolMap_yyarg), |
mInstructions (mInstructions_yyarg), |
mGenerateFixedPointArithmetic (mGenerateFixedPointArithmetic_yyarg) |
{ |
} |
|
Parser::~Parser () |
{ |
} |
|
#if YYDEBUG |
/*--------------------------------. |
| Print this symbol on YYOUTPUT. | |
`--------------------------------*/ |
|
inline void |
Parser::yy_symbol_value_print_ (int yytype, |
const semantic_type* yyvaluep, const location_type* yylocationp) |
{ |
YYUSE (yylocationp); |
YYUSE (yyvaluep); |
switch (yytype) |
{ |
default: |
break; |
} |
} |
|
|
void |
Parser::yy_symbol_print_ (int yytype, |
const semantic_type* yyvaluep, const location_type* yylocationp) |
{ |
*yycdebug_ << (yytype < yyntokens_ ? "token" : "nterm") |
<< ' ' << yytname_[yytype] << " (" |
<< *yylocationp << ": "; |
yy_symbol_value_print_ (yytype, yyvaluep, yylocationp); |
*yycdebug_ << ')'; |
} |
#endif |
|
void |
Parser::yydestruct_ (const char* yymsg, |
int yytype, semantic_type* yyvaluep, location_type* yylocationp) |
{ |
YYUSE (yylocationp); |
YYUSE (yymsg); |
YYUSE (yyvaluep); |
|
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); |
|
switch (yytype) |
{ |
|
default: |
break; |
} |
} |
|
void |
Parser::yypop_ (unsigned int n) |
{ |
yystate_stack_.pop (n); |
yysemantic_stack_.pop (n); |
yylocation_stack_.pop (n); |
} |
|
#if YYDEBUG |
std::ostream& |
Parser::debug_stream () const |
{ |
return *yycdebug_; |
} |
|
void |
Parser::set_debug_stream (std::ostream& o) |
{ |
yycdebug_ = &o; |
} |
|
|
Parser::debug_level_type |
Parser::debug_level () const |
{ |
return yydebug_; |
} |
|
void |
Parser::set_debug_level (debug_level_type l) |
{ |
yydebug_ = l; |
} |
#endif |
|
int |
Parser::parse () |
{ |
/// Lookahead and lookahead in internal form. |
int yychar = yyempty_; |
int yytoken = 0; |
|
/* State. */ |
int yyn; |
int yylen = 0; |
int yystate = 0; |
|
/* Error handling. */ |
int yynerrs_ = 0; |
int yyerrstatus_ = 0; |
|
/// Semantic value of the lookahead. |
semantic_type yylval; |
/// Location of the lookahead. |
location_type yylloc; |
/// The locations where the error started and ended. |
location_type yyerror_range[2]; |
|
/// $$. |
semantic_type yyval; |
/// @$. |
location_type yyloc; |
|
int yyresult; |
|
YYCDEBUG << "Starting parse" << std::endl; |
|
|
/* Initialize the stacks. The initial state will be pushed in |
yynewstate, since the latter expects the semantical and the |
location values to have been already stored, initialize these |
stacks with a primary value. */ |
yystate_stack_ = state_stack_type (0); |
yysemantic_stack_ = semantic_stack_type (0); |
yylocation_stack_ = location_stack_type (0); |
yysemantic_stack_.push (yylval); |
yylocation_stack_.push (yylloc); |
|
/* New state. */ |
yynewstate: |
yystate_stack_.push (yystate); |
YYCDEBUG << "Entering state " << yystate << std::endl; |
|
/* Accept? */ |
if (yystate == yyfinal_) |
goto yyacceptlab; |
|
goto yybackup; |
|
/* Backup. */ |
yybackup: |
|
/* Try to take a decision without lookahead. */ |
yyn = yypact_[yystate]; |
if (yyn == yypact_ninf_) |
goto yydefault; |
|
/* Read a lookahead token. */ |
if (yychar == yyempty_) |
{ |
YYCDEBUG << "Reading a token: "; |
yychar = yylex (&yylval, &yylloc, scanner); |
} |
|
|
/* Convert token to internal form. */ |
if (yychar <= yyeof_) |
{ |
yychar = yytoken = yyeof_; |
YYCDEBUG << "Now at end of input." << std::endl; |
} |
else |
{ |
yytoken = yytranslate_ (yychar); |
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); |
} |
|
/* If the proper action on seeing token YYTOKEN is to reduce or to |
detect an error, take that action. */ |
yyn += yytoken; |
if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) |
goto yydefault; |
|
/* Reduce or error. */ |
yyn = yytable_[yyn]; |
if (yyn <= 0) |
{ |
if (yyn == 0 || yyn == yytable_ninf_) |
goto yyerrlab; |
yyn = -yyn; |
goto yyreduce; |
} |
|
/* Shift the lookahead token. */ |
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); |
|
/* Discard the token being shifted. */ |
yychar = yyempty_; |
|
yysemantic_stack_.push (yylval); |
yylocation_stack_.push (yylloc); |
|
/* Count tokens shifted since error; after three, turn off error |
status. */ |
if (yyerrstatus_) |
--yyerrstatus_; |
|
yystate = yyn; |
goto yynewstate; |
|
/*-----------------------------------------------------------. |
| yydefault -- do the default action for the current state. | |
`-----------------------------------------------------------*/ |
yydefault: |
yyn = yydefact_[yystate]; |
if (yyn == 0) |
goto yyerrlab; |
goto yyreduce; |
|
/*-----------------------------. |
| yyreduce -- Do a reduction. | |
`-----------------------------*/ |
yyreduce: |
yylen = yyr2_[yyn]; |
/* If YYLEN is nonzero, implement the default value of the action: |
`$$ = $1'. Otherwise, use the top of the stack. |
|
Otherwise, the following line sets YYVAL to garbage. |
This behavior is undocumented and Bison |
users should not rely upon it. */ |
if (yylen) |
yyval = yysemantic_stack_[yylen - 1]; |
else |
yyval = yysemantic_stack_[0]; |
|
{ |
slice<location_type, location_stack_type> slice (yylocation_stack_, yylen); |
YYLLOC_DEFAULT (yyloc, slice, yylen); |
} |
YY_REDUCE_PRINT (yyn); |
switch (yyn) |
{ |
case 5: |
|
/* Line 678 of lalr1.cc */ |
#line 158 "parser.y" |
{ |
|
unsigned int ImmediateValue; |
std::string StringHex = (yysemantic_stack_[(5) - (3)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
|
|
I.mComment = "Start"; |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetOperation(EOPERATION_DELIVERCOMMAND); |
I.SetDestinationAddress( ImmediateValue+1 ); |
I.SetSrc1Address( VP_COMMAND_START_MAIN_THREAD ); |
mInstructions.push_back(I); |
I.Clear(); |
} |
break; |
|
case 7: |
|
/* Line 678 of lalr1.cc */ |
#line 179 "parser.y" |
{ |
|
I.SetOperation( EOPERATION_ADD ); |
I.mComment = "Setting destination ID SPR for Copy data block"; |
I.SetDestinationAddress( BLOCK_DST_REG ); |
I.SetSrc1Address( GetAddressFromIdentifier((yysemantic_stack_[(9) - (3)]),yylloc)); |
I.SetSrc0Address(0); |
mInstructions.push_back(I); |
I.Clear(); |
|
std::cout << "COPY_DATA_BLOCK I(" << GetAddressFromIdentifier((yysemantic_stack_[(9) - (3)]),yylloc) << ") " << GetAddressFromIdentifier((yysemantic_stack_[(9) - (5)]),yylloc) << " " << GetAddressFromIdentifier((yysemantic_stack_[(9) - (7)]),yylloc) << "\n"; |
I.mComment = "Copy data block"; |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetOperation(EOPERATION_COPYBLOCK); |
//I.SetCopyDestinationId(ImmediateValue); |
I.SetCopyDestinationId(0); |
I.SetCopyDestinationAddress(GetAddressFromIdentifier((yysemantic_stack_[(9) - (5)]),yylloc)); |
I.SetCopySourceAddress(GetAddressFromIdentifier((yysemantic_stack_[(9) - (7)]),yylloc)); |
I.SetCopySize(GetAddressFromIdentifier((yysemantic_stack_[(9) - (9)]),yylloc)); |
mInstructions.push_back(I); |
I.Clear(); |
} |
break; |
|
case 8: |
|
/* Line 678 of lalr1.cc */ |
#line 203 "parser.y" |
{ |
//Insert a stupid NOP before the exit... is a bug but easier to just patch like this... |
|
I.mComment = "Exit"; |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetOperation(EOPERATION_EXIT); |
mInstructions.push_back(I); |
I.Clear(); |
} |
break; |
|
case 9: |
|
/* Line 678 of lalr1.cc */ |
#line 215 "parser.y" |
{ |
|
I.mComment = "Storing constant '1'"; |
I.SetOperation( EOPERATION_SUB ); |
unsigned int TmpReg = GetFreeTempRegister(); |
I.SetDestinationAddress( TmpReg ); |
I.SetLiteral(1); |
mInstructions.push_back( I ); |
I.Clear(); |
|
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetOperation( EOPERATION_ADD ); |
I.SetDestinationAddress( GetAddressFromIdentifier((yysemantic_stack_[(4) - (1)]),yylloc) ); |
I.SetSrc1Address( GetAddressFromIdentifier((yysemantic_stack_[(4) - (3)]),yylloc)); |
I.SetSrc0Address( TmpReg ); |
mInstructions.push_back( I ); |
I.Clear(); |
gInsertedInstructions = 0; |
ResetTempRegisterIndex(); |
} |
break; |
|
case 10: |
|
/* Line 678 of lalr1.cc */ |
#line 237 "parser.y" |
{ |
|
I.mComment = "Storing constant '1'"; |
I.SetOperation( EOPERATION_ADD ); |
unsigned int TmpReg = GetFreeTempRegister(); |
I.SetDestinationAddress( TmpReg ); |
I.SetLiteral(1); |
mInstructions.push_back( I ); |
I.Clear(); |
|
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetOperation( EOPERATION_ADD ); |
I.SetDestinationAddress( GetAddressFromIdentifier((yysemantic_stack_[(4) - (1)]),yylloc) ); |
I.SetSrc1Address( GetAddressFromIdentifier((yysemantic_stack_[(4) - (3)]),yylloc)); |
I.SetSrc0Address( TmpReg ); |
mInstructions.push_back( I ); |
I.Clear(); |
gInsertedInstructions = 0; |
ResetTempRegisterIndex(); |
|
} |
break; |
|
case 11: |
|
/* Line 678 of lalr1.cc */ |
#line 260 "parser.y" |
{ |
mInstructions[mInstructions.size()-gInsertedInstructions].mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetOperation( EOPERATION_ADD ); |
I.SetDestinationAddress( GetAddressFromIdentifier((yysemantic_stack_[(4) - (1)]),yylloc) ); |
I.SetSrc1Address( GetAddressFromIdentifier((yysemantic_stack_[(4) - (3)]),yylloc)); |
I.SetSrc0Address(0); |
mInstructions.push_back( I ); |
I.Clear(); |
gInsertedInstructions = 0; |
ResetTempRegisterIndex(); |
} |
break; |
|
case 12: |
|
/* Line 678 of lalr1.cc */ |
#line 273 "parser.y" |
{ |
mInstructions[mInstructions.size()-gInsertedInstructions].mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetOperation( EOPERATION_ADD ); |
I.SetDestinationAddress( GetAddressFromIdentifier((yysemantic_stack_[(5) - (1)]),yylloc) ); |
I.SetSrc1Address( GetAddressFromIdentifier((yysemantic_stack_[(5) - (4)]),yylloc)); |
I.SetSrc0Address( GetAddressFromIdentifier((yysemantic_stack_[(5) - (1)]),yylloc) ); |
mInstructions.push_back( I ); |
I.Clear(); |
gInsertedInstructions = 0; |
} |
break; |
|
case 13: |
|
/* Line 678 of lalr1.cc */ |
#line 284 "parser.y" |
{gWhileLoopAddress = (mInstructions.size());} |
break; |
|
case 14: |
|
/* Line 678 of lalr1.cc */ |
#line 285 "parser.y" |
{ |
mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()+1); |
gBranchStack.pop_back(); |
//Now I need to put a GOTO so that the while gets evaluated again... |
//jump out of the if |
I.Clear(); |
I.SetOperation( EOPERATION_BRANCH ); |
I.mComment = "while loop goto re-eval boolean"; |
I.SetDestinationAddress( gWhileLoopAddress ); |
mInstructions.push_back(I); |
I.Clear(); |
|
I.SetOperation( EOPERATION_NOP ); |
I.mComment = "branch delay"; |
I.SetDestinationAddress( gWhileLoopAddress ); |
mInstructions.push_back(I); |
I.Clear(); |
gInsertedInstructions = 0; |
} |
break; |
|
case 15: |
|
/* Line 678 of lalr1.cc */ |
#line 306 "parser.y" |
{ |
|
} |
break; |
|
case 16: |
|
/* Line 678 of lalr1.cc */ |
#line 316 "parser.y" |
{ |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetOperation( EOPERATION_ADD ); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetSrc1Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (1)]),yylloc)); |
I.SetSrc0Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (3)]),yylloc)); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
std::stringstream ss; |
ss << "R" << TempRegIndex; |
(yyval) = ss.str(); |
|
//$$ = ss.str(); |
|
} |
break; |
|
case 17: |
|
/* Line 678 of lalr1.cc */ |
#line 334 "parser.y" |
{ |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetOperation( EOPERATION_OR ); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetSrc1Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (1)]),yylloc)); |
I.SetSrc0Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (3)]),yylloc)); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
std::stringstream ss; |
ss << "R" << TempRegIndex; |
(yyval) = ss.str(); |
} |
break; |
|
case 18: |
|
/* Line 678 of lalr1.cc */ |
#line 349 "parser.y" |
{ |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetOperation( EOPERATION_SUB ); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetSrc1Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (1)]),yylloc)); |
I.SetSrc0Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (3)]),yylloc)); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
std::stringstream ss; |
ss << "R" << TempRegIndex; |
(yyval) = ss.str(); |
} |
break; |
|
case 19: |
|
/* Line 678 of lalr1.cc */ |
#line 364 "parser.y" |
{ |
(yyval) = (yysemantic_stack_[(1) - (1)]); |
} |
break; |
|
case 20: |
|
/* Line 678 of lalr1.cc */ |
#line 372 "parser.y" |
{ |
|
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetOperation( EOPERATION_SHL ); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetSrc1Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (1)]),yylloc)); |
I.SetSrc0Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (3)]),yylloc)); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
std::stringstream ss; |
ss << "R" << TempRegIndex; |
(yyval) = ss.str(); |
} |
break; |
|
case 21: |
|
/* Line 678 of lalr1.cc */ |
#line 388 "parser.y" |
{ |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetOperation( EOPERATION_SHR ); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetSrc1Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (1)]),yylloc)); |
I.SetSrc0Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (3)]),yylloc)); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
std::stringstream ss; |
ss << "R" << TempRegIndex; |
(yyval) = ss.str(); |
} |
break; |
|
case 22: |
|
/* Line 678 of lalr1.cc */ |
#line 403 "parser.y" |
{ |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetOperation( EOPERATION_AND ); |
I.SetDestinationAddress( TempRegIndex ); |
I.SetSrc1Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (1)]),yylloc)); |
I.SetSrc0Address(GetAddressFromIdentifier((yysemantic_stack_[(3) - (3)]),yylloc)); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
I.Clear(); |
std::stringstream ss; |
ss << "R" << TempRegIndex; |
(yyval) = ss.str(); |
} |
break; |
|
case 23: |
|
/* Line 678 of lalr1.cc */ |
#line 418 "parser.y" |
{ |
(yyval) = (yysemantic_stack_[(1) - (1)]); |
} |
break; |
|
case 24: |
|
/* Line 678 of lalr1.cc */ |
#line 426 "parser.y" |
{ |
(yyval) = (yysemantic_stack_[(1) - (1)]); |
} |
break; |
|
case 25: |
|
/* Line 678 of lalr1.cc */ |
#line 431 "parser.y" |
{ |
(yyval) = (yysemantic_stack_[(3) - (2)]); |
} |
break; |
|
case 26: |
|
/* Line 678 of lalr1.cc */ |
#line 436 "parser.y" |
{ |
unsigned int ImmediateValue; |
std::string StringHex = (yysemantic_stack_[(1) - (1)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
unsigned int TempRegIndex = GetFreeTempRegister(); |
I.SetOperation( EOPERATION_ASSIGN ); |
// I.mSourceLine = GetCurrentLineNumber( yylloc ); |
|
I.SetDestinationAddress( TempRegIndex ); |
|
I.SetLiteral(ImmediateValue); |
|
mInstructions.push_back(I); |
|
gInsertedInstructions++; |
I.Clear(); |
std::stringstream ss2; |
ss2 << "R" << TempRegIndex; |
(yyval) = ss2.str(); |
} |
break; |
|
case 27: |
|
/* Line 678 of lalr1.cc */ |
#line 465 "parser.y" |
{ |
// Transform to HEX string |
unsigned int Val; |
std::string StringDec = (yysemantic_stack_[(1) - (1)]); |
std::stringstream ss; |
ss << StringDec; |
ss >> Val; |
std::stringstream ss2; |
ss2 << std::hex << Val; |
(yyval) = ss2.str(); |
} |
break; |
|
case 28: |
|
/* Line 678 of lalr1.cc */ |
#line 478 "parser.y" |
{ |
std::string StringHex = (yysemantic_stack_[(1) - (1)]); |
// Get rid of the 0x |
StringHex.erase(StringHex.begin(),StringHex.begin()+2); |
std::stringstream ss; |
ss << std::hex << StringHex; |
|
(yyval) = ss.str(); |
} |
break; |
|
case 29: |
|
/* Line 678 of lalr1.cc */ |
#line 489 "parser.y" |
{ |
// Transform to HEX string |
std::string StringBin = (yysemantic_stack_[(1) - (1)]); |
// Get rid of the 0b |
StringBin.erase(StringBin.begin(),StringBin.begin()+2); |
std::bitset<32> Bitset( StringBin ); |
std::stringstream ss2; |
ss2 << std::hex << Bitset; |
(yyval) = ss2.str(); |
} |
break; |
|
case 30: |
|
/* Line 678 of lalr1.cc */ |
#line 504 "parser.y" |
{ |
|
unsigned int ImmediateValue = 0x1; |
unsigned int TempRegIndex0 = GetFreeTempRegister(); |
I.SetOperation( EOPERATION_ASSIGN ); |
I.SetDestinationAddress( TempRegIndex0 ); |
I.SetLiteral(ImmediateValue); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
|
|
I.SetOperation( EOPERATION_BEQ ); |
I.SetDestinationAddress( 0 ); |
I.SetSrc1Address( STATUS_REG ); |
I.SetSrc0Address(TempRegIndex0); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
gBranchStack.push_back(mInstructions.size() - 1); |
I.Clear(); |
|
I.SetOperation( EOPERATION_NOP ); |
I.mComment = "branch delay"; |
I.SetDestinationAddress( gWhileLoopAddress ); |
mInstructions.push_back(I); |
I.Clear(); |
|
|
|
} |
break; |
|
case 31: |
|
/* Line 678 of lalr1.cc */ |
#line 535 "parser.y" |
{ |
|
I.SetOperation( EOPERATION_BNE ); |
I.SetDestinationAddress( 0 ); |
I.SetSrc1Address( GetAddressFromIdentifier((yysemantic_stack_[(3) - (1)]),yylloc) ); |
I.SetSrc0Address( GetAddressFromIdentifier((yysemantic_stack_[(3) - (3)]),yylloc)); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
gBranchStack.push_back(mInstructions.size() - 1); |
I.Clear(); |
|
I.SetOperation( EOPERATION_NOP ); |
I.mComment = "branch delay"; |
I.SetDestinationAddress( gWhileLoopAddress ); |
mInstructions.push_back(I); |
I.Clear(); |
|
} |
break; |
|
case 32: |
|
/* Line 678 of lalr1.cc */ |
#line 555 "parser.y" |
{ |
|
I.SetOperation( EOPERATION_BLE ); |
I.SetDestinationAddress( 0 ); |
I.SetSrc1Address( GetAddressFromIdentifier((yysemantic_stack_[(3) - (1)]),yylloc) ); |
I.SetSrc0Address( GetAddressFromIdentifier((yysemantic_stack_[(3) - (3)]),yylloc)); |
mInstructions.push_back(I); |
gInsertedInstructions++; |
gBranchStack.push_back(mInstructions.size() - 1); |
I.Clear(); |
|
I.SetOperation( EOPERATION_NOP ); |
I.mComment = "branch delay"; |
I.SetDestinationAddress( gWhileLoopAddress ); |
mInstructions.push_back(I); |
I.Clear(); |
|
} |
break; |
|
case 33: |
|
/* Line 678 of lalr1.cc */ |
#line 577 "parser.y" |
{ |
if (gVaribleMap.find((yysemantic_stack_[(3) - (1)])) != gVaribleMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol '" << (yysemantic_stack_[(3) - (1)]) << "'\n"; |
throw ret.str(); |
} |
|
gVaribleMap[ (yysemantic_stack_[(3) - (1)]) ] = AllocateVariable(); |
} |
break; |
|
case 34: |
|
/* Line 678 of lalr1.cc */ |
#line 589 "parser.y" |
{ |
if (gVaribleMap.find((yysemantic_stack_[(5) - (1)])) != gVaribleMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol '" << (yysemantic_stack_[(5) - (1)]) << "'\n"; |
throw ret.str(); |
} |
|
gVaribleMap[ (yysemantic_stack_[(5) - (1)]) ] = AllocateVariable(); |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetOperation( EOPERATION_ASSIGN ); |
I.SetDestinationAddress( gVaribleMap[ (yysemantic_stack_[(5) - (1)]) ] ); |
I.SetLiteral( atoi((yysemantic_stack_[(5) - (3)]).c_str() ) ); |
mInstructions.push_back( I ); |
I.Clear(); |
|
} |
break; |
|
case 35: |
|
/* Line 678 of lalr1.cc */ |
#line 608 "parser.y" |
{ |
if (gVaribleMap.find((yysemantic_stack_[(3) - (1)])) != gVaribleMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol '" << (yysemantic_stack_[(3) - (1)]) << "'\n"; |
throw ret.str(); |
} |
unsigned int ImmediateValue; |
std::string StringHex = (yysemantic_stack_[(3) - (3)]); |
std::stringstream ss; |
ss << std::hex << StringHex; |
ss >> ImmediateValue; |
gVaribleMap[ (yysemantic_stack_[(3) - (1)]) ] = AllocateVariable(); |
I.mSourceLine = GetCurrentLineNumber( yylloc ); |
I.SetOperation( EOPERATION_ASSIGN ); |
I.SetDestinationAddress( gVaribleMap[ (yysemantic_stack_[(3) - (1)]) ] ); |
I.SetLiteral( ImmediateValue ); |
mInstructions.push_back( I ); |
I.Clear(); |
} |
break; |
|
case 36: |
|
/* Line 678 of lalr1.cc */ |
#line 630 "parser.y" |
{ |
if (gVaribleMap.find((yysemantic_stack_[(1) - (1)])) != gVaribleMap.end()) |
{ |
std::ostringstream ret; |
ret << "Duplicated symbol '" << (yysemantic_stack_[(1) - (1)]) << "'\n"; |
throw ret.str(); |
} |
|
gVaribleMap[ (yysemantic_stack_[(1) - (1)]) ] = AllocateVariable(); |
} |
break; |
|
|
|
/* Line 678 of lalr1.cc */ |
#line 1082 "parser.tab.c" |
default: |
break; |
} |
YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc); |
|
yypop_ (yylen); |
yylen = 0; |
YY_STACK_PRINT (); |
|
yysemantic_stack_.push (yyval); |
yylocation_stack_.push (yyloc); |
|
/* Shift the result of the reduction. */ |
yyn = yyr1_[yyn]; |
yystate = yypgoto_[yyn - yyntokens_] + yystate_stack_[0]; |
if (0 <= yystate && yystate <= yylast_ |
&& yycheck_[yystate] == yystate_stack_[0]) |
yystate = yytable_[yystate]; |
else |
yystate = yydefgoto_[yyn - yyntokens_]; |
goto yynewstate; |
|
/*------------------------------------. |
| yyerrlab -- here on detecting error | |
`------------------------------------*/ |
yyerrlab: |
/* If not already recovering from an error, report this error. */ |
if (!yyerrstatus_) |
{ |
++yynerrs_; |
error (yylloc, yysyntax_error_ (yystate, yytoken)); |
} |
|
yyerror_range[0] = yylloc; |
if (yyerrstatus_ == 3) |
{ |
/* If just tried and failed to reuse lookahead token after an |
error, discard it. */ |
|
if (yychar <= yyeof_) |
{ |
/* Return failure if at end of input. */ |
if (yychar == yyeof_) |
YYABORT; |
} |
else |
{ |
yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc); |
yychar = yyempty_; |
} |
} |
|
/* Else will try to reuse lookahead token after shifting the error |
token. */ |
goto yyerrlab1; |
|
|
/*---------------------------------------------------. |
| yyerrorlab -- error raised explicitly by YYERROR. | |
`---------------------------------------------------*/ |
yyerrorlab: |
|
/* Pacify compilers like GCC when the user code never invokes |
YYERROR and the label yyerrorlab therefore never appears in user |
code. */ |
if (false) |
goto yyerrorlab; |
|
yyerror_range[0] = yylocation_stack_[yylen - 1]; |
/* Do not reclaim the symbols of the rule which action triggered |
this YYERROR. */ |
yypop_ (yylen); |
yylen = 0; |
yystate = yystate_stack_[0]; |
goto yyerrlab1; |
|
/*-------------------------------------------------------------. |
| yyerrlab1 -- common code for both syntax error and YYERROR. | |
`-------------------------------------------------------------*/ |
yyerrlab1: |
yyerrstatus_ = 3; /* Each real token shifted decrements this. */ |
|
for (;;) |
{ |
yyn = yypact_[yystate]; |
if (yyn != yypact_ninf_) |
{ |
yyn += yyterror_; |
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) |
{ |
yyn = yytable_[yyn]; |
if (0 < yyn) |
break; |
} |
} |
|
/* Pop the current state because it cannot handle the error token. */ |
if (yystate_stack_.height () == 1) |
YYABORT; |
|
yyerror_range[0] = yylocation_stack_[0]; |
yydestruct_ ("Error: popping", |
yystos_[yystate], |
&yysemantic_stack_[0], &yylocation_stack_[0]); |
yypop_ (); |
yystate = yystate_stack_[0]; |
YY_STACK_PRINT (); |
} |
|
yyerror_range[1] = yylloc; |
// Using YYLLOC is tempting, but would change the location of |
// the lookahead. YYLOC is available though. |
YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); |
yysemantic_stack_.push (yylval); |
yylocation_stack_.push (yyloc); |
|
/* Shift the error token. */ |
YY_SYMBOL_PRINT ("Shifting", yystos_[yyn], |
&yysemantic_stack_[0], &yylocation_stack_[0]); |
|
yystate = yyn; |
goto yynewstate; |
|
/* Accept. */ |
yyacceptlab: |
yyresult = 0; |
goto yyreturn; |
|
/* Abort. */ |
yyabortlab: |
yyresult = 1; |
goto yyreturn; |
|
yyreturn: |
if (yychar != yyempty_) |
yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); |
|
/* Do not reclaim the symbols of the rule which action triggered |
this YYABORT or YYACCEPT. */ |
yypop_ (yylen); |
while (yystate_stack_.height () != 1) |
{ |
yydestruct_ ("Cleanup: popping", |
yystos_[yystate_stack_[0]], |
&yysemantic_stack_[0], |
&yylocation_stack_[0]); |
yypop_ (); |
} |
|
return yyresult; |
} |
|
// Generate an error message. |
std::string |
Parser::yysyntax_error_ (int yystate, int tok) |
{ |
std::string res; |
YYUSE (yystate); |
#if YYERROR_VERBOSE |
int yyn = yypact_[yystate]; |
if (yypact_ninf_ < yyn && yyn <= yylast_) |
{ |
/* Start YYX at -YYN if negative to avoid negative indexes in |
YYCHECK. */ |
int yyxbegin = yyn < 0 ? -yyn : 0; |
|
/* Stay within bounds of both yycheck and yytname. */ |
int yychecklim = yylast_ - yyn + 1; |
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; |
int count = 0; |
for (int x = yyxbegin; x < yyxend; ++x) |
if (yycheck_[x + yyn] == x && x != yyterror_) |
++count; |
|
// FIXME: This method of building the message is not compatible |
// with internationalization. It should work like yacc.c does it. |
// That is, first build a string that looks like this: |
// "syntax error, unexpected %s or %s or %s" |
// Then, invoke YY_ on this string. |
// Finally, use the string as a format to output |
// yytname_[tok], etc. |
// Until this gets fixed, this message appears in English only. |
res = "syntax error, unexpected "; |
res += yytnamerr_ (yytname_[tok]); |
if (count < 5) |
{ |
count = 0; |
for (int x = yyxbegin; x < yyxend; ++x) |
if (yycheck_[x + yyn] == x && x != yyterror_) |
{ |
res += (!count++) ? ", expecting " : " or "; |
res += yytnamerr_ (yytname_[x]); |
} |
} |
} |
else |
#endif |
res = YY_("syntax error"); |
return res; |
} |
|
|
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing |
STATE-NUM. */ |
const signed char Parser::yypact_ninf_ = -21; |
const signed char |
Parser::yypact_[] = |
{ |
17, -19, 12, 65, -21, 16, 7, 4, -21, -14, |
22, -21, 76, 73, -3, 29, 34, 28, 76, -21, |
-21, 34, -19, -21, 76, -21, -21, -21, -21, 46, |
-21, 9, -21, 76, 40, 57, 39, 85, -21, 47, |
78, -21, 43, 76, -21, 76, 76, 76, 76, 76, |
53, -21, -21, -21, 20, 84, 86, 76, -19, -21, |
-21, -21, -21, -21, -21, -21, -21, 76, 76, 92, |
-21, 62, -21, 63, 63, 17, 76, -2, 0, -21, |
87, -21 |
}; |
|
/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE |
doesn't specify something else to do. Zero means the default is an |
error. */ |
const unsigned char |
Parser::yydefact_[] = |
{ |
2, 0, 0, 0, 13, 0, 0, 0, 4, 36, |
0, 8, 0, 0, 0, 0, 0, 0, 0, 1, |
3, 0, 0, 6, 0, 27, 28, 29, 24, 0, |
19, 23, 26, 0, 0, 0, 0, 0, 15, 0, |
35, 33, 0, 0, 11, 0, 0, 0, 0, 0, |
0, 10, 9, 30, 0, 0, 0, 0, 0, 25, |
16, 18, 17, 20, 21, 22, 12, 0, 0, 0, |
5, 0, 34, 31, 32, 2, 0, 0, 0, 14, |
0, 7 |
}; |
|
/* YYPGOTO[NTERM-NUM]. */ |
const signed char |
Parser::yypgoto_[] = |
{ |
-21, 38, -7, -21, -17, 59, 60, -1, -21, -20 |
}; |
|
/* YYDEFGOTO[NTERM-NUM]. */ |
const signed char |
Parser::yydefgoto_[] = |
{ |
-1, 7, 8, 15, 29, 30, 31, 32, 55, 10 |
}; |
|
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If |
positive, shift that token. If negative, reduce the rule which |
number is the opposite. If zero, do what YYDEFACT says. */ |
const signed char Parser::yytable_ninf_ = -1; |
const unsigned char |
Parser::yytable_[] = |
{ |
20, 39, 41, 1, 19, 2, 21, 42, 9, 1, |
80, 2, 47, 48, 22, 37, 50, 79, 18, 54, |
40, 43, 1, 35, 2, 3, 45, 16, 67, 4, |
5, 3, 68, 6, 46, 4, 5, 11, 72, 6, |
71, 43, 49, 17, 3, 36, 45, 23, 4, 5, |
73, 74, 6, 38, 46, 24, 25, 26, 27, 78, |
59, 25, 26, 27, 43, 51, 28, 43, 43, 45, |
20, 44, 45, 45, 43, 57, 53, 46, 66, 45, |
46, 46, 52, 43, 43, 12, 13, 46, 45, 45, |
76, 14, 24, 33, 34, 56, 46, 46, 25, 26, |
27, 69, 60, 28, 61, 62, 58, 63, 64, 65, |
75, 70, 81, 77 |
}; |
|
/* YYCHECK. */ |
const unsigned char |
Parser::yycheck_[] = |
{ |
7, 18, 22, 5, 0, 7, 20, 24, 27, 5, |
10, 7, 3, 4, 28, 16, 33, 19, 11, 36, |
21, 21, 5, 26, 7, 27, 26, 11, 8, 31, |
32, 27, 12, 35, 34, 31, 32, 25, 58, 35, |
57, 21, 33, 27, 27, 16, 26, 25, 31, 32, |
67, 68, 35, 25, 34, 16, 22, 23, 24, 76, |
17, 22, 23, 24, 21, 25, 27, 21, 21, 26, |
77, 25, 26, 26, 21, 28, 37, 34, 25, 26, |
34, 34, 25, 21, 21, 20, 21, 34, 26, 26, |
28, 26, 16, 20, 21, 10, 34, 34, 22, 23, |
24, 17, 43, 27, 45, 46, 28, 47, 48, 49, |
18, 25, 25, 75 |
}; |
|
/* STOS_[STATE-NUM] -- The (internal number of the) accessing |
symbol of state STATE-NUM. */ |
const unsigned char |
Parser::yystos_[] = |
{ |
0, 5, 7, 27, 31, 32, 35, 39, 40, 27, |
47, 25, 20, 21, 26, 41, 11, 27, 11, 0, |
40, 20, 28, 25, 16, 22, 23, 24, 27, 42, |
43, 44, 45, 20, 21, 26, 16, 45, 25, 42, |
45, 47, 42, 21, 25, 26, 34, 3, 4, 33, |
42, 25, 25, 37, 42, 46, 10, 28, 28, 17, |
43, 43, 43, 44, 44, 44, 25, 8, 12, 17, |
25, 42, 47, 42, 42, 18, 28, 39, 42, 19, |
10, 25 |
}; |
|
#if YYDEBUG |
/* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding |
to YYLEX-NUM. */ |
const unsigned short int |
Parser::yytoken_number_[] = |
{ |
0, 256, 257, 258, 259, 260, 261, 262, 263, 264, |
265, 266, 267, 268, 269, 270, 271, 272, 273, 274, |
275, 276, 277, 278, 279, 280, 281, 282, 283, 284, |
285, 286, 287, 288, 289, 290, 291, 292 |
}; |
#endif |
|
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ |
const unsigned char |
Parser::yyr1_[] = |
{ |
0, 38, 39, 39, 39, 40, 40, 40, 40, 40, |
40, 40, 40, 41, 40, 40, 42, 42, 42, 42, |
43, 43, 43, 43, 44, 44, 44, 45, 45, 45, |
46, 46, 46, 47, 47, 47, 47 |
}; |
|
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ |
const unsigned char |
Parser::yyr2_[] = |
{ |
0, 2, 0, 2, 1, 5, 3, 9, 2, 4, |
4, 4, 5, 0, 8, 3, 3, 3, 3, 1, |
3, 3, 3, 1, 1, 3, 1, 1, 1, 1, |
1, 3, 3, 3, 5, 3, 1 |
}; |
|
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE |
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. |
First, the terminals, then, starting at \a yyntokens_, nonterminals. */ |
const char* |
const Parser::yytname_[] = |
{ |
"$end", "error", "$undefined", "SHL", "SHR", "SCALAR", "RETURN", "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", "ADD", |
"DECCONST", "HEXCONST", "BINCONST", "EOS", "MINUS", "IDENTIFIER", |
"COMMA", "OPEN_SQUARE_BRACE", "CLOSE_SQUARE_BRACE", "WHILE", "START", |
"BITWISE_AND", "BITWISE_OR", "COPY_DATA_BLOCK", "COPY_CODE_BLOCK", |
"BLOCK_TRANSFER_IN_PROGRESS", "$accept", "statement_list", "statement", |
"$@1", "expression", "term", "factor", "constant", "boolean_expression", |
"scalar_list", 0 |
}; |
#endif |
|
#if YYDEBUG |
/* YYRHS -- A `-1'-separated list of the rules' RHS. */ |
const Parser::rhs_number_type |
Parser::yyrhs_[] = |
{ |
39, 0, -1, -1, 39, 40, -1, 40, -1, 32, |
11, 45, 10, 25, -1, 5, 47, 25, -1, 35, |
11, 42, 28, 42, 28, 42, 10, 25, -1, 7, |
25, -1, 27, 26, 26, 25, -1, 27, 21, 21, |
25, -1, 27, 20, 42, 25, -1, 27, 21, 20, |
42, 25, -1, -1, 31, 41, 16, 46, 17, 18, |
39, 19, -1, 32, 27, 25, -1, 42, 21, 43, |
-1, 42, 34, 43, -1, 42, 26, 43, -1, 43, |
-1, 44, 3, 44, -1, 44, 4, 44, -1, 44, |
33, 44, -1, 44, -1, 27, -1, 16, 42, 17, |
-1, 45, -1, 22, -1, 23, -1, 24, -1, 37, |
-1, 42, 8, 42, -1, 42, 12, 42, -1, 27, |
28, 47, -1, 27, 20, 45, 28, 47, -1, 27, |
20, 45, -1, 27, -1 |
}; |
|
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in |
YYRHS. */ |
const unsigned char |
Parser::yyprhs_[] = |
{ |
0, 0, 3, 4, 7, 9, 15, 19, 29, 32, |
37, 42, 47, 53, 54, 63, 67, 71, 75, 79, |
81, 85, 89, 93, 95, 97, 101, 103, 105, 107, |
109, 111, 115, 119, 123, 129, 133 |
}; |
|
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ |
const unsigned short int |
Parser::yyrline_[] = |
{ |
0, 148, 148, 150, 152, 157, 176, 178, 202, 214, |
236, 259, 272, 284, 284, 305, 315, 333, 348, 363, |
371, 387, 402, 417, 425, 430, 435, 464, 477, 488, |
503, 534, 554, 576, 588, 607, 629 |
}; |
|
// Print the state stack on the debug stream. |
void |
Parser::yystack_print_ () |
{ |
*yycdebug_ << "Stack now"; |
for (state_stack_type::const_iterator i = yystate_stack_.begin (); |
i != yystate_stack_.end (); ++i) |
*yycdebug_ << ' ' << *i; |
*yycdebug_ << std::endl; |
} |
|
// Report on the debug stream that the rule \a yyrule is going to be reduced. |
void |
Parser::yy_reduce_print_ (int yyrule) |
{ |
unsigned int yylno = yyrline_[yyrule]; |
int yynrhs = yyr2_[yyrule]; |
/* Print the symbols being reduced, and their result. */ |
*yycdebug_ << "Reducing stack by rule " << yyrule - 1 |
<< " (line " << yylno << "):" << std::endl; |
/* The symbols being reduced. */ |
for (int yyi = 0; yyi < yynrhs; yyi++) |
YY_SYMBOL_PRINT (" $" << yyi + 1 << " =", |
yyrhs_[yyprhs_[yyrule] + yyi], |
&(yysemantic_stack_[(yynrhs) - (yyi + 1)]), |
&(yylocation_stack_[(yynrhs) - (yyi + 1)])); |
} |
#endif // YYDEBUG |
|
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ |
Parser::token_number_type |
Parser::yytranslate_ (int t) |
{ |
static |
const token_number_type |
translate_table[] = |
{ |
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 1, 2, 3, 4, |
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, |
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, |
35, 36, 37 |
}; |
if ((unsigned int) t <= yyuser_token_number_max_) |
return translate_table[t]; |
else |
return yyundef_token_; |
} |
|
const int Parser::yyeof_ = 0; |
const int Parser::yylast_ = 113; |
const int Parser::yynnts_ = 10; |
const int Parser::yyempty_ = -2; |
const int Parser::yyfinal_ = 19; |
const int Parser::yyterror_ = 1; |
const int Parser::yyerrcode_ = 256; |
const int Parser::yyntokens_ = 38; |
|
const unsigned int Parser::yyuser_token_number_max_ = 292; |
const Parser::token_number_type Parser::yyundef_token_ = 2; |
|
|
/* Line 1054 of lalr1.cc */ |
#line 28 "parser.y" |
} // Theia |
|
/* Line 1054 of lalr1.cc */ |
#line 1574 "parser.tab.c" |
|
|
/* Line 1056 of lalr1.cc */ |
#line 643 "parser.y" |
|
|
|
|
// Error function throws an exception (std::string) with the location and error message |
void Theia::Parser::error(const Theia::Parser::location_type &loc, |
const std::string &msg) { |
std::ostringstream ret; |
ret << "\ncp_compile -- Parser Error at " << loc << ": " << msg; |
throw ret.str(); |
} |
|
// Now that we have the Parser declared, we can declare the Scanner and implement |
// the yylex function |
#include "Scanner.h" |
static int yylex(Theia::Parser::semantic_type * yylval, |
Theia::Parser::location_type * yylloc, |
Theia::Scanner &scanner) { |
return scanner.yylex(yylval, yylloc); |
} |
|
|
/branches/beta_2.0/compiler/src/cp_compiler/scanner.l
0,0 → 1,90
%{ |
|
/********************************************************************************** |
Theia, Ray Cast Programable graphic Processing Unit. |
Copyright (C) 2012 Diego Valverde (diego.valverde.g@gmail.com) |
|
This program is free software; you can redistribute it and/or |
modify it under the terms of the GNU General Public License |
as published by the Free Software Foundation; either version 2 |
of the License, or (at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
***********************************************************************************/ |
|
#include "Scanner.h" |
// used to keep track of location |
#define YY_USER_ACTION yylloc->columns(yyleng); |
int LineNumber = 1; |
%} |
|
%option nodefault yyclass="Scanner" noyywrap c++ |
|
comment "//"(.*)*\n |
separator ([ \t""])+ |
character [a-zA-Z] |
hexchar [a-fA-F] |
digit [0-9] |
decconstant {digit}({digit})* |
hexconstant 0x({digit}|{hexchar})+ |
binconstant 0b(1|0)+ |
registry (r|R)({digit})+ |
identifier ([a-wA-Z])({character}|{digit}|_)* |
|
|
%% |
|
%{ |
yylloc->step(); |
%} |
|
{comment} {yylloc->lines(); ;LineNumber++; ;} |
"\n" {yylloc->lines(); ;LineNumber++;} |
{separator} {/* do nothing */} |
{decconstant} { *yylval = yytext; return Theia::Parser::token::DECCONST; } |
{hexconstant} { *yylval = yytext; return Theia::Parser::token::HEXCONST; } |
{binconstant} { *yylval = yytext; return Theia::Parser::token::BINCONST; } |
"if" {return Theia::Parser::token::IF;} |
"else" {return Theia::Parser::token::ELSE;} |
"while" {return Theia::Parser::token::WHILE;} |
"&" {return Theia::Parser::token::BITWISE_AND;} |
"|" {return Theia::Parser::token::BITWISE_OR;} |
"exit" {return Theia::Parser::token::EXIT;} |
"scalar" {return Theia::Parser::token::SCALAR;} |
"start" {return Theia::Parser::token::START;} |
"copy_data_block" {return Theia::Parser::token::COPY_DATA_BLOCK;} |
"copy_code_block" {return Theia::Parser::token::COPY_CODE_BLOCK;} |
block_transfer_in_progress"" {return Theia::Parser::token::BLOCK_TRANSFER_IN_PROGRESS;} |
"(" {return Theia::Parser::token::OPEN_ROUND_BRACE;} |
")" {return Theia::Parser::token::CLOSE_ROUND_BRACE;} |
"{" {return Theia::Parser::token::OPEN_BRACE;} |
"}" {return Theia::Parser::token::CLOSE_BRACE;} |
"-" {*yylval = yytext;return Theia::Parser::token::MINUS; } |
"==" {return Theia::Parser::token::EQUAL; } |
"!=" {return Theia::Parser::token::NOT_EQUAL; } |
"<=" {return Theia::Parser::token::LESS_OR_EQUAL_THAN; } |
">=" {return Theia::Parser::token::GREATER_OR_EQUAL_THAN; } |
"=" {return Theia::Parser::token::ASSIGN; } |
"<<" { return Theia::Parser::token::SHL;} |
">>" { return Theia::Parser::token::SHR;} |
">" {return Theia::Parser::token::GREATER_THAN; } |
"<" {return Theia::Parser::token::LESS_THAN; } |
"+" {return Theia::Parser::token::ADD; } |
";" {return Theia::Parser::token::EOS; } |
"," {return Theia::Parser::token::COMMA; } |
|
{identifier} {*yylval = yytext; return Theia::Parser::token::IDENTIFIER;} |
. { |
std::ostringstream ret; |
ret << "Unknown Indetifier at line " << LineNumber << " '" << yytext << "'\n"; |
throw ret.str(); |
}; |
%% |
/branches/beta_2.0/compiler/src/cp_compiler/theia_cp_compile
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
branches/beta_2.0/compiler/src/cp_compiler/theia_cp_compile
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: branches/beta_2.0/compiler/src/cp_compiler/parser.tab.h
===================================================================
--- branches/beta_2.0/compiler/src/cp_compiler/parser.tab.h (nonexistent)
+++ branches/beta_2.0/compiler/src/cp_compiler/parser.tab.h (revision 216)
@@ -0,0 +1,382 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
+
+/* Skeleton interface for Bison LALR(1) parsers in C++
+
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software
+ Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C++ LALR(1) parser skeleton written by Akim Demaille. */
+
+#ifndef PARSER_HEADER_H
+# define PARSER_HEADER_H
+
+/* "%code requires" blocks. */
+
+/* Line 35 of lalr1.cc */
+#line 36 "parser.y"
+
+ #include
+ #include
+ #include
+ #include
+ #include
branches/beta_2.0/compiler/bin/theia_cp_compile
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: branches/beta_2.0/compiler/bin/cp_code.list
===================================================================
--- branches/beta_2.0/compiler/bin/cp_code.list (nonexistent)
+++ branches/beta_2.0/compiler/bin/cp_code.list (revision 216)
@@ -0,0 +1,38 @@
+//List file created by theia_compile
+0: 0 //NOP R0 R0 R0
+1: 0 //NOP R0 R0 R0
+2: 0 //NOP R0 R0 R0
+3: d000000 //ASSIGN R0 I(0 )
+// scalar SrcOffset = 0,DstOffset;
+4: d0b0000 //ASSIGN R11 I(0 )
+// DstOffset = (0x0 | (147<<20) | (1<<31) );
+5: d800000 //ASSIGN R128 I(0 )
+6: d810093 //ASSIGN R129 I(147 )
+7: d820014 //ASSIGN R130 I(20 )
+8: 11838182 //SHL R131 R129 R130
+9: 5848083 //OR R132 R128 R131
+10: d850001 //ASSIGN R133 I(1 )
+11: d86001f //ASSIGN R134 I(31 )
+12: 11878586 //SHL R135 R133 R134
+13: 5888487 //OR R136 R132 R135
+14: 20a8800 //ADD R10 R136 R0
+15: d800002 //ASSIGN R128 I(2 )
+//Setting destination ID SPR for Copy data block
+16: 2038000 //ADD R3 R128 R0
+// copy_data_block < 2 , DstOffset ,SrcOffset>;
+//Copy data block
+17: e000b0a //COPYBLOCK DstId: R0 SrcOffset: R11 DstOffsetAndLen: R10
+18: d810001 //ASSIGN R129 I(1 )
+19: 7160281 //BEQ R22 R2 R129
+//branch delay
+20: 120000 //NOP R18 R0 R0
+//while loop goto re-eval boolean
+21: 6120000 //BRANCH R18 R0 R0
+//branch delay
+22: 120000 //NOP R18 R0 R0
+// start <2>;
+//Start
+23: 1030000 //DELIVERCOMMAND R3 R0 R0
+// exit ;
+//Exit
+24: f000000 //EXIT R0 R0 R0
Index: branches/beta_2.0/compiler/bin/control_code.mem
===================================================================
--- branches/beta_2.0/compiler/bin/control_code.mem (nonexistent)
+++ branches/beta_2.0/compiler/bin/control_code.mem (revision 216)
@@ -0,0 +1,26 @@
+//Code generated bt theia_compile
+0 //NOP R0 R0 R0
+0 //NOP R0 R0 R0
+0 //NOP R0 R0 R0
+d000000 //ASSIGN R0 I(0 )
+d0b0000 //ASSIGN R11 I(0 )
+d800000 //ASSIGN R128 I(0 )
+d810093 //ASSIGN R129 I(147 )
+d820014 //ASSIGN R130 I(20 )
+11838182 //SHL R131 R129 R130
+5848083 //OR R132 R128 R131
+d850001 //ASSIGN R133 I(1 )
+d86001f //ASSIGN R134 I(31 )
+11878586 //SHL R135 R133 R134
+5888487 //OR R136 R132 R135
+20a8800 //ADD R10 R136 R0
+d800002 //ASSIGN R128 I(2 )
+2038000 //ADD R3 R128 R0
+e000b0a //COPYBLOCK DstId: R0 SrcOffset: R11 DstOffsetAndLen: R10
+d810001 //ASSIGN R129 I(1 )
+7160281 //BEQ R22 R2 R129
+120000 //NOP R18 R0 R0
+6120000 //BRANCH R18 R0 R0
+120000 //NOP R18 R0 R0
+1030000 //DELIVERCOMMAND R3 R0 R0
+f000000 //EXIT R0 R0 R0
Index: branches/beta_2.0/compiler/bin/theia_vp_compile
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: branches/beta_2.0/compiler/bin/theia_vp_compile
===================================================================
--- branches/beta_2.0/compiler/bin/theia_vp_compile (nonexistent)
+++ branches/beta_2.0/compiler/bin/theia_vp_compile (revision 216)
branches/beta_2.0/compiler/bin/theia_vp_compile
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: branches/beta_2.0/compiler/bin/code_block_header.thh
===================================================================
--- branches/beta_2.0/compiler/bin/code_block_header.thh (nonexistent)
+++ branches/beta_2.0/compiler/bin/code_block_header.thh (revision 216)
@@ -0,0 +1,3 @@
+
+#define TEST_DEFAULT_CODE1_SIZE (147<<20)
+#define TEST_DEFAULT_CODE1_OFFSET 0