1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2013 Academy of Motion Picture Arts and Sciences
3 // ("A.M.P.A.S."). Portions contributed by others as indicated.
4 // All rights reserved.
5 //
6 // A worldwide, royalty-free, non-exclusive right to copy, modify, create
7 // derivatives, and use, in source and binary forms, is hereby granted,
8 // subject to acceptance of this license. Performance of any of the
9 // aforementioned acts indicates acceptance to be bound by the following
10 // terms and conditions:
11 //
12 //  * Copies of source code, in whole or in part, must retain the
13 //    above copyright notice, this list of conditions and the
14 //    Disclaimer of Warranty.
15 //
16 //  * Use in binary form must retain the above copyright notice,
17 //    this list of conditions and the Disclaimer of Warranty in the
18 //    documentation and/or other materials provided with the distribution.
19 //
20 //  * Nothing in this license shall be deemed to grant any rights to
21 //    trademarks, copyrights, patents, trade secrets or any other
22 //    intellectual property of A.M.P.A.S. or any contributors, except
23 //    as expressly stated herein.
24 //
25 //  * Neither the name "A.M.P.A.S." nor the name of any other
26 //    contributors to this software may be used to endorse or promote
27 //    products derivative of or based on this software without express
28 //    prior written permission of A.M.P.A.S. or the contributors, as
29 //    appropriate.
30 //
31 // This license shall be construed pursuant to the laws of the State of
32 // California, and any disputes related thereto shall be subject to the
33 // jurisdiction of the courts therein.
34 //
35 // Disclaimer of Warranty: THIS SOFTWARE IS PROVIDED BY A.M.P.A.S. AND
36 // CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
37 // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
38 // FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO
39 // EVENT SHALL A.M.P.A.S., OR ANY CONTRIBUTORS OR DISTRIBUTORS, BE LIABLE
40 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, RESITUTIONARY,
41 // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
46 // THE POSSIBILITY OF SUCH DAMAGE.
47 //
48 // WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, THE ACADEMY
49 // SPECIFICALLY DISCLAIMS ANY REPRESENTATIONS OR WARRANTIES WHATSOEVER
50 // RELATED TO PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS IN THE ACADEMY
51 // COLOR ENCODING SYSTEM, OR APPLICATIONS THEREOF, HELD BY PARTIES OTHER
52 // THAN A.M.P.A.S., WHETHER DISCLOSED OR UNDISCLOSED.
53 ///////////////////////////////////////////////////////////////////////////
54 
55 //-----------------------------------------------------------------------------
56 //
57 //	class SimdLContext
58 //
59 //-----------------------------------------------------------------------------
60 
61 #include <CtlSimdLContext.h>
62 #include <CtlSimdSyntaxTree.h>
63 #include <CtlSimdType.h>
64 #include <CtlSimdModule.h>
65 #include <CtlSimdReg.h>
66 #include <CtlSimdInst.h>
67 #include <CtlSimdAddr.h>
68 #include <CtlSymbolTable.h>
69 #include <cassert>
70 
71 using namespace std;
72 
73 #if 0
74     #include <iostream>
75     #define debug(x) (cout << x << endl)
76 #else
77     #define debug(x)
78 #endif
79 
80 namespace Ctl {
81 
82 
SimdLContext(istream & file,Module * module,SymbolTable & symtab)83 SimdLContext::SimdLContext
84     (istream &file,
85      Module *module,
86      SymbolTable &symtab):
87     LContext (file, module, symtab)
88 {
89     newPath();
90     newStackFrame();
91 }
92 
93 
94 SimdModule *
simdModule()95 SimdLContext::simdModule ()
96 {
97     return static_cast <SimdModule *> (module());
98 }
99 
100 
101 void
mustFixCall(SimdCallInst * inst,const SymbolInfoPtr & info)102 SimdLContext::mustFixCall (SimdCallInst *inst, const SymbolInfoPtr &info)
103 {
104     debug ("mustFixCall (inst = " << inst << ", info = " << &info << ")");
105     _fixCallsList.push_back (FixCall (inst, info));
106 }
107 
108 
109 void
fixCalls()110 SimdLContext::fixCalls ()
111 {
112     debug ("fixCalls ()");
113 
114     for (FixCallsList::const_iterator i = _fixCallsList.begin();
115 	 i != _fixCallsList.end();
116 	 ++i)
117     {
118 	SimdInstAddrPtr addr = i->info->addr();
119 	assert (addr->inst());
120 
121 	i->inst->setCallPath (addr->inst());
122 	debug ("\tcall inst = " << i->inst << ", call path = " << addr->inst());
123     }
124 }
125 
126 
127 void
addInst(SimdInst * inst)128 SimdLContext::addInst (SimdInst *inst)
129 {
130     simdModule()->addInst (inst);
131 
132     if (_currentPath.firstInst == 0)
133 	_currentPath.firstInst = inst;
134 
135     if (_currentPath.lastInst != 0)
136 	_currentPath.lastInst->setNextInPath (inst);
137 
138     _currentPath.lastInst = inst;
139 }
140 
141 
142 void
appendPath(const Path & path)143 SimdLContext::appendPath(const Path &path)
144 {
145     if( _currentPath.lastInst )
146     {
147 	_currentPath.lastInst->setNextInPath(path.firstInst);
148     }
149     else
150     {
151 	_currentPath.firstInst= path.firstInst;
152     }
153     _currentPath.lastInst = path.lastInst;
154 
155 }
156 
157 void
addStaticData(SimdReg * reg)158 SimdLContext::addStaticData (SimdReg *reg)
159 {
160     simdModule()->addStaticData (reg);
161 }
162 
163 
164 void
newPath()165 SimdLContext::newPath ()
166 {
167     _currentPath.firstInst = 0;
168     _currentPath.lastInst = 0;
169 }
170 
171 
172 void
newStackFrame()173 SimdLContext::newStackFrame ()
174 {
175     _nextParameterAddr = -1;
176     _locals.clear();
177 }
178 
179 
180 AddrPtr
parameterAddr(const DataTypePtr & parameterType)181 SimdLContext::parameterAddr (const DataTypePtr &parameterType)
182 {
183     return new SimdDataAddr (_nextParameterAddr--);
184 }
185 
186 
187 AddrPtr
returnValueAddr(const DataTypePtr & returnType)188 SimdLContext::returnValueAddr (const DataTypePtr &returnType)
189 {
190     return new SimdDataAddr (_nextParameterAddr--);
191 }
192 
193 
194 AddrPtr
autoVariableAddr(const DataTypePtr & variableType)195 SimdLContext::autoVariableAddr (const DataTypePtr &variableType)
196 {
197     _locals.push_back(variableType);
198     return new SimdDataAddr (_locals.size() - 1);
199 }
200 
201 
202 ModuleNodePtr
newModuleNode(int lineNumber,const StatementNodePtr & constants,const FunctionNodePtr & functions) const203 SimdLContext::newModuleNode
204     (int lineNumber,
205      const StatementNodePtr &constants,
206      const FunctionNodePtr &functions) const
207 {
208     return new SimdModuleNode (lineNumber, constants, functions);
209 }
210 
211 
212 FunctionNodePtr
newFunctionNode(int lineNumber,const std::string & name,const SymbolInfoPtr & info,const StatementNodePtr & body) const213 SimdLContext::newFunctionNode
214     (int lineNumber,
215      const std::string &name,
216      const SymbolInfoPtr &info,
217      const StatementNodePtr &body) const
218 {
219     return new SimdFunctionNode (lineNumber, name, info, body, _locals);
220 }
221 
222 
223 VariableNodePtr
newVariableNode(int lineNumber,const std::string & name,const SymbolInfoPtr & info,const ExprNodePtr & initialValue,bool assignInitialValue) const224 SimdLContext::newVariableNode
225     (int lineNumber,
226      const std::string &name,
227      const SymbolInfoPtr &info,
228      const ExprNodePtr &initialValue,
229      bool assignInitialValue) const
230 {
231     return new SimdVariableNode
232 	(lineNumber, name, info, initialValue, assignInitialValue);
233 }
234 
235 
236 AssignmentNodePtr
newAssignmentNode(int lineNumber,const ExprNodePtr & lhs,const ExprNodePtr & rhs) const237 SimdLContext::newAssignmentNode
238     (int lineNumber,
239      const ExprNodePtr &lhs,
240      const ExprNodePtr &rhs) const
241 {
242     return new SimdAssignmentNode (lineNumber, lhs, rhs);
243 }
244 
245 
246 ExprStatementNodePtr
newExprStatementNode(int lineNumber,const ExprNodePtr & expr) const247 SimdLContext::newExprStatementNode
248     (int lineNumber,
249      const ExprNodePtr &expr) const
250 {
251     return new SimdExprStatementNode (lineNumber, expr);
252 }
253 
254 
255 IfNodePtr
newIfNode(int lineNumber,const ExprNodePtr & condition,const StatementNodePtr & truePath,const StatementNodePtr & falsePath) const256 SimdLContext::newIfNode
257     (int lineNumber,
258      const ExprNodePtr &condition,
259      const StatementNodePtr &truePath,
260      const StatementNodePtr &falsePath) const
261 {
262     return new SimdIfNode (lineNumber, condition, truePath, falsePath);
263 }
264 
265 
266 ReturnNodePtr
newReturnNode(int lineNumber,const SymbolInfoPtr & info,const ExprNodePtr & returnedValue) const267 SimdLContext::newReturnNode
268     (int lineNumber,
269      const SymbolInfoPtr &info,
270      const ExprNodePtr &returnedValue) const
271 {
272     return new SimdReturnNode (lineNumber, info, returnedValue);
273 }
274 
275 
276 WhileNodePtr
newWhileNode(int lineNumber,const ExprNodePtr & condition,const StatementNodePtr & loopBody) const277 SimdLContext::newWhileNode
278     (int lineNumber,
279      const ExprNodePtr &condition,
280      const StatementNodePtr &loopBody) const
281 {
282     return new SimdWhileNode (lineNumber, condition, loopBody);
283 }
284 
285 
286 BinaryOpNodePtr
newBinaryOpNode(int lineNumber,Token op,const ExprNodePtr & leftOperand,const ExprNodePtr & rightOperand) const287 SimdLContext::newBinaryOpNode
288     (int lineNumber,
289      Token op,
290      const ExprNodePtr &leftOperand,
291      const ExprNodePtr &rightOperand) const
292 {
293     return new SimdBinaryOpNode (lineNumber, op, leftOperand, rightOperand);
294 }
295 
296 
297 UnaryOpNodePtr
newUnaryOpNode(int lineNumber,Token op,const ExprNodePtr & operand) const298 SimdLContext::newUnaryOpNode
299     (int lineNumber,
300      Token op,
301      const ExprNodePtr &operand) const
302 {
303     return new SimdUnaryOpNode (lineNumber, op, operand);
304 }
305 
306 
307 ArrayIndexNodePtr
newArrayIndexNode(int lineNumber,const ExprNodePtr & array,const ExprNodePtr & index) const308 SimdLContext::newArrayIndexNode
309     (int lineNumber,
310      const ExprNodePtr &array,
311      const ExprNodePtr &index) const
312 {
313     return new SimdArrayIndexNode (lineNumber, array, index);
314 }
315 
316 MemberNodePtr
newMemberNode(int lineNumber,const ExprNodePtr & obj,const std::string & member) const317 SimdLContext::newMemberNode
318     (int lineNumber,
319      const ExprNodePtr &obj,
320      const std::string &member) const
321 {
322     return new SimdMemberNode (lineNumber, obj, member);
323 }
324 
325 
326 SizeNodePtr
newSizeNode(int lineNumber,const ExprNodePtr & obj) const327 SimdLContext::newSizeNode
328     (int lineNumber,
329      const ExprNodePtr &obj) const
330 {
331     return new SimdSizeNode (lineNumber, obj);
332 }
333 
334 NameNodePtr
newNameNode(int lineNumber,const std::string & name,const SymbolInfoPtr & info) const335 SimdLContext::newNameNode
336     (int lineNumber,
337      const std::string &name,
338      const SymbolInfoPtr &info) const
339 {
340     return new SimdNameNode (lineNumber, name, info);
341 }
342 
343 
344 BoolLiteralNodePtr
newBoolLiteralNode(int lineNumber,bool value) const345 SimdLContext::newBoolLiteralNode (int lineNumber, bool value) const
346 {
347     return new SimdBoolLiteralNode (lineNumber, *this, value);
348 }
349 
350 
351 IntLiteralNodePtr
newIntLiteralNode(int lineNumber,int value) const352 SimdLContext::newIntLiteralNode (int lineNumber, int value) const
353 {
354     return new SimdIntLiteralNode (lineNumber, *this, value);
355 }
356 
357 
358 UIntLiteralNodePtr
newUIntLiteralNode(int lineNumber,unsigned value) const359 SimdLContext::newUIntLiteralNode (int lineNumber, unsigned value) const
360 {
361     return new SimdUIntLiteralNode (lineNumber, *this, value);
362 }
363 
364 
365 HalfLiteralNodePtr
newHalfLiteralNode(int lineNumber,half value) const366 SimdLContext::newHalfLiteralNode (int lineNumber, half value) const
367 {
368     return new SimdHalfLiteralNode (lineNumber, *this, value);
369 }
370 
371 
372 FloatLiteralNodePtr
newFloatLiteralNode(int lineNumber,float value) const373 SimdLContext::newFloatLiteralNode (int lineNumber, float value) const
374 {
375     return new SimdFloatLiteralNode (lineNumber, *this, value);
376 }
377 
378 
379 StringLiteralNodePtr
newStringLiteralNode(int lineNumber,const string & value) const380 SimdLContext::newStringLiteralNode (int lineNumber, const string &value) const
381 {
382     return new SimdStringLiteralNode (lineNumber, *this, value);
383 }
384 
385 
386 CallNodePtr
newCallNode(int lineNumber,const NameNodePtr & function,const ExprNodeVector & arguments) const387 SimdLContext::newCallNode
388     (int lineNumber,
389      const NameNodePtr &function,
390      const ExprNodeVector &arguments) const
391 {
392     return new SimdCallNode (lineNumber, function, arguments);
393 }
394 
395 
396 ValueNodePtr
newValueNode(int lineNumber,const ExprNodeVector & elements) const397 SimdLContext::newValueNode
398     (int lineNumber,
399      const ExprNodeVector &elements) const
400 {
401     return new SimdValueNode (lineNumber, elements);
402 }
403 
404 
405 VoidTypePtr
newVoidType() const406 SimdLContext::newVoidType () const
407 {
408     static VoidTypePtr voidType = new SimdVoidType;
409     return voidType;
410 }
411 
412 
413 BoolTypePtr
newBoolType() const414 SimdLContext::newBoolType () const
415 {
416     static BoolTypePtr boolType = new SimdBoolType ();
417     return boolType;
418 }
419 
420 
421 IntTypePtr
newIntType() const422 SimdLContext::newIntType () const
423 {
424     static IntTypePtr intType = new SimdIntType ();
425     return intType;
426 }
427 
428 
429 UIntTypePtr
newUIntType() const430 SimdLContext::newUIntType () const
431 {
432     static UIntTypePtr uintType = new SimdUIntType ();
433     return uintType;
434 }
435 
436 
437 HalfTypePtr
newHalfType() const438 SimdLContext::newHalfType () const
439 {
440     static HalfTypePtr halfType = new SimdHalfType ();
441     return halfType;
442 }
443 
444 
445 FloatTypePtr
newFloatType() const446 SimdLContext::newFloatType () const
447 {
448     static FloatTypePtr floatType = new SimdFloatType ();
449     return floatType;
450 }
451 
452 
453 StringTypePtr
newStringType() const454 SimdLContext::newStringType () const
455 {
456     static StringTypePtr stringType = new SimdStringType ();
457     return stringType;
458 }
459 
460 
461 ArrayTypePtr
newArrayType(const DataTypePtr & baseType,int size,ArrayTypeUsage usage)462 SimdLContext::newArrayType (const DataTypePtr &baseType,
463 			    int size,
464 			    ArrayTypeUsage usage /*= NON_PARAMETER */)
465 {
466     if( usage == PARAMETER)
467 	return new SimdArrayType (baseType, size, this);
468     else
469 	return new SimdArrayType (baseType, size);
470 }
471 
472 
473 StructTypePtr
newStructType(const std::string & name,const MemberVector & members) const474 SimdLContext::newStructType
475    (const std::string &name,
476     const MemberVector &members) const
477 {
478     return new SimdStructType(name, members);
479 }
480 
481 FunctionTypePtr
newFunctionType(const DataTypePtr & returnType,bool returnVarying,const ParamVector & parameters) const482 SimdLContext::newFunctionType
483     (const DataTypePtr &returnType,
484      bool returnVarying,
485      const ParamVector &parameters) const
486 {
487     return new SimdFunctionType (returnType, returnVarying, parameters);
488 }
489 
490 
491 } // namespace Ctl
492