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

Subversion Repositories theia_gpu

[/] [theia_gpu/] [branches/] [beta_2.0/] [compiler/] [src/] [vp_compiler/] [parser.y] - Blame information for rev 227

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 216 diegovalve
 
2
/**********************************************************************************
3
Theia, Ray Cast Programable graphic Processing Unit.
4
Copyright (C) 2012  Diego Valverde (diego.valverde.g@gmail.com)
5
 
6
This program is free software; you can redistribute it and/or
7
modify it under the terms of the GNU General Public License
8
as published by the Free Software Foundation; either version 2
9
of the License, or (at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19
 
20
***********************************************************************************/
21
 
22
 
23
%require "2.4.1"
24
%skeleton "lalr1.cc"
25
%defines
26
%error-verbose
27
%locations
28
%define namespace "Theia"
29
%define parser_class_name "Parser"
30
%parse-param { Theia::Scanner &scanner }
31
%parse-param { std::map  & mSymbolMap }
32
%parse-param { std::vector< Instruction > &mInstructions }
33
%parse-param { bool &mGenerateFixedPointArithmetic }
34
%lex-param   { Theia::Scanner &scanner }
35
 
36
%code requires {
37
        #include 
38
        #include 
39
        #include 
40
        #include 
41
        #include 
42
        #include "Instruction.h"
43
        #include 
44
 
45
 
46
        // We want to return a string
47
        #define YYSTYPE std::string
48
 
49
 
50
                namespace Theia
51
                {
52
                        // Forward-declare the Scanner class; the Parser needs to be assigned a
53
                        // Scanner, but the Scanner can't be declared without the Parser
54
                        class Scanner;
55
 
56
                        // We use a map to store the INI data
57
                        typedef std::map > mapData;
58
 
59
 
60
 
61
 
62
 
63
                }
64
 
65
}
66
 
67
%code
68
{
69
        #include "Instruction.h"
70
        #include 
71
        Instruction I,tmpI;
72
 
73
        std::vector< unsigned int > gBranchStack;
74
        static int gInsertedInstructions = 0;
75
        static int gWhileLoopAddress = 0;
76
#define FUNCTION_PARAM_START_REGION 4
77
#define FUNCTION_PARAM_LAST_REGION  10
78
        std::map gFunctionParameters;
79
        std::map gAutoVarMap;
80
        std::map gThreadMap; //Key: Symbol, value: start code addr
81
        bool gThreadScope = false;
82
#define AUTOVAR_START_REGION 9
83
#define THREAD_OFFSET 128
84
unsigned int gExtraDestModifications = 0;
85
unsigned int gAutoVarIndex = AUTOVAR_START_REGION;
86
unsigned int gThreadAutoVarIndex = THREAD_OFFSET;
87
unsigned int gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;
88
//----------------------------------------------------------
89
unsigned int GetNextFunctionParamRegister()
90
{
91
        unsigned Ret = gFunctionParameterIndex++;
92
        return Ret;
93
}
94
 
95
//----------------------------------------------------------
96
void AddFunctionParameter( std::string aVar, Theia::Parser::location_type  yylloc)
97
{
98
        ////std::cout << "Adding " << aVar << "\n";
99
        if (gFunctionParameterIndex+1 > FUNCTION_PARAM_LAST_REGION)
100
        {
101
                        std::ostringstream ret;
102
                        ret << "Cannot allocate more parameters '" << aVar << "' at line " << yylloc << " \n";
103
                        throw ret.str();
104
        }
105
        if (gFunctionParameters.find(aVar) != gFunctionParameters.end())
106
        {
107
                        std::ostringstream ret;
108
                        ret << "Parameter '" << aVar << "' at line " << yylloc << " is already defined\n";
109
                        throw ret.str();
110
        }
111
 
112
        gFunctionParameters[ aVar ] = gFunctionParameterIndex++;
113
 
114
}
115
//----------------------------------------------------------
116
std::string  GetRegisterFromFunctionParameter( std::string aVar )
117
{
118
        ////std::cout << "Looking for " << aVar << "\n";
119
        if (gFunctionParameters.find(aVar) == gFunctionParameters.end())
120
                return "NULL";
121
 
122
        std::ostringstream ss;
123
        ss << gFunctionParameters[ aVar ];
124
        return  ("R" + ss.str());
125
}
126
//----------------------------------------------------------
127
unsigned int GetCurretAutoVarFrameSize()
128
{
129
 
130
        return gAutoVarMap.size();
131
 
132
}
133
//----------------------------------------------------------
134
std::string GetRegisterFromAutoVar( std::string aVar, Theia::Parser::location_type  yylloc )
135
{
136
        if (gAutoVarMap.find(aVar) == gAutoVarMap.end())
137
        {
138
                        std::ostringstream ret;
139
                        ret << "Undefined variable '" << aVar << "' at line " << yylloc << " \n";
140
                        throw ret.str();
141
        }
142
 
143
                std::ostringstream ss;
144
                ss << gAutoVarMap[ aVar ];
145
                return  ("R" + ss.str());
146
}
147
//----------------------------------------------------------
148
int GetCurrentLineNumber( const Theia::Parser::location_type &loc )
149
{
150
                int ret = -1;
151
                std::stringstream ss2;
152
                std::string where;
153
                ss2 << loc;
154
                ss2 >> where;
155
                where.erase(where.find_first_of("."));
156
                std::stringstream ss3;
157
                ss3 << where;
158
                ss3 >> ret;
159
                return ret;
160
}
161
//----------------------------------------------------------
162
unsigned int AllocAutoVar( unsigned int aSize = 1)
163
{
164
 
165
        if (!gThreadScope)
166
        {
167
                gAutoVarIndex += aSize;
168
                return gAutoVarIndex - (aSize-1);
169
        }else{
170
                gThreadAutoVarIndex += aSize;
171
                return (gThreadAutoVarIndex - (aSize-1));
172
        }
173
}
174
//----------------------------------------------------------
175
void ClearFunctionParameterMap()
176
{
177
        gFunctionParameters.clear();
178
        gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;
179
}
180
//----------------------------------------------------------
181
void ClearAutoVarMap()
182
{
183
        gAutoVarMap.clear();
184
        gAutoVarIndex = AUTOVAR_START_REGION;
185
}
186
//----------------------------------------------------------
187
unsigned int gTempRegisterIndex = 1;
188
unsigned int GetFreeTempRegister( )
189
{
190
        if (!gThreadScope)
191
                return gAutoVarIndex + (gTempRegisterIndex++);
192
        else
193
                return gThreadAutoVarIndex + (gTempRegisterIndex++);
194
 
195
}
196
//----------------------------------------------------------
197
void ResetTempRegisterIndex( void )
198
{
199
 
200
        gTempRegisterIndex = 1;
201
}
202
//----------------------------------------------------------
203
bool IsSwizzled( std::string aSource)
204
{
205
        if (aSource.find(".") != std::string::npos)
206
                return true;
207
        else
208
                return false;
209
}
210
 
211
//----------------------------------------------------------
212
void SetSwizzleAndSign( unsigned int aSourceIndex, std::string aSwizzle, Instruction & I )
213
{
214
        std::string Reg,X,Y,Z, junk;
215
        std::stringstream ss( aSwizzle );
216
        ss >> Reg >> junk >> X >> Y >> Z;
217
 
218
 
219
        if (aSourceIndex == 1)
220
        {
221
                if (X == "X") { I.SetSrc1SwizzleX(SWX_X);       }
222
                if (X == "Y") { I.SetSrc1SwizzleX(SWX_Y);       }
223
                if (X == "Z") { I.SetSrc1SwizzleX(SWX_Z);       }
224
                if (X == "-X") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_X);      }
225
                if (X == "-Y") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Y);      }
226
                if (X == "-Z") { I.SetSrc1SignX( true ); I.SetSrc1SwizzleX(SWX_Z);      }
227
 
228
                if (Y == "X") { I.SetSrc1SwizzleY(SWY_X);       }
229
                if (Y == "Y") { I.SetSrc1SwizzleY(SWY_Y);       }
230
                if (Y == "Z") { I.SetSrc1SwizzleY(SWY_Z);       }
231
                if (Y == "-X") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_X);      }
232
                if (Y == "-Y") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Y);      }
233
                if (Y == "-Z") { I.SetSrc1SignY( true ); I.SetSrc1SwizzleY(SWY_Z);      }
234
 
235
                if (Z == "X") { I.SetSrc1SwizzleZ(SWZ_X);       }
236
                if (Z == "Y") { I.SetSrc1SwizzleZ(SWZ_Y);       }
237
                if (Z == "Z") { I.SetSrc1SwizzleZ(SWZ_Z);       }
238
                if (Z == "-X") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_X);      }
239
                if (Z == "-Y") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Y);      }
240
                if (Z == "-Z") { I.SetSrc1SignZ( true ); I.SetSrc1SwizzleZ(SWZ_Z);      }
241
        } else {
242
                if (X == "X") { I.SetSrc0SwizzleX(SWX_X);       }
243
                if (X == "Y") { I.SetSrc0SwizzleX(SWX_Y);       }
244
                if (X == "Z") { I.SetSrc0SwizzleX(SWX_Z);       }
245
                if (X == "-X") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_X);      }
246
                if (X == "-Y") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Y);      }
247
                if (X == "-Z") { I.SetSrc0SignX( true ); I.SetSrc0SwizzleX(SWX_Z);      }
248
 
249
                if (Y == "X") { I.SetSrc0SwizzleY(SWY_X);       }
250
                if (Y == "Y") { I.SetSrc0SwizzleY(SWY_Y);       }
251
                if (Y == "Z") { I.SetSrc0SwizzleY(SWY_Z);       }
252
                if (Y == "-X") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_X);      }
253
                if (Y == "-Y") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Y);      }
254
                if (Y == "-Z") { I.SetSrc0SignY( true ); I.SetSrc0SwizzleY(SWY_Z);      }
255
 
256
                if (Z == "X") { I.SetSrc0SwizzleZ(SWZ_X);       }
257
                if (Z == "Y") { I.SetSrc0SwizzleZ(SWZ_Y);       }
258
                if (Z == "Z") { I.SetSrc0SwizzleZ(SWZ_Z);       }
259
                if (Z == "-X") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_X);      }
260
                if (Z == "-Y") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Y);      }
261
                if (Z == "-Z") { I.SetSrc0SignZ( true ); I.SetSrc0SwizzleZ(SWZ_Z);      }
262
        }
263
}
264
//----------------------------------------------------------
265
void StoreReturnAddress( std::vector & aInstructions, Theia::Parser::location_type & yylloc )
266
{
267
                I.SetCode( EOPERATION_ADD );
268
                I.mComment = "store return address**";
269
                I.SetImm( aInstructions.size()+4 );
270
                I.SetWriteChannel(ECHANNEL_X);
271
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
272
                I.SetDestZero( true );
273
                I.mSourceLine = GetCurrentLineNumber( yylloc );
274
                aInstructions.push_back( I );
275
                I.Clear();
276
}
277
//----------------------------------------------------------
278
void SavePreviousFramePointer( std::vector & aInstructions )
279
{
280
                I.SetCode( EOPERATION_ADD );
281
                I.mComment = "store current frame offset";
282
                I.SetWriteChannel(ECHANNEL_Y);
283
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
284
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
285
                I.SetSrc1SwizzleX(SWX_X);
286
                I.SetSrc1SwizzleY(SWY_X);
287
                I.SetSrc1SwizzleZ(SWZ_X);
288
                I.SetSrc0Address(0);
289
                I.SetSrc0SwizzleX(SWX_X);
290
                I.SetSrc0SwizzleY(SWY_X);
291
                I.SetSrc0SwizzleZ(SWZ_X);
292
                aInstructions.push_back( I );
293
                I.Clear();
294
}
295
//----------------------------------------------------------
296
void SetIndexRegister( unsigned int aIndex, std::vector & aInstructions  )
297
{
298
                Instruction Tmp;
299
                Tmp.SetCode( EOPERATION_ADD );
300
                Tmp.mComment = "store array index register";
301
                Tmp.SetWriteChannel(ECHANNEL_Z);
302
                Tmp.SetDestinationAddress( SPR_CONTROL_REGISTER );
303
                Tmp.SetSrc1Address( aIndex );
304
                Tmp.SetSrc1Displace( true );
305
                Tmp.SetSrc1SwizzleX(SWX_X);
306
                Tmp.SetSrc1SwizzleY(SWY_X);
307
                Tmp.SetSrc1SwizzleZ(SWZ_X);
308
                Tmp.SetSrc0Address(0);
309
                Tmp.SetSrc0SwizzleX(SWX_X);
310
                Tmp.SetSrc0SwizzleY(SWY_X);
311
                Tmp.SetSrc0SwizzleZ(SWZ_X);
312
                //Tmp.SetImm( aIndex );
313
                //Tmp.SetDestZero( true );
314
                aInstructions.push_back( Tmp );
315
 
316
}
317
//----------------------------------------------------------
318
void UpdateFramePointer( std::vector & aInstructions )
319
{
320
                I.SetCode( EOPERATION_ADD );
321
                I.mComment = "displace next frame offset by the number of auto variables in current frame";
322
                I.SetWriteChannel(ECHANNEL_X);
323
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
324
                I.SetImm( GetCurretAutoVarFrameSize() );
325
                I.SetDestZero( false );
326
                aInstructions.push_back( I );
327
                I.Clear();
328
}
329
//----------------------------------------------------------
330
void CallFunction( std::string aFunctionName,  std::vector & aInstructions, std::map  &  aSymbolMap)
331
{
332
                I.SetCode( EOPERATION_ADD );
333
                I.mComment = "call the function";
334
                I.SetBranchFlag( true );
335
                I.SetBranchType( EBRANCH_ALWAYS );
336
                //Now do the branch
337
                if (aSymbolMap.find(aFunctionName) == aSymbolMap.end())
338
                        I.SetDestinationSymbol( "@"+aFunctionName );
339
                else
340
                        I.SetDestinationAddress( aSymbolMap[ aFunctionName ] );
341
 
342
                aInstructions.push_back( I );
343
                I.Clear();
344
}
345
//----------------------------------------------------------
346
void SetDestinationFromRegister( std::string aDestination, Instruction & aInst, bool Imm  )
347
{
348
                //Look for displament addressing mode
349
 
350
                if (aDestination.find("OFFSET") != std::string::npos)
351
                {
352
                        aDestination.erase(aDestination.find("OFFSET"));
353
                        ////std::cout << "^_^ left_hand_side " << Destination << "\n";
354
                        if (Imm == true)
355
                                aInst.SetSrc0Displace( true ); //When Imm == 0, then setting this makes offset
356
                        else
357
                                aInst.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
358
                }
359
                if (aDestination.find(".") != std::string::npos)
360
                {
361
                        aInst.ClearWriteChannel();
362
                        if (aDestination.find("x") != std::string::npos)
363
                                aInst.SetWriteChannel(ECHANNEL_X);
364
                        if (aDestination.find("y") != std::string::npos)
365
                                aInst.SetWriteChannel(ECHANNEL_Y);
366
                        if (aDestination.find("z") != std::string::npos)
367
                                aInst.SetWriteChannel(ECHANNEL_Z);
368
 
369
                        aDestination.erase(aDestination.find("."));
370
 
371
                }
372
                aInst.SetDestinationAddress( atoi(aDestination.c_str()+1) );
373
}
374
//----------------------------------------------------------
375
void PopulateSourceRegisters( std::string a1, std::string a2, Instruction & I, std::vector & aInstructions )
376
{
377
 
378
 
379
                        if ( a1.find("R") == std::string::npos )
380
                        {
381
                                //This is for constants
382
                                unsigned int ImmediateValue;
383
                                std::string StringHex = a1;
384
                                std::stringstream ss;
385
                                ss << std::hex << StringHex;
386
                                ss >> ImmediateValue;
387
                                I.SetImm( ImmediateValue );
388
                        } else {
389
 
390
 
391
 
392
                                if (a1.find("array_element") != std::string::npos)
393
                                {
394
 
395
 
396
                                        std::string Index = a1.substr(a1.find("array_element"));
397
                                        ////std::cout << "XXXXX " << Index << "\n\n\n";
398
                                        Index = Index.substr(Index.find_first_not_of("array_element R"));
399
                                        ////std::cout << "XXXXX " << Index << "\n\n\n";
400
                                        SetIndexRegister( atoi(Index.c_str()), aInstructions );
401
                                        a1.erase(a1.find("array_element"));
402
                                        I.SetSrc0Displace( true );
403
                                        I.SetSrc1Displace( true );
404
                                        I.SetImmBit( true );
405
                                }
406
                                        //Look for displament addressing mode
407
                                else if (a1.find("OFFSET") != std::string::npos)
408
                                {
409
                                        a1.erase(a1.find("OFFSET"));
410
                                        ////std::cout << "^_^ a1" << a1 << "\n";
411
                                        I.SetSrc1Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
412
                                }
413
 
414
                                std::string Src1 = a1;
415
                                if (IsSwizzled( Src1 ))
416
                                {
417
                                        SetSwizzleAndSign( 1, Src1,  I );
418
                                        Src1.erase(Src1.find("."));
419
                                }
420
                                I.SetSrc1Address( atoi( Src1.c_str()+1 ) );
421
                        }
422
 
423
                        if ( a2.find("R") == std::string::npos)
424
                        {
425
                        } else {
426
 
427
 
428
 
429
                                //Look for displament addressing mode
430
                                if (a2.find("OFFSET") != std::string::npos)
431
                                {
432
                                        a2.erase(a2.find("OFFSET"));
433
                                        ////std::cout << "^_^ a2 " << a2 << "\n";
434
                                        I.SetSrc0Displace( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
435
                                }
436
 
437
                                std::string Src0 = a2;
438
                                if (IsSwizzled( Src0 ))
439
                                {
440
                                        SetSwizzleAndSign( 0, Src0,  I );
441
                                        Src0.erase(Src0.find("."));
442
                                }
443
                                I.SetSrc0Address( atoi( Src0.c_str()+1 ) );
444
                        }
445
}
446
//----------------------------------------------------------
447
void ClearNextFunctionParamRegister()
448
{
449
        gFunctionParameterIndex = FUNCTION_PARAM_START_REGION;
450
}
451
//----------------------------------------------------------
452
void AddFunctionInputList( std::string aVar, std::vector & aInstructions,Theia::Parser::location_type  yylloc)
453
{
454
        //Get the value from the variable
455 227 diegovalve
        DCOUT << "Calling AddFunctionInputList input arg: " << aVar << " \n";
456 216 diegovalve
        //Copy the value into function parameter register
457
        unsigned FunctionParamReg = GetNextFunctionParamRegister();
458
        I.Clear();
459
        I.SetCode( EOPERATION_ADD );
460
        I.mComment = "copy the value into function parameter register";
461
        I.SetWriteChannel(ECHANNEL_XYZ);
462
        //I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
463
        I.SetDestinationAddress( FunctionParamReg );
464
 
465
        if (aVar.find("R") != std::string::npos)
466
        {
467
                if (aVar.find("OFFSET") != std::string::npos)
468
                {
469
                        I.SetSrc1Displace( true );
470
                        aVar.erase(aVar.find("OFFSET"));
471
                }
472
                I.SetSrc1Address(atoi(aVar.c_str()+1));
473 227 diegovalve
                I.SetSrc1SwizzleX(SWX_X);
474
                I.SetSrc1SwizzleY(SWY_Y);
475
                I.SetSrc1SwizzleZ(SWZ_Z);
476
                I.SetSrc0Address(0);
477
                I.SetSrc0SwizzleX(SWX_X);
478
                I.SetSrc0SwizzleY(SWY_X);
479
                I.SetSrc0SwizzleZ(SWZ_X);
480
                aInstructions.push_back( I );
481
                I.Clear();
482 216 diegovalve
                return;
483
        }
484
        std::string Reg = GetRegisterFromFunctionParameter( aVar );
485
        if (Reg == "NULL")
486
        {
487
                Reg = GetRegisterFromAutoVar( aVar, yylloc );
488
                I.SetSrc1Address(atoi(Reg.c_str()+1));
489
                I.SetSrc1Displace( true );
490
        } else {
491
                I.SetSrc1Address(atoi(Reg.c_str()+1));
492
                I.SetSrc1Displace( false );
493
        }
494
 
495
 
496
 
497
        I.SetSrc1SwizzleX(SWX_X);
498
        I.SetSrc1SwizzleY(SWY_Y);
499
        I.SetSrc1SwizzleZ(SWZ_Z);
500
        I.SetSrc0Address(0);
501
        I.SetSrc0SwizzleX(SWX_X);
502
        I.SetSrc0SwizzleY(SWY_X);
503
        I.SetSrc0SwizzleZ(SWZ_X);
504
        aInstructions.push_back( I );
505
        I.Clear();
506
}
507
//----------------------------------------------------------
508
void SetExpressionDestination( std::string aStringDestination, Instruction & I )
509
{
510
                std::string Destination = aStringDestination;
511
 
512
                //Look for indirect addressing
513
                if (Destination.find("INDEX") != std::string::npos)
514
                {
515
 
516
                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
517
                        Destination.erase(Destination.find("INDEX"));
518
                        I.SetImm( 0 );
519
                        I.SetCode( EOPERATION_ADD );
520
 
521
                        if (Destination.find(".") != std::string::npos)
522
                        {
523
                                I.ClearWriteChannel();
524
                                if (Destination.find("x") != std::string::npos)
525
                                        I.SetWriteChannel(ECHANNEL_X);
526
                                if (Destination.find("y") != std::string::npos)
527
                                        I.SetWriteChannel(ECHANNEL_Y);
528
                                if (Destination.find("z") != std::string::npos)
529
                                        I.SetWriteChannel(ECHANNEL_Z);
530
                                Destination.erase(Destination.find("."));
531
 
532
                        }
533
 
534
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
535
 
536
                } else {
537
 
538
                        //Look for displament addressing mode
539
                        if (Destination.find("OFFSET") != std::string::npos)
540
                        {
541
                                Destination.erase(Destination.find("OFFSET"));
542
                                I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
543
                        }
544
                        if (Destination.find(".") != std::string::npos)
545
                        {
546
                                I.ClearWriteChannel();
547
                                if (Destination.find("x") != std::string::npos)
548
                                        I.SetWriteChannel(ECHANNEL_X);
549
                                if (Destination.find("y") != std::string::npos)
550
                                        I.SetWriteChannel(ECHANNEL_Y);
551
                                if (Destination.find("z") != std::string::npos)
552
                                        I.SetWriteChannel(ECHANNEL_Z);
553
 
554
                                Destination.erase(Destination.find("."));
555
 
556
                        }
557
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
558
 
559
 
560
 
561
                }
562
}
563
 
564
//----------------------------------------------------------
565
bool SourceNull( std::string aSource )
566
{
567
        if (aSource == "NULL")
568
                return true;
569
 
570
        return false;
571
}
572
//----------------------------------------------------------
573
 
574
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)
575
{
576
 
577
 
578
        bool DestinationHasOffset  = false;
579
        bool DetinationHasIndex    = false;
580
        bool Source0HasOffset      = false;
581
        bool Source1HasOffset      = false;
582
        bool Source1HasIndex       = false;
583
        bool Source0HasIndex       = false;
584
 
585
 
586
        if (aDestination.find("INDEX") != std::string::npos)
587
        {
588
                std::string ArrayIndex = aDestination.substr(aDestination.find("INDEX")+5);
589
                aSource1 = ArrayIndex;
590
                DetinationHasIndex      = true;
591
 
592
        }
593
 
594
        if (aSource1.find("INDEX") != std::string::npos)
595
                Source1HasIndex = true;
596
 
597
        if (aSource0.find("INDEX") != std::string::npos)
598
                Source0HasIndex = true;
599
 
600
        if (aDestination.find("OFFSET") != std::string::npos)
601
                DestinationHasOffset = true;
602
 
603
        if      (aSource0.find("OFFSET") != std::string::npos)
604
                Source0HasOffset = true;
605
 
606
        if      (aSource1.find("OFFSET") != std::string::npos)
607
                Source1HasOffset = true;
608
 
609
        if (IsSwizzled( aSource1 ))
610
                SetSwizzleAndSign( 1, aSource1,  I );
611
        I.SetSrc1Address( atoi( aSource1.c_str()+1 ) );
612
 
613
        if (IsSwizzled( aSource0 ))
614
                SetSwizzleAndSign( 0, aSource0,  I );
615
        I.SetSrc0Address( atoi( aSource0.c_str()+1 ) );
616
 
617
 
618
 
619
        //Fisrt take care of the destination write channel
620
        if (aDestination.find(".") != std::string::npos)
621
                {
622
                        I.ClearWriteChannel();
623
                        if (aDestination.find("x") != std::string::npos)
624
                                I.SetWriteChannel(ECHANNEL_X);
625
                        if (aDestination.find("y") != std::string::npos)
626
                                I.SetWriteChannel(ECHANNEL_Y);
627
                        if (aDestination.find("z") != std::string::npos)
628
                                I.SetWriteChannel(ECHANNEL_Z);
629
                        aDestination.erase(aDestination.find("."));
630
        } else {
631
                I.SetWriteChannel(ECHANNEL_XYZ);
632
        }
633
        //Now set the destination Index
634
        I.SetDestinationAddress( atoi(aDestination.c_str()+1) );
635
 
636
 
637
        //Now determine the addressing mode
638
        //Simple addressing modes
639
        if (!aHasLiteral &&     !DetinationHasIndex && !Source0HasIndex && !Source1HasIndex)
640
        {
641
 
642
                I.SetAddressingMode( DestinationHasOffset,Source1HasOffset,Source0HasOffset);
643
                return;
644
        }
645
 
646
 
647
        I.SetImmBit( true ); //This is to set the IMM bit = 1, may be overwritten latter
648
        //Complex addressing modes
649
        if
650
        (
651
        aHasLiteral &&
652
        !SourceNull( aSource0 ) &&
653
        !Source0HasOffset &&
654
        !Source1HasOffset &&
655
        !DestinationHasOffset
656
        )
657
        {
658
                I.SetAddressingMode( false,false,false);
659
                I.SetImm( aLiteral );
660
 
661
        }
662
        else
663
        if
664
        (
665
        aHasLiteral &&
666
        !SourceNull( aSource0 ) &&
667
        Source0HasOffset &&
668
        !Source0HasIndex &&
669
        DestinationHasOffset
670
 
671
        )
672
        {
673
 
674
                I.SetAddressingMode( false,false,true);
675
                I.SetImm( aLiteral );
676
 
677
 
678
        }
679
        else
680
        if
681
        (
682
        !aHasLiteral &&
683
        !SourceNull( aSource1 ) &&
684
        !Source1HasOffset &&
685
        !SourceNull( aSource0 ) &&
686
        Source0HasOffset &&
687
        Source0HasIndex &&
688
        DestinationHasOffset
689
 
690
        )
691
        {
692
                I.SetAddressingMode( false,true,false);
693
 
694
        }
695
        else
696
        if
697
        (
698
        !aHasLiteral &&
699
        !Source1HasOffset &&
700
        !SourceNull( aSource0 ) &&
701
        Source0HasOffset &&
702
        !Source0HasIndex &&
703
        DestinationHasOffset &&
704
        DetinationHasIndex
705
 
706
        )
707
        {
708
                I.SetAddressingMode( false,true,true);
709
 
710
        }
711
        else
712
        if
713
        (
714
        aHasLiteral &&
715
        SourceNull( aSource0 ) &&
716
        !DestinationHasOffset &&
717
        !DetinationHasIndex
718
 
719
        )
720
        {
721
 
722
 
723
                I.SetAddressingMode( true,false,false);
724
                I.SetImm( aLiteral );
725
        }
726
        else
727
        if
728
        (
729
        aHasLiteral &&
730
        SourceNull( aSource0 ) &&
731
        DestinationHasOffset &&
732
        !DetinationHasIndex
733
 
734
        )
735
        {
736
 
737
                I.SetAddressingMode( true,false,true);
738
                I.SetImm( aLiteral );
739
        }
740
        else
741
        if
742
        (
743
        !aHasLiteral &&
744
        Source1HasOffset &&
745
        Source1HasIndex &&
746
        SourceNull( aSource0 ) &&
747
        DestinationHasOffset &&
748
        !DetinationHasIndex
749
 
750
        )
751
        {
752
 
753
                I.SetAddressingMode( true,true,false);
754
        }
755
        else
756
        if
757
        (
758
        !aHasLiteral &&
759
        Source1HasOffset &&
760
        Source1HasIndex &&
761
        Source0HasOffset &&
762
        !Source0HasIndex &&
763
        DestinationHasOffset &&
764
        !DetinationHasIndex
765
 
766
        )
767
        {
768
 
769
                I.SetAddressingMode( true,true,true);
770
        } else {
771
                        std::ostringstream ret;
772
                        ret << "Could not determine addressing mode  at line " << yylloc << " \n";
773
                        throw ret.str();
774
        }
775
 
776
 
777
}
778
 
779
//-------------------------------------------------------------
780
void PopulateBoolean(EBRANCHTYPE aBranchType, std::string Source1, std::string Source0, Instruction & I, std::vector & aInstructions, Theia::Parser::location_type & yylloc )
781
{
782
 
783
                                        if (Source0.find("R") == std::string::npos)
784
                                        {
785
                                                I.mSourceLine = GetCurrentLineNumber( yylloc );
786
                                                I.SetCode( EOPERATION_ADD );
787
                                                unsigned int TempRegIndex  = GetFreeTempRegister();
788
                                                I.SetDestinationAddress( TempRegIndex );
789
                                                unsigned int ImmediateValue;
790
                                                std::string StringHex = Source0;
791
                                                std::stringstream ss;
792
                                                ss << std::hex << StringHex;
793
                                                ss >> ImmediateValue;
794
                                                I.SetImm( ImmediateValue );
795
                                                I.SetDestZero( true );
796
                                                I.SetSrc0Displace( true );
797
                                                I.SetWriteChannel(ECHANNEL_X);
798
                                                I.SetWriteChannel(ECHANNEL_Y);
799
                                                I.SetWriteChannel(ECHANNEL_Z);
800
                                                aInstructions.push_back(I);
801
                                                I.Clear();
802
 
803
                                                std::stringstream ss2;
804
                                                ss2 << "R" << TempRegIndex;
805
                                                ss2 >> Source0;
806
                                                Source0 += " OFFSET ";
807
 
808
                                        }
809
                                        else
810
                                                I.mSourceLine = GetCurrentLineNumber( yylloc );
811
 
812
                                        I.SetCode( EOPERATION_ADD );
813
                                        I.SetSrc0SignX( true );
814
                                        I.SetSrc0SignY( true );
815
                                        I.SetSrc0SignZ( true );
816
                                        I.SetBranchFlag( true );
817
                                        I.ClearWriteChannel();
818
                                        I.SetBranchType( aBranchType );
819
 
820
                                        PopulateSourceRegisters( Source1, Source0, I, aInstructions);
821
                                        aInstructions.push_back(I);
822
                                        I.Clear();
823
                                        ////std::cout << "pushing code at position " << (mInstructions.size() - 1) << "\n";
824
                                        gBranchStack.push_back(aInstructions.size() - 1);
825
                                        ResetTempRegisterIndex();
826
}
827
 
828
//-------------------------------------------------------------
829
        // Prototype for the yylex function
830
        static int yylex(Theia::Parser::semantic_type * yylval,
831
                         Theia::Parser::location_type * yylloc,
832
                         Theia::Scanner &scanner);
833
}
834
 
835
%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
836
%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
837
%%
838
 
839
statement_list: //empty
840
        |
841
        statement_list statement
842
        |
843
        statement
844
        ;
845
 
846
statement
847
        :
848
        AUTO auto_var_list EOS
849
        |
850
        USING FIXED_POINT EOS
851
        {
852
                mGenerateFixedPointArithmetic = true;
853
        }
854
        |
855
        EXIT EOS
856
        {
857
                //Insert a stupid NOP before the exit... is a bug but easier to just patch like this...
858
 
859
                I.Clear();
860
                I.mComment = "NOP";
861
                I.SetCode( EOPERATION_NOP );
862
                mInstructions.push_back(I);
863
                I.Clear();
864
 
865
                I.SetEofFlag(true);
866
                I.mComment = "Set the Exit bit";
867
                I.SetCode( EOPERATION_ADD );
868
                mInstructions.push_back(I);
869
                I.Clear();
870
        }
871
        |
872
        RETURN expression EOS
873
        {
874
 
875
                //////////////////////////////////////////////////////////////////////////////
876
                // This means this that the expression was just a constant.
877
                // No operations were inserted
878
                //////////////////////////////////////////////////////////////////////////////
879
                if (gInsertedInstructions == 0)
880
                {
881
                        I.Clear();
882
                        I.SetCode(EOPERATION_ADD);
883
                        I.mComment ="Set the return value";
884
                        if ($3.find("R") != std::string::npos)
885
                        {
886
                                PopulateInstruction( "R1", $2,"R0 . X X X",I,yylloc);
887
                        }
888
                        else
889
                        {
890
                                unsigned int ImmediateValue = 0;
891
                                std::string StringHex = $3;
892
                                std::stringstream ss;
893
                                ss << std::hex << StringHex;
894
                                ss >> ImmediateValue;
895
                                PopulateInstruction( "R1", $3,"NULL",I, yylloc, true, ImmediateValue);
896
                        }
897
                        mInstructions.push_back(I);
898
                        I.Clear();
899
                } else {
900
 
901
                        mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc);
902
                        gInsertedInstructions = 0;
903
                        mInstructions.back().mComment ="Assigning return value";
904
                        mInstructions.back().SetDestinationAddress( RETURN_VALUE_REGISTER );
905
 
906
                }
907
                ResetTempRegisterIndex();
908
 
909
                I.SetCode( EOPERATION_ADD );
910
                I.mComment = "Restore previous function frame offset";
911
                I.ClearWriteChannel();
912
                I.SetWriteChannel(ECHANNEL_X);
913
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
914
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
915
                I.SetSrc1SwizzleX(SWX_Y);
916
                I.SetSrc1SwizzleY(SWY_Y);
917
                I.SetSrc1SwizzleZ(SWZ_Y);
918
                I.SetSrc0Address(0);
919
                I.SetSrc0SwizzleX(SWX_X);
920
                I.SetSrc0SwizzleY(SWY_X);
921
                I.SetSrc0SwizzleZ(SWZ_X);
922
                mInstructions.push_back( I );
923
                I.Clear();
924
 
925
                //Now return
926
                I.SetImm( 0 );
927
                I.SetCode( EOPERATION_ADD );
928
                I.mComment = "return from function";
929
                I.SetBranchFlag( true );
930
                I.SetBranchType( EBRANCH_ALWAYS );
931
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
932
                mInstructions.push_back(I);
933
                I.Clear();
934
 
935
 
936
 
937
        }
938
        |
939
        RETURN EOS
940
        {
941
                I.SetCode( EOPERATION_ADD );
942
                I.mComment = "Restore previous function frame offset";
943
                I.SetWriteChannel(ECHANNEL_X);
944
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
945
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
946
                I.SetSrc1SwizzleX(SWX_Y);
947
                I.SetSrc1SwizzleY(SWY_Y);
948
                I.SetSrc1SwizzleZ(SWZ_Y);
949
                I.SetSrc0Address(0);
950
                I.SetSrc0SwizzleX(SWX_X);
951
                I.SetSrc0SwizzleY(SWY_X);
952
                I.SetSrc0SwizzleZ(SWZ_X);
953
                mInstructions.push_back( I );
954
                I.Clear();
955
 
956
                I.SetImm( 0 );
957
                I.SetCode( EOPERATION_ADD );
958
                I.mComment = "return from function";
959
                I.SetBranchFlag( true );
960
                I.SetBranchType( EBRANCH_ALWAYS );
961
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
962
                mInstructions.push_back(I);
963
                I.Clear();
964
        }
965
 
966
         |
967
         left_hand_side ADD_EQ constant EOS
968
          {
969
 
970
                 I.mSourceLine = GetCurrentLineNumber( yylloc );
971
                 I.SetCode( EOPERATION_ADD );
972
                 SetDestinationFromRegister( $1, I , true);
973
                 unsigned int ImmediateValue;
974
                 std::string StringHex = $3;
975
                 std::stringstream ss;
976
                 ss << std::hex << StringHex;
977
                 ss >> ImmediateValue;
978
                 I.SetImm( ImmediateValue );
979
                 I.SetDestZero( false );
980
 
981
                 mInstructions.push_back( I );
982
                 I.Clear();
983
         }
984
         |
985
         left_hand_side MINUS MINUS EOS
986
         {
987
 
988
                I.mSourceLine = GetCurrentLineNumber( yylloc );
989
                I.SetCode( EOPERATION_ADD );
990
                SetDestinationFromRegister( $1, I, false );
991
                I.SetSrc0SignX( true );
992
                I.SetSrc0SignY( true );
993
                I.SetSrc0SignZ( true );
994
                std::string Destination = $1;
995
                if (Destination.find("OFFSET") != std::string::npos)
996
                {
997
                        I.SetSrc1Displace( true );
998
                        Destination.erase(Destination.find("OFFSET"));
999
                }
1000
 
1001
                if (Destination.find(".") != std::string::npos)
1002
                        Destination.erase(Destination.find("."));
1003
 
1004
 
1005
                I.SetSrc1Address(atoi(Destination.c_str()+1));
1006
                I.SetSrc0Address(0);
1007
                I.SetSrc0SwizzleX(SWX_Y);
1008
                I.SetSrc0SwizzleY(SWY_Y);
1009
                I.SetSrc0SwizzleZ(SWZ_Y);
1010
                mInstructions.push_back( I );
1011
                I.Clear();
1012
         }
1013
         |
1014
         left_hand_side ADD ADD EOS
1015
         {
1016
 
1017
                I.mSourceLine = GetCurrentLineNumber( yylloc );
1018
                I.SetCode( EOPERATION_ADD );
1019
                SetDestinationFromRegister( $1, I, false );
1020
                std::string Destination = $1;
1021
                if (Destination.find("OFFSET") != std::string::npos)
1022
                {
1023
                        I.SetSrc1Displace( true );
1024
                        Destination.erase(Destination.find("OFFSET"));
1025
                }
1026
 
1027
                if (Destination.find(".") != std::string::npos)
1028
                        Destination.erase(Destination.find("."));
1029
 
1030
                I.SetSrc1Address(atoi(Destination.c_str()+1));
1031
                I.SetSrc0Address(0);
1032
                I.SetSrc0SwizzleX(SWX_Y);
1033
                I.SetSrc0SwizzleY(SWY_Y);
1034
                I.SetSrc0SwizzleZ(SWZ_Y);
1035
                mInstructions.push_back( I );
1036
                I.Clear();
1037
         }
1038
         |
1039
         left_hand_side ASSIGN expression  EOS
1040
        {
1041
 
1042
                //////////////////////////////////////////////////////////////////////////////
1043
                // This means this that the expression will write into the output memory
1044
                // constant index
1045
                //////////////////////////////////////////////////////////////////////////////
1046
 
1047
                if ($1.find("OUT") != std::string::npos && $1.find("INDEX") == std::string::npos )
1048
                {
1049
                        //PopulateInstruction( "R0", "R0 . X X X",$3,I,yylloc);
1050
 
1051
                        I.SetCode(EOPERATION_OUT);
1052
                        $1.erase($1.find("OUT"),3);
1053
 
1054
                        unsigned int ImmediateValue;
1055
                        std::stringstream ss;
1056
                        ss << std::hex << $1;
1057
                        ss >> ImmediateValue;
1058
                        PopulateInstruction( $3, "R0 OFFSET", "R0 OFFSET", I, yylloc, true, ImmediateValue );
1059
                        #ifdef DEBUG
1060
                        I.PrintFields();
1061
                        #endif
1062
                        mInstructions.push_back(I);
1063
                        I.Clear();
1064
                        ResetTempRegisterIndex();
1065
                        goto LABEL_EXPRESSION_DONE;
1066
                }
1067
                //////////////////////////////////////////////////////////////////////////////
1068
                // This means this that the expression will write into the output memory
1069
                // variable index
1070
                //////////////////////////////////////////////////////////////////////////////
1071
 
1072
                if ($1.find("OUT") != std::string::npos && $1.find("INDEX") != std::string::npos )
1073
                {
1074
                        std::string Destination = $1;
1075
                        DCOUT << "!!!!!!!!!!!!!!!!!Destination " << Destination << "\n";
1076
                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
1077
                        Destination.erase(Destination.find("INDEX"));
1078
 
1079
 
1080
                        I.SetDestZero( true ); //Use indexing for DST
1081
                        I.SetWriteChannel(ECHANNEL_XYZ);
1082
 
1083 227 diegovalve
                //      PopulateSourceRegisters( IndexRegister + " OFFSET ", $3, I, mInstructions );
1084
                        PopulateSourceRegisters( IndexRegister, $3, I, mInstructions );
1085 216 diegovalve
 
1086
 
1087
                        //I.SetImm( 0 );
1088
                        I.SetCode( EOPERATION_OUT );
1089
                        std::string Source0 = $3;
1090
                        DCOUT << "!!!!!!!!!!!!!!!!!Source0 '" << Source0 << "'\n";
1091
                /*      if (Source0.find("OFFSET") != std::string::npos)
1092
                        {
1093
                                        Source0.erase(Source0.find("OFFSET"));
1094
                                        I.SetSrc0Displace(1);
1095
                        }
1096
                        I.SetSrc1Address(atoi(IndexRegister.c_str()+1));
1097
                        I.SetSrc0Address(atoi(Source0.c_str()+1));*/
1098
 
1099
                /*      if (Destination.find(".") != std::string::npos)
1100
                        {
1101
                                I.ClearWriteChannel();
1102
                                if (Destination.find("x") != std::string::npos)
1103
                                        I.SetWriteChannel(ECHANNEL_X);
1104
                                if (Destination.find("y") != std::string::npos)
1105
                                        I.SetWriteChannel(ECHANNEL_Y);
1106
                                if (Destination.find("z") != std::string::npos)
1107
                                        I.SetWriteChannel(ECHANNEL_Z);
1108
 
1109
                                Destination.erase(Destination.find("."));
1110
 
1111
                        }
1112
 
1113
                        std::string Source0 = $3;
1114
                        if (Source0.find("OFFSET") != std::string::npos)
1115
                        {
1116
                                        Source0.erase(Source0.find("OFFSET"));
1117
                                        I.SetSrc0Displace(1);
1118
                        }
1119
                        I.SetSrc1Address(atoi(IndexRegister.c_str()+1));
1120
                        I.SetSrc0Address(atoi(Source0.c_str()+1));
1121
 
1122
 
1123
                                //      I.SetSrc0Address(mInstructions.back().GetDestinationAddress());
1124
                        I.SetDestZero(0);
1125
                        I.SetSrc1Displace(1);
1126
                        I.SetSrc0Displace(1);
1127
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );*/
1128
                        mInstructions.push_back( I );
1129
                        I.Clear();
1130
                        ResetTempRegisterIndex();
1131
                        goto LABEL_EXPRESSION_DONE;
1132
                }
1133
                //////////////////////////////////////////////////////////////////////////////
1134
                // This means this that the expression was just a constant.
1135
                // No operations were inserted
1136
                //////////////////////////////////////////////////////////////////////////////
1137
                if (gInsertedInstructions == 0)
1138
                {
1139
 
1140
                        I.Clear();
1141
 
1142
                        I.SetCode(EOPERATION_ADD);
1143
                        I.mSourceLine = GetCurrentLineNumber(yylloc);
1144
                        if ($3.find("R") != std::string::npos)
1145
                        {
1146
                        // case 1:
1147
                        // foo = 0;        //$$ = R0 . X X X
1148
                        /*      SetDestinationFromRegister( $1, I, false );
1149
                                PopulateSourceRegisters( $3, "R0 . X X X", I, mInstructions);*/
1150
 
1151
                                PopulateInstruction( $1, "R0 . X X X",$3,I,yylloc);
1152
 
1153
                        } else {
1154
                        // case 2:
1155
                        // foo = 0xcafe;  //$$ = 0xcafe
1156
                                SetDestinationFromRegister( $1, I, true );
1157
                                unsigned int ImmediateValue = 0;
1158
                                std::string StringHex = $3;
1159
                                std::stringstream ss;
1160
                                ss << std::hex << StringHex;
1161
                                ss >> ImmediateValue;
1162
 
1163
                                PopulateInstruction( $1, $3,"NULL",I, yylloc, true, ImmediateValue);
1164
                        }
1165
                        std::string strConstant = $3;
1166
 
1167
                        mInstructions.push_back(I);
1168
                        I.Clear();
1169
                        ResetTempRegisterIndex();
1170
                        goto LABEL_EXPRESSION_DONE;
1171
                }
1172
 
1173
                //////////////////////////////////////////////////////////////////////////////
1174
                // This means that the last instruction which was inserted was a tripple
1175
                // constant assignement, like foo = (1,2,3)
1176
                //////////////////////////////////////////////////////////////////////////////
1177
                if (mInstructions.back().mBisonFlagTrippleConstAssign)
1178
                {
1179
                        unsigned int LastIndex = mInstructions.size() - 1;
1180
                        mInstructions[LastIndex].SetDestinationAddress(atoi($1.c_str()+1));
1181
                        mInstructions[LastIndex-1].SetDestinationAddress(atoi($1.c_str()+1));
1182
                        mInstructions[LastIndex-2].SetDestinationAddress(atoi($1.c_str()+1));
1183
                        mInstructions[LastIndex-2].mSourceLine = GetCurrentLineNumber( yylloc );
1184
                        if($1.find("OFFSET") == std::string::npos)
1185
                        {
1186
                                mInstructions[LastIndex].SetAddressingMode(true,false,false);
1187
                                mInstructions[LastIndex-1].SetAddressingMode(true,false,false);
1188
                                mInstructions[LastIndex-2].SetAddressingMode(true,false,false);
1189
                        }
1190
 
1191
                        ResetTempRegisterIndex();
1192
                        goto LABEL_EXPRESSION_DONE;
1193
                }
1194
                //////////////////////////////////////////////////////////////////////////////
1195
                // Handle the case where the destination is an array of vector
1196
                // ej: R = v1[ i ]  + V2
1197
                //////////////////////////////////////////////////////////////////////////////
1198
                if (I.GetOperation() == 0 && $3.find("array_element") != std::string::npos)
1199
                {
1200
                        //No operation meaning the the expression only has a single variable
1201
                        //See if the expression returned is an array_element
1202
                        if ($3.find("array_element") != std::string::npos)
1203
                        {
1204
                                ////std::cout << "expression is an array element\n\n";
1205
                                std::string Index = $3.substr($3.find("array_element"));
1206
                                Index = Index.substr(Index.find_first_not_of("array_element R"));
1207
                                SetIndexRegister( atoi(Index.c_str()), mInstructions );
1208
                                $3.erase($3.find("array_element"));
1209
                                SetExpressionDestination( $1, I );
1210
                                I.SetCode(EOPERATION_ADD);
1211
                                I.SetImmBit( true );
1212
                                I.SetDestZero( true );
1213
                                I.SetSrc1Displace( true );
1214
                                I.SetSrc0Displace( false );
1215
                                I.mSourceLine = GetCurrentLineNumber(yylloc);
1216
 
1217
                                if ($3.find("OFFSET") != std::string::npos)
1218
                                        $3.erase($3.find("OFFSET"));
1219
 
1220
                                I.SetSrc1Address(atoi($3.c_str()+1));
1221
                                I.SetSrc0Address(0);
1222
                                mInstructions.push_back(I);
1223
                                I.Clear();
1224
                        }
1225
                }
1226
                else
1227
                {
1228
 
1229
                                mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc);
1230
                                gInsertedInstructions = 0;
1231
                                std::string Destination = $1;
1232
                                //std::cout << "DST " << Destination << " \n";
1233
                                //Look for indirect addressing
1234
                                if (Destination.find("INDEX") != std::string::npos)
1235
                                {
1236
 
1237
                                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
1238
 
1239
                                        Destination.erase(Destination.find("INDEX"));
1240
 
1241
                                        I.SetImm( 0 );
1242
                                        I.SetCode( EOPERATION_ADD );
1243
 
1244
                                        if (Destination.find(".") != std::string::npos)
1245
                                        {
1246
                                                I.ClearWriteChannel();
1247
                                                if (Destination.find("x") != std::string::npos)
1248
                                                        I.SetWriteChannel(ECHANNEL_X);
1249
                                                if (Destination.find("y") != std::string::npos)
1250
                                                        I.SetWriteChannel(ECHANNEL_Y);
1251
                                                if (Destination.find("z") != std::string::npos)
1252
                                                        I.SetWriteChannel(ECHANNEL_Z);
1253
 
1254
                                                Destination.erase(Destination.find("."));
1255
 
1256
                                        }
1257
 
1258
                                        std::string Source0 = $3;
1259
                                        if (Source0.find("OFFSET") != std::string::npos)
1260
                                        {
1261
                                                Source0.erase(Source0.find("OFFSET"));
1262
                                                I.SetSrc0Displace(1);
1263
                                        }
1264
                                        I.SetSrc1Address(atoi(IndexRegister.c_str()+1));
1265
                                        I.SetSrc0Address(atoi(Source0.c_str()+1));
1266
 
1267
 
1268
                                //      I.SetSrc0Address(mInstructions.back().GetDestinationAddress());
1269
                                        I.SetDestZero(0);
1270
                                        I.SetSrc1Displace(1);
1271
                                        I.SetSrc0Displace(1);
1272
                                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
1273
                                        mInstructions.push_back( I );
1274
                                        I.Clear();
1275
                                } else {
1276
 
1277
                                        if (mInstructions.back().GetImm())
1278
                                        {
1279
                                                //Look for displament addressing mode
1280
                                                unsigned int AddressingMode = mInstructions.back().GetAddressingMode();
1281
                                                if (Destination.find("OFFSET") != std::string::npos)
1282
                                                {
1283
                                                        //This means AddressMode is '101', so leave the way it is
1284
                                                        mInstructions.back().ClearWriteChannel();
1285
                                                        mInstructions.back().SetWriteChannel(ECHANNEL_Z);
1286
                                                        Destination.erase(Destination.find("OFFSET"));
1287
                                                } else {
1288
                                                        //This is not supposed to have index, so change addressing mode to '100'
1289
 
1290
                                                        mInstructions.back().SetDestZero( true );
1291
                                                        mInstructions.back().SetSrc1Displace( false );
1292
                                                        mInstructions.back().SetSrc0Displace( false );
1293
                                                        mInstructions.back().ClearWriteChannel();
1294
                                                        mInstructions.back().SetWriteChannel(ECHANNEL_Z);
1295
                                                }
1296
 
1297
                                        } else {
1298
                                                mInstructions.back().SetDestZero( false ); //First assume no offset was used
1299
 
1300
 
1301
 
1302
                                                //Look for displament addressing mode
1303
                                                if (Destination.find("OFFSET") != std::string::npos)
1304
                                                {
1305
                                                        Destination.erase(Destination.find("OFFSET"));
1306
                                                        mInstructions.back().SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
1307
                                                }
1308
                                        }
1309
                                                if (Destination.find(".") != std::string::npos)
1310
                                                {
1311
                                                        mInstructions.back().ClearWriteChannel();
1312
                                                        if (Destination.find("x") != std::string::npos)
1313
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_X);
1314
                                                        if (Destination.find("y") != std::string::npos)
1315
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_Y);
1316
                                                        if (Destination.find("z") != std::string::npos)
1317
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_Z);
1318
 
1319
                                                        Destination.erase(Destination.find("."));
1320
 
1321
                                                }
1322
                                                mInstructions.back().SetDestinationAddress( atoi($1.c_str()+1) );
1323
                                                for (int i = 1; i <= gExtraDestModifications; i++ )
1324
                                                {
1325
                                                        int idx = (mInstructions.size()-1)-i;
1326
                                                        mInstructions[idx].SetDestinationAddress( atoi($1.c_str()+1) );
1327
                                                        if (mInstructions[idx].GetImm())
1328
                                                        {
1329
 
1330
                                                                //This is not supposed to have index, so change addressing mode to '100'
1331
                                                                mInstructions[idx].SetDestZero( true );
1332
                                                                mInstructions[idx].SetSrc1Displace( false );
1333
                                                                mInstructions[idx].SetSrc0Displace( false );
1334
 
1335
 
1336
                                                        }
1337
 
1338
                                                }
1339
                                                gExtraDestModifications = 0;
1340
 
1341
 
1342
 
1343
                                }
1344
                                ResetTempRegisterIndex();
1345
                }
1346
 
1347
                LABEL_EXPRESSION_DONE:
1348
                gInsertedInstructions = 0;
1349
                while(0);
1350
 
1351
        }
1352
        |
1353
        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
1354
        {
1355
                mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()+1);
1356
                gBranchStack.pop_back();
1357
                //Now I need to put a GOTO so that the while gets evaluated again...
1358
                //jump out of the if
1359
           I.Clear();
1360
           I.SetCode( EOPERATION_ADD );
1361
           I.mComment = "while loop goto re-eval boolean";
1362
           I.SetDestinationAddress( gWhileLoopAddress );
1363
           I.SetBranchFlag( true );
1364
           I.SetBranchType( EBRANCH_ALWAYS );
1365
           mInstructions.push_back(I);
1366
           I.Clear();
1367
 
1368
        }
1369
        | IF
1370
          OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE
1371
          OPEN_BRACE statement_list CLOSE_BRACE
1372
      ELSE
1373
        {
1374
 
1375
           //jump out of the if
1376
           I.Clear();
1377
           I.SetCode( EOPERATION_ADD );
1378
           I.SetBranchFlag( true );
1379
           I.SetBranchType( EBRANCH_ALWAYS );
1380
           mInstructions.push_back(I);
1381
           I.Clear();
1382
           //Take care of the destination addr of the if statement.
1383
           mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
1384
          gBranchStack.pop_back();
1385
          //push the inconditional jump into the stack
1386
          gBranchStack.push_back(mInstructions.size() - 1);
1387
          ////std::cout << "else\n";
1388
 
1389
        }
1390
          OPEN_BRACE  statement_list CLOSE_BRACE
1391
        {
1392
 
1393
           mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
1394
           gBranchStack.pop_back();
1395
           //Now push the JMP
1396
 
1397
                ////std::cout << "END elseif\n";
1398
        }
1399
        |
1400
        //NOW the if statement
1401
        IF OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE OPEN_BRACE statement_list CLOSE_BRACE
1402
        {
1403
                mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
1404
                //mInstructions[gBranchStack.back()].mSourceLine = GetCurrentLineNumber(yylloc);
1405
 
1406
                gBranchStack.pop_back();
1407
                ////std::cout << "if closing at " << mInstructions.size() << "\n";
1408
 
1409
        }
1410 227 diegovalve
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1411
        /////                                                                                                                                                                                                             /////
1412
        /////   Function declaration                                                                                                                                                              /////
1413
        /////                                                                                                                                                                                                             /////
1414
        /////   function  ( [ , ... , ])                                                                                                          /////
1415
        /////   {                                                                                                                                                                                                         /////
1416
        /////                                                                                                                                                                             /////
1417
        /////                                                                                                                                                                                                             /////
1418
        /////   }                                                                                                                                                                                                         /////
1419
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1420 216 diegovalve
        |
1421
        FUNCTION IDENTIFIER OPEN_ROUND_BRACE function_argument_list CLOSE_ROUND_BRACE
1422
        {
1423 227 diegovalve
          DCOUT << "Function declaration for " << $2 << " at " << mInstructions.size() << "\n" ;
1424 216 diegovalve
          mSymbolMap[ $2 ] = mInstructions.size();
1425
        } OPEN_BRACE statement_list CLOSE_BRACE
1426
        {
1427
                //Clear the auto var index now that we leave the function scope
1428
                ClearAutoVarMap();
1429
                ClearFunctionParameterMap();
1430
 
1431
                //Now uddate the current SPR_CONTROL_REGISTER.x = SPR_CONTROL_REGISTER.y
1432
                I.SetCode( EOPERATION_ADD );
1433
                I.mComment = "Restore previous function frame offset";
1434
                I.SetWriteChannel(ECHANNEL_X);
1435
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
1436
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
1437
                I.SetSrc1SwizzleX(SWX_Y);
1438
                I.SetSrc1SwizzleY(SWY_Y);
1439
                I.SetSrc1SwizzleZ(SWZ_Y);
1440
                I.SetSrc0Address(0);
1441
                I.SetSrc0SwizzleX(SWX_X);
1442
                I.SetSrc0SwizzleY(SWY_X);
1443
                I.SetSrc0SwizzleZ(SWZ_X);
1444
 
1445
                mInstructions.push_back( I );
1446
                I.Clear();
1447
        }
1448 227 diegovalve
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1449
        /////                                                                                                                                                                                                             /////
1450
        /////   Thread declaration                                                                                                                                                                        /////
1451
        /////                                                                                                                                                                                                             /////
1452
        /////   thread  ( )                                                                                                                                                       /////
1453
        /////   {                                                                                                                                                                                                         /////
1454
        /////                                                                                                                                                                             /////
1455
        /////                                                                                                                                                                                                             /////
1456
        /////   }                                                                                                                                                                                                         /////
1457
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1458 216 diegovalve
        |
1459
        //Thread declaration
1460
        THREAD IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE
1461
        {
1462
                gThreadMap[ $2 ] = mInstructions.size();
1463
                gThreadScope = true;
1464
        }
1465
        OPEN_BRACE statement_list CLOSE_BRACE
1466
        {
1467
                ////std::cout << "Defining thread" << "\n";
1468
                gThreadScope = false;
1469
                ClearAutoVarMap();
1470
                //Since the thread is done, then disable threading
1471
                I.SetCode( EOPERATION_ADD );
1472
                I.mComment = "Disable multi-threading";
1473
                I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
1474
                unsigned int Value = 0;
1475
                I.SetImm( Value );
1476
                I.SetDestZero( true );
1477
                I.SetWriteChannel(ECHANNEL_Z);
1478
                mInstructions.push_back( I );
1479
                I.Clear();
1480
 
1481
        }
1482 227 diegovalve
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1483
        /////                                                                                                                                                                                                             /////
1484
        /////   Start thread                                                                                                                                                                              /////
1485
        /////                                                                                                                                                                                                             /////
1486
        /////   start  ( );                                                                                                                                                       /////
1487
        /////                                                                                                                                                                                                             /////
1488
        /////                                                                                                                                                                                                             /////
1489
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1490 216 diegovalve
        |
1491
        START IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE EOS
1492
        {
1493
                unsigned int ThreadCodeOffset = 0;
1494
                ////std::cout << "Starting thread" << "\n";
1495
                if (gThreadMap.find($2) == gThreadMap.end())
1496
                {
1497
 
1498
                        std::ostringstream ret;
1499
                        ret << "Undefined thread '" << $2 << "' at line " << yylloc << " \n";
1500
                        ret << "Current version of the compiler needs thread defintion prior of thread instantiation\n";
1501
                        throw ret.str();
1502
                } else {
1503
                        ThreadCodeOffset = gThreadMap[$2];
1504
                        //Now enable the multithreading and set instruction offset
1505
                        I.SetCode( EOPERATION_ADD );
1506
                        std::ostringstream ss;
1507
                        ss << "Set thread instruction offset to 8'd" << ThreadCodeOffset;
1508
                        I.mComment = ss.str();
1509
                        I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
1510
                        unsigned int Value = (ThreadCodeOffset << 1);
1511
                        I.SetImm( Value );
1512
                        I.SetDestZero( true );
1513
                        I.SetWriteChannel(ECHANNEL_Z);
1514
                        mInstructions.push_back( I );
1515
                        I.Clear();
1516
 
1517
 
1518
                        I.SetCode( EOPERATION_ADD );
1519
                        I.mComment = "Enable multi-threading";
1520
                        I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
1521
                        Value = (ThreadCodeOffset << 1 | 1);
1522
                        I.SetImm( Value );
1523
                        I.SetDestZero( true );
1524
                        I.SetWriteChannel(ECHANNEL_Z);
1525
                        mInstructions.push_back( I );
1526
                        I.Clear();
1527
 
1528
                }
1529
 
1530
        }
1531 227 diegovalve
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1532
        /////                                                                                                                                                                                                             /////
1533
        /////   Function call and assign return value to variable                                                                                                         /////
1534
        /////                                                                                                                                                                                                             /////
1535
        /////    =  ( [ , ... , ]);                                                                                       /////
1536
        /////                                                                                                                                                                                                             /////
1537
        /////                                                                                                                                                                                                             /////
1538
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1539 216 diegovalve
        |
1540
        left_hand_side ASSIGN IDENTIFIER OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS
1541
        {
1542
                ////std::cout << "Function call returning to var\n";
1543
                StoreReturnAddress( mInstructions, yylloc );
1544
                SavePreviousFramePointer( mInstructions );
1545
                UpdateFramePointer( mInstructions );
1546
                CallFunction( $3, mInstructions, mSymbolMap );
1547
 
1548
 
1549
                //Return value comes in R1, so let's store this in our variable
1550
                I.SetCode( EOPERATION_ADD );
1551
                SetDestinationFromRegister( $1, I, false );
1552
                I.mComment = "grab the return value from the function";
1553
                I.SetSrc1Address( RETURN_VALUE_REGISTER);
1554
                I.SetSrc0Address(0);
1555
                I.SetSrc0SwizzleX(SWX_X);
1556
                I.SetSrc0SwizzleY(SWY_X);
1557
                I.SetSrc0SwizzleZ(SWZ_X);
1558
                mInstructions.push_back( I );
1559
                I.Clear();
1560
                ClearNextFunctionParamRegister();
1561
        }
1562
        |
1563 227 diegovalve
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1564
        /////                                                                                                                                                                                                             /////
1565
        /////   Function call (return value is ignored)                                                                                                                           /////
1566
        /////                                                                                                                                                                                                             /////
1567
        /////    ( [ , ... , ]);                                                                                                                          /////
1568
        /////                                                                                                                                                                                                             /////
1569
        /////                                                                                                                                                                                                             /////
1570
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1571 216 diegovalve
        IDENTIFIER  OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS
1572
        {
1573
 
1574
                //Store the return address
1575
                StoreReturnAddress( mInstructions, yylloc );
1576
 
1577
 
1578
                //Store the current SPR_CONTROL_REGISTER.x into the previous SPR_CONTROL_REGISTER.y
1579
                //SPR_CONTROL_REGISTER.y = SPR_CONTROL_REGISTER.xxx + 0;
1580
                I.SetCode( EOPERATION_ADD );
1581
                I.mComment = "store current frame offset";
1582
                I.SetWriteChannel(ECHANNEL_Y);
1583
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
1584
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
1585
                I.SetSrc1SwizzleX(SWX_X);
1586
                I.SetSrc1SwizzleY(SWY_X);
1587
                I.SetSrc1SwizzleZ(SWZ_X);
1588
                I.SetSrc0Address(0);
1589
                I.SetSrc0SwizzleX(SWX_X);
1590
                I.SetSrc0SwizzleY(SWY_X);
1591
                I.SetSrc0SwizzleZ(SWZ_X);
1592
                mInstructions.push_back( I );
1593
                I.Clear();
1594
                //Now uddate the current SPR_CONTROL_REGISTER.x += number of auto variables
1595
                I.SetCode( EOPERATION_ADD );
1596
                I.mComment = "displace next frame offset by the number of auto variables in current frame";
1597
                I.SetWriteChannel(ECHANNEL_X);
1598
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
1599
                I.SetImm( GetCurretAutoVarFrameSize() );
1600
                I.SetDestZero( false );
1601
                mInstructions.push_back( I );
1602
                I.Clear();
1603
                //Call the function with a JMP
1604
                I.SetCode( EOPERATION_ADD );
1605
                I.mComment = "call the function";
1606
                I.SetBranchFlag( true );
1607
                I.SetBranchType( EBRANCH_ALWAYS );
1608 227 diegovalve
 
1609
                //Now assign the destination of the branch (our function virtual address)
1610 216 diegovalve
                if (mSymbolMap.find($1) == mSymbolMap.end())
1611
                {
1612 227 diegovalve
                        //The destination is not yet declared
1613
                        //so leave it as a symbol so that it can latter
1614
                        //resolved by the linker
1615 216 diegovalve
                        I.SetDestinationSymbol( "@"+$1 );
1616
                } else {
1617 227 diegovalve
                        //The destination symbol has already been declared
1618
                        //so assign it right away
1619 216 diegovalve
                        I.SetDestinationAddress( mSymbolMap[ $1 ] );
1620
                }
1621
 
1622 227 diegovalve
                //Push the last instruction in the sequence and clean up
1623 216 diegovalve
                mInstructions.push_back( I );
1624
                I.Clear();
1625
 
1626
        }
1627
        ;
1628
 
1629
 
1630
 
1631
        function_input_list
1632
                                          :
1633
                                          |//empty
1634
                                          expression COMMA function_input_list
1635
                                          {
1636
                                                AddFunctionInputList( $1, mInstructions,yylloc );
1637
                                          }
1638
                                          |
1639
                                          expression
1640
                                          {
1641
                                                AddFunctionInputList( $1,mInstructions, yylloc );
1642
                                          }
1643
                                          ;
1644
 
1645
        function_argument_list
1646
                                                :
1647
                                                | //empty
1648
                                                IDENTIFIER COMMA function_argument_list
1649
                                                {
1650
                                                        AddFunctionParameter( $1, yylloc );
1651
                                                }
1652
                                                |
1653
                                                IDENTIFIER
1654
                                                {
1655
                                                        AddFunctionParameter( $1, yylloc );
1656
                                                }
1657
                                                ;
1658
 
1659
//  ::=  +  |
1660
          //  -  |
1661
          // 
1662
 
1663
//  ::=  *  |
1664
           //  /  |
1665
           // 
1666
 
1667
//  ::= x | y | ... |
1668
             // (  ) |
1669
             // -  |
1670
             // 
1671
 
1672
expression
1673
                :
1674
                expression ADD term
1675
                {
1676
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1677
                        gExtraDestModifications = 0;
1678
 
1679
                        I.SetCode( EOPERATION_ADD );
1680
                        I.SetDestinationAddress( TempRegIndex );
1681
                        I.SetDestZero( true ); //Use indexing for DST
1682
                        I.SetWriteChannel(ECHANNEL_XYZ);
1683
 
1684
                        PopulateSourceRegisters( $1, $3, I, mInstructions );
1685
                        mInstructions.push_back(I);
1686
                        gInsertedInstructions++;
1687
                        I.Clear();
1688
 
1689
                        std::stringstream ss;
1690
                        ss << "R" << TempRegIndex << " OFFSET ";
1691
                        $$ = ss.str();
1692
 
1693
                }
1694
                |
1695
                expression MINUS term
1696
                {
1697
                        gExtraDestModifications = 0;
1698
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1699
                        I.SetCode( EOPERATION_ADD );
1700
                        I.SetDestinationAddress( TempRegIndex );
1701
                        I.SetDestZero( true ); //Use indexing for DST
1702
                        I.SetWriteChannel(ECHANNEL_XYZ);
1703
                        I.SetSrc0SignX( true );
1704
                        I.SetSrc0SignY( true );
1705
                        I.SetSrc0SignZ( true );
1706
 
1707
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
1708
                        mInstructions.push_back(I);
1709
                        gInsertedInstructions++;
1710
                        I.Clear();
1711
 
1712
                        std::stringstream ss;
1713
                        ss << "R" << TempRegIndex << " OFFSET ";
1714
                        $$ = ss.str();
1715
                }
1716
                |
1717
                expression BITWISE_OR term
1718
                {
1719
                        gExtraDestModifications = 0;
1720
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1721
                        I.SetDestinationAddress( TempRegIndex );
1722
                        I.SetDestZero( true ); //Use indexing for DST
1723
                        I.SetWriteChannel(ECHANNEL_XYZ);
1724
                        I.SetCode( EOPERATION_LOGIC );
1725
                        I.SetLogicOperation( ELOGIC_OR );
1726
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
1727
 
1728
 
1729
                        mInstructions.push_back(I);
1730
                        gInsertedInstructions++;
1731
                        I.Clear();
1732
 
1733
                        std::stringstream ss;
1734
                        ss << "R" << TempRegIndex << " OFFSET ";
1735
                        $$ = ss.str();
1736
                }
1737
                |
1738
                term
1739
                {
1740
                        $$ = $1;
1741
                }
1742
                ;
1743
 
1744
                term
1745
                :
1746
                term MUL factor
1747
                {
1748
                        gExtraDestModifications = 0;
1749
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1750
                        I.SetDestinationAddress( TempRegIndex );
1751
                        I.SetDestZero( true ); //Use indexing for DST
1752
                        I.SetWriteChannel(ECHANNEL_XYZ);
1753
                        I.SetCode( EOPERATION_MUL );
1754
 
1755
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
1756
 
1757
                        //If we are using fixed point aritmethic then we need to apply the scale
1758
                        //R = A * ( B >> SCALE)
1759
                        if (mGenerateFixedPointArithmetic)
1760
                                I.SetSrc0Rotation( EROT_RESULT_RIGHT );
1761
 
1762
                        mInstructions.push_back(I);
1763
                        gInsertedInstructions++;
1764
                        I.Clear();
1765
 
1766
                        std::stringstream ss;
1767
                        ss << "R" << TempRegIndex << " OFFSET ";
1768
                        $$ = ss.str();
1769
                }
1770
                |
1771
                term DIV factor
1772
                {
1773
                        gExtraDestModifications = 0;
1774
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1775
                        I.SetDestinationAddress( TempRegIndex );
1776
                        I.SetDestZero( true ); //Use indexing for DST
1777
                        I.SetWriteChannel(ECHANNEL_XYZ);
1778
                        I.SetCode( EOPERATION_DIV );
1779
 
1780
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
1781
 
1782
                        //If we are using fixed point aritmethic then we need to apply the scale
1783
                        // R = (A << N) / B
1784
                        if (mGenerateFixedPointArithmetic)
1785
                                I.SetSrc1Rotation( EROT_SRC1_LEFT );
1786
 
1787
                        mInstructions.push_back(I);
1788
                        gInsertedInstructions++;
1789
                        I.Clear();
1790
 
1791
                        std::stringstream ss;
1792
                        ss << "R" << TempRegIndex << " OFFSET ";
1793
                        $$ = ss.str();
1794
                }
1795
                |
1796
                term BITWISE_AND factor
1797
                {
1798
                        gExtraDestModifications = 0;
1799
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1800
                        I.SetDestinationAddress( TempRegIndex );
1801
                        I.SetDestZero( true ); //Use indexing for DST
1802
                        I.SetWriteChannel(ECHANNEL_XYZ);
1803
                        I.SetCode( EOPERATION_LOGIC );
1804
                        I.SetLogicOperation( ELOGIC_AND );
1805
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
1806
 
1807
 
1808
                        mInstructions.push_back(I);
1809
                        gInsertedInstructions++;
1810
                        I.Clear();
1811
 
1812
                        std::stringstream ss;
1813
                        ss << "R" << TempRegIndex << " OFFSET ";
1814
                        $$ = ss.str();
1815
                }
1816
                |
1817
                factor
1818
                {
1819
                        $$ = $1;
1820
                }
1821
                ;
1822
 
1823
                factor
1824
                :
1825
                source
1826
                {
1827
                        $$ = $1;
1828
                }
1829
                |
1830
                SQRT OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE
1831
                {
1832
                        gExtraDestModifications = 0;
1833
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1834
                        I.SetDestinationAddress( TempRegIndex );
1835
                        I.SetDestZero( true ); //Use indexing for DST
1836
                        I.SetWriteChannel(ECHANNEL_XYZ);
1837
                        I.SetCode( EOPERATION_SQRT );
1838
                        I.SetSrc0Address( 0 );
1839
                        PopulateSourceRegisters( $3 ,"R0 . X X X", I, mInstructions);
1840
                        mInstructions.push_back(I);
1841
                        gInsertedInstructions++;
1842
                        I.Clear();
1843
 
1844
                        std::stringstream ss;
1845
                        ss << "R" << TempRegIndex << " OFFSET ";
1846
                        $$ = ss.str();
1847
                }
1848
                |
1849
                OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE
1850
                {
1851
                        $$ = $2;
1852
                }
1853
                ;
1854
 
1855
 
1856
 
1857
        source
1858
        :
1859
        constant
1860
        {
1861
 
1862
                unsigned int ImmediateValue;
1863
                std::string StringHex = $1;
1864
                std::stringstream ss;
1865
                ss << std::hex << StringHex;
1866
                ss >> ImmediateValue;
1867
 
1868
                switch (ImmediateValue)
1869
                {
1870
                case 0:
1871
                        $$ = "R0 . X X X";
1872
                break;
1873
                case 1:
1874
                        $$ = "R0 . Y Y Y";
1875
                break;
1876
                case 2:
1877
                        $$ = "R0 . Z Z Z";
1878
                break;
1879
                default:
1880
                        std::string StringHex = $1;
1881
                        std::stringstream ss;
1882
                        ss << std::hex << StringHex;
1883
                        ss >> ImmediateValue;
1884
                        $$ = ss.str();
1885
                        break;
1886
                }
1887
        }
1888
        |
1889
        OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE
1890
        {
1891
                unsigned int TempRegIndex  = GetFreeTempRegister();
1892
                unsigned int ImmediateValue;
1893
 
1894
                {
1895
 
1896
                std::string StringHex = $2;
1897
                std::stringstream ss;
1898
                ss << std::hex << StringHex;
1899
                ss >> ImmediateValue;
1900
 
1901
 
1902
                I.SetDestinationAddress( TempRegIndex );
1903
                I.SetImm( ImmediateValue );
1904
                I.SetDestZero(true);
1905
                I.SetSrc0Displace(true);
1906
                I.SetWriteChannel(ECHANNEL_X);
1907
                I.SetCode( EOPERATION_ADD );
1908
                mInstructions.push_back(I);
1909
                gInsertedInstructions++;
1910
                I.Clear();
1911
                }
1912
 
1913
                {
1914
                std::string StringHex = $4;
1915
                std::stringstream ss;
1916
                ss << std::hex << StringHex;
1917
                ss >> ImmediateValue;
1918
 
1919
                I.SetDestinationAddress( TempRegIndex );
1920
                I.SetImm( ImmediateValue );
1921
                I.SetDestZero(true);
1922
                I.SetSrc0Displace(true);
1923
                I.SetWriteChannel(ECHANNEL_Y);
1924
                I.SetCode( EOPERATION_ADD );
1925
                mInstructions.push_back(I);
1926
                gInsertedInstructions++;
1927
                I.Clear();
1928
                }
1929
 
1930
                {
1931
                std::string StringHex = $6;
1932
                std::stringstream ss;
1933
                ss << std::hex << StringHex;
1934
                ss >> ImmediateValue;
1935
 
1936
                I.SetDestinationAddress( TempRegIndex );
1937
                I.SetImm( ImmediateValue );
1938
                I.SetDestZero(true);
1939
                I.SetSrc0Displace(true);
1940
                I.SetWriteChannel(ECHANNEL_Z);
1941
                I.SetCode( EOPERATION_ADD );
1942
                I.mBisonFlagTrippleConstAssign = true;
1943
                mInstructions.push_back(I);
1944
                gInsertedInstructions++;
1945
                I.Clear();
1946
                }
1947
 
1948
                gExtraDestModifications = 2;
1949
                std::stringstream ss2;
1950
                ss2 << "R" << TempRegIndex << " OFFSET ";
1951
                $$ = ss2.str();
1952
        }
1953
        |
1954
        IDENTIFIER array_index
1955
        {
1956
 
1957
 
1958
                std::string Register;
1959
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
1960
                        $$ = Register;
1961
                 else
1962
                        $$ = GetRegisterFromAutoVar( $1, yylloc) + " OFFSET ";
1963
 
1964
                if ($2 != "NULL")
1965
                {
1966
 
1967
                        $$ += " array_element " + $2;
1968
 
1969
                }
1970
        }
1971
        |
1972
        IDENTIFIER DOT coordinate coordinate coordinate
1973
        {
1974
 
1975
                std::string X = $3,Y = $4,Z = $5;
1976
                std::string Register;
1977
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
1978 227 diegovalve
                        $$ = (Register + " . " + " " + X + " " + Y  + " " + Z/* + " OFFSET "*/);
1979 216 diegovalve
                else
1980
                        $$ = (GetRegisterFromAutoVar( $1, yylloc) + " . " + " " + X + " " + Y  + " " + Z + " OFFSET ");
1981
        }
1982
        |
1983
        REG
1984
        {
1985
 
1986
                std::string R = $1;
1987
                R.erase(0,1);
1988
                $$ = "R" + R;
1989
 
1990
        }
1991
        |
1992
        SCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE
1993
        {
1994
 
1995
                std::string R = $1;
1996
                R.erase(0,1);
1997
                $$ = "<
1998
        }
1999
        |
2000
        UNSCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE
2001
        {
2002
 
2003
                std::string R = $1;
2004
                R.erase(0,1);
2005
                $$ = ">>R" + R;
2006
        }
2007
        |
2008
        REG DOT coordinate coordinate coordinate
2009
        {
2010
                std::string R = $1;
2011
                std::string X = $3,Y = $4,Z = $5;
2012
                R.erase(0,1);
2013
                $$ = "R" + R + " . " + " " + X + " " + Y  + " " + Z;
2014
 
2015
        }
2016
        ;
2017
 
2018
 
2019
        coordinate
2020
        :
2021
        TK_X
2022
        {
2023
                $$ = "X";
2024
        }
2025
        |
2026
        MINUS TK_X
2027
        {
2028
                $$ = "-X";
2029
        }
2030
        |
2031
        TK_Y
2032
        {
2033
                $$ = "Y";
2034
        }
2035
        |
2036
        MINUS TK_Y
2037
        {
2038
                $$ = "-Y";
2039
        }
2040
        |
2041
        TK_Z
2042
        {
2043
                $$ = "Z";
2044
        }
2045
        |
2046
        MINUS TK_Z
2047
        {
2048
                $$ = "-Z";
2049
        }
2050
        ;
2051
 
2052
 
2053
array_index
2054
        :
2055
        {
2056
                $$ = "NULL";
2057
        }
2058
        |
2059
        OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE
2060
        {
2061
                /*std::string Register;
2062
                if ((Register = GetRegisterFromFunctionParameter($2)) != "NULL")
2063
                        $$ = Register;
2064
                else*/
2065
                //Indexes into arrays can only be auto variables!
2066
                $$ = GetRegisterFromAutoVar( $2, yylloc );
2067
        }
2068
        ;
2069
 
2070
left_hand_side
2071
        :
2072
        OUT OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE
2073
        {
2074
 
2075
                $$ = "OUT " + $3;
2076
        }
2077
        |
2078
        OUT OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE
2079
        {
2080 227 diegovalve
        /*
2081 216 diegovalve
                std::string Register;
2082
                if ((Register = GetRegisterFromFunctionParameter($3)) == "NULL")
2083
                        Register = GetRegisterFromAutoVar( $3, yylloc );
2084
 
2085
                $$ = "OUT INDEX" + Register;
2086 227 diegovalve
                */
2087
                std::string Register;
2088
                if ((Register = GetRegisterFromFunctionParameter($3)) != "NULL")
2089
                        $$ = "OUT INDEX" + Register;
2090
                else
2091
                        $$ = "OUT INDEX" + GetRegisterFromAutoVar( $3, yylloc ) + " OFFSET ";
2092
 
2093
 
2094
 
2095 216 diegovalve
        }
2096
        |
2097
        IDENTIFIER array_index
2098
        {
2099
 
2100
                std::string Register;
2101
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
2102
                        $$ = Register + ".xyz";
2103
                else
2104
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".xyz" + " OFFSET " + (($2 != "NULL")?" INDEX"+$2:"");
2105
 
2106
        }
2107
        |
2108
        IDENTIFIER DOT TK_X
2109
        {
2110
                std::string Register;
2111
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
2112
                        $$ = Register + ".x";
2113
                else
2114
                $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".x" + " OFFSET ";
2115
        }
2116
        |
2117
        IDENTIFIER DOT TK_Y
2118
        {
2119
                std::string Register;
2120
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
2121
                        $$ = Register + ".y";
2122
                else
2123
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".y" + " OFFSET ";
2124
        }
2125
        |
2126
        IDENTIFIER DOT TK_Z
2127
        {
2128
                std::string Register;
2129
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
2130
                        $$ = Register + ".z";
2131
                else
2132
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".z" + " OFFSET ";
2133
        }
2134
        |
2135
        REG
2136
        {
2137
                std::string R = $1;
2138
                R.erase(0,1);
2139
                $$ = "R" + R + ".xyz";
2140
        }
2141
        |
2142
        REG DOT TK_X
2143
        {
2144
                std::string R = $1;
2145
                R.erase(0,1);
2146
                $$ = "R" + R + ".x";
2147
        }
2148
        |
2149
        REG DOT TK_Y
2150
        {
2151
                std::string R = $1;
2152
                R.erase(0,1);
2153
                $$ = "R" + R + ".y";
2154
        }
2155
        |
2156
        REG DOT TK_Z
2157
        {
2158
 
2159
                std::string R = $1;
2160
                R.erase(0,1);
2161
                $$ = "R" + R + ".z";
2162
        }
2163
        |
2164
        REG DOT TK_X TK_Y TK_N
2165
        {
2166
                std::string R = $1;
2167
                R.erase(0,1);
2168
                $$ = "R" + R + ".xy";
2169
        }
2170
        |
2171
        REG DOT TK_X TK_N TK_Z
2172
        {
2173
                std::string R = $1;
2174
                R.erase(0,1);
2175
                $$ = "R" + R + ".xz";
2176
        }
2177
        |
2178
        REG DOT TK_N TK_Y TK_Z
2179
        {
2180
                std::string R = $1;
2181
                R.erase(0,1);
2182
                $$ = "R" + R + ".yz";
2183
        }
2184
        ;
2185
 
2186
 
2187
boolean_expression
2188
                                :
2189
                                expression NOT_EQUAL expression
2190
                                {
2191
                                        PopulateBoolean(EBRANCH_IF_ZERO, $1, $3, I, mInstructions, yylloc );
2192
 
2193
                                }
2194
                                |
2195
                                expression EQUAL expression
2196
                                {
2197
                                        PopulateBoolean(EBRANCH_IF_NOT_ZERO, $1, $3, I, mInstructions, yylloc );
2198
 
2199
                                }
2200
                                |
2201
                                expression GREATER_THAN expression
2202
                                {
2203
                                        PopulateBoolean(EBRANCH_IF_ZERO_OR_SIGN, $1, $3, I, mInstructions, yylloc );
2204
 
2205
                                }
2206
 
2207
                                |
2208
                                expression LESS_THAN expression
2209
                                {
2210
                                        PopulateBoolean(EBRANCH_IF_ZERO_OR_NOT_SIGN, $1, $3, I, mInstructions, yylloc );
2211
 
2212
                                }
2213
                                |
2214
                                expression LESS_OR_EQUAL_THAN expression
2215
                                {
2216
                                        PopulateBoolean(EBRANCH_IF_NOT_SIGN, $1, $3, I, mInstructions, yylloc );
2217
 
2218
                                }
2219
                                |
2220
                                expression GREATER_OR_EQUAL_THAN expression
2221
                                {
2222
                                        PopulateBoolean(EBRANCH_IF_SIGN, $1, $3, I, mInstructions, yylloc );
2223
 
2224
                                }
2225
                                ;
2226
 
2227
constant
2228
        :
2229
                DECCONST
2230
                {
2231
                        // Transform to HEX string
2232
                        unsigned int Val;
2233
                        std::string StringDec = $1;
2234
                        std::stringstream ss;
2235
                        ss << StringDec;
2236
                        ss >> Val;
2237
                        std::stringstream ss2;
2238
                        ss2 << std::hex << Val;
2239
                        $$ = ss2.str();
2240
                }
2241
                |
2242
                HEXCONST
2243
                {
2244
                        std::string StringHex = $1;
2245
                        // Get rid of the 0x
2246
                        StringHex.erase(StringHex.begin(),StringHex.begin()+2);
2247
                        std::stringstream ss;
2248
                        ss << std::hex << StringHex;
2249
 
2250
                        $$ = ss.str();
2251
                }
2252
                |
2253
                BINCONST
2254
                {
2255
                        // Transform to HEX string
2256
                        std::string StringBin = $1;
2257
                        // Get rid of the 0b
2258
                        StringBin.erase(StringBin.begin(),StringBin.begin()+2);
2259
                        std::bitset<32> Bitset( StringBin );
2260
                        std::stringstream ss2;
2261
                        ss2 << std::hex <<  Bitset.to_ulong();
2262
                        $$ = ss2.str();
2263
                }
2264
        ;
2265
auto_var_list
2266
                        :
2267
                        IDENTIFIER array_size COMMA auto_var_list
2268
                        {
2269
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
2270
                                {
2271
                                        std::ostringstream ret;
2272
                                        ret << "Duplicated symbol '" << $1 << "'\n";
2273
                                        throw ret.str();
2274
                                }
2275
 
2276
                                std::stringstream ss;
2277
                                ss << $2;
2278
                                unsigned int Size;
2279
                                ss >> Size;
2280
                                gAutoVarMap[ $1 ] = AllocAutoVar(Size);
2281
                        }
2282
                        |
2283
                        IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE COMMA auto_var_list
2284
                        {
2285
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
2286
                                {
2287
                                std::ostringstream ret;
2288
                                ret << "Duplicated symbol " << $1 << "'\n";
2289
                                throw ret.str();
2290
                                }
2291
                                gAutoVarMap[ $1 ] = AllocAutoVar();
2292
 
2293
                                unsigned int Destination = gAutoVarMap[ $1 ];
2294
 
2295
 
2296
 
2297
                                I.ClearWriteChannel();
2298
                                unsigned int ImmediateValue;
2299
                                {
2300
                                I.SetDestinationAddress( Destination );
2301
                                I.SetWriteChannel(ECHANNEL_X);
2302
                                std::string StringHex = $4;
2303
                                std::stringstream ss;
2304
                                ss << std::hex << StringHex;
2305
                                ss >> ImmediateValue;
2306
                                I.SetImm( ImmediateValue );
2307
                                I.SetDestZero( true );
2308
                                I.SetSrc1Displace( false );
2309
                                I.SetSrc0Displace( true );
2310
                                I.SetCode( EOPERATION_ADD );
2311
                                I.mSourceLine = GetCurrentLineNumber( yylloc );
2312
                                mInstructions.push_back(I);
2313
                                I.Clear();
2314
                                }
2315
                                {
2316
                                I.SetDestinationAddress( Destination );
2317
                                I.SetWriteChannel(ECHANNEL_Y);
2318
                                std::string StringHex = $6;
2319
                                std::stringstream ss;
2320
                                ss << std::hex << StringHex;
2321
                                ss >> ImmediateValue;
2322
                                I.SetImm( ImmediateValue );
2323
                                I.SetDestZero( true );
2324
                                I.SetSrc1Displace( false );
2325
                                I.SetSrc0Displace( true );
2326
                                I.SetCode( EOPERATION_ADD );
2327
                                mInstructions.push_back(I);
2328
                                I.Clear();
2329
                                }
2330
                                {
2331
                                I.SetDestinationAddress( Destination );
2332
                                I.SetWriteChannel(ECHANNEL_Z);
2333
                                std::string StringHex = $8;
2334
                                std::stringstream ss;
2335
                                ss << std::hex << StringHex;
2336
                                ss >> ImmediateValue;
2337
                                I.SetImm( ImmediateValue );
2338
                                I.SetDestZero( true );
2339
                                I.SetSrc1Displace( false );
2340
                                I.SetSrc0Displace( true );
2341
                                I.SetCode( EOPERATION_ADD );
2342
                                mInstructions.push_back(I);
2343
                                I.Clear();
2344
                                }
2345
                        }
2346
                        |
2347
                        IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE
2348
                        {
2349
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
2350
                                {
2351
                                std::ostringstream ret;
2352
                                ret << "Duplicated symbol " << $1 << "'\n";
2353
                                throw ret.str();
2354
                                }
2355
                                gAutoVarMap[ $1 ] = AllocAutoVar();
2356
 
2357
                                unsigned int Destination = gAutoVarMap[ $1 ];
2358
 
2359
 
2360
                                I.SetDestZero( true );
2361
                                I.SetSrc1Displace( false );
2362
                                I.SetSrc0Displace( true );
2363
 
2364
 
2365
                                I.ClearWriteChannel();
2366
                                unsigned int ImmediateValue;
2367
                                {
2368
                                I.SetDestinationAddress( Destination );
2369
                                I.SetWriteChannel(ECHANNEL_X);
2370
                                std::string StringHex = $4;
2371
                                std::stringstream ss;
2372
                                ss << std::hex << StringHex;
2373
                                ss >> ImmediateValue;
2374
                                I.SetImm( ImmediateValue );
2375
                                I.SetDestZero( true );
2376
                                I.SetSrc1Displace( false );
2377
                                I.SetSrc0Displace( true );
2378
                                I.SetCode( EOPERATION_ADD );
2379
                                I.mSourceLine = GetCurrentLineNumber( yylloc );
2380
                                mInstructions.push_back(I);
2381
                                I.Clear();
2382
                                }
2383
                                {
2384
                                I.SetDestinationAddress( Destination );
2385
                                I.SetWriteChannel(ECHANNEL_Y);
2386
                                std::string StringHex = $6;
2387
                                std::stringstream ss;
2388
                                ss << std::hex << StringHex;
2389
                                ss >> ImmediateValue;
2390
                                I.SetImm( ImmediateValue );
2391
                                I.SetDestZero( true );
2392
                                I.SetSrc1Displace( false );
2393
                                I.SetSrc0Displace( true );
2394
                                I.SetCode( EOPERATION_ADD );
2395
                                mInstructions.push_back(I);
2396
                                I.Clear();
2397
                                }
2398
                                {
2399
                                I.SetDestinationAddress( Destination );
2400
                                I.SetWriteChannel(ECHANNEL_Z);
2401
                                std::string StringHex = $8;
2402
                                std::stringstream ss;
2403
                                ss << std::hex << StringHex;
2404
                                ss >> ImmediateValue;
2405
                                I.SetImm( ImmediateValue );
2406
                                I.SetDestZero( true );
2407
                                I.SetSrc1Displace( false );
2408
                                I.SetSrc0Displace( true );
2409
                                I.SetCode( EOPERATION_ADD );
2410
                                mInstructions.push_back(I);
2411
                                I.Clear();
2412
                                }
2413
                        }
2414
                        |
2415
                        IDENTIFIER array_size
2416
                        {
2417
 
2418
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
2419
                                {
2420
                                        std::ostringstream ret;
2421
                                        ret << "Duplicated symbol " << $1 << "'\n";
2422
                                        throw ret.str();
2423
                                }
2424
                                std::stringstream ss;
2425
                                ss << std::hex << $2;
2426
                                unsigned int Size;
2427
                                ss >> Size;
2428
                                ////std::cout  << "Array Size is " << Size << " " << $2 << "\n";
2429
                                gAutoVarMap[ $1 ] = AllocAutoVar(Size);
2430
                        }
2431
                        ;
2432
 
2433
array_size
2434
                 :
2435
                 {
2436
                 $$ = "1";
2437
                 }
2438
                 |
2439
                 OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE
2440
                 {
2441
 
2442
                 $$ = $2;
2443
                 }
2444
                 ;
2445
%%
2446
 
2447
 
2448
 
2449
// Error function throws an exception (std::string) with the location and error message
2450
void Theia::Parser::error(const Theia::Parser::location_type &loc,
2451
                                          const std::string &msg) {
2452
        std::ostringstream ret;
2453
        ret << "Parser Error at " << loc << ": "  << msg;
2454
        throw ret.str();
2455
}
2456
 
2457
// Now that we have the Parser declared, we can declare the Scanner and implement
2458
// the yylex function
2459
#include "Scanner.h"
2460
static int yylex(Theia::Parser::semantic_type * yylval,
2461
                 Theia::Parser::location_type * yylloc,
2462
                 Theia::Scanner &scanner) {
2463
        return scanner.yylex(yylval, yylloc);
2464
}
2465
 

powered by: WebSVN 2.1.0

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