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 230

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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