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 216

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
 
456
        //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
                return;
474
        }
475
        std::string Reg = GetRegisterFromFunctionParameter( aVar );
476
        if (Reg == "NULL")
477
        {
478
                Reg = GetRegisterFromAutoVar( aVar, yylloc );
479
                I.SetSrc1Address(atoi(Reg.c_str()+1));
480
                I.SetSrc1Displace( true );
481
        } else {
482
                I.SetSrc1Address(atoi(Reg.c_str()+1));
483
                I.SetSrc1Displace( false );
484
        }
485
 
486
 
487
 
488
        I.SetSrc1SwizzleX(SWX_X);
489
        I.SetSrc1SwizzleY(SWY_Y);
490
        I.SetSrc1SwizzleZ(SWZ_Z);
491
        I.SetSrc0Address(0);
492
        I.SetSrc0SwizzleX(SWX_X);
493
        I.SetSrc0SwizzleY(SWY_X);
494
        I.SetSrc0SwizzleZ(SWZ_X);
495
        aInstructions.push_back( I );
496
        I.Clear();
497
}
498
//----------------------------------------------------------
499
void SetExpressionDestination( std::string aStringDestination, Instruction & I )
500
{
501
                std::string Destination = aStringDestination;
502
 
503
                //Look for indirect addressing
504
                if (Destination.find("INDEX") != std::string::npos)
505
                {
506
 
507
                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
508
                        Destination.erase(Destination.find("INDEX"));
509
                        I.SetImm( 0 );
510
                        I.SetCode( EOPERATION_ADD );
511
 
512
                        if (Destination.find(".") != std::string::npos)
513
                        {
514
                                I.ClearWriteChannel();
515
                                if (Destination.find("x") != std::string::npos)
516
                                        I.SetWriteChannel(ECHANNEL_X);
517
                                if (Destination.find("y") != std::string::npos)
518
                                        I.SetWriteChannel(ECHANNEL_Y);
519
                                if (Destination.find("z") != std::string::npos)
520
                                        I.SetWriteChannel(ECHANNEL_Z);
521
                                Destination.erase(Destination.find("."));
522
 
523
                        }
524
 
525
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
526
 
527
                } else {
528
 
529
                        //Look for displament addressing mode
530
                        if (Destination.find("OFFSET") != std::string::npos)
531
                        {
532
                                Destination.erase(Destination.find("OFFSET"));
533
                                I.SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
534
                        }
535
                        if (Destination.find(".") != std::string::npos)
536
                        {
537
                                I.ClearWriteChannel();
538
                                if (Destination.find("x") != std::string::npos)
539
                                        I.SetWriteChannel(ECHANNEL_X);
540
                                if (Destination.find("y") != std::string::npos)
541
                                        I.SetWriteChannel(ECHANNEL_Y);
542
                                if (Destination.find("z") != std::string::npos)
543
                                        I.SetWriteChannel(ECHANNEL_Z);
544
 
545
                                Destination.erase(Destination.find("."));
546
 
547
                        }
548
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
549
 
550
 
551
 
552
                }
553
}
554
 
555
//----------------------------------------------------------
556
bool SourceNull( std::string aSource )
557
{
558
        if (aSource == "NULL")
559
                return true;
560
 
561
        return false;
562
}
563
//----------------------------------------------------------
564
 
565
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)
566
{
567
 
568
 
569
        bool DestinationHasOffset  = false;
570
        bool DetinationHasIndex    = false;
571
        bool Source0HasOffset      = false;
572
        bool Source1HasOffset      = false;
573
        bool Source1HasIndex       = false;
574
        bool Source0HasIndex       = false;
575
 
576
 
577
        if (aDestination.find("INDEX") != std::string::npos)
578
        {
579
                std::string ArrayIndex = aDestination.substr(aDestination.find("INDEX")+5);
580
                aSource1 = ArrayIndex;
581
                DetinationHasIndex      = true;
582
 
583
        }
584
 
585
        if (aSource1.find("INDEX") != std::string::npos)
586
                Source1HasIndex = true;
587
 
588
        if (aSource0.find("INDEX") != std::string::npos)
589
                Source0HasIndex = true;
590
 
591
        if (aDestination.find("OFFSET") != std::string::npos)
592
                DestinationHasOffset = true;
593
 
594
        if      (aSource0.find("OFFSET") != std::string::npos)
595
                Source0HasOffset = true;
596
 
597
        if      (aSource1.find("OFFSET") != std::string::npos)
598
                Source1HasOffset = true;
599
 
600
        if (IsSwizzled( aSource1 ))
601
                SetSwizzleAndSign( 1, aSource1,  I );
602
        I.SetSrc1Address( atoi( aSource1.c_str()+1 ) );
603
 
604
        if (IsSwizzled( aSource0 ))
605
                SetSwizzleAndSign( 0, aSource0,  I );
606
        I.SetSrc0Address( atoi( aSource0.c_str()+1 ) );
607
 
608
 
609
 
610
        //Fisrt take care of the destination write channel
611
        if (aDestination.find(".") != std::string::npos)
612
                {
613
                        I.ClearWriteChannel();
614
                        if (aDestination.find("x") != std::string::npos)
615
                                I.SetWriteChannel(ECHANNEL_X);
616
                        if (aDestination.find("y") != std::string::npos)
617
                                I.SetWriteChannel(ECHANNEL_Y);
618
                        if (aDestination.find("z") != std::string::npos)
619
                                I.SetWriteChannel(ECHANNEL_Z);
620
                        aDestination.erase(aDestination.find("."));
621
        } else {
622
                I.SetWriteChannel(ECHANNEL_XYZ);
623
        }
624
        //Now set the destination Index
625
        I.SetDestinationAddress( atoi(aDestination.c_str()+1) );
626
 
627
 
628
        //Now determine the addressing mode
629
        //Simple addressing modes
630
        if (!aHasLiteral &&     !DetinationHasIndex && !Source0HasIndex && !Source1HasIndex)
631
        {
632
 
633
                I.SetAddressingMode( DestinationHasOffset,Source1HasOffset,Source0HasOffset);
634
                return;
635
        }
636
 
637
 
638
        I.SetImmBit( true ); //This is to set the IMM bit = 1, may be overwritten latter
639
        //Complex addressing modes
640
        if
641
        (
642
        aHasLiteral &&
643
        !SourceNull( aSource0 ) &&
644
        !Source0HasOffset &&
645
        !Source1HasOffset &&
646
        !DestinationHasOffset
647
        )
648
        {
649
                I.SetAddressingMode( false,false,false);
650
                I.SetImm( aLiteral );
651
 
652
        }
653
        else
654
        if
655
        (
656
        aHasLiteral &&
657
        !SourceNull( aSource0 ) &&
658
        Source0HasOffset &&
659
        !Source0HasIndex &&
660
        DestinationHasOffset
661
 
662
        )
663
        {
664
 
665
                I.SetAddressingMode( false,false,true);
666
                I.SetImm( aLiteral );
667
 
668
 
669
        }
670
        else
671
        if
672
        (
673
        !aHasLiteral &&
674
        !SourceNull( aSource1 ) &&
675
        !Source1HasOffset &&
676
        !SourceNull( aSource0 ) &&
677
        Source0HasOffset &&
678
        Source0HasIndex &&
679
        DestinationHasOffset
680
 
681
        )
682
        {
683
                I.SetAddressingMode( false,true,false);
684
 
685
        }
686
        else
687
        if
688
        (
689
        !aHasLiteral &&
690
        !Source1HasOffset &&
691
        !SourceNull( aSource0 ) &&
692
        Source0HasOffset &&
693
        !Source0HasIndex &&
694
        DestinationHasOffset &&
695
        DetinationHasIndex
696
 
697
        )
698
        {
699
                I.SetAddressingMode( false,true,true);
700
 
701
        }
702
        else
703
        if
704
        (
705
        aHasLiteral &&
706
        SourceNull( aSource0 ) &&
707
        !DestinationHasOffset &&
708
        !DetinationHasIndex
709
 
710
        )
711
        {
712
 
713
 
714
                I.SetAddressingMode( true,false,false);
715
                I.SetImm( aLiteral );
716
        }
717
        else
718
        if
719
        (
720
        aHasLiteral &&
721
        SourceNull( aSource0 ) &&
722
        DestinationHasOffset &&
723
        !DetinationHasIndex
724
 
725
        )
726
        {
727
 
728
                I.SetAddressingMode( true,false,true);
729
                I.SetImm( aLiteral );
730
        }
731
        else
732
        if
733
        (
734
        !aHasLiteral &&
735
        Source1HasOffset &&
736
        Source1HasIndex &&
737
        SourceNull( aSource0 ) &&
738
        DestinationHasOffset &&
739
        !DetinationHasIndex
740
 
741
        )
742
        {
743
 
744
                I.SetAddressingMode( true,true,false);
745
        }
746
        else
747
        if
748
        (
749
        !aHasLiteral &&
750
        Source1HasOffset &&
751
        Source1HasIndex &&
752
        Source0HasOffset &&
753
        !Source0HasIndex &&
754
        DestinationHasOffset &&
755
        !DetinationHasIndex
756
 
757
        )
758
        {
759
 
760
                I.SetAddressingMode( true,true,true);
761
        } else {
762
                        std::ostringstream ret;
763
                        ret << "Could not determine addressing mode  at line " << yylloc << " \n";
764
                        throw ret.str();
765
        }
766
 
767
 
768
}
769
 
770
//-------------------------------------------------------------
771
void PopulateBoolean(EBRANCHTYPE aBranchType, std::string Source1, std::string Source0, Instruction & I, std::vector & aInstructions, Theia::Parser::location_type & yylloc )
772
{
773
 
774
                                        if (Source0.find("R") == std::string::npos)
775
                                        {
776
                                                I.mSourceLine = GetCurrentLineNumber( yylloc );
777
                                                I.SetCode( EOPERATION_ADD );
778
                                                unsigned int TempRegIndex  = GetFreeTempRegister();
779
                                                I.SetDestinationAddress( TempRegIndex );
780
                                                unsigned int ImmediateValue;
781
                                                std::string StringHex = Source0;
782
                                                std::stringstream ss;
783
                                                ss << std::hex << StringHex;
784
                                                ss >> ImmediateValue;
785
                                                I.SetImm( ImmediateValue );
786
                                                I.SetDestZero( true );
787
                                                I.SetSrc0Displace( true );
788
                                                I.SetWriteChannel(ECHANNEL_X);
789
                                                I.SetWriteChannel(ECHANNEL_Y);
790
                                                I.SetWriteChannel(ECHANNEL_Z);
791
                                                aInstructions.push_back(I);
792
                                                I.Clear();
793
 
794
                                                std::stringstream ss2;
795
                                                ss2 << "R" << TempRegIndex;
796
                                                ss2 >> Source0;
797
                                                Source0 += " OFFSET ";
798
 
799
                                        }
800
                                        else
801
                                                I.mSourceLine = GetCurrentLineNumber( yylloc );
802
 
803
                                        I.SetCode( EOPERATION_ADD );
804
                                        I.SetSrc0SignX( true );
805
                                        I.SetSrc0SignY( true );
806
                                        I.SetSrc0SignZ( true );
807
                                        I.SetBranchFlag( true );
808
                                        I.ClearWriteChannel();
809
                                        I.SetBranchType( aBranchType );
810
 
811
                                        PopulateSourceRegisters( Source1, Source0, I, aInstructions);
812
                                        aInstructions.push_back(I);
813
                                        I.Clear();
814
                                        ////std::cout << "pushing code at position " << (mInstructions.size() - 1) << "\n";
815
                                        gBranchStack.push_back(aInstructions.size() - 1);
816
                                        ResetTempRegisterIndex();
817
}
818
 
819
//-------------------------------------------------------------
820
        // Prototype for the yylex function
821
        static int yylex(Theia::Parser::semantic_type * yylval,
822
                         Theia::Parser::location_type * yylloc,
823
                         Theia::Scanner &scanner);
824
}
825
 
826
%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
827
%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
828
%%
829
 
830
statement_list: //empty
831
        |
832
        statement_list statement
833
        |
834
        statement
835
        ;
836
 
837
statement
838
        :
839
        AUTO auto_var_list EOS
840
        |
841
        USING FIXED_POINT EOS
842
        {
843
                mGenerateFixedPointArithmetic = true;
844
        }
845
        |
846
        EXIT EOS
847
        {
848
                //Insert a stupid NOP before the exit... is a bug but easier to just patch like this...
849
 
850
                I.Clear();
851
                I.mComment = "NOP";
852
                I.SetCode( EOPERATION_NOP );
853
                mInstructions.push_back(I);
854
                I.Clear();
855
 
856
                I.SetEofFlag(true);
857
                I.mComment = "Set the Exit bit";
858
                I.SetCode( EOPERATION_ADD );
859
                mInstructions.push_back(I);
860
                I.Clear();
861
        }
862
        |
863
        RETURN expression EOS
864
        {
865
 
866
                //////////////////////////////////////////////////////////////////////////////
867
                // This means this that the expression was just a constant.
868
                // No operations were inserted
869
                //////////////////////////////////////////////////////////////////////////////
870
                if (gInsertedInstructions == 0)
871
                {
872
                        I.Clear();
873
                        I.SetCode(EOPERATION_ADD);
874
                        I.mComment ="Set the return value";
875
                        if ($3.find("R") != std::string::npos)
876
                        {
877
                                PopulateInstruction( "R1", $2,"R0 . X X X",I,yylloc);
878
                        }
879
                        else
880
                        {
881
                                unsigned int ImmediateValue = 0;
882
                                std::string StringHex = $3;
883
                                std::stringstream ss;
884
                                ss << std::hex << StringHex;
885
                                ss >> ImmediateValue;
886
                                PopulateInstruction( "R1", $3,"NULL",I, yylloc, true, ImmediateValue);
887
                        }
888
                        mInstructions.push_back(I);
889
                        I.Clear();
890
                } else {
891
 
892
                        mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc);
893
                        gInsertedInstructions = 0;
894
                        mInstructions.back().mComment ="Assigning return value";
895
                        mInstructions.back().SetDestinationAddress( RETURN_VALUE_REGISTER );
896
 
897
                }
898
                ResetTempRegisterIndex();
899
 
900
                I.SetCode( EOPERATION_ADD );
901
                I.mComment = "Restore previous function frame offset";
902
                I.ClearWriteChannel();
903
                I.SetWriteChannel(ECHANNEL_X);
904
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
905
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
906
                I.SetSrc1SwizzleX(SWX_Y);
907
                I.SetSrc1SwizzleY(SWY_Y);
908
                I.SetSrc1SwizzleZ(SWZ_Y);
909
                I.SetSrc0Address(0);
910
                I.SetSrc0SwizzleX(SWX_X);
911
                I.SetSrc0SwizzleY(SWY_X);
912
                I.SetSrc0SwizzleZ(SWZ_X);
913
                mInstructions.push_back( I );
914
                I.Clear();
915
 
916
                //Now return
917
                I.SetImm( 0 );
918
                I.SetCode( EOPERATION_ADD );
919
                I.mComment = "return from function";
920
                I.SetBranchFlag( true );
921
                I.SetBranchType( EBRANCH_ALWAYS );
922
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
923
                mInstructions.push_back(I);
924
                I.Clear();
925
 
926
 
927
 
928
        }
929
        |
930
        RETURN EOS
931
        {
932
                I.SetCode( EOPERATION_ADD );
933
                I.mComment = "Restore previous function frame offset";
934
                I.SetWriteChannel(ECHANNEL_X);
935
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
936
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
937
                I.SetSrc1SwizzleX(SWX_Y);
938
                I.SetSrc1SwizzleY(SWY_Y);
939
                I.SetSrc1SwizzleZ(SWZ_Y);
940
                I.SetSrc0Address(0);
941
                I.SetSrc0SwizzleX(SWX_X);
942
                I.SetSrc0SwizzleY(SWY_X);
943
                I.SetSrc0SwizzleZ(SWZ_X);
944
                mInstructions.push_back( I );
945
                I.Clear();
946
 
947
                I.SetImm( 0 );
948
                I.SetCode( EOPERATION_ADD );
949
                I.mComment = "return from function";
950
                I.SetBranchFlag( true );
951
                I.SetBranchType( EBRANCH_ALWAYS );
952
                I.SetDestinationAddress( RETURN_ADDRESS_REGISTER );
953
                mInstructions.push_back(I);
954
                I.Clear();
955
        }
956
 
957
         |
958
         left_hand_side ADD_EQ constant EOS
959
          {
960
 
961
                 I.mSourceLine = GetCurrentLineNumber( yylloc );
962
                 I.SetCode( EOPERATION_ADD );
963
                 SetDestinationFromRegister( $1, I , true);
964
                 unsigned int ImmediateValue;
965
                 std::string StringHex = $3;
966
                 std::stringstream ss;
967
                 ss << std::hex << StringHex;
968
                 ss >> ImmediateValue;
969
                 I.SetImm( ImmediateValue );
970
                 I.SetDestZero( false );
971
 
972
                 mInstructions.push_back( I );
973
                 I.Clear();
974
         }
975
         |
976
         left_hand_side MINUS MINUS EOS
977
         {
978
 
979
                I.mSourceLine = GetCurrentLineNumber( yylloc );
980
                I.SetCode( EOPERATION_ADD );
981
                SetDestinationFromRegister( $1, I, false );
982
                I.SetSrc0SignX( true );
983
                I.SetSrc0SignY( true );
984
                I.SetSrc0SignZ( true );
985
                std::string Destination = $1;
986
                if (Destination.find("OFFSET") != std::string::npos)
987
                {
988
                        I.SetSrc1Displace( true );
989
                        Destination.erase(Destination.find("OFFSET"));
990
                }
991
 
992
                if (Destination.find(".") != std::string::npos)
993
                        Destination.erase(Destination.find("."));
994
 
995
 
996
                I.SetSrc1Address(atoi(Destination.c_str()+1));
997
                I.SetSrc0Address(0);
998
                I.SetSrc0SwizzleX(SWX_Y);
999
                I.SetSrc0SwizzleY(SWY_Y);
1000
                I.SetSrc0SwizzleZ(SWZ_Y);
1001
                mInstructions.push_back( I );
1002
                I.Clear();
1003
         }
1004
         |
1005
         left_hand_side ADD ADD EOS
1006
         {
1007
 
1008
                I.mSourceLine = GetCurrentLineNumber( yylloc );
1009
                I.SetCode( EOPERATION_ADD );
1010
                SetDestinationFromRegister( $1, I, false );
1011
                std::string Destination = $1;
1012
                if (Destination.find("OFFSET") != std::string::npos)
1013
                {
1014
                        I.SetSrc1Displace( true );
1015
                        Destination.erase(Destination.find("OFFSET"));
1016
                }
1017
 
1018
                if (Destination.find(".") != std::string::npos)
1019
                        Destination.erase(Destination.find("."));
1020
 
1021
                I.SetSrc1Address(atoi(Destination.c_str()+1));
1022
                I.SetSrc0Address(0);
1023
                I.SetSrc0SwizzleX(SWX_Y);
1024
                I.SetSrc0SwizzleY(SWY_Y);
1025
                I.SetSrc0SwizzleZ(SWZ_Y);
1026
                mInstructions.push_back( I );
1027
                I.Clear();
1028
         }
1029
         |
1030
         left_hand_side ASSIGN expression  EOS
1031
        {
1032
 
1033
                //////////////////////////////////////////////////////////////////////////////
1034
                // This means this that the expression will write into the output memory
1035
                // constant index
1036
                //////////////////////////////////////////////////////////////////////////////
1037
 
1038
                if ($1.find("OUT") != std::string::npos && $1.find("INDEX") == std::string::npos )
1039
                {
1040
                        //PopulateInstruction( "R0", "R0 . X X X",$3,I,yylloc);
1041
 
1042
                        I.SetCode(EOPERATION_OUT);
1043
                        $1.erase($1.find("OUT"),3);
1044
 
1045
                        unsigned int ImmediateValue;
1046
                        std::stringstream ss;
1047
                        ss << std::hex << $1;
1048
                        ss >> ImmediateValue;
1049
                        PopulateInstruction( $3, "R0 OFFSET", "R0 OFFSET", I, yylloc, true, ImmediateValue );
1050
                        #ifdef DEBUG
1051
                        I.PrintFields();
1052
                        #endif
1053
                        mInstructions.push_back(I);
1054
                        I.Clear();
1055
                        ResetTempRegisterIndex();
1056
                        goto LABEL_EXPRESSION_DONE;
1057
                }
1058
                //////////////////////////////////////////////////////////////////////////////
1059
                // This means this that the expression will write into the output memory
1060
                // variable index
1061
                //////////////////////////////////////////////////////////////////////////////
1062
 
1063
                if ($1.find("OUT") != std::string::npos && $1.find("INDEX") != std::string::npos )
1064
                {
1065
                        std::string Destination = $1;
1066
                        DCOUT << "!!!!!!!!!!!!!!!!!Destination " << Destination << "\n";
1067
                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
1068
                        Destination.erase(Destination.find("INDEX"));
1069
 
1070
 
1071
                        I.SetDestZero( true ); //Use indexing for DST
1072
                        I.SetWriteChannel(ECHANNEL_XYZ);
1073
 
1074
                        PopulateSourceRegisters( IndexRegister + " OFFSET ", $3, I, mInstructions );
1075
 
1076
 
1077
                        //I.SetImm( 0 );
1078
                        I.SetCode( EOPERATION_OUT );
1079
                        std::string Source0 = $3;
1080
                        DCOUT << "!!!!!!!!!!!!!!!!!Source0 '" << Source0 << "'\n";
1081
                /*      if (Source0.find("OFFSET") != std::string::npos)
1082
                        {
1083
                                        Source0.erase(Source0.find("OFFSET"));
1084
                                        I.SetSrc0Displace(1);
1085
                        }
1086
                        I.SetSrc1Address(atoi(IndexRegister.c_str()+1));
1087
                        I.SetSrc0Address(atoi(Source0.c_str()+1));*/
1088
 
1089
                /*      if (Destination.find(".") != std::string::npos)
1090
                        {
1091
                                I.ClearWriteChannel();
1092
                                if (Destination.find("x") != std::string::npos)
1093
                                        I.SetWriteChannel(ECHANNEL_X);
1094
                                if (Destination.find("y") != std::string::npos)
1095
                                        I.SetWriteChannel(ECHANNEL_Y);
1096
                                if (Destination.find("z") != std::string::npos)
1097
                                        I.SetWriteChannel(ECHANNEL_Z);
1098
 
1099
                                Destination.erase(Destination.find("."));
1100
 
1101
                        }
1102
 
1103
                        std::string Source0 = $3;
1104
                        if (Source0.find("OFFSET") != std::string::npos)
1105
                        {
1106
                                        Source0.erase(Source0.find("OFFSET"));
1107
                                        I.SetSrc0Displace(1);
1108
                        }
1109
                        I.SetSrc1Address(atoi(IndexRegister.c_str()+1));
1110
                        I.SetSrc0Address(atoi(Source0.c_str()+1));
1111
 
1112
 
1113
                                //      I.SetSrc0Address(mInstructions.back().GetDestinationAddress());
1114
                        I.SetDestZero(0);
1115
                        I.SetSrc1Displace(1);
1116
                        I.SetSrc0Displace(1);
1117
                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );*/
1118
                        mInstructions.push_back( I );
1119
                        I.Clear();
1120
                        ResetTempRegisterIndex();
1121
                        goto LABEL_EXPRESSION_DONE;
1122
                }
1123
                //////////////////////////////////////////////////////////////////////////////
1124
                // This means this that the expression was just a constant.
1125
                // No operations were inserted
1126
                //////////////////////////////////////////////////////////////////////////////
1127
                if (gInsertedInstructions == 0)
1128
                {
1129
 
1130
                        I.Clear();
1131
 
1132
                        I.SetCode(EOPERATION_ADD);
1133
                        I.mSourceLine = GetCurrentLineNumber(yylloc);
1134
                        if ($3.find("R") != std::string::npos)
1135
                        {
1136
                        // case 1:
1137
                        // foo = 0;        //$$ = R0 . X X X
1138
                        /*      SetDestinationFromRegister( $1, I, false );
1139
                                PopulateSourceRegisters( $3, "R0 . X X X", I, mInstructions);*/
1140
 
1141
                                PopulateInstruction( $1, "R0 . X X X",$3,I,yylloc);
1142
 
1143
                        } else {
1144
                        // case 2:
1145
                        // foo = 0xcafe;  //$$ = 0xcafe
1146
                                SetDestinationFromRegister( $1, I, true );
1147
                                unsigned int ImmediateValue = 0;
1148
                                std::string StringHex = $3;
1149
                                std::stringstream ss;
1150
                                ss << std::hex << StringHex;
1151
                                ss >> ImmediateValue;
1152
 
1153
                                PopulateInstruction( $1, $3,"NULL",I, yylloc, true, ImmediateValue);
1154
                        }
1155
                        std::string strConstant = $3;
1156
 
1157
                        mInstructions.push_back(I);
1158
                        I.Clear();
1159
                        ResetTempRegisterIndex();
1160
                        goto LABEL_EXPRESSION_DONE;
1161
                }
1162
 
1163
                //////////////////////////////////////////////////////////////////////////////
1164
                // This means that the last instruction which was inserted was a tripple
1165
                // constant assignement, like foo = (1,2,3)
1166
                //////////////////////////////////////////////////////////////////////////////
1167
                if (mInstructions.back().mBisonFlagTrippleConstAssign)
1168
                {
1169
                        unsigned int LastIndex = mInstructions.size() - 1;
1170
                        mInstructions[LastIndex].SetDestinationAddress(atoi($1.c_str()+1));
1171
                        mInstructions[LastIndex-1].SetDestinationAddress(atoi($1.c_str()+1));
1172
                        mInstructions[LastIndex-2].SetDestinationAddress(atoi($1.c_str()+1));
1173
                        mInstructions[LastIndex-2].mSourceLine = GetCurrentLineNumber( yylloc );
1174
                        if($1.find("OFFSET") == std::string::npos)
1175
                        {
1176
                                mInstructions[LastIndex].SetAddressingMode(true,false,false);
1177
                                mInstructions[LastIndex-1].SetAddressingMode(true,false,false);
1178
                                mInstructions[LastIndex-2].SetAddressingMode(true,false,false);
1179
                        }
1180
 
1181
                        ResetTempRegisterIndex();
1182
                        goto LABEL_EXPRESSION_DONE;
1183
                }
1184
                //////////////////////////////////////////////////////////////////////////////
1185
                // Handle the case where the destination is an array of vector
1186
                // ej: R = v1[ i ]  + V2
1187
                //////////////////////////////////////////////////////////////////////////////
1188
                if (I.GetOperation() == 0 && $3.find("array_element") != std::string::npos)
1189
                {
1190
                        //No operation meaning the the expression only has a single variable
1191
                        //See if the expression returned is an array_element
1192
                        if ($3.find("array_element") != std::string::npos)
1193
                        {
1194
                                ////std::cout << "expression is an array element\n\n";
1195
                                std::string Index = $3.substr($3.find("array_element"));
1196
                                Index = Index.substr(Index.find_first_not_of("array_element R"));
1197
                                SetIndexRegister( atoi(Index.c_str()), mInstructions );
1198
                                $3.erase($3.find("array_element"));
1199
                                SetExpressionDestination( $1, I );
1200
                                I.SetCode(EOPERATION_ADD);
1201
                                I.SetImmBit( true );
1202
                                I.SetDestZero( true );
1203
                                I.SetSrc1Displace( true );
1204
                                I.SetSrc0Displace( false );
1205
                                I.mSourceLine = GetCurrentLineNumber(yylloc);
1206
 
1207
                                if ($3.find("OFFSET") != std::string::npos)
1208
                                        $3.erase($3.find("OFFSET"));
1209
 
1210
                                I.SetSrc1Address(atoi($3.c_str()+1));
1211
                                I.SetSrc0Address(0);
1212
                                mInstructions.push_back(I);
1213
                                I.Clear();
1214
                        }
1215
                }
1216
                else
1217
                {
1218
 
1219
                                mInstructions[ mInstructions.size() - gInsertedInstructions].mSourceLine = GetCurrentLineNumber(yylloc);
1220
                                gInsertedInstructions = 0;
1221
                                std::string Destination = $1;
1222
                                //std::cout << "DST " << Destination << " \n";
1223
                                //Look for indirect addressing
1224
                                if (Destination.find("INDEX") != std::string::npos)
1225
                                {
1226
 
1227
                                        std::string IndexRegister = Destination.substr(Destination.find("INDEX")+5);
1228
 
1229
                                        Destination.erase(Destination.find("INDEX"));
1230
 
1231
                                        I.SetImm( 0 );
1232
                                        I.SetCode( EOPERATION_ADD );
1233
 
1234
                                        if (Destination.find(".") != std::string::npos)
1235
                                        {
1236
                                                I.ClearWriteChannel();
1237
                                                if (Destination.find("x") != std::string::npos)
1238
                                                        I.SetWriteChannel(ECHANNEL_X);
1239
                                                if (Destination.find("y") != std::string::npos)
1240
                                                        I.SetWriteChannel(ECHANNEL_Y);
1241
                                                if (Destination.find("z") != std::string::npos)
1242
                                                        I.SetWriteChannel(ECHANNEL_Z);
1243
 
1244
                                                Destination.erase(Destination.find("."));
1245
 
1246
                                        }
1247
 
1248
                                        std::string Source0 = $3;
1249
                                        if (Source0.find("OFFSET") != std::string::npos)
1250
                                        {
1251
                                                Source0.erase(Source0.find("OFFSET"));
1252
                                                I.SetSrc0Displace(1);
1253
                                        }
1254
                                        I.SetSrc1Address(atoi(IndexRegister.c_str()+1));
1255
                                        I.SetSrc0Address(atoi(Source0.c_str()+1));
1256
 
1257
 
1258
                                //      I.SetSrc0Address(mInstructions.back().GetDestinationAddress());
1259
                                        I.SetDestZero(0);
1260
                                        I.SetSrc1Displace(1);
1261
                                        I.SetSrc0Displace(1);
1262
                                        I.SetDestinationAddress( atoi(Destination.c_str()+1) );
1263
                                        mInstructions.push_back( I );
1264
                                        I.Clear();
1265
                                } else {
1266
 
1267
                                        if (mInstructions.back().GetImm())
1268
                                        {
1269
                                                //Look for displament addressing mode
1270
                                                unsigned int AddressingMode = mInstructions.back().GetAddressingMode();
1271
                                                if (Destination.find("OFFSET") != std::string::npos)
1272
                                                {
1273
                                                        //This means AddressMode is '101', so leave the way it is
1274
                                                        mInstructions.back().ClearWriteChannel();
1275
                                                        mInstructions.back().SetWriteChannel(ECHANNEL_Z);
1276
                                                        Destination.erase(Destination.find("OFFSET"));
1277
                                                } else {
1278
                                                        //This is not supposed to have index, so change addressing mode to '100'
1279
 
1280
                                                        mInstructions.back().SetDestZero( true );
1281
                                                        mInstructions.back().SetSrc1Displace( false );
1282
                                                        mInstructions.back().SetSrc0Displace( false );
1283
                                                        mInstructions.back().ClearWriteChannel();
1284
                                                        mInstructions.back().SetWriteChannel(ECHANNEL_Z);
1285
                                                }
1286
 
1287
                                        } else {
1288
                                                mInstructions.back().SetDestZero( false ); //First assume no offset was used
1289
 
1290
 
1291
 
1292
                                                //Look for displament addressing mode
1293
                                                if (Destination.find("OFFSET") != std::string::npos)
1294
                                                {
1295
                                                        Destination.erase(Destination.find("OFFSET"));
1296
                                                        mInstructions.back().SetDestZero( true ); //When Imm != 0, DestZero means DST = DSTINDEX + offset
1297
                                                }
1298
                                        }
1299
                                                if (Destination.find(".") != std::string::npos)
1300
                                                {
1301
                                                        mInstructions.back().ClearWriteChannel();
1302
                                                        if (Destination.find("x") != std::string::npos)
1303
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_X);
1304
                                                        if (Destination.find("y") != std::string::npos)
1305
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_Y);
1306
                                                        if (Destination.find("z") != std::string::npos)
1307
                                                                mInstructions.back().SetWriteChannel(ECHANNEL_Z);
1308
 
1309
                                                        Destination.erase(Destination.find("."));
1310
 
1311
                                                }
1312
                                                mInstructions.back().SetDestinationAddress( atoi($1.c_str()+1) );
1313
                                                for (int i = 1; i <= gExtraDestModifications; i++ )
1314
                                                {
1315
                                                        int idx = (mInstructions.size()-1)-i;
1316
                                                        mInstructions[idx].SetDestinationAddress( atoi($1.c_str()+1) );
1317
                                                        if (mInstructions[idx].GetImm())
1318
                                                        {
1319
 
1320
                                                                //This is not supposed to have index, so change addressing mode to '100'
1321
                                                                mInstructions[idx].SetDestZero( true );
1322
                                                                mInstructions[idx].SetSrc1Displace( false );
1323
                                                                mInstructions[idx].SetSrc0Displace( false );
1324
 
1325
 
1326
                                                        }
1327
 
1328
                                                }
1329
                                                gExtraDestModifications = 0;
1330
 
1331
 
1332
 
1333
                                }
1334
                                ResetTempRegisterIndex();
1335
                }
1336
 
1337
                LABEL_EXPRESSION_DONE:
1338
                gInsertedInstructions = 0;
1339
                while(0);
1340
 
1341
        }
1342
        |
1343
        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
1344
        {
1345
                mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size()+1);
1346
                gBranchStack.pop_back();
1347
                //Now I need to put a GOTO so that the while gets evaluated again...
1348
                //jump out of the if
1349
           I.Clear();
1350
           I.SetCode( EOPERATION_ADD );
1351
           I.mComment = "while loop goto re-eval boolean";
1352
           I.SetDestinationAddress( gWhileLoopAddress );
1353
           I.SetBranchFlag( true );
1354
           I.SetBranchType( EBRANCH_ALWAYS );
1355
           mInstructions.push_back(I);
1356
           I.Clear();
1357
 
1358
        }
1359
        | IF
1360
          OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE
1361
          OPEN_BRACE statement_list CLOSE_BRACE
1362
      ELSE
1363
        {
1364
 
1365
           //jump out of the if
1366
           I.Clear();
1367
           I.SetCode( EOPERATION_ADD );
1368
           I.SetBranchFlag( true );
1369
           I.SetBranchType( EBRANCH_ALWAYS );
1370
           mInstructions.push_back(I);
1371
           I.Clear();
1372
           //Take care of the destination addr of the if statement.
1373
           mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
1374
          gBranchStack.pop_back();
1375
          //push the inconditional jump into the stack
1376
          gBranchStack.push_back(mInstructions.size() - 1);
1377
          ////std::cout << "else\n";
1378
 
1379
        }
1380
          OPEN_BRACE  statement_list CLOSE_BRACE
1381
        {
1382
 
1383
           mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
1384
           gBranchStack.pop_back();
1385
           //Now push the JMP
1386
 
1387
                ////std::cout << "END elseif\n";
1388
        }
1389
        |
1390
        //NOW the if statement
1391
        IF OPEN_ROUND_BRACE boolean_expression CLOSE_ROUND_BRACE OPEN_BRACE statement_list CLOSE_BRACE
1392
        {
1393
                mInstructions[gBranchStack.back()].SetDestinationAddress(mInstructions.size());
1394
                //mInstructions[gBranchStack.back()].mSourceLine = GetCurrentLineNumber(yylloc);
1395
 
1396
                gBranchStack.pop_back();
1397
                ////std::cout << "if closing at " << mInstructions.size() << "\n";
1398
 
1399
        }
1400
        |
1401
        FUNCTION IDENTIFIER OPEN_ROUND_BRACE function_argument_list CLOSE_ROUND_BRACE
1402
        {
1403
          ////std::cout << "Function declaration for " << $2 << " at " << mInstructions.size() << "\n" ;
1404
          mSymbolMap[ $2 ] = mInstructions.size();
1405
        } OPEN_BRACE statement_list CLOSE_BRACE
1406
        {
1407
                //Clear the auto var index now that we leave the function scope
1408
                ClearAutoVarMap();
1409
                ClearFunctionParameterMap();
1410
 
1411
                //Now uddate the current SPR_CONTROL_REGISTER.x = SPR_CONTROL_REGISTER.y
1412
                I.SetCode( EOPERATION_ADD );
1413
                I.mComment = "Restore previous function frame offset";
1414
                I.SetWriteChannel(ECHANNEL_X);
1415
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
1416
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
1417
                I.SetSrc1SwizzleX(SWX_Y);
1418
                I.SetSrc1SwizzleY(SWY_Y);
1419
                I.SetSrc1SwizzleZ(SWZ_Y);
1420
                I.SetSrc0Address(0);
1421
                I.SetSrc0SwizzleX(SWX_X);
1422
                I.SetSrc0SwizzleY(SWY_X);
1423
                I.SetSrc0SwizzleZ(SWZ_X);
1424
 
1425
                mInstructions.push_back( I );
1426
                I.Clear();
1427
        }
1428
        |
1429
        //Thread declaration
1430
        THREAD IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE
1431
        {
1432
                gThreadMap[ $2 ] = mInstructions.size();
1433
                gThreadScope = true;
1434
        }
1435
        OPEN_BRACE statement_list CLOSE_BRACE
1436
        {
1437
                ////std::cout << "Defining thread" << "\n";
1438
                gThreadScope = false;
1439
                ClearAutoVarMap();
1440
                //Since the thread is done, then disable threading
1441
                I.SetCode( EOPERATION_ADD );
1442
                I.mComment = "Disable multi-threading";
1443
                I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
1444
                unsigned int Value = 0;
1445
                I.SetImm( Value );
1446
                I.SetDestZero( true );
1447
                I.SetWriteChannel(ECHANNEL_Z);
1448
                mInstructions.push_back( I );
1449
                I.Clear();
1450
 
1451
        }
1452
        |
1453
        START IDENTIFIER OPEN_ROUND_BRACE CLOSE_ROUND_BRACE EOS
1454
        {
1455
                unsigned int ThreadCodeOffset = 0;
1456
                ////std::cout << "Starting thread" << "\n";
1457
                if (gThreadMap.find($2) == gThreadMap.end())
1458
                {
1459
 
1460
                        std::ostringstream ret;
1461
                        ret << "Undefined thread '" << $2 << "' at line " << yylloc << " \n";
1462
                        ret << "Current version of the compiler needs thread defintion prior of thread instantiation\n";
1463
                        throw ret.str();
1464
                } else {
1465
                        ThreadCodeOffset = gThreadMap[$2];
1466
                        //Now enable the multithreading and set instruction offset
1467
                        I.SetCode( EOPERATION_ADD );
1468
                        std::ostringstream ss;
1469
                        ss << "Set thread instruction offset to 8'd" << ThreadCodeOffset;
1470
                        I.mComment = ss.str();
1471
                        I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
1472
                        unsigned int Value = (ThreadCodeOffset << 1);
1473
                        I.SetImm( Value );
1474
                        I.SetDestZero( true );
1475
                        I.SetWriteChannel(ECHANNEL_Z);
1476
                        mInstructions.push_back( I );
1477
                        I.Clear();
1478
 
1479
 
1480
                        I.SetCode( EOPERATION_ADD );
1481
                        I.mComment = "Enable multi-threading";
1482
                        I.SetDestinationAddress( SPR_CONTROL_REGISTER0 );
1483
                        Value = (ThreadCodeOffset << 1 | 1);
1484
                        I.SetImm( Value );
1485
                        I.SetDestZero( true );
1486
                        I.SetWriteChannel(ECHANNEL_Z);
1487
                        mInstructions.push_back( I );
1488
                        I.Clear();
1489
 
1490
                }
1491
 
1492
        }
1493
        |
1494
        left_hand_side ASSIGN IDENTIFIER OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS
1495
        {
1496
                ////std::cout << "Function call returning to var\n";
1497
                StoreReturnAddress( mInstructions, yylloc );
1498
                SavePreviousFramePointer( mInstructions );
1499
                UpdateFramePointer( mInstructions );
1500
                CallFunction( $3, mInstructions, mSymbolMap );
1501
 
1502
 
1503
                //Return value comes in R1, so let's store this in our variable
1504
                I.SetCode( EOPERATION_ADD );
1505
                SetDestinationFromRegister( $1, I, false );
1506
                I.mComment = "grab the return value from the function";
1507
                I.SetSrc1Address( RETURN_VALUE_REGISTER);
1508
                I.SetSrc0Address(0);
1509
                I.SetSrc0SwizzleX(SWX_X);
1510
                I.SetSrc0SwizzleY(SWY_X);
1511
                I.SetSrc0SwizzleZ(SWZ_X);
1512
                mInstructions.push_back( I );
1513
                I.Clear();
1514
                ClearNextFunctionParamRegister();
1515
        }
1516
        |
1517
        //Function call
1518
        IDENTIFIER  OPEN_ROUND_BRACE function_input_list CLOSE_ROUND_BRACE EOS
1519
        {
1520
 
1521
                //Store the return address
1522
                StoreReturnAddress( mInstructions, yylloc );
1523
 
1524
 
1525
                //Store the current SPR_CONTROL_REGISTER.x into the previous SPR_CONTROL_REGISTER.y
1526
                //SPR_CONTROL_REGISTER.y = SPR_CONTROL_REGISTER.xxx + 0;
1527
                I.SetCode( EOPERATION_ADD );
1528
                I.mComment = "store current frame offset";
1529
                I.SetWriteChannel(ECHANNEL_Y);
1530
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
1531
                I.SetSrc1Address(SPR_CONTROL_REGISTER);
1532
                I.SetSrc1SwizzleX(SWX_X);
1533
                I.SetSrc1SwizzleY(SWY_X);
1534
                I.SetSrc1SwizzleZ(SWZ_X);
1535
                I.SetSrc0Address(0);
1536
                I.SetSrc0SwizzleX(SWX_X);
1537
                I.SetSrc0SwizzleY(SWY_X);
1538
                I.SetSrc0SwizzleZ(SWZ_X);
1539
                mInstructions.push_back( I );
1540
                I.Clear();
1541
                //Now uddate the current SPR_CONTROL_REGISTER.x += number of auto variables
1542
                I.SetCode( EOPERATION_ADD );
1543
                I.mComment = "displace next frame offset by the number of auto variables in current frame";
1544
                I.SetWriteChannel(ECHANNEL_X);
1545
                I.SetDestinationAddress( SPR_CONTROL_REGISTER );
1546
                I.SetImm( GetCurretAutoVarFrameSize() );
1547
                I.SetDestZero( false );
1548
                mInstructions.push_back( I );
1549
                I.Clear();
1550
                //Call the function with a JMP
1551
                I.SetCode( EOPERATION_ADD );
1552
                I.mComment = "call the function";
1553
                I.SetBranchFlag( true );
1554
                I.SetBranchType( EBRANCH_ALWAYS );
1555
                //Now do the branch
1556
                if (mSymbolMap.find($1) == mSymbolMap.end())
1557
                {
1558
                //      ////std::cout << "Error in line : " << $1 <<" undelcared IDENTIFIER\n";
1559
                        I.SetDestinationSymbol( "@"+$1 );
1560
                //      exit(1);
1561
                } else {
1562
                        I.SetDestinationAddress( mSymbolMap[ $1 ] );
1563
                }
1564
 
1565
 
1566
                mInstructions.push_back( I );
1567
                I.Clear();
1568
 
1569
        }
1570
        ;
1571
 
1572
 
1573
 
1574
        function_input_list
1575
                                          :
1576
                                          |//empty
1577
                                          expression COMMA function_input_list
1578
                                          {
1579
                                                AddFunctionInputList( $1, mInstructions,yylloc );
1580
                                          }
1581
                                          |
1582
                                          expression
1583
                                          {
1584
                                                AddFunctionInputList( $1,mInstructions, yylloc );
1585
                                          }
1586
                                          ;
1587
 
1588
        function_argument_list
1589
                                                :
1590
                                                | //empty
1591
                                                IDENTIFIER COMMA function_argument_list
1592
                                                {
1593
                                                        AddFunctionParameter( $1, yylloc );
1594
                                                }
1595
                                                |
1596
                                                IDENTIFIER
1597
                                                {
1598
                                                        AddFunctionParameter( $1, yylloc );
1599
                                                }
1600
                                                ;
1601
 
1602
//  ::=  +  |
1603
          //  -  |
1604
          // 
1605
 
1606
//  ::=  *  |
1607
           //  /  |
1608
           // 
1609
 
1610
//  ::= x | y | ... |
1611
             // (  ) |
1612
             // -  |
1613
             // 
1614
 
1615
expression
1616
                :
1617
                expression ADD term
1618
                {
1619
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1620
                        gExtraDestModifications = 0;
1621
 
1622
                        I.SetCode( EOPERATION_ADD );
1623
                        I.SetDestinationAddress( TempRegIndex );
1624
                        I.SetDestZero( true ); //Use indexing for DST
1625
                        I.SetWriteChannel(ECHANNEL_XYZ);
1626
 
1627
                        PopulateSourceRegisters( $1, $3, I, mInstructions );
1628
                        mInstructions.push_back(I);
1629
                        gInsertedInstructions++;
1630
                        I.Clear();
1631
 
1632
                        std::stringstream ss;
1633
                        ss << "R" << TempRegIndex << " OFFSET ";
1634
                        $$ = ss.str();
1635
 
1636
                }
1637
                |
1638
                expression MINUS term
1639
                {
1640
                        gExtraDestModifications = 0;
1641
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1642
                        I.SetCode( EOPERATION_ADD );
1643
                        I.SetDestinationAddress( TempRegIndex );
1644
                        I.SetDestZero( true ); //Use indexing for DST
1645
                        I.SetWriteChannel(ECHANNEL_XYZ);
1646
                        I.SetSrc0SignX( true );
1647
                        I.SetSrc0SignY( true );
1648
                        I.SetSrc0SignZ( true );
1649
 
1650
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
1651
                        mInstructions.push_back(I);
1652
                        gInsertedInstructions++;
1653
                        I.Clear();
1654
 
1655
                        std::stringstream ss;
1656
                        ss << "R" << TempRegIndex << " OFFSET ";
1657
                        $$ = ss.str();
1658
                }
1659
                |
1660
                expression BITWISE_OR term
1661
                {
1662
                        gExtraDestModifications = 0;
1663
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1664
                        I.SetDestinationAddress( TempRegIndex );
1665
                        I.SetDestZero( true ); //Use indexing for DST
1666
                        I.SetWriteChannel(ECHANNEL_XYZ);
1667
                        I.SetCode( EOPERATION_LOGIC );
1668
                        I.SetLogicOperation( ELOGIC_OR );
1669
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
1670
 
1671
 
1672
                        mInstructions.push_back(I);
1673
                        gInsertedInstructions++;
1674
                        I.Clear();
1675
 
1676
                        std::stringstream ss;
1677
                        ss << "R" << TempRegIndex << " OFFSET ";
1678
                        $$ = ss.str();
1679
                }
1680
                |
1681
                term
1682
                {
1683
                        $$ = $1;
1684
                }
1685
                ;
1686
 
1687
                term
1688
                :
1689
                term MUL factor
1690
                {
1691
                        gExtraDestModifications = 0;
1692
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1693
                        I.SetDestinationAddress( TempRegIndex );
1694
                        I.SetDestZero( true ); //Use indexing for DST
1695
                        I.SetWriteChannel(ECHANNEL_XYZ);
1696
                        I.SetCode( EOPERATION_MUL );
1697
 
1698
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
1699
 
1700
                        //If we are using fixed point aritmethic then we need to apply the scale
1701
                        //R = A * ( B >> SCALE)
1702
                        if (mGenerateFixedPointArithmetic)
1703
                                I.SetSrc0Rotation( EROT_RESULT_RIGHT );
1704
 
1705
                        mInstructions.push_back(I);
1706
                        gInsertedInstructions++;
1707
                        I.Clear();
1708
 
1709
                        std::stringstream ss;
1710
                        ss << "R" << TempRegIndex << " OFFSET ";
1711
                        $$ = ss.str();
1712
                }
1713
                |
1714
                term DIV factor
1715
                {
1716
                        gExtraDestModifications = 0;
1717
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1718
                        I.SetDestinationAddress( TempRegIndex );
1719
                        I.SetDestZero( true ); //Use indexing for DST
1720
                        I.SetWriteChannel(ECHANNEL_XYZ);
1721
                        I.SetCode( EOPERATION_DIV );
1722
 
1723
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
1724
 
1725
                        //If we are using fixed point aritmethic then we need to apply the scale
1726
                        // R = (A << N) / B
1727
                        if (mGenerateFixedPointArithmetic)
1728
                                I.SetSrc1Rotation( EROT_SRC1_LEFT );
1729
 
1730
                        mInstructions.push_back(I);
1731
                        gInsertedInstructions++;
1732
                        I.Clear();
1733
 
1734
                        std::stringstream ss;
1735
                        ss << "R" << TempRegIndex << " OFFSET ";
1736
                        $$ = ss.str();
1737
                }
1738
                |
1739
                term BITWISE_AND factor
1740
                {
1741
                        gExtraDestModifications = 0;
1742
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1743
                        I.SetDestinationAddress( TempRegIndex );
1744
                        I.SetDestZero( true ); //Use indexing for DST
1745
                        I.SetWriteChannel(ECHANNEL_XYZ);
1746
                        I.SetCode( EOPERATION_LOGIC );
1747
                        I.SetLogicOperation( ELOGIC_AND );
1748
                        PopulateSourceRegisters( $1, $3, I, mInstructions);
1749
 
1750
 
1751
                        mInstructions.push_back(I);
1752
                        gInsertedInstructions++;
1753
                        I.Clear();
1754
 
1755
                        std::stringstream ss;
1756
                        ss << "R" << TempRegIndex << " OFFSET ";
1757
                        $$ = ss.str();
1758
                }
1759
                |
1760
                factor
1761
                {
1762
                        $$ = $1;
1763
                }
1764
                ;
1765
 
1766
                factor
1767
                :
1768
                source
1769
                {
1770
                        $$ = $1;
1771
                }
1772
                |
1773
                SQRT OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE
1774
                {
1775
                        gExtraDestModifications = 0;
1776
                        unsigned int TempRegIndex  = GetFreeTempRegister();
1777
                        I.SetDestinationAddress( TempRegIndex );
1778
                        I.SetDestZero( true ); //Use indexing for DST
1779
                        I.SetWriteChannel(ECHANNEL_XYZ);
1780
                        I.SetCode( EOPERATION_SQRT );
1781
                        I.SetSrc0Address( 0 );
1782
                        PopulateSourceRegisters( $3 ,"R0 . X X X", I, mInstructions);
1783
                        mInstructions.push_back(I);
1784
                        gInsertedInstructions++;
1785
                        I.Clear();
1786
 
1787
                        std::stringstream ss;
1788
                        ss << "R" << TempRegIndex << " OFFSET ";
1789
                        $$ = ss.str();
1790
                }
1791
                |
1792
                OPEN_ROUND_BRACE expression CLOSE_ROUND_BRACE
1793
                {
1794
                        $$ = $2;
1795
                }
1796
                ;
1797
 
1798
 
1799
 
1800
        source
1801
        :
1802
        constant
1803
        {
1804
 
1805
                unsigned int ImmediateValue;
1806
                std::string StringHex = $1;
1807
                std::stringstream ss;
1808
                ss << std::hex << StringHex;
1809
                ss >> ImmediateValue;
1810
 
1811
                switch (ImmediateValue)
1812
                {
1813
                case 0:
1814
                        $$ = "R0 . X X X";
1815
                break;
1816
                case 1:
1817
                        $$ = "R0 . Y Y Y";
1818
                break;
1819
                case 2:
1820
                        $$ = "R0 . Z Z Z";
1821
                break;
1822
                default:
1823
                        std::string StringHex = $1;
1824
                        std::stringstream ss;
1825
                        ss << std::hex << StringHex;
1826
                        ss >> ImmediateValue;
1827
                        $$ = ss.str();
1828
                        break;
1829
                }
1830
        }
1831
        |
1832
        OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE
1833
        {
1834
                unsigned int TempRegIndex  = GetFreeTempRegister();
1835
                unsigned int ImmediateValue;
1836
 
1837
                {
1838
 
1839
                std::string StringHex = $2;
1840
                std::stringstream ss;
1841
                ss << std::hex << StringHex;
1842
                ss >> ImmediateValue;
1843
 
1844
 
1845
                I.SetDestinationAddress( TempRegIndex );
1846
                I.SetImm( ImmediateValue );
1847
                I.SetDestZero(true);
1848
                I.SetSrc0Displace(true);
1849
                I.SetWriteChannel(ECHANNEL_X);
1850
                I.SetCode( EOPERATION_ADD );
1851
                mInstructions.push_back(I);
1852
                gInsertedInstructions++;
1853
                I.Clear();
1854
                }
1855
 
1856
                {
1857
                std::string StringHex = $4;
1858
                std::stringstream ss;
1859
                ss << std::hex << StringHex;
1860
                ss >> ImmediateValue;
1861
 
1862
                I.SetDestinationAddress( TempRegIndex );
1863
                I.SetImm( ImmediateValue );
1864
                I.SetDestZero(true);
1865
                I.SetSrc0Displace(true);
1866
                I.SetWriteChannel(ECHANNEL_Y);
1867
                I.SetCode( EOPERATION_ADD );
1868
                mInstructions.push_back(I);
1869
                gInsertedInstructions++;
1870
                I.Clear();
1871
                }
1872
 
1873
                {
1874
                std::string StringHex = $6;
1875
                std::stringstream ss;
1876
                ss << std::hex << StringHex;
1877
                ss >> ImmediateValue;
1878
 
1879
                I.SetDestinationAddress( TempRegIndex );
1880
                I.SetImm( ImmediateValue );
1881
                I.SetDestZero(true);
1882
                I.SetSrc0Displace(true);
1883
                I.SetWriteChannel(ECHANNEL_Z);
1884
                I.SetCode( EOPERATION_ADD );
1885
                I.mBisonFlagTrippleConstAssign = true;
1886
                mInstructions.push_back(I);
1887
                gInsertedInstructions++;
1888
                I.Clear();
1889
                }
1890
 
1891
                gExtraDestModifications = 2;
1892
                std::stringstream ss2;
1893
                ss2 << "R" << TempRegIndex << " OFFSET ";
1894
                $$ = ss2.str();
1895
        }
1896
        |
1897
        IDENTIFIER array_index
1898
        {
1899
 
1900
 
1901
                std::string Register;
1902
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
1903
                        $$ = Register;
1904
                 else
1905
                        $$ = GetRegisterFromAutoVar( $1, yylloc) + " OFFSET ";
1906
 
1907
                if ($2 != "NULL")
1908
                {
1909
 
1910
                        $$ += " array_element " + $2;
1911
 
1912
                }
1913
        }
1914
        |
1915
        IDENTIFIER DOT coordinate coordinate coordinate
1916
        {
1917
 
1918
                std::string X = $3,Y = $4,Z = $5;
1919
                std::string Register;
1920
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
1921
                        $$ = (Register + " . " + " " + X + " " + Y  + " " + Z + " OFFSET ");
1922
                else
1923
                        $$ = (GetRegisterFromAutoVar( $1, yylloc) + " . " + " " + X + " " + Y  + " " + Z + " OFFSET ");
1924
        }
1925
        |
1926
        REG
1927
        {
1928
 
1929
                std::string R = $1;
1930
                R.erase(0,1);
1931
                $$ = "R" + R;
1932
 
1933
        }
1934
        |
1935
        SCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE
1936
        {
1937
 
1938
                std::string R = $1;
1939
                R.erase(0,1);
1940
                $$ = "<
1941
        }
1942
        |
1943
        UNSCALE OPEN_ROUND_BRACE REG CLOSE_ROUND_BRACE
1944
        {
1945
 
1946
                std::string R = $1;
1947
                R.erase(0,1);
1948
                $$ = ">>R" + R;
1949
        }
1950
        |
1951
        REG DOT coordinate coordinate coordinate
1952
        {
1953
                std::string R = $1;
1954
                std::string X = $3,Y = $4,Z = $5;
1955
                R.erase(0,1);
1956
                $$ = "R" + R + " . " + " " + X + " " + Y  + " " + Z;
1957
 
1958
        }
1959
        ;
1960
 
1961
 
1962
        coordinate
1963
        :
1964
        TK_X
1965
        {
1966
                $$ = "X";
1967
        }
1968
        |
1969
        MINUS TK_X
1970
        {
1971
                $$ = "-X";
1972
        }
1973
        |
1974
        TK_Y
1975
        {
1976
                $$ = "Y";
1977
        }
1978
        |
1979
        MINUS TK_Y
1980
        {
1981
                $$ = "-Y";
1982
        }
1983
        |
1984
        TK_Z
1985
        {
1986
                $$ = "Z";
1987
        }
1988
        |
1989
        MINUS TK_Z
1990
        {
1991
                $$ = "-Z";
1992
        }
1993
        ;
1994
 
1995
 
1996
array_index
1997
        :
1998
        {
1999
                $$ = "NULL";
2000
        }
2001
        |
2002
        OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE
2003
        {
2004
                /*std::string Register;
2005
                if ((Register = GetRegisterFromFunctionParameter($2)) != "NULL")
2006
                        $$ = Register;
2007
                else*/
2008
                //Indexes into arrays can only be auto variables!
2009
                $$ = GetRegisterFromAutoVar( $2, yylloc );
2010
        }
2011
        ;
2012
 
2013
left_hand_side
2014
        :
2015
        OUT OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE
2016
        {
2017
 
2018
                $$ = "OUT " + $3;
2019
        }
2020
        |
2021
        OUT OPEN_SQUARE_BRACE IDENTIFIER CLOSE_SQUARE_BRACE
2022
        {
2023
                std::string Register;
2024
                if ((Register = GetRegisterFromFunctionParameter($3)) == "NULL")
2025
                        Register = GetRegisterFromAutoVar( $3, yylloc );
2026
 
2027
                $$ = "OUT INDEX" + Register;
2028
        }
2029
        |
2030
        IDENTIFIER array_index
2031
        {
2032
 
2033
                std::string Register;
2034
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
2035
                        $$ = Register + ".xyz";
2036
                else
2037
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".xyz" + " OFFSET " + (($2 != "NULL")?" INDEX"+$2:"");
2038
 
2039
        }
2040
        |
2041
        IDENTIFIER DOT TK_X
2042
        {
2043
                std::string Register;
2044
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
2045
                        $$ = Register + ".x";
2046
                else
2047
                $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".x" + " OFFSET ";
2048
        }
2049
        |
2050
        IDENTIFIER DOT TK_Y
2051
        {
2052
                std::string Register;
2053
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
2054
                        $$ = Register + ".y";
2055
                else
2056
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".y" + " OFFSET ";
2057
        }
2058
        |
2059
        IDENTIFIER DOT TK_Z
2060
        {
2061
                std::string Register;
2062
                if ((Register = GetRegisterFromFunctionParameter($1)) != "NULL")
2063
                        $$ = Register + ".z";
2064
                else
2065
                        $$ = GetRegisterFromAutoVar( $1, yylloc ) + ".z" + " OFFSET ";
2066
        }
2067
        |
2068
        REG
2069
        {
2070
                std::string R = $1;
2071
                R.erase(0,1);
2072
                $$ = "R" + R + ".xyz";
2073
        }
2074
        |
2075
        REG DOT TK_X
2076
        {
2077
                std::string R = $1;
2078
                R.erase(0,1);
2079
                $$ = "R" + R + ".x";
2080
        }
2081
        |
2082
        REG DOT TK_Y
2083
        {
2084
                std::string R = $1;
2085
                R.erase(0,1);
2086
                $$ = "R" + R + ".y";
2087
        }
2088
        |
2089
        REG DOT TK_Z
2090
        {
2091
 
2092
                std::string R = $1;
2093
                R.erase(0,1);
2094
                $$ = "R" + R + ".z";
2095
        }
2096
        |
2097
        REG DOT TK_X TK_Y TK_N
2098
        {
2099
                std::string R = $1;
2100
                R.erase(0,1);
2101
                $$ = "R" + R + ".xy";
2102
        }
2103
        |
2104
        REG DOT TK_X TK_N TK_Z
2105
        {
2106
                std::string R = $1;
2107
                R.erase(0,1);
2108
                $$ = "R" + R + ".xz";
2109
        }
2110
        |
2111
        REG DOT TK_N TK_Y TK_Z
2112
        {
2113
                std::string R = $1;
2114
                R.erase(0,1);
2115
                $$ = "R" + R + ".yz";
2116
        }
2117
        ;
2118
 
2119
 
2120
boolean_expression
2121
                                :
2122
                                expression NOT_EQUAL expression
2123
                                {
2124
                                        PopulateBoolean(EBRANCH_IF_ZERO, $1, $3, I, mInstructions, yylloc );
2125
 
2126
                                }
2127
                                |
2128
                                expression EQUAL expression
2129
                                {
2130
                                        PopulateBoolean(EBRANCH_IF_NOT_ZERO, $1, $3, I, mInstructions, yylloc );
2131
 
2132
                                }
2133
                                |
2134
                                expression GREATER_THAN expression
2135
                                {
2136
                                        PopulateBoolean(EBRANCH_IF_ZERO_OR_SIGN, $1, $3, I, mInstructions, yylloc );
2137
 
2138
                                }
2139
 
2140
                                |
2141
                                expression LESS_THAN expression
2142
                                {
2143
                                        PopulateBoolean(EBRANCH_IF_ZERO_OR_NOT_SIGN, $1, $3, I, mInstructions, yylloc );
2144
 
2145
                                }
2146
                                |
2147
                                expression LESS_OR_EQUAL_THAN expression
2148
                                {
2149
                                        PopulateBoolean(EBRANCH_IF_NOT_SIGN, $1, $3, I, mInstructions, yylloc );
2150
 
2151
                                }
2152
                                |
2153
                                expression GREATER_OR_EQUAL_THAN expression
2154
                                {
2155
                                        PopulateBoolean(EBRANCH_IF_SIGN, $1, $3, I, mInstructions, yylloc );
2156
 
2157
                                }
2158
                                ;
2159
 
2160
constant
2161
        :
2162
                DECCONST
2163
                {
2164
                        // Transform to HEX string
2165
                        unsigned int Val;
2166
                        std::string StringDec = $1;
2167
                        std::stringstream ss;
2168
                        ss << StringDec;
2169
                        ss >> Val;
2170
                        std::stringstream ss2;
2171
                        ss2 << std::hex << Val;
2172
                        $$ = ss2.str();
2173
                }
2174
                |
2175
                HEXCONST
2176
                {
2177
                        std::string StringHex = $1;
2178
                        // Get rid of the 0x
2179
                        StringHex.erase(StringHex.begin(),StringHex.begin()+2);
2180
                        std::stringstream ss;
2181
                        ss << std::hex << StringHex;
2182
 
2183
                        $$ = ss.str();
2184
                }
2185
                |
2186
                BINCONST
2187
                {
2188
                        // Transform to HEX string
2189
                        std::string StringBin = $1;
2190
                        // Get rid of the 0b
2191
                        StringBin.erase(StringBin.begin(),StringBin.begin()+2);
2192
                        std::bitset<32> Bitset( StringBin );
2193
                        std::stringstream ss2;
2194
                        ss2 << std::hex <<  Bitset.to_ulong();
2195
                        $$ = ss2.str();
2196
                }
2197
        ;
2198
auto_var_list
2199
                        :
2200
                        IDENTIFIER array_size COMMA auto_var_list
2201
                        {
2202
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
2203
                                {
2204
                                        std::ostringstream ret;
2205
                                        ret << "Duplicated symbol '" << $1 << "'\n";
2206
                                        throw ret.str();
2207
                                }
2208
 
2209
                                std::stringstream ss;
2210
                                ss << $2;
2211
                                unsigned int Size;
2212
                                ss >> Size;
2213
                                gAutoVarMap[ $1 ] = AllocAutoVar(Size);
2214
                        }
2215
                        |
2216
                        IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE COMMA auto_var_list
2217
                        {
2218
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
2219
                                {
2220
                                std::ostringstream ret;
2221
                                ret << "Duplicated symbol " << $1 << "'\n";
2222
                                throw ret.str();
2223
                                }
2224
                                gAutoVarMap[ $1 ] = AllocAutoVar();
2225
 
2226
                                unsigned int Destination = gAutoVarMap[ $1 ];
2227
 
2228
 
2229
 
2230
                                I.ClearWriteChannel();
2231
                                unsigned int ImmediateValue;
2232
                                {
2233
                                I.SetDestinationAddress( Destination );
2234
                                I.SetWriteChannel(ECHANNEL_X);
2235
                                std::string StringHex = $4;
2236
                                std::stringstream ss;
2237
                                ss << std::hex << StringHex;
2238
                                ss >> ImmediateValue;
2239
                                I.SetImm( ImmediateValue );
2240
                                I.SetDestZero( true );
2241
                                I.SetSrc1Displace( false );
2242
                                I.SetSrc0Displace( true );
2243
                                I.SetCode( EOPERATION_ADD );
2244
                                I.mSourceLine = GetCurrentLineNumber( yylloc );
2245
                                mInstructions.push_back(I);
2246
                                I.Clear();
2247
                                }
2248
                                {
2249
                                I.SetDestinationAddress( Destination );
2250
                                I.SetWriteChannel(ECHANNEL_Y);
2251
                                std::string StringHex = $6;
2252
                                std::stringstream ss;
2253
                                ss << std::hex << StringHex;
2254
                                ss >> ImmediateValue;
2255
                                I.SetImm( ImmediateValue );
2256
                                I.SetDestZero( true );
2257
                                I.SetSrc1Displace( false );
2258
                                I.SetSrc0Displace( true );
2259
                                I.SetCode( EOPERATION_ADD );
2260
                                mInstructions.push_back(I);
2261
                                I.Clear();
2262
                                }
2263
                                {
2264
                                I.SetDestinationAddress( Destination );
2265
                                I.SetWriteChannel(ECHANNEL_Z);
2266
                                std::string StringHex = $8;
2267
                                std::stringstream ss;
2268
                                ss << std::hex << StringHex;
2269
                                ss >> ImmediateValue;
2270
                                I.SetImm( ImmediateValue );
2271
                                I.SetDestZero( true );
2272
                                I.SetSrc1Displace( false );
2273
                                I.SetSrc0Displace( true );
2274
                                I.SetCode( EOPERATION_ADD );
2275
                                mInstructions.push_back(I);
2276
                                I.Clear();
2277
                                }
2278
                        }
2279
                        |
2280
                        IDENTIFIER ASSIGN OPEN_ROUND_BRACE constant COMMA constant COMMA constant CLOSE_ROUND_BRACE
2281
                        {
2282
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
2283
                                {
2284
                                std::ostringstream ret;
2285
                                ret << "Duplicated symbol " << $1 << "'\n";
2286
                                throw ret.str();
2287
                                }
2288
                                gAutoVarMap[ $1 ] = AllocAutoVar();
2289
 
2290
                                unsigned int Destination = gAutoVarMap[ $1 ];
2291
 
2292
 
2293
                                I.SetDestZero( true );
2294
                                I.SetSrc1Displace( false );
2295
                                I.SetSrc0Displace( true );
2296
 
2297
 
2298
                                I.ClearWriteChannel();
2299
                                unsigned int ImmediateValue;
2300
                                {
2301
                                I.SetDestinationAddress( Destination );
2302
                                I.SetWriteChannel(ECHANNEL_X);
2303
                                std::string StringHex = $4;
2304
                                std::stringstream ss;
2305
                                ss << std::hex << StringHex;
2306
                                ss >> ImmediateValue;
2307
                                I.SetImm( ImmediateValue );
2308
                                I.SetDestZero( true );
2309
                                I.SetSrc1Displace( false );
2310
                                I.SetSrc0Displace( true );
2311
                                I.SetCode( EOPERATION_ADD );
2312
                                I.mSourceLine = GetCurrentLineNumber( yylloc );
2313
                                mInstructions.push_back(I);
2314
                                I.Clear();
2315
                                }
2316
                                {
2317
                                I.SetDestinationAddress( Destination );
2318
                                I.SetWriteChannel(ECHANNEL_Y);
2319
                                std::string StringHex = $6;
2320
                                std::stringstream ss;
2321
                                ss << std::hex << StringHex;
2322
                                ss >> ImmediateValue;
2323
                                I.SetImm( ImmediateValue );
2324
                                I.SetDestZero( true );
2325
                                I.SetSrc1Displace( false );
2326
                                I.SetSrc0Displace( true );
2327
                                I.SetCode( EOPERATION_ADD );
2328
                                mInstructions.push_back(I);
2329
                                I.Clear();
2330
                                }
2331
                                {
2332
                                I.SetDestinationAddress( Destination );
2333
                                I.SetWriteChannel(ECHANNEL_Z);
2334
                                std::string StringHex = $8;
2335
                                std::stringstream ss;
2336
                                ss << std::hex << StringHex;
2337
                                ss >> ImmediateValue;
2338
                                I.SetImm( ImmediateValue );
2339
                                I.SetDestZero( true );
2340
                                I.SetSrc1Displace( false );
2341
                                I.SetSrc0Displace( true );
2342
                                I.SetCode( EOPERATION_ADD );
2343
                                mInstructions.push_back(I);
2344
                                I.Clear();
2345
                                }
2346
                        }
2347
                        |
2348
                        IDENTIFIER array_size
2349
                        {
2350
 
2351
                                if (gAutoVarMap.find($1) != gAutoVarMap.end())
2352
                                {
2353
                                        std::ostringstream ret;
2354
                                        ret << "Duplicated symbol " << $1 << "'\n";
2355
                                        throw ret.str();
2356
                                }
2357
                                std::stringstream ss;
2358
                                ss << std::hex << $2;
2359
                                unsigned int Size;
2360
                                ss >> Size;
2361
                                ////std::cout  << "Array Size is " << Size << " " << $2 << "\n";
2362
                                gAutoVarMap[ $1 ] = AllocAutoVar(Size);
2363
                        }
2364
                        ;
2365
 
2366
array_size
2367
                 :
2368
                 {
2369
                 $$ = "1";
2370
                 }
2371
                 |
2372
                 OPEN_SQUARE_BRACE constant CLOSE_SQUARE_BRACE
2373
                 {
2374
 
2375
                 $$ = $2;
2376
                 }
2377
                 ;
2378
%%
2379
 
2380
 
2381
 
2382
// Error function throws an exception (std::string) with the location and error message
2383
void Theia::Parser::error(const Theia::Parser::location_type &loc,
2384
                                          const std::string &msg) {
2385
        std::ostringstream ret;
2386
        ret << "Parser Error at " << loc << ": "  << msg;
2387
        throw ret.str();
2388
}
2389
 
2390
// Now that we have the Parser declared, we can declare the Scanner and implement
2391
// the yylex function
2392
#include "Scanner.h"
2393
static int yylex(Theia::Parser::semantic_type * yylval,
2394
                 Theia::Parser::location_type * yylloc,
2395
                 Theia::Scanner &scanner) {
2396
        return scanner.yylex(yylval, yylloc);
2397
}
2398
 

powered by: WebSVN 2.1.0

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