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 // Types in the SIMD implementation of the color transformation language
58 //
59 //-----------------------------------------------------------------------------
60
61 #include <CtlSimdType.h>
62 #include <CtlSyntaxTree.h>
63 #include <CtlSymbolTable.h>
64 #include <CtlSimdLContext.h>
65 #include <CtlSimdModule.h>
66 #include <CtlSimdInst.h>
67 #include <CtlSimdOp.h>
68 #include <CtlAlign.h>
69 #include <CtlMessage.h>
70 #include <cassert>
71 #include <CtlErrors.h>
72
73 using namespace std;
74
75 namespace Ctl {
76 namespace {
77
78 bool
isAssignment(const SyntaxNodePtr & node)79 isAssignment (const SyntaxNodePtr &node)
80 {
81 return node.cast<AssignmentNode>() ||
82 node.cast<VariableNode>() ||
83 node.cast<ReturnNode>();
84 }
85
86 } // namespace
87
88
SimdVoidType()89 SimdVoidType::SimdVoidType(): VoidType ()
90 {
91 // empty
92 }
93
94
95 size_t
objectSize() const96 SimdVoidType::objectSize () const
97 {
98 return 0;
99 }
100
101
102 size_t
alignedObjectSize() const103 SimdVoidType::alignedObjectSize () const
104 {
105 return 0;
106 }
107
108
109 size_t
objectAlignment() const110 SimdVoidType::objectAlignment () const
111 {
112 return 1;
113 }
114
115
116 void
generateCastFrom(const ExprNodePtr & expr,LContext & lcontext) const117 SimdVoidType::generateCastFrom
118 (const ExprNodePtr &expr,
119 LContext &lcontext) const
120 {
121 return;
122 }
123
124
125 void
generateCode(const SyntaxNodePtr & node,LContext & lcontext) const126 SimdVoidType::generateCode
127 (const SyntaxNodePtr &node,
128 LContext &lcontext) const
129 {
130 }
131
132
SimdBoolType()133 SimdBoolType::SimdBoolType (): BoolType ()
134 {
135 // empty
136 }
137
138
139 size_t
objectSize() const140 SimdBoolType::objectSize () const
141 {
142 return sizeof (bool);
143 }
144
145
146 size_t
alignedObjectSize() const147 SimdBoolType::alignedObjectSize () const
148 {
149 return sizeof (bool);
150 }
151
152
153 size_t
objectAlignment() const154 SimdBoolType::objectAlignment () const
155 {
156 return sizeof (bool);
157 }
158
159
160 void
generateCastFrom(const ExprNodePtr & expr,LContext & lcontext) const161 SimdBoolType::generateCastFrom
162 (const ExprNodePtr &expr,
163 LContext &lcontext) const
164 {
165 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
166
167 if (expr->type.cast<BoolType>())
168 {
169 return;
170 }
171
172 if (expr->type.cast<IntType>())
173 {
174 slcontext.addInst (new SimdUnaryOpInst <int, bool, CopyOp>
175 (expr->lineNumber));
176 return;
177 }
178
179 if (expr->type.cast<UIntType>())
180 {
181 slcontext.addInst (new SimdUnaryOpInst <unsigned, bool, CopyOp>
182 (expr->lineNumber));
183 return;
184 }
185
186 if (expr->type.cast<HalfType>())
187 {
188 slcontext.addInst (new SimdUnaryOpInst <half, bool, CopyOp>
189 (expr->lineNumber));
190 return;
191 }
192
193 if (expr->type.cast<FloatType>())
194 {
195 slcontext.addInst (new SimdUnaryOpInst <float, bool, CopyOp>
196 (expr->lineNumber));
197 return;
198 }
199
200 MESSAGE_LE (lcontext, ERR_TYPE, expr->lineNumber,
201 "Cannot cast value of type " << expr->type->asString() <<
202 " to type " << asString() << ".");
203 }
204
205
206 void
generateCode(const SyntaxNodePtr & node,LContext & lcontext) const207 SimdBoolType::generateCode
208 (const SyntaxNodePtr &node,
209 LContext &lcontext) const
210 {
211 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
212
213 if (isAssignment (node))
214 {
215 slcontext.addInst
216 (new SimdAssignInst (alignedObjectSize(), node->lineNumber));
217 return;
218 }
219
220 if (UnaryOpNodePtr unOp = node.cast<UnaryOpNode>())
221 {
222 switch (unOp->op)
223 {
224 case TK_BITNOT:
225
226 //
227 // We use the C++ ! operation to evaluate the CTL expression ~x,
228 // where x is of type bool. This ensures that ~true == false
229 // and ~false == true.
230 //
231
232 slcontext.addInst
233 (new SimdUnaryOpInst <bool, bool, NotOp>(node->lineNumber));
234 break;
235
236 case TK_NOT:
237 slcontext.addInst
238 (new SimdUnaryOpInst <bool, bool, NotOp>(node->lineNumber));
239 break;
240
241 default:
242
243 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
244 "Cannot apply " << tokenAsString (unOp->op) << " "
245 "operator to value of type " <<
246 unOp->operand->type->asString() << ".");
247 }
248
249 return;
250 }
251
252 if (BinaryOpNodePtr binOp = node.cast<BinaryOpNode>())
253 {
254 switch (binOp->op)
255 {
256 case TK_BITAND:
257
258 //
259 // For the bit-wise &, | and ^ operators, we normalize bool
260 // operands before applying the operators. This avoids
261 // surprises, for example, true^true == true.
262 //
263
264 slcontext.addInst
265 (new SimdBinaryOpInst <bool, bool, bool, BoolBitAndOp>
266 (node->lineNumber));
267 break;
268
269 case TK_BITOR:
270 slcontext.addInst
271 (new SimdBinaryOpInst <bool, bool, bool, BoolBitOrOp>
272 (node->lineNumber));
273 break;
274
275 case TK_BITXOR:
276 slcontext.addInst
277 (new SimdBinaryOpInst <bool, bool, bool, BoolBitXorOp>
278 (node->lineNumber));
279 break;
280
281 case TK_EQUAL:
282 slcontext.addInst
283 (new SimdBinaryOpInst <bool, bool, bool, EqualOp>
284 (node->lineNumber));
285 break;
286
287 case TK_GREATER:
288 slcontext.addInst
289 (new SimdBinaryOpInst <bool, bool, bool, GreaterOp>
290 (node->lineNumber));
291 break;
292
293 case TK_GREATEREQUAL:
294 slcontext.addInst
295 (new SimdBinaryOpInst <bool, bool, bool, GreaterEqualOp>
296 (node->lineNumber));
297 break;
298
299 case TK_LESS:
300 slcontext.addInst
301 (new SimdBinaryOpInst <bool, bool, bool, LessOp>
302 (node->lineNumber));
303 break;
304
305 case TK_LESSEQUAL:
306 slcontext.addInst
307 (new SimdBinaryOpInst <bool, bool, bool, LessEqualOp>
308 (node->lineNumber));
309 break;
310
311 case TK_NOTEQUAL:
312 slcontext.addInst
313 (new SimdBinaryOpInst <bool, bool, bool, NotEqualOp>
314 (node->lineNumber));
315 break;
316
317 default:
318
319 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
320 "Invalid operand types "
321 "for " << tokenAsString (binOp->op) << " operator "
322 "(" << binOp->leftOperand->type->asString() << " " <<
323 tokenAsString (binOp->op) << " " <<
324 binOp->rightOperand->type->asString() << ").");
325 }
326
327 return;
328 }
329
330 if (node.cast<CallNode>())
331 {
332 //
333 // Push a placeholder for the return value for a call to
334 // a function that returns an int.
335 //
336 slcontext.addInst (new SimdPushPlaceholderInst(alignedObjectSize(),
337 node->lineNumber));
338 return;
339 }
340 }
341
342 AddrPtr
newStaticVariableGeneric(Module * module,size_t objectSize)343 newStaticVariableGeneric(Module *module, size_t objectSize)
344 {
345 SimdModule *smodule = static_cast <SimdModule *> (module);
346 SimdReg* reg = new SimdReg (false, objectSize);
347
348 smodule->addStaticData (reg);
349 return new SimdDataAddr (reg);
350 }
351
352
353 AddrPtr
newStaticVariable(Module * module) const354 SimdBoolType::newStaticVariable (Module *module) const
355 {
356 return newStaticVariableGeneric(module, objectSize());
357 }
358
359 void
newAutomaticVariable(StatementNodePtr node,LContext & lcontext) const360 SimdBoolType::newAutomaticVariable (StatementNodePtr node,
361 LContext &lcontext) const
362 {
363 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
364 slcontext.addInst (new SimdPushPlaceholderInst
365 (objectSize(), node->lineNumber));
366 }
367
368
SimdIntType()369 SimdIntType::SimdIntType (): IntType ()
370 {
371 // empty
372 }
373
374
375 size_t
objectSize() const376 SimdIntType::objectSize () const
377 {
378 return sizeof (int);
379 }
380
381
382 size_t
alignedObjectSize() const383 SimdIntType::alignedObjectSize () const
384 {
385 return sizeof (int);
386 }
387
388
389 size_t
objectAlignment() const390 SimdIntType::objectAlignment () const
391 {
392 return sizeof (int);
393 }
394
395
396 void
generateCastFrom(const ExprNodePtr & expr,LContext & lcontext) const397 SimdIntType::generateCastFrom
398 (const ExprNodePtr &expr,
399 LContext &lcontext) const
400 {
401 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
402
403 if (expr->type.cast<BoolType>())
404 {
405 slcontext.addInst (new SimdUnaryOpInst <bool, int, CopyOp>
406 (expr->lineNumber));
407 return;
408 }
409
410 if (expr->type.cast<IntType>())
411 {
412 return;
413 }
414
415 if (expr->type.cast<UIntType>())
416 {
417 slcontext.addInst (new SimdUnaryOpInst <unsigned, int, CopyOp>
418 (expr->lineNumber));
419 return;
420 }
421
422 if (expr->type.cast<HalfType>())
423 {
424 slcontext.addInst (new SimdUnaryOpInst <half, int, CopyOp>
425 (expr->lineNumber));
426 return;
427 }
428
429 if (expr->type.cast<FloatType>())
430 {
431 slcontext.addInst (new SimdUnaryOpInst <float, int, CopyOp>
432 (expr->lineNumber));
433 return;
434 }
435
436 MESSAGE_LE (lcontext, ERR_TYPE, expr->lineNumber,
437 "Cannot cast value of type " << expr->type->asString() <<
438 " to type " << asString() << ".");
439 }
440
441
442 void
generateCode(const SyntaxNodePtr & node,LContext & lcontext) const443 SimdIntType::generateCode
444 (const SyntaxNodePtr &node,
445 LContext &lcontext) const
446 {
447 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
448
449 if (isAssignment (node))
450 {
451 slcontext.addInst
452 (new SimdAssignInst (alignedObjectSize(), node->lineNumber));
453 return;
454 }
455
456 if (UnaryOpNodePtr unOp = node.cast<UnaryOpNode>())
457 {
458 switch (unOp->op)
459 {
460 case TK_BITNOT:
461 slcontext.addInst
462 (new SimdUnaryOpInst <int, int, BitNotOp>(node->lineNumber));
463 break;
464
465 case TK_MINUS:
466 slcontext.addInst
467 (new SimdUnaryOpInst <int, int, UnaryMinusOp>
468 (node->lineNumber));
469 break;
470
471 default:
472
473 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
474 "Cannot apply " << tokenAsString (unOp->op) << " "
475 "operator to value of type " <<
476 unOp->operand->type->asString() << ".");
477 }
478
479 return;
480 }
481
482 if (BinaryOpNodePtr binOp = node.cast<BinaryOpNode>())
483 {
484 switch (binOp->op)
485 {
486 case TK_BITAND:
487 slcontext.addInst
488 (new SimdBinaryOpInst <int, int, int, BitAndOp>
489 (node->lineNumber));
490 break;
491
492 case TK_BITOR:
493 slcontext.addInst
494 (new SimdBinaryOpInst <int, int, int, BitOrOp>
495 (node->lineNumber));
496 break;
497
498 case TK_BITXOR:
499 slcontext.addInst
500 (new SimdBinaryOpInst <int, int, int, BitXorOp>
501 (node->lineNumber));
502 break;
503
504 case TK_DIV:
505 slcontext.addInst
506 (new SimdBinaryOpInst <int, int, int, IntDivOp>
507 (node->lineNumber));
508 break;
509
510 case TK_EQUAL:
511 slcontext.addInst
512 (new SimdBinaryOpInst <int, int, bool, EqualOp>
513 (node->lineNumber));
514 break;
515
516 case TK_GREATER:
517 slcontext.addInst
518 (new SimdBinaryOpInst <int, int, bool, GreaterOp>
519 (node->lineNumber));
520 break;
521
522 case TK_GREATEREQUAL:
523 slcontext.addInst
524 (new SimdBinaryOpInst <int, int, bool, GreaterEqualOp>
525 (node->lineNumber));
526 break;
527
528 case TK_LEFTSHIFT:
529 slcontext.addInst
530 (new SimdBinaryOpInst <int, int, int, LeftShiftOp>
531 (node->lineNumber));
532 break;
533
534 case TK_LESS:
535 slcontext.addInst
536 (new SimdBinaryOpInst <int, int, bool, LessOp>
537 (node->lineNumber));
538 break;
539
540 case TK_LESSEQUAL:
541 slcontext.addInst
542 (new SimdBinaryOpInst <int, int, bool, LessEqualOp>
543 (node->lineNumber));
544 break;
545
546 case TK_MINUS:
547 slcontext.addInst
548 (new SimdBinaryOpInst <int, int, int, BinaryMinusOp>
549 (node->lineNumber));
550 break;
551
552 case TK_MOD:
553 slcontext.addInst
554 (new SimdBinaryOpInst <int, int, int, ModOp>
555 (node->lineNumber));
556 break;
557
558 case TK_NOTEQUAL:
559 slcontext.addInst
560 (new SimdBinaryOpInst <int, int, bool, NotEqualOp>
561 (node->lineNumber));
562 break;
563
564 case TK_PLUS:
565 slcontext.addInst
566 (new SimdBinaryOpInst <int, int, int, PlusOp>
567 (node->lineNumber));
568 break;
569
570 case TK_RIGHTSHIFT:
571 slcontext.addInst
572 (new SimdBinaryOpInst <int, int, int, RightShiftOp>
573 (node->lineNumber));
574 break;
575
576 case TK_TIMES:
577 slcontext.addInst
578 (new SimdBinaryOpInst <int, int, int, TimesOp>
579 (node->lineNumber));
580 break;
581
582 default:
583
584 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
585 "Invalid operand types "
586 "for " << tokenAsString (binOp->op) << " operator "
587 "(" << binOp->leftOperand->type->asString() << " " <<
588 tokenAsString (binOp->op) << " " <<
589 binOp->rightOperand->type->asString() << ").");
590 }
591
592 return;
593 }
594
595 if (node.cast<CallNode>())
596 {
597 //
598 // Push a placeholder for the return value for a call to
599 // a function that returns an int.
600 //
601 slcontext.addInst (new SimdPushPlaceholderInst(alignedObjectSize(),
602 node->lineNumber));
603 return;
604 }
605 }
606
607
608
609 AddrPtr
newStaticVariable(Module * module) const610 SimdIntType::newStaticVariable (Module *module) const
611 {
612 return newStaticVariableGeneric(module, objectSize());
613 }
614
615 void
newAutomaticVariable(StatementNodePtr node,LContext & lcontext) const616 SimdIntType::newAutomaticVariable (StatementNodePtr node,
617 LContext &lcontext) const
618 {
619 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
620 slcontext.addInst (new SimdPushPlaceholderInst
621 (objectSize(), node->lineNumber));
622 }
623
624
SimdUIntType()625 SimdUIntType::SimdUIntType (): UIntType ()
626 {
627 // empty
628 }
629
630
631 size_t
objectSize() const632 SimdUIntType::objectSize () const
633 {
634 return sizeof (unsigned int);
635 }
636
637
638 size_t
alignedObjectSize() const639 SimdUIntType::alignedObjectSize () const
640 {
641 return sizeof (unsigned int);
642 }
643
644
645 size_t
objectAlignment() const646 SimdUIntType::objectAlignment () const
647 {
648 return sizeof (unsigned int);
649 }
650
651
652 void
generateCastFrom(const ExprNodePtr & expr,LContext & lcontext) const653 SimdUIntType::generateCastFrom
654 (const ExprNodePtr &expr,
655 LContext &lcontext) const
656 {
657 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
658
659 if (expr->type.cast<BoolType>())
660 {
661 slcontext.addInst (new SimdUnaryOpInst <bool, unsigned, CopyOp>
662 (expr->lineNumber));
663 return;
664 }
665
666 if (expr->type.cast<IntType>())
667 {
668 slcontext.addInst (new SimdUnaryOpInst <int, unsigned, CopyOp>
669 (expr->lineNumber));
670 return;
671 }
672
673 if (expr->type.cast<UIntType>())
674 {
675 return;
676 }
677
678 if (expr->type.cast<HalfType>())
679 {
680 slcontext.addInst (new SimdUnaryOpInst <half, unsigned, CopyOp>
681 (expr->lineNumber));
682 return;
683 }
684
685 if (expr->type.cast<FloatType>())
686 {
687 slcontext.addInst (new SimdUnaryOpInst <float, unsigned, CopyOp>
688 (expr->lineNumber));
689 return;
690 }
691
692 MESSAGE_LE (lcontext, ERR_TYPE, expr->lineNumber,
693 "Cannot cast value of type " << expr->type->asString() <<
694 " to type " << asString() << ".");
695 }
696
697
698 void
generateCode(const SyntaxNodePtr & node,LContext & lcontext) const699 SimdUIntType::generateCode
700 (const SyntaxNodePtr &node,
701 LContext &lcontext) const
702 {
703 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
704
705 if (isAssignment (node))
706 {
707 slcontext.addInst
708 (new SimdAssignInst (alignedObjectSize(), node->lineNumber));
709 return;
710 }
711
712 if (UnaryOpNodePtr unOp = node.cast<UnaryOpNode>())
713 {
714 switch (unOp->op)
715 {
716 case TK_BITNOT:
717 slcontext.addInst
718 (new SimdUnaryOpInst <unsigned, unsigned, BitNotOp>
719 (node->lineNumber));
720 break;
721
722 case TK_MINUS:
723 slcontext.addInst
724 (new SimdUnaryOpInst <unsigned, int, UnaryMinusOp>
725 (node->lineNumber));
726 break;
727
728 default:
729
730 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
731 "Cannot apply " << tokenAsString (unOp->op) << " "
732 "operator to value of type " <<
733 unOp->operand->type->asString() << ".");
734 }
735
736 return;
737 }
738
739 if (BinaryOpNodePtr binOp = node.cast<BinaryOpNode>())
740 {
741 switch (binOp->op)
742 {
743 case TK_BITAND:
744 slcontext.addInst
745 (new SimdBinaryOpInst <unsigned, unsigned, unsigned, BitAndOp>
746 (node->lineNumber));
747 break;
748
749 case TK_BITOR:
750 slcontext.addInst
751 (new SimdBinaryOpInst <unsigned, unsigned, unsigned, BitOrOp>
752 (node->lineNumber));
753 break;
754
755 case TK_BITXOR:
756 slcontext.addInst
757 (new SimdBinaryOpInst <unsigned, unsigned, unsigned, BitXorOp>
758 (node->lineNumber));
759 break;
760
761 case TK_DIV:
762 slcontext.addInst
763 (new SimdBinaryOpInst <unsigned, unsigned, unsigned, IntDivOp>
764 (node->lineNumber));
765 break;
766
767 case TK_EQUAL:
768 slcontext.addInst
769 (new SimdBinaryOpInst <unsigned, unsigned, bool, EqualOp>
770 (node->lineNumber));
771 break;
772
773 case TK_GREATER:
774 slcontext.addInst
775 (new SimdBinaryOpInst <unsigned, unsigned, bool, GreaterOp>
776 (node->lineNumber));
777 break;
778
779 case TK_GREATEREQUAL:
780 slcontext.addInst
781 (new SimdBinaryOpInst <unsigned, unsigned, bool, GreaterEqualOp>
782 (node->lineNumber));
783 break;
784
785 case TK_LEFTSHIFT:
786 slcontext.addInst
787 (new SimdBinaryOpInst
788 <unsigned, unsigned, unsigned, LeftShiftOp>
789 (node->lineNumber));
790 break;
791
792 case TK_LESS:
793 slcontext.addInst
794 (new SimdBinaryOpInst <unsigned, unsigned, bool, LessOp>
795 (node->lineNumber));
796 break;
797
798 case TK_LESSEQUAL:
799 slcontext.addInst
800 (new SimdBinaryOpInst <unsigned, unsigned, bool, LessEqualOp>
801 (node->lineNumber));
802 break;
803
804 case TK_MINUS:
805 slcontext.addInst
806 (new SimdBinaryOpInst
807 <unsigned, unsigned, unsigned, BinaryMinusOp>
808 (node->lineNumber));
809 break;
810
811 case TK_MOD:
812 slcontext.addInst
813 (new SimdBinaryOpInst <unsigned, unsigned, unsigned, ModOp>
814 (node->lineNumber));
815 break;
816
817 case TK_NOTEQUAL:
818 slcontext.addInst
819 (new SimdBinaryOpInst <unsigned, unsigned, bool, NotEqualOp>
820 (node->lineNumber));
821 break;
822
823 case TK_PLUS:
824 slcontext.addInst
825 (new SimdBinaryOpInst <unsigned, unsigned, unsigned, PlusOp>
826 (node->lineNumber));
827 break;
828
829 case TK_RIGHTSHIFT:
830 slcontext.addInst
831 (new SimdBinaryOpInst
832 <unsigned, unsigned, unsigned, RightShiftOp>
833 (node->lineNumber));
834 break;
835
836 case TK_TIMES:
837 slcontext.addInst
838 (new SimdBinaryOpInst <unsigned, unsigned, unsigned, TimesOp>
839 (node->lineNumber));
840 break;
841
842 default:
843
844 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
845 "Invalid operand types "
846 "for " << tokenAsString (binOp->op) << " operator "
847 "(" << binOp->leftOperand->type->asString() << " " <<
848 tokenAsString (binOp->op) << " " <<
849 binOp->rightOperand->type->asString() << ").");
850 }
851
852 return;
853 }
854
855 if (node.cast<CallNode>())
856 {
857 //
858 // Push a placeholder for the return value for a call to
859 // a function that returns an int.
860 //
861 slcontext.addInst
862 (new SimdPushPlaceholderInst (alignedObjectSize(),
863 node->lineNumber));
864 return;
865 }
866 }
867
868
869 AddrPtr
newStaticVariable(Module * module) const870 SimdUIntType::newStaticVariable (Module *module) const
871 {
872 return newStaticVariableGeneric(module, objectSize());
873 }
874
875
876 void
newAutomaticVariable(StatementNodePtr node,LContext & lcontext) const877 SimdUIntType::newAutomaticVariable (StatementNodePtr node,
878 LContext &lcontext) const
879 {
880 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
881 slcontext.addInst (new SimdPushPlaceholderInst
882 (objectSize(), node->lineNumber));
883 }
884
885
SimdHalfType()886 SimdHalfType::SimdHalfType (): HalfType ()
887 {
888 // empty
889 }
890
891
892 size_t
objectSize() const893 SimdHalfType::objectSize () const
894 {
895 return sizeof (half);
896 }
897
898
899 size_t
alignedObjectSize() const900 SimdHalfType::alignedObjectSize () const
901 {
902 return sizeof (half);
903 }
904
905
906 size_t
objectAlignment() const907 SimdHalfType::objectAlignment () const
908 {
909 return sizeof (half);
910 }
911
912
913 void
generateCastFrom(const ExprNodePtr & expr,LContext & lcontext) const914 SimdHalfType::generateCastFrom
915 (const ExprNodePtr &expr,
916 LContext &lcontext) const
917 {
918 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
919
920 if (expr->type.cast<BoolType>())
921 {
922 slcontext.addInst (new SimdUnaryOpInst <bool, half, CopyOp>
923 (expr->lineNumber));
924 return;
925 }
926
927 if (expr->type.cast<IntType>())
928 {
929 slcontext.addInst (new SimdUnaryOpInst <int, half, CopyOp>
930 (expr->lineNumber));
931 return;
932 }
933
934 if (expr->type.cast<UIntType>())
935 {
936 slcontext.addInst (new SimdUnaryOpInst <unsigned, half, CopyOp>
937 (expr->lineNumber));
938 return;
939 }
940
941 if (expr->type.cast<HalfType>())
942 {
943 return;
944 }
945
946 if (expr->type.cast<FloatType>())
947 {
948 slcontext.addInst (new SimdUnaryOpInst <float, half, CopyOp>
949 (expr->lineNumber));
950 return;
951 }
952
953 MESSAGE_LE (lcontext, ERR_TYPE, expr->lineNumber,
954 "Cannot cast value of type " << expr->type->asString() <<
955 " to type " << asString() << ".");
956 }
957
958
959 void
generateCode(const SyntaxNodePtr & node,LContext & lcontext) const960 SimdHalfType::generateCode
961 (const SyntaxNodePtr &node,
962 LContext &lcontext) const
963 {
964 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
965
966 if (isAssignment (node))
967 {
968 slcontext.addInst
969 (new SimdAssignInst (alignedObjectSize(), node->lineNumber));
970 return;
971 }
972
973 if (UnaryOpNodePtr unOp = node.cast<UnaryOpNode>())
974 {
975 switch (unOp->op)
976 {
977 case TK_MINUS:
978 slcontext.addInst
979 (new SimdUnaryOpInst <half, half, UnaryMinusOp>
980 (node->lineNumber));
981 break;
982
983 default:
984
985 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
986 "Cannot apply " << tokenAsString (unOp->op) << " "
987 "operator to value of type " <<
988 unOp->operand->type->asString() << ".");
989 }
990
991 return;
992 }
993
994 if (BinaryOpNodePtr binOp = node.cast<BinaryOpNode>())
995 {
996 switch (binOp->op)
997 {
998 case TK_DIV:
999 slcontext.addInst
1000 (new SimdBinaryOpInst <half, half, half, DivOp>
1001 (node->lineNumber));
1002 break;
1003
1004 case TK_EQUAL:
1005 slcontext.addInst
1006 (new SimdBinaryOpInst <half, half, bool, EqualOp>
1007 (node->lineNumber));
1008 break;
1009
1010 case TK_GREATER:
1011 slcontext.addInst
1012 (new SimdBinaryOpInst <half, half, bool, GreaterOp>
1013 (node->lineNumber));
1014 break;
1015
1016 case TK_GREATEREQUAL:
1017 slcontext.addInst
1018 (new SimdBinaryOpInst <half, half, bool, GreaterEqualOp>
1019 (node->lineNumber));
1020 break;
1021
1022 case TK_LESS:
1023 slcontext.addInst
1024 (new SimdBinaryOpInst <half, half, bool, LessOp>
1025 (node->lineNumber));
1026 break;
1027
1028 case TK_LESSEQUAL:
1029 slcontext.addInst
1030 (new SimdBinaryOpInst <half, half, bool, LessEqualOp>
1031 (node->lineNumber));
1032 break;
1033
1034 case TK_MINUS:
1035 slcontext.addInst
1036 (new SimdBinaryOpInst <half, half, half, BinaryMinusOp>
1037 (node->lineNumber));
1038 break;
1039
1040 case TK_NOTEQUAL:
1041 slcontext.addInst
1042 (new SimdBinaryOpInst <half, half, bool, NotEqualOp>
1043 (node->lineNumber));
1044 break;
1045
1046 case TK_PLUS:
1047 slcontext.addInst
1048 (new SimdBinaryOpInst <half, half, half, PlusOp>
1049 (node->lineNumber));
1050 break;
1051
1052 case TK_TIMES:
1053 slcontext.addInst
1054 (new SimdBinaryOpInst <half, half, half, TimesOp>
1055 (node->lineNumber));
1056 break;
1057
1058 default:
1059
1060 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
1061 "Invalid operand types "
1062 "for " << tokenAsString (binOp->op) << " operator "
1063 "(" << binOp->leftOperand->type->asString() << " " <<
1064 tokenAsString (binOp->op) << " " <<
1065 binOp->rightOperand->type->asString() << ").");
1066 }
1067
1068 return;
1069 }
1070
1071 if (node.cast<CallNode>())
1072 {
1073 //
1074 // Push a placeholder for the return value for a call to
1075 // a function that returns an int.
1076 //
1077
1078 slcontext.addInst
1079 (new SimdPushPlaceholderInst (alignedObjectSize(),
1080 node->lineNumber));
1081 return;
1082 }
1083 }
1084
1085
1086 AddrPtr
newStaticVariable(Module * module) const1087 SimdHalfType::newStaticVariable (Module *module) const
1088 {
1089 return newStaticVariableGeneric(module, objectSize());
1090 }
1091
1092
1093 void
newAutomaticVariable(StatementNodePtr node,LContext & lcontext) const1094 SimdHalfType::newAutomaticVariable (StatementNodePtr node,
1095 LContext &lcontext) const
1096 {
1097 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
1098 slcontext.addInst (new SimdPushPlaceholderInst
1099 (objectSize(), node->lineNumber));
1100 }
1101
1102
SimdFloatType()1103 SimdFloatType::SimdFloatType (): FloatType ()
1104 {
1105 // empty
1106 }
1107
1108
1109 size_t
objectSize() const1110 SimdFloatType::objectSize () const
1111 {
1112 return sizeof (float);
1113 }
1114
1115
1116 size_t
alignedObjectSize() const1117 SimdFloatType::alignedObjectSize () const
1118 {
1119 return sizeof (float);
1120 }
1121
1122
1123 size_t
objectAlignment() const1124 SimdFloatType::objectAlignment () const
1125 {
1126 return sizeof (float);
1127 }
1128
1129
1130 void
generateCastFrom(const ExprNodePtr & expr,LContext & lcontext) const1131 SimdFloatType::generateCastFrom
1132 (const ExprNodePtr &expr,
1133 LContext &lcontext) const
1134 {
1135 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
1136
1137 if (expr->type.cast<BoolType>())
1138 {
1139 slcontext.addInst (new SimdUnaryOpInst <bool, float, CopyOp>
1140 (expr->lineNumber));
1141 return;
1142 }
1143
1144 if (expr->type.cast<IntType>())
1145 {
1146 slcontext.addInst (new SimdUnaryOpInst <int, float, CopyOp>
1147 (expr->lineNumber));
1148 return;
1149 }
1150
1151 if (expr->type.cast<UIntType>())
1152 {
1153 slcontext.addInst (new SimdUnaryOpInst <unsigned, float, CopyOp>
1154 (expr->lineNumber));
1155 return;
1156 }
1157
1158 if (expr->type.cast<HalfType>())
1159 {
1160 slcontext.addInst (new SimdUnaryOpInst <half, float, CopyOp>
1161 (expr->lineNumber));
1162 return;
1163 }
1164
1165 if (expr->type.cast<FloatType>())
1166 {
1167 return;
1168 }
1169
1170 MESSAGE_LE (lcontext, ERR_TYPE, expr->lineNumber,
1171 "Cannot cast value of type " << expr->type->asString() <<
1172 " to type " << asString() << ".");
1173 }
1174
1175
1176 void
generateCode(const SyntaxNodePtr & node,LContext & lcontext) const1177 SimdFloatType::generateCode
1178 (const SyntaxNodePtr &node,
1179 LContext &lcontext) const
1180 {
1181 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
1182
1183 if (isAssignment (node))
1184 {
1185 slcontext.addInst
1186 (new SimdAssignInst(alignedObjectSize(), node->lineNumber));
1187 return;
1188 }
1189
1190 if (UnaryOpNodePtr unOp = node.cast<UnaryOpNode>())
1191 {
1192 switch (unOp->op)
1193 {
1194 case TK_MINUS:
1195 slcontext.addInst
1196 (new SimdUnaryOpInst <float, float, UnaryMinusOp>
1197 (node->lineNumber));
1198 break;
1199
1200 default:
1201
1202 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
1203 "Cannot apply " << tokenAsString (unOp->op) << " "
1204 "operator to value of type " <<
1205 unOp->operand->type->asString() << ".");
1206 }
1207
1208 return;
1209 }
1210
1211 if (BinaryOpNodePtr binOp = node.cast<BinaryOpNode>())
1212 {
1213 switch (binOp->op)
1214 {
1215 case TK_DIV:
1216 slcontext.addInst
1217 (new SimdBinaryOpInst <float, float, float, DivOp>
1218 (node->lineNumber));
1219 break;
1220
1221 case TK_EQUAL:
1222 slcontext.addInst
1223 (new SimdBinaryOpInst <float, float, bool, EqualOp>
1224 (node->lineNumber));
1225 break;
1226
1227 case TK_GREATER:
1228 slcontext.addInst
1229 (new SimdBinaryOpInst <float, float, bool, GreaterOp>
1230 (node->lineNumber));
1231 break;
1232
1233 case TK_GREATEREQUAL:
1234 slcontext.addInst
1235 (new SimdBinaryOpInst <float, float, bool, GreaterEqualOp>
1236 (node->lineNumber));
1237 break;
1238
1239 case TK_LESS:
1240 slcontext.addInst
1241 (new SimdBinaryOpInst <float, float, bool, LessOp>
1242 (node->lineNumber));
1243 break;
1244
1245 case TK_LESSEQUAL:
1246 slcontext.addInst
1247 (new SimdBinaryOpInst <float, float, bool, LessEqualOp>
1248 (node->lineNumber));
1249 break;
1250
1251 case TK_MINUS:
1252 slcontext.addInst
1253 (new SimdBinaryOpInst <float, float, float, BinaryMinusOp>
1254 (node->lineNumber));
1255 break;
1256
1257 case TK_NOTEQUAL:
1258 slcontext.addInst
1259 (new SimdBinaryOpInst <float, float, bool, NotEqualOp>
1260 (node->lineNumber));
1261 break;
1262
1263 case TK_PLUS:
1264 slcontext.addInst
1265 (new SimdBinaryOpInst <float, float, float, PlusOp>
1266 (node->lineNumber));
1267 break;
1268
1269 case TK_TIMES:
1270 slcontext.addInst
1271 (new SimdBinaryOpInst <float, float, float, TimesOp>
1272 (node->lineNumber));
1273 break;
1274
1275 default:
1276
1277 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
1278 "Invalid operand types "
1279 "for " << tokenAsString (binOp->op) << " operator "
1280 "(" << binOp->leftOperand->type->asString() << " " <<
1281 tokenAsString (binOp->op) << " " <<
1282 binOp->rightOperand->type->asString() << ").");
1283 }
1284
1285 return;
1286 }
1287
1288 if (node.cast<CallNode>())
1289 {
1290 //
1291 // Push a placeholder for the return value for a call to
1292 // a function that returns an int.
1293 //
1294
1295 slcontext.addInst (new SimdPushPlaceholderInst (alignedObjectSize(),
1296 node->lineNumber));
1297 return;
1298 }
1299 }
1300
1301
1302 AddrPtr
newStaticVariable(Module * module) const1303 SimdFloatType::newStaticVariable (Module *module) const
1304 {
1305 return newStaticVariableGeneric(module, objectSize());
1306 }
1307
1308
1309 void
newAutomaticVariable(StatementNodePtr node,LContext & lcontext) const1310 SimdFloatType::newAutomaticVariable (StatementNodePtr node,
1311 LContext &lcontext) const
1312 {
1313 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
1314 slcontext.addInst (new SimdPushPlaceholderInst
1315 (objectSize(), node->lineNumber));
1316 }
1317
1318
SimdStringType()1319 SimdStringType::SimdStringType (): StringType ()
1320 {
1321 // empty
1322 }
1323
1324
1325 size_t
objectSize() const1326 SimdStringType::objectSize () const
1327 {
1328 return sizeof (string *);
1329 }
1330
1331
1332 size_t
alignedObjectSize() const1333 SimdStringType::alignedObjectSize () const
1334 {
1335 return sizeof (string *);
1336 }
1337
1338
1339 size_t
objectAlignment() const1340 SimdStringType::objectAlignment () const
1341 {
1342 return sizeof (string *);
1343 }
1344
1345
1346 void
generateCastFrom(const ExprNodePtr & expr,LContext & lcontext) const1347 SimdStringType::generateCastFrom
1348 (const ExprNodePtr &expr,
1349 LContext &lcontext) const
1350 {
1351 if (expr->type.cast<StringType>())
1352 {
1353 return;
1354 }
1355
1356 MESSAGE_LE (lcontext, ERR_TYPE, expr->lineNumber,
1357 "Cannot cast value of type " << expr->type->asString() <<
1358 " to type " << asString() << ".");
1359 }
1360
1361
1362 void
generateCode(const SyntaxNodePtr & node,LContext & lcontext) const1363 SimdStringType::generateCode
1364 (const SyntaxNodePtr &node,
1365 LContext &lcontext) const
1366 {
1367 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
1368
1369 if (isAssignment (node))
1370 {
1371 slcontext.addInst
1372 (new SimdAssignInst (alignedObjectSize(), node->lineNumber));
1373 return;
1374 }
1375
1376 if (UnaryOpNodePtr unOp = node.cast<UnaryOpNode>())
1377 {
1378 switch (unOp->op)
1379 {
1380 default:
1381
1382 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
1383 "Cannot apply " << tokenAsString (unOp->op) << " "
1384 "operator to value of type " <<
1385 unOp->operand->type->asString() << ".");
1386 }
1387
1388 return;
1389 }
1390
1391 if (BinaryOpNodePtr binOp = node.cast<BinaryOpNode>())
1392 {
1393 switch (binOp->op)
1394 {
1395 default:
1396
1397 MESSAGE_LE (lcontext, ERR_OP_TYPE, node->lineNumber,
1398 "Invalid operand types "
1399 "for " << tokenAsString (binOp->op) << " operator "
1400 "(" << binOp->leftOperand->type->asString() << " " <<
1401 tokenAsString (binOp->op) << " " <<
1402 binOp->rightOperand->type->asString() << ").");
1403 }
1404
1405 return;
1406 }
1407
1408 if (node.cast<CallNode>())
1409 {
1410 //
1411 // Push a placeholder for the return value for a call to
1412 // a function that returns an int.
1413 //
1414
1415 slcontext.addInst (new SimdPushPlaceholderInst (alignedObjectSize(),
1416 node->lineNumber));
1417 return;
1418 }
1419 }
1420
1421
1422 AddrPtr
newStaticVariable(Module * module) const1423 SimdStringType::newStaticVariable (Module *module) const
1424 {
1425 return newStaticVariableGeneric (module, alignedObjectSize());
1426 }
1427
1428
1429 void
newAutomaticVariable(StatementNodePtr node,LContext & lcontext) const1430 SimdStringType::newAutomaticVariable (StatementNodePtr node,
1431 LContext &lcontext) const
1432 {
1433 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
1434
1435 slcontext.addInst (new SimdPushPlaceholderInst
1436 (alignedObjectSize(), node->lineNumber));
1437 }
1438
1439
SimdArrayType(const DataTypePtr & elementType,int size,SimdLContext * lcontext)1440 SimdArrayType::SimdArrayType (const DataTypePtr &elementType, int size,
1441 SimdLContext *lcontext /* = 0 */):
1442 ArrayType (elementType, size),
1443 _unknownSize(0),
1444 _unknownESize(0)
1445 {
1446 if( lcontext)
1447 {
1448 // If size is not specified, this is a function parameter
1449 // size will be stored as a parameter
1450 if( size == 0 )
1451 {
1452 IntTypePtr intType = lcontext->newIntType ();
1453 _unknownSize = lcontext->parameterAddr (intType);
1454 }
1455
1456 // if the element size is not known, create a local variable
1457 // to store the element size computed later
1458 SimdArrayTypePtr at = elementType.cast<SimdArrayType>();
1459 if( at && (at->unknownElementSize() || at->unknownSize() ))
1460 {
1461 IntTypePtr intType = lcontext->newIntType ();
1462 _unknownESize = lcontext->autoVariableAddr (intType);
1463 }
1464 }
1465 }
1466
1467
1468 size_t
objectSize() const1469 SimdArrayType::objectSize () const
1470 {
1471 return elementSize() * size();
1472 }
1473
1474
1475 size_t
alignedObjectSize() const1476 SimdArrayType::alignedObjectSize () const
1477 {
1478 return elementSize() * size();
1479 }
1480
1481
1482 size_t
objectAlignment() const1483 SimdArrayType::objectAlignment () const
1484 {
1485 return elementType()->objectAlignment();
1486 }
1487
1488 SimdDataAddrPtr
unknownElementSize() const1489 SimdArrayType::unknownElementSize () const
1490 {
1491 return _unknownESize;
1492 }
1493
1494 SimdDataAddrPtr
unknownSize() const1495 SimdArrayType::unknownSize () const
1496 {
1497 return _unknownSize;
1498 }
1499
1500 void
generateCastFrom(const ExprNodePtr & expr,LContext & lcontext) const1501 SimdArrayType::generateCastFrom
1502 (const ExprNodePtr &expr,
1503 LContext &lcontext) const
1504 {
1505 assert(isSameTypeAs(expr->type));
1506 return;
1507 }
1508
1509
1510 void
generateCode(const SyntaxNodePtr & node,LContext & lcontext) const1511 SimdArrayType::generateCode
1512 (const SyntaxNodePtr &node,
1513 LContext &lcontext) const
1514 {
1515 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
1516
1517 VariableNodePtr var = node.cast<VariableNode>();
1518 if( var && var->initialValue.cast<ValueNode>())
1519 {
1520 SizeVector sizes;
1521 SizeVector offsets;
1522 coreSizes(0, sizes, offsets);
1523 slcontext.addInst (new SimdInitializeInst(sizes,
1524 offsets,
1525 node->lineNumber));
1526 return;
1527 }
1528 else if (isAssignment(node)) // return or assignment
1529 {
1530 slcontext.addInst (new SimdAssignArrayInst
1531 (size(), elementSize(), node->lineNumber));
1532 return;
1533 }
1534 else if ( node.cast<ArrayIndexNode>() )
1535 {
1536 if(unknownSize() || unknownElementSize())
1537 {
1538
1539 slcontext.addInst (new SimdIndexVSArrayInst(elementSize(),
1540 unknownElementSize(),
1541 size(),
1542 unknownSize(),
1543 node->lineNumber));
1544 }
1545 else
1546 {
1547 slcontext.addInst (new SimdIndexArrayInst(elementSize(),
1548 node->lineNumber,
1549 size()));
1550 }
1551 return;
1552 }
1553 else if (node.cast<SizeNode>())
1554 {
1555 assert(size() == 0);
1556 slcontext.addInst (new SimdPushRefInst (unknownSize(),
1557 node->lineNumber));
1558 }
1559 else if (node.cast<CallNode>())
1560 {
1561 slcontext.addInst (new SimdPushPlaceholderInst(objectSize(),
1562 node->lineNumber));
1563 return;
1564 }
1565 }
1566
1567
1568 AddrPtr
newStaticVariable(Module * module) const1569 SimdArrayType::newStaticVariable (Module *module) const
1570 {
1571 return newStaticVariableGeneric(module, objectSize());
1572 }
1573
1574
1575 void
newAutomaticVariable(StatementNodePtr node,LContext & lcontext) const1576 SimdArrayType::newAutomaticVariable (StatementNodePtr node,
1577 LContext &lcontext ) const
1578 {
1579 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
1580 slcontext.addInst (new SimdPushPlaceholderInst
1581 (objectSize(), node->lineNumber));
1582 }
1583
1584
1585
SimdStructType(const string & name,const MemberVector & members)1586 SimdStructType::SimdStructType
1587 (const string &name,
1588 const MemberVector &members)
1589 :
1590 StructType (name, members),
1591 _objectSize (0),
1592 _alignedObjectSize (0),
1593 _objectAlignment (1)
1594 {
1595 for (size_t i = 0; i < this->members().size(); ++i)
1596 {
1597 Member &m = member (i);
1598
1599 m.offset = align (_objectSize, m.type->objectAlignment());
1600 _objectSize = m.offset + m.type->objectSize();
1601
1602 _objectAlignment =
1603 leastCommonMultiple (_objectAlignment, m.type->objectAlignment());
1604 }
1605
1606 _alignedObjectSize = align (_objectSize, _objectAlignment);
1607 }
1608
1609
1610 size_t
objectSize() const1611 SimdStructType::objectSize () const
1612 {
1613 return _objectSize;
1614 }
1615
1616
1617 size_t
alignedObjectSize() const1618 SimdStructType::alignedObjectSize () const
1619 {
1620 return _alignedObjectSize;
1621 }
1622
1623
1624 size_t
objectAlignment() const1625 SimdStructType::objectAlignment () const
1626 {
1627 return _objectAlignment;
1628 }
1629
1630
1631 void
generateCastFrom(const ExprNodePtr & expr,LContext & lcontext) const1632 SimdStructType::generateCastFrom
1633 (const ExprNodePtr &expr,
1634 LContext &lcontext) const
1635 {
1636 return;
1637 }
1638
1639
1640 void
generateCode(const SyntaxNodePtr & node,LContext & lcontext) const1641 SimdStructType::generateCode
1642 (const SyntaxNodePtr &node,
1643 LContext &lcontext) const
1644 {
1645 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
1646
1647 VariableNodePtr var = node.cast<VariableNode>();
1648 if( var && var->initialValue.cast<ValueNode>())
1649 {
1650 SizeVector sizes;
1651 SizeVector offsets;
1652 coreSizes(0, sizes, offsets);
1653 slcontext.addInst (new SimdInitializeInst(sizes,
1654 offsets,
1655 node->lineNumber));
1656 return;
1657 }
1658
1659 if( MemberNodePtr mem = node.cast<MemberNode>() )
1660 {
1661 slcontext.addInst (new SimdAccessMemberInst(mem->offset,
1662 (node->lineNumber)));
1663 return;
1664 }
1665
1666 if (isAssignment (node))
1667 {
1668 slcontext.addInst (new SimdAssignInst
1669 (alignedObjectSize(), node->lineNumber));
1670 return;
1671 }
1672
1673 if (node.cast<CallNode>())
1674 {
1675 // Push a placeholder for the return value for a call to
1676 // a function that returns a struct
1677 slcontext.addInst (new SimdPushPlaceholderInst (alignedObjectSize(),
1678 node->lineNumber));
1679 return;
1680 }
1681 }
1682
1683
1684 AddrPtr
newStaticVariable(Module * module) const1685 SimdStructType::newStaticVariable (Module *module) const
1686 {
1687 return newStaticVariableGeneric(module, alignedObjectSize());
1688 }
1689
1690
1691 void
newAutomaticVariable(StatementNodePtr node,LContext & lcontext) const1692 SimdStructType::newAutomaticVariable (StatementNodePtr node,
1693 LContext &lcontext ) const
1694 {
1695 SimdLContext &slcontext = static_cast <SimdLContext &> (lcontext);
1696 slcontext.addInst (new SimdPushPlaceholderInst
1697 (alignedObjectSize(), node->lineNumber));
1698 }
1699
1700
SimdFunctionType(const DataTypePtr & returnType,bool returnVarying,const ParamVector & parameters)1701 SimdFunctionType::SimdFunctionType
1702 (const DataTypePtr &returnType,
1703 bool returnVarying,
1704 const ParamVector ¶meters)
1705 :
1706 FunctionType (returnType, returnVarying, parameters)
1707 {
1708 // empty
1709 }
1710
1711
1712 void
generateCastFrom(const ExprNodePtr & expr,LContext & lcontext) const1713 SimdFunctionType::generateCastFrom
1714 (const ExprNodePtr &expr,
1715 LContext &lcontext) const
1716 {
1717 // empty
1718 }
1719
1720
1721 void
generateCode(const SyntaxNodePtr & node,LContext & lcontext) const1722 SimdFunctionType::generateCode
1723 (const SyntaxNodePtr &node,
1724 LContext &lcontext) const
1725 {
1726 // empty
1727 }
1728
1729
1730 } // namespace Ctl
1731
1732