Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from M2ALU. */
2 : : /* M2ALU.mod gcc implementation of the M2ALU module.
3 : :
4 : : Copyright (C) 2001-2024 Free Software Foundation, Inc.
5 : : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 : :
7 : : This file is part of GNU Modula-2.
8 : :
9 : : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : : it under the terms of the GNU General Public License as published by
11 : : the Free Software Foundation; either version 3, or (at your option)
12 : : any later version.
13 : :
14 : : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU General Public License
20 : : along with GNU Modula-2; see the file COPYING3. If not see
21 : : <http://www.gnu.org/licenses/>. */
22 : :
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include <stdbool.h>
26 : : # if !defined (PROC_D)
27 : : # define PROC_D
28 : : typedef void (*PROC_t) (void);
29 : : typedef struct { PROC_t proc; } PROC;
30 : : # endif
31 : :
32 : : # if !defined (TRUE)
33 : : # define TRUE (1==1)
34 : : # endif
35 : :
36 : : # if !defined (FALSE)
37 : : # define FALSE (1==0)
38 : : # endif
39 : :
40 : : # include "GStorage.h"
41 : : # include "Gmcrts.h"
42 : : #if defined(__cplusplus)
43 : : # undef NULL
44 : : # define NULL 0
45 : : #endif
46 : : #define _M2ALU_H
47 : : #define _M2ALU_C
48 : :
49 : : # include "GASCII.h"
50 : : # include "GSYSTEM.h"
51 : : # include "GNameKey.h"
52 : : # include "GM2Error.h"
53 : : # include "GM2Debug.h"
54 : : # include "GStorage.h"
55 : : # include "GStringConvert.h"
56 : : # include "GM2GCCDeclare.h"
57 : : # include "GM2GenGCC.h"
58 : : # include "GM2Bitset.h"
59 : : # include "GSymbolConversion.h"
60 : : # include "GM2Printf.h"
61 : : # include "GM2Base.h"
62 : : # include "GDynamicStrings.h"
63 : : # include "GM2LexBuf.h"
64 : : # include "GM2MetaError.h"
65 : : # include "GSymbolTable.h"
66 : : # include "Gm2tree.h"
67 : : # include "Gm2linemap.h"
68 : : # include "Gm2expr.h"
69 : : # include "Gm2decl.h"
70 : : # include "Gm2misc.h"
71 : : # include "Gm2type.h"
72 : : # include "Gm2convert.h"
73 : : # include "Gm2block.h"
74 : :
75 : : # define Debugging false
76 : : # define DebugGarbage true
77 : : typedef struct M2ALU_rList_r M2ALU_rList;
78 : :
79 : : typedef M2ALU_rList *M2ALU_listOfRange;
80 : :
81 : : typedef struct M2ALU_fList_r M2ALU_fList;
82 : :
83 : : typedef M2ALU_fList *M2ALU_listOfFields;
84 : :
85 : : typedef struct M2ALU_eList_r M2ALU_eList;
86 : :
87 : : typedef M2ALU_eList *M2ALU_listOfElements;
88 : :
89 : : typedef struct M2ALU_cell_r M2ALU_cell;
90 : :
91 : : typedef struct M2ALU_DoSetProcedure_p M2ALU_DoSetProcedure;
92 : :
93 : : typedef enum {M2ALU_none, M2ALU_integer, M2ALU_real, M2ALU_complex, M2ALU_set, M2ALU_constructor, M2ALU_array, M2ALU_record} M2ALU_cellType;
94 : :
95 : : typedef M2ALU_cell *M2ALU_PtrToValue;
96 : :
97 : : struct M2ALU_rList_r {
98 : : unsigned int low;
99 : : unsigned int high;
100 : : M2ALU_listOfRange next;
101 : : };
102 : :
103 : : struct M2ALU_fList_r {
104 : : unsigned int field;
105 : : M2ALU_listOfFields next;
106 : : };
107 : :
108 : : struct M2ALU_eList_r {
109 : : unsigned int element;
110 : : unsigned int by;
111 : : M2ALU_listOfElements next;
112 : : };
113 : :
114 : : struct M2ALU_cell_r {
115 : : m2linemap_location_t location;
116 : : bool areAllConstants;
117 : : bool solved;
118 : : unsigned int constructorType;
119 : : M2ALU_PtrToValue next;
120 : : m2tree_Tree numberValue;
121 : : M2ALU_cellType type; /* case tag */
122 : : union {
123 : : M2ALU_listOfRange setValue;
124 : : M2ALU_listOfFields fieldValues;
125 : : M2ALU_listOfElements arrayValues;
126 : : };
127 : : };
128 : :
129 : : typedef M2ALU_listOfRange (*M2ALU_DoSetProcedure_t) (unsigned int, M2ALU_listOfRange, M2ALU_listOfRange);
130 : : struct M2ALU_DoSetProcedure_p { M2ALU_DoSetProcedure_t proc; };
131 : :
132 : : static M2ALU_listOfElements ElementFreeList;
133 : : static M2ALU_listOfFields FieldFreeList;
134 : : static M2ALU_listOfRange RangeFreeList;
135 : : static M2ALU_PtrToValue FreeList;
136 : : static M2ALU_PtrToValue TopOfStack;
137 : : static m2tree_Tree EnumerationValue;
138 : : static unsigned int EnumerationField;
139 : : static unsigned int CurrentTokenNo;
140 : :
141 : : /*
142 : : InitValue - initializes and returns a memory cell.
143 : : */
144 : :
145 : : extern "C" M2ALU_PtrToValue M2ALU_InitValue (void);
146 : :
147 : : /*
148 : : IsValueTypeNone - returns TRUE if the value on the top stack has no value.
149 : : */
150 : :
151 : : extern "C" bool M2ALU_IsValueTypeNone (void);
152 : :
153 : : /*
154 : : IsValueTypeInteger - returns TRUE if the value on the top stack is an integer.
155 : : */
156 : :
157 : : extern "C" bool M2ALU_IsValueTypeInteger (void);
158 : :
159 : : /*
160 : : IsValueTypeReal - returns TRUE if the value on the top stack is a real.
161 : : */
162 : :
163 : : extern "C" bool M2ALU_IsValueTypeReal (void);
164 : :
165 : : /*
166 : : IsValueTypeComplex - returns TRUE if the value on the top stack is a complex.
167 : : */
168 : :
169 : : extern "C" bool M2ALU_IsValueTypeComplex (void);
170 : :
171 : : /*
172 : : IsValueTypeSet - returns TRUE if the value on the top stack is a set.
173 : : */
174 : :
175 : : extern "C" bool M2ALU_IsValueTypeSet (void);
176 : :
177 : : /*
178 : : IsValueTypeConstructor - returns TRUE if the value on the top
179 : : stack is a constructor.
180 : : */
181 : :
182 : : extern "C" bool M2ALU_IsValueTypeConstructor (void);
183 : :
184 : : /*
185 : : IsValueTypeArray - returns TRUE if the value on the top stack is
186 : : an array.
187 : : */
188 : :
189 : : extern "C" bool M2ALU_IsValueTypeArray (void);
190 : :
191 : : /*
192 : : IsValueTypeRecord - returns TRUE if the value on the top stack is
193 : : a record.
194 : : */
195 : :
196 : : extern "C" bool M2ALU_IsValueTypeRecord (void);
197 : :
198 : : /*
199 : : GetSetValueType - returns the set type on top of the ALU stack.
200 : : */
201 : :
202 : : extern "C" unsigned int M2ALU_GetSetValueType (void);
203 : :
204 : : /*
205 : : PushIntegerTree - pushes a gcc tree value onto the ALU stack.
206 : : */
207 : :
208 : : extern "C" void M2ALU_PushIntegerTree (m2tree_Tree t);
209 : :
210 : : /*
211 : : PopIntegerTree - pops a gcc tree value from the ALU stack.
212 : : */
213 : :
214 : : extern "C" m2tree_Tree M2ALU_PopIntegerTree (void);
215 : :
216 : : /*
217 : : PushRealTree - pushes a gcc tree value onto the ALU stack.
218 : : */
219 : :
220 : : extern "C" void M2ALU_PushRealTree (m2tree_Tree t);
221 : :
222 : : /*
223 : : PopRealTree - pops a gcc tree value from the ALU stack.
224 : : */
225 : :
226 : : extern "C" m2tree_Tree M2ALU_PopRealTree (void);
227 : :
228 : : /*
229 : : PushComplexTree - pushes a gcc tree value onto the ALU stack.
230 : : */
231 : :
232 : : extern "C" void M2ALU_PushComplexTree (m2tree_Tree t);
233 : :
234 : : /*
235 : : PopComplexTree - pops a gcc tree value from the ALU stack.
236 : : */
237 : :
238 : : extern "C" m2tree_Tree M2ALU_PopComplexTree (void);
239 : :
240 : : /*
241 : : PushSetTree - pushes a gcc tree onto the ALU stack.
242 : : The tree, t, is expected to contain a
243 : : word value. It is converted into a set
244 : : type (sym). Bit 0 maps onto MIN(sym).
245 : : */
246 : :
247 : : extern "C" void M2ALU_PushSetTree (unsigned int tokenno, m2tree_Tree t, unsigned int sym);
248 : :
249 : : /*
250 : : PopSetTree - pops a gcc tree from the ALU stack.
251 : : */
252 : :
253 : : extern "C" m2tree_Tree M2ALU_PopSetTree (unsigned int tokenno);
254 : :
255 : : /*
256 : : PopConstructorTree - returns a tree containing the compound literal.
257 : : */
258 : :
259 : : extern "C" m2tree_Tree M2ALU_PopConstructorTree (unsigned int tokenno);
260 : :
261 : : /*
262 : : PushFrom - pushes a copy of the contents of, v, onto stack.
263 : : */
264 : :
265 : : extern "C" void M2ALU_PushFrom (M2ALU_PtrToValue v);
266 : :
267 : : /*
268 : : PopInto - pops the top element from the stack and places it into, v.
269 : : */
270 : :
271 : : extern "C" void M2ALU_PopInto (M2ALU_PtrToValue v);
272 : :
273 : : /*
274 : : PushCard - pushes a cardinal onto the stack.
275 : : */
276 : :
277 : : extern "C" void M2ALU_PushCard (unsigned int c);
278 : :
279 : : /*
280 : : PushInt - pushes an integer onto the stack.
281 : : */
282 : :
283 : : extern "C" void M2ALU_PushInt (int i);
284 : :
285 : : /*
286 : : PushChar - pushes a char onto the stack.
287 : : */
288 : :
289 : : extern "C" void M2ALU_PushChar (char c);
290 : :
291 : : /*
292 : : PopChar - pops a char from the stack.
293 : : */
294 : :
295 : : extern "C" char M2ALU_PopChar (unsigned int tokenno);
296 : :
297 : : /*
298 : : PushString - pushes the numerical value of the string onto the stack.
299 : : */
300 : :
301 : : extern "C" void M2ALU_PushString (unsigned int tokenno, NameKey_Name s, bool issueError);
302 : :
303 : : /*
304 : : CoerseLongRealToCard - performs a coersion between a REAL to a CARDINAL
305 : : */
306 : :
307 : : extern "C" void M2ALU_CoerseLongRealToCard (void);
308 : :
309 : : /*
310 : : ConvertRealToInt - converts a REAL into an INTEGER
311 : : */
312 : :
313 : : extern "C" void M2ALU_ConvertRealToInt (void);
314 : :
315 : : /*
316 : : ConvertToInt - converts the value into an INTEGER. This should be used
317 : : if we are computing the number of elements in a char set to
318 : : avoid an overflow.
319 : : */
320 : :
321 : : extern "C" void M2ALU_ConvertToInt (void);
322 : :
323 : : /*
324 : : ConvertToType - converts the top of stack to type, t.
325 : : */
326 : :
327 : : extern "C" void M2ALU_ConvertToType (unsigned int t);
328 : :
329 : : /*
330 : : IsSolved - returns true if the memory cell indicated by v
331 : : has a known value.
332 : : */
333 : :
334 : : extern "C" bool M2ALU_IsSolved (M2ALU_PtrToValue v);
335 : :
336 : : /*
337 : : PutConstructorSolved - records that this constructor is solved.
338 : : */
339 : :
340 : : extern "C" void M2ALU_PutConstructorSolved (unsigned int sym);
341 : :
342 : : /*
343 : : EvaluateValue - attempts to evaluate the symbol, sym, value.
344 : : */
345 : :
346 : : extern "C" void M2ALU_EvaluateValue (unsigned int sym);
347 : :
348 : : /*
349 : : TryEvaluateValue - attempts to evaluate the symbol, sym, value.
350 : : */
351 : :
352 : : extern "C" void M2ALU_TryEvaluateValue (unsigned int sym);
353 : : extern "C" void M2ALU_Addn (void);
354 : :
355 : : /*
356 : : Sub - subtracts the top two elements on the stack.
357 : :
358 : : The Stack:
359 : :
360 : : Entry Exit
361 : :
362 : : Ptr ->
363 : : +------------+
364 : : | Op1 | <- Ptr
365 : : |------------| +------------+
366 : : | Op2 | | Op2 - Op1 |
367 : : |------------| |------------|
368 : : */
369 : :
370 : : extern "C" void M2ALU_Sub (void);
371 : : extern "C" void M2ALU_Multn (void);
372 : :
373 : : /*
374 : : DivFloor - divides the top two elements on the stack.
375 : :
376 : : The Stack:
377 : :
378 : : Entry Exit
379 : :
380 : : Ptr ->
381 : : +------------+
382 : : | Op1 | <- Ptr
383 : : |------------| +--------------+
384 : : | Op2 | | Op2 DIV Op1 |
385 : : |------------| |--------------|
386 : : */
387 : :
388 : : extern "C" void M2ALU_DivFloor (void);
389 : :
390 : : /*
391 : : ModFloor - modulus of the top two elements on the stack.
392 : :
393 : : The Stack:
394 : :
395 : : Entry Exit
396 : :
397 : : Ptr ->
398 : : +------------+
399 : : | Op1 | <- Ptr
400 : : |------------| +--------------+
401 : : | Op2 | | Op2 MOD Op1 |
402 : : |------------| |--------------|
403 : : */
404 : :
405 : : extern "C" void M2ALU_ModFloor (void);
406 : :
407 : : /*
408 : : DivTrunc - divides the top two elements on the stack.
409 : :
410 : : The Stack:
411 : :
412 : : Entry Exit
413 : :
414 : : Ptr ->
415 : : +------------+
416 : : | Op1 | <- Ptr
417 : : |------------| +--------------+
418 : : | Op2 | | Op2 DIV Op1 |
419 : : |------------| |--------------|
420 : : */
421 : :
422 : : extern "C" void M2ALU_DivTrunc (void);
423 : :
424 : : /*
425 : : ModTrunc - modulus of the top two elements on the stack.
426 : :
427 : : The Stack:
428 : :
429 : : Entry Exit
430 : :
431 : : Ptr ->
432 : : +------------+
433 : : | Op1 | <- Ptr
434 : : |------------| +--------------+
435 : : | Op2 | | Op2 MOD Op1 |
436 : : |------------| |--------------|
437 : : */
438 : :
439 : : extern "C" void M2ALU_ModTrunc (void);
440 : :
441 : : /*
442 : : Equ - returns true if the top two elements on the stack
443 : : are identical.
444 : :
445 : : The Stack:
446 : :
447 : : Entry Exit
448 : :
449 : : Ptr ->
450 : : +------------+
451 : : | Op1 |
452 : : |------------|
453 : : | Op2 |
454 : : |------------| Empty
455 : :
456 : : RETURN( Op2 = Op1 )
457 : : */
458 : :
459 : : extern "C" bool M2ALU_Equ (unsigned int tokenno);
460 : :
461 : : /*
462 : : NotEqu - returns true if the top two elements on the stack
463 : : are not identical.
464 : :
465 : : The Stack:
466 : :
467 : : Entry Exit
468 : :
469 : : Ptr ->
470 : : +------------+
471 : : | Op1 |
472 : : |------------|
473 : : | Op2 |
474 : : |------------| Empty
475 : :
476 : : RETURN( Op2 # Op1 )
477 : : */
478 : :
479 : : extern "C" bool M2ALU_NotEqu (unsigned int tokenno);
480 : :
481 : : /*
482 : : Less - returns true if Op2 < Op1
483 : :
484 : : The Stack:
485 : :
486 : : Entry Exit
487 : :
488 : : Ptr ->
489 : : +------------+
490 : : | Op1 |
491 : : |------------|
492 : : | Op2 |
493 : : |------------| Empty
494 : :
495 : : RETURN( Op2 < Op1 )
496 : : */
497 : :
498 : : extern "C" bool M2ALU_Less (unsigned int tokenno);
499 : :
500 : : /*
501 : : Gre - returns true if Op2 > Op1
502 : :
503 : : The Stack:
504 : :
505 : : Entry Exit
506 : :
507 : : Ptr ->
508 : : +------------+
509 : : | Op1 |
510 : : |------------|
511 : : | Op2 |
512 : : |------------| Empty
513 : :
514 : : RETURN( Op2 > Op1 )
515 : : */
516 : :
517 : : extern "C" bool M2ALU_Gre (unsigned int tokenno);
518 : :
519 : : /*
520 : : LessEqu - returns true if Op2<Op1
521 : :
522 : : The Stack:
523 : :
524 : : Entry Exit
525 : :
526 : : Ptr ->
527 : : +------------+
528 : : | Op1 |
529 : : |------------|
530 : : | Op2 |
531 : : |------------| Empty
532 : :
533 : : RETURN( Op2 <= Op1 )
534 : : */
535 : :
536 : : extern "C" bool M2ALU_LessEqu (unsigned int tokenno);
537 : :
538 : : /*
539 : : GreEqu - returns true if Op2 >= Op1
540 : : are not identical.
541 : :
542 : : The Stack:
543 : :
544 : : Entry Exit
545 : :
546 : : Ptr ->
547 : : +------------+
548 : : | Op1 |
549 : : |------------|
550 : : | Op2 |
551 : : |------------| Empty
552 : :
553 : : RETURN( Op2 >= Op1 )
554 : : */
555 : :
556 : : extern "C" bool M2ALU_GreEqu (unsigned int tokenno);
557 : :
558 : : /*
559 : : IsNulSet - returns TRUE if the top element is the nul set constant, {}.
560 : : */
561 : :
562 : : extern "C" bool M2ALU_IsNulSet (void);
563 : :
564 : : /*
565 : : IsGenericNulSet - returns TRUE if the top element is the generic nul set constant, {}.
566 : : */
567 : :
568 : : extern "C" bool M2ALU_IsGenericNulSet (void);
569 : :
570 : : /*
571 : : PushNulSet - pushes an empty set {} onto the ALU stack. The subrange type used
572 : : to construct the set is defined by, constructorType.
573 : : If this is NulSym then
574 : : the set is generic and compatible with all sets.
575 : :
576 : : The Stack:
577 : :
578 : : Entry Exit
579 : :
580 : : <- Ptr
581 : : +------------+
582 : : | {} |
583 : : Ptr -> |------------|
584 : :
585 : : */
586 : :
587 : : extern "C" void M2ALU_PushNulSet (unsigned int settype);
588 : :
589 : : /*
590 : : AddBitRange - adds the range op1..op2 to the underlying set.
591 : :
592 : : Ptr ->
593 : : <- Ptr
594 : : +------------+ +------------+
595 : : | Set | | Set |
596 : : |------------| |------------|
597 : :
598 : : */
599 : :
600 : : extern "C" void M2ALU_AddBitRange (unsigned int tokenno, unsigned int op1, unsigned int op2);
601 : :
602 : : /*
603 : : AddBit - adds the bit op1 to the underlying set. INCL(Set, op1)
604 : :
605 : : Ptr ->
606 : : <- Ptr
607 : : +------------+ +------------+
608 : : | Set | | Set |
609 : : |------------| |------------|
610 : : */
611 : :
612 : : extern "C" void M2ALU_AddBit (unsigned int tokenno, unsigned int op1);
613 : :
614 : : /*
615 : : SubBit - removes a bit op1 from the underlying set. EXCL(Set, Op1)
616 : :
617 : : Ptr ->
618 : : <- Ptr
619 : : +------------+ +------------+
620 : : | Set | | Set |
621 : : |------------| |------------|
622 : : */
623 : :
624 : : extern "C" void M2ALU_SubBit (unsigned int tokenno, unsigned int op1);
625 : :
626 : : /*
627 : : SetIn - returns true if Op2 IN Op1
628 : :
629 : : The Stack:
630 : :
631 : : Entry Exit
632 : :
633 : : Ptr ->
634 : : +------------+
635 : : | Set |
636 : : |------------| Empty
637 : :
638 : : RETURN( Op1 IN Set )
639 : : */
640 : :
641 : : extern "C" bool M2ALU_SetIn (unsigned int tokenno, unsigned int Op1);
642 : :
643 : : /*
644 : : SetOr - performs an inclusive OR of the top two elements on the stack.
645 : :
646 : : The Stack:
647 : :
648 : : Entry Exit
649 : :
650 : : Ptr ->
651 : : +------------+
652 : : | Set1 | <- Ptr
653 : : |------------| +------------+
654 : : | Set2 | | Set1 + Set2|
655 : : |------------| |------------|
656 : :
657 : : */
658 : :
659 : : extern "C" void M2ALU_SetOr (unsigned int tokenno);
660 : :
661 : : /*
662 : : SetAnd - performs a set AND the top two elements on the stack.
663 : :
664 : : The Stack:
665 : :
666 : : Entry Exit
667 : :
668 : : Ptr ->
669 : : +------------+
670 : : | Op1 | <- Ptr
671 : : |------------| +------------+
672 : : | Op2 | | Op2 * Op1 |
673 : : |------------| |------------|
674 : : */
675 : :
676 : : extern "C" void M2ALU_SetAnd (unsigned int tokenno);
677 : :
678 : : /*
679 : : SetDifference - performs a set difference of the top two elements on the stack.
680 : : For each member in the set
681 : : if member in Op2 and not member in Op1
682 : :
683 : : The Stack:
684 : :
685 : : Entry Exit
686 : :
687 : : Ptr ->
688 : : +------------+
689 : : | Op1 | <- Ptr
690 : : |------------| +-------------------+
691 : : | Op2 | | Op2 and (not Op1) |
692 : : |------------| |-------------------|
693 : : */
694 : :
695 : : extern "C" void M2ALU_SetDifference (unsigned int tokenno);
696 : :
697 : : /*
698 : : SetSymmetricDifference - performs a set difference of the top two elements on the stack.
699 : :
700 : : The Stack:
701 : :
702 : : Entry Exit
703 : :
704 : : Ptr ->
705 : : +------------+
706 : : | Op1 | <- Ptr
707 : : |------------| +-------------+
708 : : | Op2 | | Op2 xor Op1 |
709 : : |------------| |-------------|
710 : : */
711 : :
712 : : extern "C" void M2ALU_SetSymmetricDifference (unsigned int tokenno);
713 : :
714 : : /*
715 : : SetNegate - negates the top set on the stack.
716 : :
717 : : Ptr -> <- Ptr
718 : : +-----------+ +------------+
719 : : | Set | | Set |
720 : : |-----------| |------------|
721 : : */
722 : :
723 : : extern "C" void M2ALU_SetNegate (unsigned int tokenno);
724 : :
725 : : /*
726 : : SetShift - if op1 is positive
727 : : then
728 : : result := op2 << op1
729 : : else
730 : : result := op2 >> op1
731 : : fi
732 : :
733 : :
734 : : The Stack:
735 : :
736 : : Entry Exit
737 : :
738 : : Ptr ->
739 : : +------------+
740 : : | Op1 | <- Ptr
741 : : |------------| +------------+
742 : : | Op2 | | result |
743 : : |------------| |------------|
744 : :
745 : : */
746 : :
747 : : extern "C" void M2ALU_SetShift (unsigned int tokenno);
748 : :
749 : : /*
750 : : SetRotate - if op1 is positive
751 : : then
752 : : result := ROTATERIGHT(op2, op1)
753 : : else
754 : : result := ROTATELEFT(op2, op1)
755 : : fi
756 : :
757 : :
758 : : The Stack:
759 : :
760 : : Entry Exit
761 : :
762 : : Ptr ->
763 : : +------------+
764 : : | Op1 | <- Ptr
765 : : |------------| +------------+
766 : : | Op2 | | result |
767 : : |------------| |------------|
768 : : */
769 : :
770 : : extern "C" void M2ALU_SetRotate (unsigned int tokenno);
771 : :
772 : : /*
773 : : GetValue - returns and pops the value from the top of stack.
774 : : */
775 : :
776 : : extern "C" M2ALU_PtrToValue M2ALU_GetValue (unsigned int tokenno);
777 : :
778 : : /*
779 : : GetRange - returns TRUE if range number, n, exists in the value, v.
780 : : A non empty set is defined by having 1..N ranges
781 : : */
782 : :
783 : : extern "C" bool M2ALU_GetRange (M2ALU_PtrToValue v, unsigned int n, unsigned int *low, unsigned int *high);
784 : :
785 : : /*
786 : : ConstructSetConstant - builds a struct of integers which represents the
787 : : set const as defined by, v.
788 : : */
789 : :
790 : : extern "C" m2tree_Tree M2ALU_ConstructSetConstant (unsigned int tokenno, M2ALU_PtrToValue v);
791 : :
792 : : /*
793 : : BuildRange - returns a integer sized constant which represents the
794 : : value {e1..e2}.
795 : : */
796 : :
797 : : extern "C" m2tree_Tree M2ALU_BuildRange (unsigned int tokenno, m2tree_Tree e1, m2tree_Tree e2);
798 : :
799 : : /*
800 : : IsConstructorDependants - return TRUE if all q(dependants) of,
801 : : sym, return TRUE.
802 : : */
803 : :
804 : : extern "C" bool M2ALU_IsConstructorDependants (unsigned int sym, M2GCCDeclare_IsAction q);
805 : :
806 : : /*
807 : : WalkConstructorDependants - walk the constructor, sym, calling
808 : : p for each dependant.
809 : : */
810 : :
811 : : extern "C" void M2ALU_WalkConstructorDependants (unsigned int sym, M2GCCDeclare_WalkAction p);
812 : :
813 : : /*
814 : : IsValueAndTreeKnown - returns TRUE if the value is known and the gcc tree
815 : : is defined.
816 : :
817 : : The Stack:
818 : :
819 : : Entry Exit
820 : :
821 : : Ptr ->
822 : : +------------+
823 : : | Op1 | <- Ptr
824 : : |------------| +------------+
825 : : */
826 : :
827 : : extern "C" bool M2ALU_IsValueAndTreeKnown (void);
828 : :
829 : : /*
830 : : CheckOrResetOverflow - tests to see whether the tree, t, has caused
831 : : an overflow error and if so it generates an
832 : : error message.
833 : : */
834 : :
835 : : extern "C" void M2ALU_CheckOrResetOverflow (unsigned int tokenno, m2tree_Tree t, bool check);
836 : :
837 : : /*
838 : : AddElements - adds the elements, el BY, n, to the array constant.
839 : :
840 : : Ptr ->
841 : : <- Ptr
842 : : +------------+ +------------+
843 : : | Array | | Array |
844 : : |------------| |------------|
845 : :
846 : : */
847 : :
848 : : extern "C" void M2ALU_AddElements (unsigned int tokenno, unsigned int el, unsigned int n);
849 : :
850 : : /*
851 : : AddField - adds the field op1 to the underlying constructor.
852 : :
853 : : Ptr ->
854 : : <- Ptr
855 : : +------------+ +------------+
856 : : | const | | const |
857 : : |------------| |------------|
858 : :
859 : : */
860 : :
861 : : extern "C" void M2ALU_AddField (unsigned int tokenno, unsigned int op1);
862 : :
863 : : /*
864 : : PushEmptyConstructor - pushes an empty constructor {} onto the ALU stack.
865 : : This is expected to be filled in by subsequent
866 : : calls to AddElements, AddRange or AddField.
867 : :
868 : : The Stack:
869 : :
870 : : Entry Exit
871 : :
872 : : <- Ptr
873 : : +------------+
874 : : | {} |
875 : : Ptr -> |------------|
876 : :
877 : : */
878 : :
879 : : extern "C" void M2ALU_PushEmptyConstructor (unsigned int constype);
880 : :
881 : : /*
882 : : PushEmptyArray - pushes an empty array {} onto the ALU stack.
883 : : This is expected to be filled in by subsequent
884 : : calls to AddElements.
885 : :
886 : : The Stack:
887 : :
888 : : Entry Exit
889 : :
890 : : <- Ptr
891 : : +------------+
892 : : | {} |
893 : : Ptr -> |------------|
894 : :
895 : : */
896 : :
897 : : extern "C" void M2ALU_PushEmptyArray (unsigned int arraytype);
898 : :
899 : : /*
900 : : PushEmptyRecord - pushes an empty record {} onto the ALU stack.
901 : : This is expected to be filled in by subsequent
902 : : calls to AddField.
903 : :
904 : : The Stack:
905 : :
906 : : Entry Exit
907 : :
908 : : <- Ptr
909 : : +------------+
910 : : | {} |
911 : : Ptr -> |------------|
912 : :
913 : : */
914 : :
915 : : extern "C" void M2ALU_PushEmptyRecord (unsigned int recordtype);
916 : :
917 : : /*
918 : : ChangeToConstructor - change the top of stack value to a constructor, type.
919 : : (Constructor, Set, Array or Record).
920 : : */
921 : :
922 : : extern "C" void M2ALU_ChangeToConstructor (unsigned int tokenno, unsigned int constype);
923 : :
924 : : /*
925 : : IsValueConst - returns true if the memory cell indicated by v
926 : : is only defined by constants. For example
927 : : no variables are used in the constructor.
928 : : */
929 : :
930 : : extern "C" bool M2ALU_IsValueConst (M2ALU_PtrToValue v);
931 : :
932 : : /*
933 : : PushTypeOfTree - pushes tree, gcc, to the stack and records the
934 : : front end type.
935 : : */
936 : :
937 : : extern "C" void M2ALU_PushTypeOfTree (unsigned int sym, m2tree_Tree gcc);
938 : :
939 : : /*
940 : : New - allocate a PtrToValue. Firstly check the FreeList, if empty call upon New.
941 : : */
942 : :
943 : : static M2ALU_PtrToValue New (void);
944 : :
945 : : /*
946 : : InitRecord - initialize the non variant fields of, v. Return v.
947 : : */
948 : :
949 : : static M2ALU_PtrToValue InitRecord (M2ALU_PtrToValue v);
950 : :
951 : : /*
952 : : NewRange - assigns, v, to a new area of memory.
953 : : */
954 : :
955 : : static void NewRange (M2ALU_listOfRange *v);
956 : :
957 : : /*
958 : : DisposeRange - adds the list, v, to the free list.
959 : : */
960 : :
961 : : static void DisposeRange (M2ALU_listOfRange *v);
962 : :
963 : : /*
964 : : IsOnFieldFreeList - returns TRUE if, r, is on the FieldFreeList.
965 : : */
966 : :
967 : : static bool IsOnFieldFreeList (M2ALU_listOfFields r);
968 : :
969 : : /*
970 : : IsOnElementFreeList - returns TRUE if, r, is on the ElementFreeList.
971 : : */
972 : :
973 : : static bool IsOnElementFreeList (M2ALU_listOfElements r);
974 : :
975 : : /*
976 : : DisposeFields - adds the list, v, to the free list.
977 : : */
978 : :
979 : : static void DisposeFields (M2ALU_listOfFields *v);
980 : :
981 : : /*
982 : : NewField - adds the list, v, to the free list.
983 : : */
984 : :
985 : : static void NewField (M2ALU_listOfFields *v);
986 : :
987 : : /*
988 : : NewElement - returns a new element record.
989 : : */
990 : :
991 : : static void NewElement (M2ALU_listOfElements *e);
992 : :
993 : : /*
994 : : DisposeElements - returns the list, e, to the free list.
995 : : */
996 : :
997 : : static void DisposeElements (M2ALU_listOfElements *e);
998 : :
999 : : /*
1000 : : CheckNotAlreadyOnFreeList - checks to see whether, v, is already on the free list
1001 : : and aborts if this is the case.
1002 : : */
1003 : :
1004 : : static void CheckNotAlreadyOnFreeList (M2ALU_PtrToValue v);
1005 : :
1006 : : /*
1007 : : CheckNotOnStack - checks to see whether, v, is already on the stack
1008 : : and aborts if this is the case.
1009 : : */
1010 : :
1011 : : static void CheckNotOnStack (M2ALU_PtrToValue v);
1012 : :
1013 : : /*
1014 : : Dispose - place, v, onto the FreeList.
1015 : : */
1016 : :
1017 : : static void Dispose (M2ALU_PtrToValue v);
1018 : :
1019 : : /*
1020 : : AddRange - returns a ListOfRange which is prepended to the front of the current list.
1021 : : */
1022 : :
1023 : : static M2ALU_listOfRange AddRange (M2ALU_listOfRange head, unsigned int l, unsigned int h);
1024 : :
1025 : : /*
1026 : : DupRange - duplicates and returns the list, t.
1027 : : */
1028 : :
1029 : : static M2ALU_listOfRange DupRange (M2ALU_listOfRange r);
1030 : :
1031 : : /*
1032 : : Pop - pops and returns top element from the stack.
1033 : : */
1034 : :
1035 : : static M2ALU_PtrToValue Pop (void);
1036 : :
1037 : : /*
1038 : : Push - pushes the value onto the stack.
1039 : : */
1040 : :
1041 : : static void Push (M2ALU_PtrToValue v);
1042 : :
1043 : : /*
1044 : : Reduce - remove the top element of the stack.
1045 : : */
1046 : :
1047 : : static void Reduce (void);
1048 : :
1049 : : /*
1050 : : PrintValue - debugging procedure to display the value on the top of the stack.
1051 : : */
1052 : :
1053 : : static void PrintValue (void);
1054 : :
1055 : : /*
1056 : : DupFields - duplicates the field list in order.
1057 : : */
1058 : :
1059 : : static M2ALU_listOfFields DupFields (M2ALU_listOfFields f);
1060 : :
1061 : : /*
1062 : : DupElements - duplicates the array list in order.
1063 : : */
1064 : :
1065 : : static M2ALU_listOfElements DupElements (M2ALU_listOfElements f);
1066 : :
1067 : : /*
1068 : : IsReal - returns TRUE if a is a REAL number.
1069 : : */
1070 : :
1071 : : static bool IsReal (DynamicStrings_String a);
1072 : :
1073 : : /*
1074 : : IsSolvedGCC - returns TRUE if the value, sym, is solved.
1075 : : If TRUE then it also ensures this symbol is
1076 : : entered into the double book keeping table
1077 : : for GM2 <-> GCC.
1078 : : */
1079 : :
1080 : : static bool IsSolvedGCC (unsigned int sym);
1081 : :
1082 : : /*
1083 : : ConvertIntToReal - converts a INTEGER into a LONGREAL
1084 : : */
1085 : :
1086 : : static void ConvertIntToReal (void);
1087 : :
1088 : : /*
1089 : : EitherReal - returns TRUE if either, Op1, or, Op2, are Real.
1090 : : */
1091 : :
1092 : : static bool EitherReal (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2);
1093 : :
1094 : : /*
1095 : : EitherComplex - returns TRUE if either, Op1, or, Op2, are Real.
1096 : : */
1097 : :
1098 : : static bool EitherComplex (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2);
1099 : :
1100 : : /*
1101 : : RealAdd - adds two numbers. One of which is a Real.
1102 : : */
1103 : :
1104 : : static void RealAdd (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2);
1105 : :
1106 : : /*
1107 : : ComplexAdd - adds two complex numbers.
1108 : : */
1109 : :
1110 : : static void ComplexAdd (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2);
1111 : :
1112 : : /*
1113 : : RealSub - subtracts two numbers. One of which is a Real.
1114 : : */
1115 : :
1116 : : static void RealSub (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2);
1117 : :
1118 : : /*
1119 : : ComplexSub - subtracts two complex numbers.
1120 : : */
1121 : :
1122 : : static void ComplexSub (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2);
1123 : :
1124 : : /*
1125 : : RealMult - multiplies two numbers. One of which is a Real.
1126 : : */
1127 : :
1128 : : static void RealMult (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2);
1129 : :
1130 : : /*
1131 : : ComplexMult - multiplies two complex numbers.
1132 : : */
1133 : :
1134 : : static void ComplexMult (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2);
1135 : :
1136 : : /*
1137 : : RealDiv - divides two numbers. One of which is a Real.
1138 : : */
1139 : :
1140 : : static void RealDiv (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2);
1141 : :
1142 : : /*
1143 : : ComplexDiv - divides two complex numbers.
1144 : : */
1145 : :
1146 : : static void ComplexDiv (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2);
1147 : :
1148 : : /*
1149 : : AreSetsEqual - returns TRUE if sets, op1, and, op2, contain the same
1150 : : members.
1151 : : */
1152 : :
1153 : : static bool AreSetsEqual (unsigned int tokenno, M2ALU_PtrToValue op1, M2ALU_PtrToValue op2);
1154 : :
1155 : : /*
1156 : : IsSubset - returns TRUE if the set as defined by, s1, is a subset of set, s2.
1157 : : */
1158 : :
1159 : : static bool IsSubset (unsigned int tokenno, M2ALU_PtrToValue s1, M2ALU_PtrToValue s2);
1160 : :
1161 : : /*
1162 : : IsSuperset - returns TRUE if the set as defined by, s1, is a superset of set, s2.
1163 : : */
1164 : :
1165 : : static bool IsSuperset (unsigned int tokenno, M2ALU_PtrToValue s1, M2ALU_PtrToValue s2);
1166 : :
1167 : : /*
1168 : : cellTypeString - returns a string corresponding to, s.
1169 : : */
1170 : :
1171 : : static DynamicStrings_String cellTypeString (M2ALU_cellType s);
1172 : :
1173 : : /*
1174 : : ToSetValue - converts a list of fields into a list of ranges.
1175 : : In effect it turns a generic constructor into
1176 : : a set type.
1177 : : */
1178 : :
1179 : : static M2ALU_listOfRange ToSetValue (M2ALU_listOfFields f);
1180 : :
1181 : : /*
1182 : : ToArrayValue - converts a list of fields into an array initialiser.
1183 : : In effect it turns a generic constructor into
1184 : : an array type.
1185 : : */
1186 : :
1187 : : static M2ALU_listOfElements ToArrayValue (unsigned int tok, M2ALU_listOfFields f);
1188 : :
1189 : : /*
1190 : : CoerseTo - attempts to coerses a cellType, v, into, type, t.
1191 : : Normally this will be a generic constructors converting
1192 : : into set or array.
1193 : : */
1194 : :
1195 : : static M2ALU_PtrToValue CoerseTo (unsigned int tokenno, M2ALU_cellType t, M2ALU_PtrToValue v);
1196 : :
1197 : : /*
1198 : : AddElementToEnd - appends, e, to the end of list, v.
1199 : : */
1200 : :
1201 : : static void AddElementToEnd (M2ALU_PtrToValue v, M2ALU_listOfElements e);
1202 : :
1203 : : /*
1204 : : AddFieldToEnd - appends, f, to the end of list, v.
1205 : : */
1206 : :
1207 : : static void AddFieldToEnd (M2ALU_PtrToValue v, M2ALU_listOfFields f);
1208 : :
1209 : : /*
1210 : : ElementsSolved - returns TRUE if all ranges in the set have been solved.
1211 : : */
1212 : :
1213 : : static bool ElementsSolved (unsigned int tokenno, M2ALU_listOfRange r);
1214 : :
1215 : : /*
1216 : : ArrayElementsSolved - returns TRUE if all ranges in the set have been solved.
1217 : : */
1218 : :
1219 : : static bool ArrayElementsSolved (M2ALU_listOfElements e);
1220 : :
1221 : : /*
1222 : : EvalFieldValues - returns TRUE if all fields in the record have been solved.
1223 : : */
1224 : :
1225 : : static bool EvalFieldValues (M2ALU_listOfFields e);
1226 : :
1227 : : /*
1228 : : Swap - swaps the contents of, i, and, j.
1229 : : */
1230 : :
1231 : : static void Swap (M2ALU_listOfRange i, M2ALU_listOfRange j);
1232 : :
1233 : : /*
1234 : : DisplayElements -
1235 : : */
1236 : :
1237 : : static void DisplayElements (M2ALU_listOfRange i);
1238 : :
1239 : : /*
1240 : : SortElements - sorts the list as defined by, h, into ascending range order.
1241 : : The low element is the sort key.
1242 : : */
1243 : :
1244 : : static void SortElements (unsigned int tokenno, M2ALU_listOfRange h);
1245 : :
1246 : : /*
1247 : : CombineElements - given a sorted list determine whether there is any
1248 : : overlap in the low..high bounds. If overlap exists
1249 : : then remove it.
1250 : : */
1251 : :
1252 : : static void CombineElements (unsigned int tokenno, M2ALU_listOfRange r);
1253 : :
1254 : : /*
1255 : : EvalSetValues - returns TRUE if all elements in this set have been resolved.
1256 : : */
1257 : :
1258 : : static bool EvalSetValues (unsigned int tokenno, M2ALU_listOfRange r);
1259 : :
1260 : : /*
1261 : : Eval - attempts to solve a constructor type.
1262 : : */
1263 : :
1264 : : static void Eval (unsigned int tokenno, M2ALU_PtrToValue v);
1265 : :
1266 : : /*
1267 : : WalkSetValueDependants -
1268 : : */
1269 : :
1270 : : static void WalkSetValueDependants (M2ALU_listOfRange r, M2GCCDeclare_WalkAction p);
1271 : :
1272 : : /*
1273 : : IsSetValueDependants -
1274 : : */
1275 : :
1276 : : static bool IsSetValueDependants (M2ALU_listOfRange r, M2GCCDeclare_IsAction q);
1277 : :
1278 : : /*
1279 : : WalkFieldValueDependants -
1280 : : */
1281 : :
1282 : : static void WalkFieldValueDependants (M2ALU_listOfFields f, M2GCCDeclare_WalkAction p);
1283 : :
1284 : : /*
1285 : : IsFieldValueDependants -
1286 : : */
1287 : :
1288 : : static bool IsFieldValueDependants (M2ALU_listOfFields f, M2GCCDeclare_IsAction q);
1289 : :
1290 : : /*
1291 : : WalkArrayValueDependants -
1292 : : */
1293 : :
1294 : : static void WalkArrayValueDependants (M2ALU_listOfElements a, M2GCCDeclare_WalkAction p);
1295 : :
1296 : : /*
1297 : : IsArrayValueDependants -
1298 : : */
1299 : :
1300 : : static bool IsArrayValueDependants (M2ALU_listOfElements a, M2GCCDeclare_IsAction q);
1301 : :
1302 : : /*
1303 : : DefinedByConstants - returns TRUE if the value, v, is defined by constants.
1304 : : It assigns, v^.areAllConstants, with the result.
1305 : : */
1306 : :
1307 : : static bool DefinedByConstants (M2ALU_PtrToValue v);
1308 : :
1309 : : /*
1310 : : rangeConstant - returns TRUE if all the range entities are constant.
1311 : : */
1312 : :
1313 : : static bool rangeConstant (M2ALU_listOfRange r);
1314 : :
1315 : : /*
1316 : : fieldsConstant - returns TRUE if all the field entities are constant.
1317 : : */
1318 : :
1319 : : static bool fieldsConstant (M2ALU_listOfFields f);
1320 : :
1321 : : /*
1322 : : arrayConstant - returns TRUE if the, element, and, by, components
1323 : : of an array constructor are constant.
1324 : : */
1325 : :
1326 : : static bool arrayConstant (M2ALU_listOfElements e);
1327 : :
1328 : : /*
1329 : : FindValueEnum -
1330 : : */
1331 : :
1332 : : static void FindValueEnum (unsigned int field);
1333 : :
1334 : : /*
1335 : : Val - returns a GCC symbol enumeration or a GCC constant which has, value, and which is
1336 : : of type, type.
1337 : : */
1338 : :
1339 : : static unsigned int Val (unsigned int tokenno, unsigned int type, m2tree_Tree value);
1340 : :
1341 : : /*
1342 : : DupConst - duplicates and returns a constant, sym, but adds, offset to its value.
1343 : : */
1344 : :
1345 : : static unsigned int DupConst (unsigned int tokenno, unsigned int sym, int offset);
1346 : :
1347 : : /*
1348 : : DupConstAndAdd - duplicates and returns a constant, sym,
1349 : : but adds the symbol, extra.
1350 : : */
1351 : :
1352 : : static unsigned int DupConstAndAdd (unsigned int tokenno, unsigned int sym, m2tree_Tree extra);
1353 : :
1354 : : /*
1355 : : DupConstAndAddMod - duplicates and returns a constant, sym,
1356 : : but adds the symbol, extra, and ensures that
1357 : : the result in within limits: min..max using
1358 : : modulo arithmetic.
1359 : : */
1360 : :
1361 : : static unsigned int DupConstAndAddMod (unsigned int tokenno, unsigned int sym, m2tree_Tree extra, unsigned int l, unsigned int h);
1362 : :
1363 : : /*
1364 : : Remove - removes, v, from list, h.
1365 : : */
1366 : :
1367 : : static void Remove (M2ALU_listOfRange *h, M2ALU_listOfRange v);
1368 : :
1369 : : /*
1370 : : RemoveBit - remove bit, op1, from range, v, on list, h.
1371 : : */
1372 : :
1373 : : static void RemoveBit (unsigned int tokenno, M2ALU_listOfRange *h, M2ALU_listOfRange v, unsigned int op1);
1374 : :
1375 : : /*
1376 : : PerformSubBit -
1377 : : */
1378 : :
1379 : : static void PerformSubBit (unsigned int tokenno, M2ALU_listOfRange *h, unsigned int op1);
1380 : :
1381 : : /*
1382 : : PerformSetIn - returns TRUE if op1 is in set.
1383 : : */
1384 : :
1385 : : static bool PerformSetIn (unsigned int tokenno, unsigned int op1, M2ALU_listOfRange h);
1386 : :
1387 : : /*
1388 : : SetOp - perform the function doOp on the top two elements of the stack.
1389 : : */
1390 : :
1391 : : static void SetOp (unsigned int tokenno, M2ALU_DoSetProcedure doOp);
1392 : :
1393 : : /*
1394 : : PerformOr - performs a logical OR between the two ranges.
1395 : : The ranges, r1, r2, are destroyed.
1396 : : */
1397 : :
1398 : : static M2ALU_listOfRange PerformOr (unsigned int tokenno, M2ALU_listOfRange r1, M2ALU_listOfRange r2);
1399 : :
1400 : : /*
1401 : : Min - returns the symbol which has the least value.
1402 : : */
1403 : :
1404 : : static unsigned int Min (unsigned int tokenno, unsigned int a, unsigned int b);
1405 : :
1406 : : /*
1407 : : Max - returns the symbol which has the greatest value.
1408 : : */
1409 : :
1410 : : static unsigned int Max (unsigned int tokenno, unsigned int a, unsigned int b);
1411 : :
1412 : : /*
1413 : : IsRangeIntersection - returns TRUE if ranges, r1, and, r2, intersect.
1414 : : */
1415 : :
1416 : : static bool IsRangeIntersection (unsigned int tokenno, M2ALU_listOfRange r1, M2ALU_listOfRange r2);
1417 : :
1418 : : /*
1419 : : IsRangeLess - returns TRUE if r1^.low is < r2^.low
1420 : : */
1421 : :
1422 : : static bool IsRangeLess (unsigned int tokenno, M2ALU_listOfRange r1, M2ALU_listOfRange r2);
1423 : :
1424 : : /*
1425 : : MinTree - returns the tree symbol which has the least value.
1426 : : */
1427 : :
1428 : : static m2tree_Tree MinTree (unsigned int tokenno, m2tree_Tree a, m2tree_Tree b);
1429 : :
1430 : : /*
1431 : : MaxTree - returns the symbol which has the greatest value.
1432 : : */
1433 : :
1434 : : static m2tree_Tree MaxTree (unsigned int tokenno, m2tree_Tree a, m2tree_Tree b);
1435 : :
1436 : : /*
1437 : : IsIntersectionTree - returns TRUE if ranges, a..b, and, c..d, intersect.
1438 : : */
1439 : :
1440 : : static bool IsIntersectionTree (unsigned int tokenno, m2tree_Tree a, m2tree_Tree b, m2tree_Tree c, m2tree_Tree d);
1441 : :
1442 : : /*
1443 : : SubTree - returns the tree value containing (a-b)
1444 : : */
1445 : :
1446 : : static m2tree_Tree SubTree (m2tree_Tree a, m2tree_Tree b);
1447 : :
1448 : : /*
1449 : : PerformAnd - performs a logical AND between the two ranges.
1450 : : The ranges, r1, r2, are unaltered.
1451 : : */
1452 : :
1453 : : static M2ALU_listOfRange PerformAnd (unsigned int tokenno, M2ALU_listOfRange r1, M2ALU_listOfRange r2);
1454 : :
1455 : : /*
1456 : : BuildStructBitset - v is the PtrToValue.
1457 : : low and high are the limits of the subrange.
1458 : : */
1459 : :
1460 : : static m2tree_Tree BuildStructBitset (unsigned int tokenno, M2ALU_PtrToValue v, m2tree_Tree low, m2tree_Tree high);
1461 : :
1462 : : /*
1463 : : ConstructLargeOrSmallSet - generates a constant representing the set value of the symbol, sym.
1464 : : We manufacture the constant by using a initialization
1465 : : structure of cardinals.
1466 : :
1467 : : { (cardinal), (cardinal) etc }
1468 : : */
1469 : :
1470 : : static m2tree_Tree ConstructLargeOrSmallSet (unsigned int tokenno, M2ALU_PtrToValue v, unsigned int low, unsigned int high);
1471 : :
1472 : : /*
1473 : : ConvertConstToType - returns a Tree containing an initialiser,
1474 : : init, ready to be assigned to a record or
1475 : : array constructor.
1476 : : */
1477 : :
1478 : : static m2tree_Tree ConvertConstToType (unsigned int tokenno, unsigned int field, unsigned int init);
1479 : :
1480 : : /*
1481 : : ConstructRecordConstant - builds a struct initializer, as defined by, v.
1482 : : */
1483 : :
1484 : : static m2tree_Tree ConstructRecordConstant (unsigned int tokenno, M2ALU_PtrToValue v);
1485 : :
1486 : : /*
1487 : : GetConstructorField - returns a symbol containing the constructor field, i.
1488 : : */
1489 : :
1490 : : static unsigned int GetConstructorField (M2ALU_PtrToValue v, unsigned int i);
1491 : :
1492 : : /*
1493 : : GetConstructorElement - returns a symbol containing the array constructor element, i.
1494 : : */
1495 : :
1496 : : static unsigned int GetConstructorElement (unsigned int tokenno, M2ALU_PtrToValue v, unsigned int i);
1497 : :
1498 : : /*
1499 : : IsString - returns TRUE if sym is an ARRAY [..] OF CHAR
1500 : : */
1501 : :
1502 : : static bool IsString (unsigned int sym);
1503 : :
1504 : : /*
1505 : : StringFitsArray -
1506 : : */
1507 : :
1508 : : static bool StringFitsArray (unsigned int arrayType, unsigned int el, unsigned int tokenno);
1509 : :
1510 : : /*
1511 : : GetArrayLimits -
1512 : : */
1513 : :
1514 : : static void GetArrayLimits (unsigned int array, unsigned int *low, unsigned int *high);
1515 : :
1516 : : /*
1517 : : InitialiseArrayOfCharWithString -
1518 : : */
1519 : :
1520 : : static m2tree_Tree InitialiseArrayOfCharWithString (unsigned int tokenno, m2tree_Tree cons, unsigned int el, unsigned int baseType, unsigned int arrayType);
1521 : :
1522 : : /*
1523 : : CheckElementString -
1524 : : */
1525 : :
1526 : : static m2tree_Tree CheckElementString (unsigned int el, unsigned int arrayType, unsigned int tokenno);
1527 : :
1528 : : /*
1529 : : InitialiseArrayWith -
1530 : : */
1531 : :
1532 : : static m2tree_Tree InitialiseArrayWith (unsigned int tokenno, m2tree_Tree cons, M2ALU_PtrToValue v, unsigned int el, unsigned int high, unsigned int low, unsigned int arrayType);
1533 : :
1534 : : /*
1535 : : CheckGetCharFromString - return TRUE if a char from the position arrayIndex in the list of
1536 : : constDecl elements can be extracted. The character is returned
1537 : : in value.
1538 : : */
1539 : :
1540 : : static bool CheckGetCharFromString (m2linemap_location_t location, unsigned int tokenno, M2ALU_PtrToValue constDecl, unsigned int consType, unsigned int arrayIndex, m2tree_Tree *value);
1541 : :
1542 : : /*
1543 : : InitialiseArrayOfCharWith -
1544 : : */
1545 : :
1546 : : static m2tree_Tree InitialiseArrayOfCharWith (unsigned int tokenno, m2tree_Tree cons, M2ALU_PtrToValue constDecl, unsigned int el, unsigned int high, unsigned int low, unsigned int consType, unsigned int arrayType);
1547 : :
1548 : : /*
1549 : : ConstructArrayConstant - builds a struct initializer, as defined by, v.
1550 : : */
1551 : :
1552 : : static m2tree_Tree ConstructArrayConstant (unsigned int tokenno, M2ALU_PtrToValue v);
1553 : :
1554 : : /*
1555 : : BuildBitset - given a set, v, construct the bitmask for its
1556 : : constant value which lie in the range low..high.
1557 : : */
1558 : :
1559 : : static m2tree_Tree BuildBitset (unsigned int tokenno, M2ALU_PtrToValue v, m2tree_Tree low, m2tree_Tree high);
1560 : :
1561 : : /*
1562 : : CheckOverflow - tests to see whether the tree, t, has caused
1563 : : an overflow error and if so it generates an
1564 : : error message.
1565 : : */
1566 : :
1567 : : static void CheckOverflow (unsigned int tokenno, m2tree_Tree t);
1568 : :
1569 : : /*
1570 : : PushGCCArrayTree - pushes a gcc tree value onto the ALU stack.
1571 : : */
1572 : :
1573 : : static void PushGCCArrayTree (m2tree_Tree gcc, unsigned int t);
1574 : :
1575 : : /*
1576 : : PushGCCSetTree - pushes a gcc tree value onto the ALU stack.
1577 : : */
1578 : :
1579 : : static void PushGCCSetTree (m2tree_Tree gcc, unsigned int t);
1580 : :
1581 : : /*
1582 : : PushGCCRecordTree - pushes a gcc tree value onto the ALU stack.
1583 : : */
1584 : :
1585 : : static void PushGCCRecordTree (m2tree_Tree gcc, unsigned int t);
1586 : :
1587 : : /*
1588 : : Init - initialises the stack and the free list.
1589 : : */
1590 : :
1591 : : static void Init (void);
1592 : :
1593 : :
1594 : : /*
1595 : : New - allocate a PtrToValue. Firstly check the FreeList, if empty call upon New.
1596 : : */
1597 : :
1598 : 50013429 : static M2ALU_PtrToValue New (void)
1599 : : {
1600 : 50013429 : M2ALU_PtrToValue v;
1601 : :
1602 : 50013429 : if (FreeList == NULL)
1603 : : {
1604 : 27054304 : Storage_ALLOCATE ((void **) &v, sizeof (M2ALU_cell));
1605 : : }
1606 : : else
1607 : : {
1608 : 22959125 : v = FreeList;
1609 : 22959125 : FreeList = FreeList->next;
1610 : : }
1611 : 50013429 : v->numberValue = NULL;
1612 : 100026858 : return InitRecord (v);
1613 : : /* static analysis guarentees a RETURN statement will be used before here. */
1614 : : __builtin_unreachable ();
1615 : : }
1616 : :
1617 : :
1618 : : /*
1619 : : InitRecord - initialize the non variant fields of, v. Return v.
1620 : : */
1621 : :
1622 : 50013429 : static M2ALU_PtrToValue InitRecord (M2ALU_PtrToValue v)
1623 : : {
1624 : 50013429 : v->location = m2linemap_UnknownLocation ();
1625 : 50013429 : v->areAllConstants = false;
1626 : 50013429 : v->solved = false;
1627 : 50013429 : v->constructorType = SymbolTable_NulSym;
1628 : 50013429 : v->numberValue = NULL;
1629 : 50013429 : return v;
1630 : : /* static analysis guarentees a RETURN statement will be used before here. */
1631 : : __builtin_unreachable ();
1632 : : }
1633 : :
1634 : :
1635 : : /*
1636 : : NewRange - assigns, v, to a new area of memory.
1637 : : */
1638 : :
1639 : 138749 : static void NewRange (M2ALU_listOfRange *v)
1640 : : {
1641 : 138749 : if (RangeFreeList == NULL)
1642 : : {
1643 : : /* avoid dangling else. */
1644 : 127002 : Storage_ALLOCATE ((void **) &(*v), sizeof (M2ALU_rList));
1645 : 127002 : if ((*v) == NULL)
1646 : : {
1647 : 0 : M2Error_InternalError ((const char *) "out of memory error", 19);
1648 : : }
1649 : : }
1650 : : else
1651 : : {
1652 : 11747 : (*v) = RangeFreeList;
1653 : 11747 : RangeFreeList = RangeFreeList->next;
1654 : : }
1655 : 138749 : }
1656 : :
1657 : :
1658 : : /*
1659 : : DisposeRange - adds the list, v, to the free list.
1660 : : */
1661 : :
1662 : 51652 : static void DisposeRange (M2ALU_listOfRange *v)
1663 : : {
1664 : 51652 : M2ALU_listOfRange r;
1665 : :
1666 : 51652 : if ((*v) != NULL)
1667 : : {
1668 : : r = (*v);
1669 : 11855 : while ((r != NULL) && (r->next != NULL))
1670 : : {
1671 : : r = r->next;
1672 : : }
1673 : 9741 : if (r != NULL)
1674 : : {
1675 : 9741 : r->next = RangeFreeList;
1676 : : }
1677 : 9741 : RangeFreeList = (*v);
1678 : 9741 : (*v) = NULL;
1679 : : }
1680 : 51652 : }
1681 : :
1682 : :
1683 : : /*
1684 : : IsOnFieldFreeList - returns TRUE if, r, is on the FieldFreeList.
1685 : : */
1686 : :
1687 : 7292 : static bool IsOnFieldFreeList (M2ALU_listOfFields r)
1688 : : {
1689 : 7292 : M2ALU_listOfFields s;
1690 : :
1691 : 7292 : s = FieldFreeList;
1692 : 7292 : while (s != NULL)
1693 : : {
1694 : 0 : if (s == r)
1695 : : {
1696 : : return true;
1697 : : }
1698 : : else
1699 : : {
1700 : 0 : s = s->next;
1701 : : }
1702 : : }
1703 : : return false;
1704 : : /* static analysis guarentees a RETURN statement will be used before here. */
1705 : : __builtin_unreachable ();
1706 : : }
1707 : :
1708 : :
1709 : : /*
1710 : : IsOnElementFreeList - returns TRUE if, r, is on the ElementFreeList.
1711 : : */
1712 : :
1713 : 5482 : static bool IsOnElementFreeList (M2ALU_listOfElements r)
1714 : : {
1715 : 5482 : M2ALU_listOfElements s;
1716 : :
1717 : 5482 : s = ElementFreeList;
1718 : 5482 : while (s != NULL)
1719 : : {
1720 : 0 : if (s == r)
1721 : : {
1722 : : return true;
1723 : : }
1724 : : else
1725 : : {
1726 : 0 : s = s->next;
1727 : : }
1728 : : }
1729 : : return false;
1730 : : /* static analysis guarentees a RETURN statement will be used before here. */
1731 : : __builtin_unreachable ();
1732 : : }
1733 : :
1734 : :
1735 : : /*
1736 : : DisposeFields - adds the list, v, to the free list.
1737 : : */
1738 : :
1739 : 42186 : static void DisposeFields (M2ALU_listOfFields *v)
1740 : : {
1741 : 42186 : M2ALU_listOfFields r;
1742 : :
1743 : 42186 : if ((*v) != NULL)
1744 : : {
1745 : : r = (*v);
1746 : 9624 : while (r->next != NULL)
1747 : : {
1748 : 14584 : M2Debug_Assert (! (IsOnFieldFreeList (r)));
1749 : 7292 : r = r->next;
1750 : : }
1751 : 2332 : r->next = FieldFreeList;
1752 : 2332 : FieldFreeList = (*v);
1753 : 2332 : (*v) = NULL;
1754 : : }
1755 : 42186 : }
1756 : :
1757 : :
1758 : : /*
1759 : : NewField - adds the list, v, to the free list.
1760 : : */
1761 : :
1762 : 541128 : static void NewField (M2ALU_listOfFields *v)
1763 : : {
1764 : 541128 : if (FieldFreeList == NULL)
1765 : : {
1766 : : /* avoid dangling else. */
1767 : 531540 : Storage_ALLOCATE ((void **) &(*v), sizeof (M2ALU_fList));
1768 : 531540 : if ((*v) == NULL)
1769 : : {
1770 : 0 : M2Error_InternalError ((const char *) "out of memory error", 19);
1771 : : }
1772 : : }
1773 : : else
1774 : : {
1775 : 9588 : (*v) = FieldFreeList;
1776 : 9588 : FieldFreeList = FieldFreeList->next;
1777 : : }
1778 : 541128 : }
1779 : :
1780 : :
1781 : : /*
1782 : : NewElement - returns a new element record.
1783 : : */
1784 : :
1785 : 341164 : static void NewElement (M2ALU_listOfElements *e)
1786 : : {
1787 : 341164 : if (ElementFreeList == NULL)
1788 : : {
1789 : : /* avoid dangling else. */
1790 : 334958 : Storage_ALLOCATE ((void **) &(*e), sizeof (M2ALU_eList));
1791 : 334958 : if ((*e) == NULL)
1792 : : {
1793 : 0 : M2Error_InternalError ((const char *) "out of memory error", 19);
1794 : : }
1795 : : }
1796 : : else
1797 : : {
1798 : 6206 : (*e) = ElementFreeList;
1799 : 6206 : ElementFreeList = ElementFreeList->next;
1800 : : }
1801 : 341164 : }
1802 : :
1803 : :
1804 : : /*
1805 : : DisposeElements - returns the list, e, to the free list.
1806 : : */
1807 : :
1808 : 7284 : static void DisposeElements (M2ALU_listOfElements *e)
1809 : : {
1810 : 7284 : M2ALU_listOfElements r;
1811 : :
1812 : 7284 : if ((*e) != NULL)
1813 : : {
1814 : : r = (*e);
1815 : 6206 : while (r->next != NULL)
1816 : : {
1817 : 10964 : M2Debug_Assert (! (IsOnElementFreeList (r)));
1818 : 5482 : r = r->next;
1819 : : }
1820 : 724 : r->next = ElementFreeList;
1821 : 724 : ElementFreeList = (*e);
1822 : 724 : (*e) = NULL;
1823 : : }
1824 : 7284 : }
1825 : :
1826 : :
1827 : : /*
1828 : : CheckNotAlreadyOnFreeList - checks to see whether, v, is already on the free list
1829 : : and aborts if this is the case.
1830 : : */
1831 : :
1832 : 88800164 : static void CheckNotAlreadyOnFreeList (M2ALU_PtrToValue v)
1833 : : {
1834 : 88800164 : M2ALU_PtrToValue l;
1835 : :
1836 : 88800164 : if (DebugGarbage)
1837 : : {
1838 : 88800164 : l = FreeList;
1839 : 163872662 : while (l != NULL)
1840 : : {
1841 : 75072498 : if (l == v)
1842 : : {
1843 : 0 : M2Error_InternalError ((const char *) "value is already on the free list", 33);
1844 : : }
1845 : 75072498 : l = l->next;
1846 : : }
1847 : : }
1848 : 88800164 : }
1849 : :
1850 : :
1851 : : /*
1852 : : CheckNotOnStack - checks to see whether, v, is already on the stack
1853 : : and aborts if this is the case.
1854 : : */
1855 : :
1856 : 49104699 : static void CheckNotOnStack (M2ALU_PtrToValue v)
1857 : : {
1858 : 49104699 : M2ALU_PtrToValue l;
1859 : :
1860 : 49104699 : if (DebugGarbage)
1861 : : {
1862 : 49104699 : l = TopOfStack;
1863 : 75372164 : while (l != NULL)
1864 : : {
1865 : 26267465 : if (l == v)
1866 : : {
1867 : 0 : M2Error_InternalError ((const char *) "value is already on the stack", 29);
1868 : : }
1869 : 26267465 : l = l->next;
1870 : : }
1871 : : }
1872 : 49104699 : }
1873 : :
1874 : :
1875 : : /*
1876 : : Dispose - place, v, onto the FreeList.
1877 : : */
1878 : :
1879 : 22990323 : static void Dispose (M2ALU_PtrToValue v)
1880 : : {
1881 : 22990323 : CheckNotAlreadyOnFreeList (v);
1882 : 22990323 : CheckNotOnStack (v);
1883 : 22990323 : switch (v->type)
1884 : : {
1885 : 48556 : case M2ALU_set:
1886 : 48556 : DisposeRange (&v->setValue);
1887 : 48556 : break;
1888 : :
1889 : 23982 : case M2ALU_constructor:
1890 : 23982 : case M2ALU_record:
1891 : 23982 : DisposeFields (&v->fieldValues);
1892 : 23982 : break;
1893 : :
1894 : 7284 : case M2ALU_array:
1895 : 7284 : DisposeElements (&v->arrayValues);
1896 : 7284 : break;
1897 : :
1898 : :
1899 : : default:
1900 : : break;
1901 : : }
1902 : 22990323 : v->next = FreeList;
1903 : 22990323 : FreeList = v;
1904 : 22990323 : }
1905 : :
1906 : :
1907 : : /*
1908 : : AddRange - returns a ListOfRange which is prepended to the front of the current list.
1909 : : */
1910 : :
1911 : 138749 : static M2ALU_listOfRange AddRange (M2ALU_listOfRange head, unsigned int l, unsigned int h)
1912 : : {
1913 : 138749 : M2ALU_listOfRange r;
1914 : :
1915 : 0 : NewRange (&r);
1916 : 138749 : r->low = l;
1917 : 138749 : r->high = h;
1918 : 138749 : r->next = head;
1919 : 138749 : return r;
1920 : : /* static analysis guarentees a RETURN statement will be used before here. */
1921 : : __builtin_unreachable ();
1922 : : }
1923 : :
1924 : :
1925 : : /*
1926 : : DupRange - duplicates and returns the list, t.
1927 : : */
1928 : :
1929 : 103951 : static M2ALU_listOfRange DupRange (M2ALU_listOfRange r)
1930 : : {
1931 : 103951 : M2ALU_listOfRange s;
1932 : :
1933 : 103951 : s = NULL;
1934 : 231793 : while (r != NULL)
1935 : : {
1936 : 127842 : s = AddRange (s, r->low, r->high);
1937 : 127842 : r = r->next;
1938 : : }
1939 : 103951 : return s;
1940 : : /* static analysis guarentees a RETURN statement will be used before here. */
1941 : : __builtin_unreachable ();
1942 : : }
1943 : :
1944 : :
1945 : : /*
1946 : : Pop - pops and returns top element from the stack.
1947 : : */
1948 : :
1949 : 26111027 : static M2ALU_PtrToValue Pop (void)
1950 : : {
1951 : 26111027 : M2ALU_PtrToValue v;
1952 : :
1953 : 26111027 : if (TopOfStack == NULL)
1954 : : {
1955 : 0 : M2Error_InternalError ((const char *) "stack underflow error", 21);
1956 : : }
1957 : : else
1958 : : {
1959 : 26111027 : v = TopOfStack;
1960 : 26111027 : TopOfStack = TopOfStack->next;
1961 : : }
1962 : 26111027 : CheckNotAlreadyOnFreeList (v);
1963 : 26111027 : return v;
1964 : : /* static analysis guarentees a RETURN statement will be used before here. */
1965 : : __builtin_unreachable ();
1966 : : }
1967 : :
1968 : :
1969 : : /*
1970 : : Push - pushes the value onto the stack.
1971 : : */
1972 : :
1973 : 26114376 : static void Push (M2ALU_PtrToValue v)
1974 : : {
1975 : 26114376 : CheckNotAlreadyOnFreeList (v);
1976 : 26114376 : CheckNotOnStack (v);
1977 : 26114376 : v->next = TopOfStack;
1978 : 26114376 : TopOfStack = v;
1979 : 26114376 : }
1980 : :
1981 : :
1982 : : /*
1983 : : Reduce - remove the top element of the stack.
1984 : : */
1985 : :
1986 : 0 : static void Reduce (void)
1987 : : {
1988 : 0 : Dispose (Pop ());
1989 : 0 : }
1990 : :
1991 : :
1992 : : /*
1993 : : PrintValue - debugging procedure to display the value on the top of the stack.
1994 : : */
1995 : :
1996 : 0 : static void PrintValue (void)
1997 : : {
1998 : 0 : M2ALU_PtrToValue v;
1999 : :
2000 : 0 : v = Pop ();
2001 : 0 : if (v->type == M2ALU_integer)
2002 : : {
2003 : 0 : m2misc_DebugTree (v->numberValue);
2004 : : }
2005 : 0 : Push (v);
2006 : 0 : }
2007 : :
2008 : :
2009 : : /*
2010 : : DupFields - duplicates the field list in order.
2011 : : */
2012 : :
2013 : 129930 : static M2ALU_listOfFields DupFields (M2ALU_listOfFields f)
2014 : : {
2015 : 129930 : M2ALU_listOfFields p;
2016 : 129930 : M2ALU_listOfFields q;
2017 : 129930 : M2ALU_listOfFields l;
2018 : :
2019 : 129930 : p = NULL;
2020 : 129930 : l = NULL;
2021 : 661626 : while (f != NULL)
2022 : : {
2023 : 531696 : NewField (&q);
2024 : 531696 : if (p == NULL)
2025 : : {
2026 : 127672 : p = q;
2027 : : }
2028 : 531696 : q->field = f->field;
2029 : 531696 : q->next = NULL;
2030 : 531696 : if (l != NULL)
2031 : : {
2032 : 404024 : l->next = q;
2033 : : }
2034 : 531696 : l = q;
2035 : 531696 : f = f->next;
2036 : : }
2037 : 129930 : return p;
2038 : : /* static analysis guarentees a RETURN statement will be used before here. */
2039 : : __builtin_unreachable ();
2040 : : }
2041 : :
2042 : :
2043 : : /*
2044 : : DupElements - duplicates the array list in order.
2045 : : */
2046 : :
2047 : 29428 : static M2ALU_listOfElements DupElements (M2ALU_listOfElements f)
2048 : : {
2049 : 29428 : M2ALU_listOfElements p;
2050 : 29428 : M2ALU_listOfElements q;
2051 : 29428 : M2ALU_listOfElements l;
2052 : :
2053 : 29428 : p = NULL;
2054 : 29428 : l = NULL;
2055 : 366390 : while (f != NULL)
2056 : : {
2057 : 336962 : NewElement (&q);
2058 : 336962 : if (p == NULL)
2059 : : {
2060 : 28962 : p = q;
2061 : : }
2062 : 336962 : q->element = f->element;
2063 : 336962 : q->by = f->by;
2064 : 336962 : q->next = NULL;
2065 : 336962 : if (l != NULL)
2066 : : {
2067 : 308000 : l->next = q;
2068 : : }
2069 : 336962 : l = q;
2070 : 336962 : f = f->next;
2071 : : }
2072 : 29428 : return p;
2073 : : /* static analysis guarentees a RETURN statement will be used before here. */
2074 : : __builtin_unreachable ();
2075 : : }
2076 : :
2077 : :
2078 : : /*
2079 : : IsReal - returns TRUE if a is a REAL number.
2080 : : */
2081 : :
2082 : 428801 : static bool IsReal (DynamicStrings_String a)
2083 : : {
2084 : 0 : return (DynamicStrings_Index (a, '.', 0)) != -1;
2085 : : /* static analysis guarentees a RETURN statement will be used before here. */
2086 : : __builtin_unreachable ();
2087 : : }
2088 : :
2089 : :
2090 : : /*
2091 : : IsSolvedGCC - returns TRUE if the value, sym, is solved.
2092 : : If TRUE then it also ensures this symbol is
2093 : : entered into the double book keeping table
2094 : : for GM2 <-> GCC.
2095 : : */
2096 : :
2097 : 41968 : static bool IsSolvedGCC (unsigned int sym)
2098 : : {
2099 : 41968 : if (SymbolTable_IsValueSolved (sym))
2100 : : {
2101 : 40224 : if (! (SymbolConversion_GccKnowsAbout (sym)))
2102 : : {
2103 : 9986 : M2GCCDeclare_DeclareConstant (SymbolTable_GetDeclaredMod (sym), sym);
2104 : : }
2105 : 40224 : return true;
2106 : : }
2107 : : else
2108 : : {
2109 : : return false;
2110 : : }
2111 : : /* static analysis guarentees a RETURN statement will be used before here. */
2112 : : __builtin_unreachable ();
2113 : : }
2114 : :
2115 : :
2116 : : /*
2117 : : ConvertIntToReal - converts a INTEGER into a LONGREAL
2118 : : */
2119 : :
2120 : 0 : static void ConvertIntToReal (void)
2121 : : {
2122 : 0 : M2ALU_PtrToValue v;
2123 : :
2124 : 0 : v = Pop ();
2125 : 0 : if (v->type == M2ALU_integer)
2126 : : {
2127 : 0 : v->numberValue = m2convert_ConvertConstantAndCheck (v->location, m2type_GetLongRealType (), v->numberValue);
2128 : 0 : v->type = M2ALU_real;
2129 : 0 : v->areAllConstants = true;
2130 : 0 : v->solved = true;
2131 : : }
2132 : : else
2133 : : {
2134 : 0 : M2Error_InternalError ((const char *) "expecting an INTEGER number", 27);
2135 : : }
2136 : 0 : Push (v);
2137 : 0 : }
2138 : :
2139 : :
2140 : : /*
2141 : : EitherReal - returns TRUE if either, Op1, or, Op2, are Real.
2142 : : */
2143 : :
2144 : 597755 : static bool EitherReal (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2)
2145 : : {
2146 : 597755 : return (Op1->type == M2ALU_real) || (Op2->type == M2ALU_real);
2147 : : /* static analysis guarentees a RETURN statement will be used before here. */
2148 : : __builtin_unreachable ();
2149 : : }
2150 : :
2151 : :
2152 : : /*
2153 : : EitherComplex - returns TRUE if either, Op1, or, Op2, are Real.
2154 : : */
2155 : :
2156 : 597755 : static bool EitherComplex (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2)
2157 : : {
2158 : 597755 : return (Op1->type == M2ALU_complex) || (Op2->type == M2ALU_complex);
2159 : : /* static analysis guarentees a RETURN statement will be used before here. */
2160 : : __builtin_unreachable ();
2161 : : }
2162 : :
2163 : :
2164 : : /*
2165 : : RealAdd - adds two numbers. One of which is a Real.
2166 : : */
2167 : :
2168 : 0 : static void RealAdd (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2)
2169 : : {
2170 : 0 : M2ALU_PtrToValue Temp;
2171 : :
2172 : 0 : if (Op1->type == M2ALU_integer)
2173 : : {
2174 : 0 : Push (Op1);
2175 : 0 : ConvertIntToReal ();
2176 : 0 : Op1 = Pop ();
2177 : : }
2178 : 0 : if (Op2->type == M2ALU_integer)
2179 : : {
2180 : 0 : Push (Op2);
2181 : 0 : ConvertIntToReal ();
2182 : 0 : Op2 = Pop ();
2183 : : }
2184 : 0 : Temp = New ();
2185 : 0 : Temp->location = Op1->location;
2186 : 0 : Temp->numberValue = m2expr_BuildAdd (Temp->location, Op1->numberValue, Op2->numberValue, false);
2187 : 0 : Temp->type = M2ALU_real;
2188 : 0 : Temp->solved = true;
2189 : 0 : Push (Temp);
2190 : 0 : }
2191 : :
2192 : :
2193 : : /*
2194 : : ComplexAdd - adds two complex numbers.
2195 : : */
2196 : :
2197 : 0 : static void ComplexAdd (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2)
2198 : : {
2199 : 0 : M2ALU_PtrToValue Temp;
2200 : :
2201 : 0 : if ((Op1->type == M2ALU_complex) && (Op2->type == M2ALU_complex))
2202 : : {
2203 : 0 : Temp = New ();
2204 : 0 : Temp->location = Op1->location;
2205 : 0 : Temp->numberValue = m2expr_BuildAdd (Temp->location, Op1->numberValue, Op2->numberValue, false);
2206 : 0 : Temp->type = M2ALU_complex;
2207 : 0 : Temp->solved = true;
2208 : 0 : Push (Temp);
2209 : : }
2210 : : else
2211 : : {
2212 : 0 : M2Error_InternalError ((const char *) "expecting both operands to be of type COMPLEX", 45);
2213 : : }
2214 : 0 : }
2215 : :
2216 : :
2217 : : /*
2218 : : RealSub - subtracts two numbers. One of which is a Real.
2219 : : */
2220 : :
2221 : 0 : static void RealSub (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2)
2222 : : {
2223 : 0 : M2ALU_PtrToValue Temp;
2224 : :
2225 : 0 : if (Op1->type == M2ALU_integer)
2226 : : {
2227 : 0 : Push (Op1);
2228 : 0 : ConvertIntToReal ();
2229 : 0 : Op1 = Pop ();
2230 : : }
2231 : 0 : if (Op2->type == M2ALU_integer)
2232 : : {
2233 : 0 : Push (Op2);
2234 : 0 : ConvertIntToReal ();
2235 : 0 : Op2 = Pop ();
2236 : : }
2237 : 0 : Temp = New ();
2238 : 0 : Temp->location = Op1->location;
2239 : 0 : Temp->numberValue = m2expr_BuildSub (Temp->location, Op2->numberValue, Op1->numberValue, false);
2240 : 0 : Temp->type = M2ALU_real;
2241 : 0 : Temp->solved = true;
2242 : 0 : Push (Temp);
2243 : 0 : }
2244 : :
2245 : :
2246 : : /*
2247 : : ComplexSub - subtracts two complex numbers.
2248 : : */
2249 : :
2250 : 0 : static void ComplexSub (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2)
2251 : : {
2252 : 0 : M2ALU_PtrToValue Temp;
2253 : :
2254 : 0 : if ((Op1->type == M2ALU_complex) && (Op2->type == M2ALU_complex))
2255 : : {
2256 : 0 : Temp = New ();
2257 : 0 : Temp->location = Op1->location;
2258 : 0 : Temp->numberValue = m2expr_BuildSub (Temp->location, Op2->numberValue, Op1->numberValue, false);
2259 : 0 : Temp->type = M2ALU_complex;
2260 : 0 : Temp->solved = true;
2261 : 0 : Push (Temp);
2262 : : }
2263 : : else
2264 : : {
2265 : 0 : M2Error_InternalError ((const char *) "expecting both operands to be of type COMPLEX", 45);
2266 : : }
2267 : 0 : }
2268 : :
2269 : :
2270 : : /*
2271 : : RealMult - multiplies two numbers. One of which is a Real.
2272 : : */
2273 : :
2274 : 0 : static void RealMult (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2)
2275 : : {
2276 : 0 : M2ALU_PtrToValue Temp;
2277 : :
2278 : 0 : if (Op1->type == M2ALU_integer)
2279 : : {
2280 : 0 : Push (Op1);
2281 : 0 : ConvertIntToReal ();
2282 : 0 : Op1 = Pop ();
2283 : : }
2284 : 0 : if (Op2->type == M2ALU_integer)
2285 : : {
2286 : 0 : Push (Op2);
2287 : 0 : ConvertIntToReal ();
2288 : 0 : Op2 = Pop ();
2289 : : }
2290 : 0 : Temp = New (); /* as it is a temp */
2291 : 0 : Temp->location = Op1->location; /* as it is a temp */
2292 : 0 : Temp->numberValue = m2expr_BuildMult (Temp->location, Op2->numberValue, Op1->numberValue, false);
2293 : 0 : Temp->type = M2ALU_real;
2294 : 0 : Temp->solved = true;
2295 : 0 : Push (Temp);
2296 : 0 : }
2297 : :
2298 : :
2299 : : /*
2300 : : ComplexMult - multiplies two complex numbers.
2301 : : */
2302 : :
2303 : 0 : static void ComplexMult (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2)
2304 : : {
2305 : 0 : M2ALU_PtrToValue Temp;
2306 : :
2307 : 0 : if ((Op1->type == M2ALU_complex) && (Op2->type == M2ALU_complex))
2308 : : {
2309 : 0 : Temp = New ();
2310 : 0 : Temp->location = Op1->location;
2311 : 0 : Temp->numberValue = m2expr_BuildMult (Temp->location, Op2->numberValue, Op1->numberValue, false);
2312 : 0 : Temp->type = M2ALU_complex;
2313 : 0 : Temp->solved = true;
2314 : 0 : Push (Temp);
2315 : : }
2316 : : else
2317 : : {
2318 : 0 : M2Error_InternalError ((const char *) "expecting both operands to be of type COMPLEX", 45);
2319 : : }
2320 : 0 : }
2321 : :
2322 : :
2323 : : /*
2324 : : RealDiv - divides two numbers. One of which is a Real.
2325 : : */
2326 : :
2327 : 0 : static void RealDiv (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2)
2328 : : {
2329 : 0 : M2ALU_PtrToValue Temp;
2330 : :
2331 : 0 : if (Op1->type == M2ALU_integer)
2332 : : {
2333 : 0 : Push (Op1);
2334 : 0 : ConvertIntToReal ();
2335 : 0 : Op1 = Pop ();
2336 : : }
2337 : 0 : if (Op2->type == M2ALU_integer)
2338 : : {
2339 : 0 : Push (Op2);
2340 : 0 : ConvertIntToReal ();
2341 : 0 : Op2 = Pop ();
2342 : : }
2343 : 0 : Temp = New (); /* as it is a temp */
2344 : 0 : Temp->location = Op1->location; /* as it is a temp */
2345 : 0 : Temp->numberValue = m2expr_BuildDivTrunc (Temp->location, Op2->numberValue, Op1->numberValue, false);
2346 : 0 : Temp->type = M2ALU_real;
2347 : 0 : Temp->solved = true;
2348 : 0 : Push (Temp);
2349 : 0 : }
2350 : :
2351 : :
2352 : : /*
2353 : : ComplexDiv - divides two complex numbers.
2354 : : */
2355 : :
2356 : 0 : static void ComplexDiv (M2ALU_PtrToValue Op1, M2ALU_PtrToValue Op2)
2357 : : {
2358 : 0 : M2ALU_PtrToValue Temp;
2359 : :
2360 : 0 : if ((Op1->type == M2ALU_complex) && (Op2->type == M2ALU_complex))
2361 : : {
2362 : 0 : Temp = New ();
2363 : 0 : Temp->location = Op1->location;
2364 : 0 : Temp->numberValue = m2expr_BuildDivTrunc (Temp->location, Op2->numberValue, Op1->numberValue, false);
2365 : 0 : Temp->type = M2ALU_complex;
2366 : 0 : Temp->solved = true;
2367 : 0 : Push (Temp);
2368 : : }
2369 : : else
2370 : : {
2371 : 0 : M2Error_InternalError ((const char *) "expecting both operands to be of type COMPLEX", 45);
2372 : : }
2373 : 0 : }
2374 : :
2375 : :
2376 : : /*
2377 : : AreSetsEqual - returns TRUE if sets, op1, and, op2, contain the same
2378 : : members.
2379 : : */
2380 : :
2381 : 0 : static bool AreSetsEqual (unsigned int tokenno, M2ALU_PtrToValue op1, M2ALU_PtrToValue op2)
2382 : : {
2383 : 0 : unsigned int low1;
2384 : 0 : unsigned int low2;
2385 : 0 : unsigned int high1;
2386 : 0 : unsigned int high2;
2387 : 0 : unsigned int i;
2388 : :
2389 : 0 : i = 1;
2390 : 0 : Eval (tokenno, op1);
2391 : 0 : Eval (tokenno, op2);
2392 : 0 : if (! (op1->solved && op2->solved))
2393 : : {
2394 : 0 : M2Error_InternalError ((const char *) "can only compare set values when they are known", 47);
2395 : : }
2396 : 0 : for (;;)
2397 : : {
2398 : 0 : if (M2ALU_GetRange (op1, i, &low1, &high1))
2399 : : {
2400 : 0 : if (M2ALU_GetRange (op2, i, &low2, &high2))
2401 : : {
2402 : 0 : SymbolTable_PushValue (low1);
2403 : 0 : SymbolTable_PushValue (low2);
2404 : 0 : if (M2ALU_NotEqu (tokenno))
2405 : : {
2406 : : return false;
2407 : : }
2408 : 0 : SymbolTable_PushValue (high1);
2409 : 0 : SymbolTable_PushValue (high2);
2410 : 0 : if (M2ALU_NotEqu (tokenno))
2411 : : {
2412 : : return false;
2413 : : }
2414 : 0 : i += 1;
2415 : : }
2416 : : else
2417 : : {
2418 : : /* op2 is out of ranges, but op1 still has >= 1 range left */
2419 : : return false;
2420 : : }
2421 : : }
2422 : : else
2423 : : {
2424 : 0 : if (M2ALU_GetRange (op2, i, &low2, &high2))
2425 : : {
2426 : : /* op1 is out of ranges, but op2 still has >= 1 range left */
2427 : : return false;
2428 : : }
2429 : : else
2430 : : {
2431 : : /* both out of ranges and they were the same */
2432 : : return true;
2433 : : }
2434 : : }
2435 : : }
2436 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2ALU.def", 20, 1);
2437 : : __builtin_unreachable ();
2438 : : }
2439 : :
2440 : :
2441 : : /*
2442 : : IsSubset - returns TRUE if the set as defined by, s1, is a subset of set, s2.
2443 : : */
2444 : :
2445 : 0 : static bool IsSubset (unsigned int tokenno, M2ALU_PtrToValue s1, M2ALU_PtrToValue s2)
2446 : : {
2447 : 0 : Push (s1);
2448 : 0 : Push (s2);
2449 : 0 : M2ALU_SetAnd (tokenno);
2450 : 0 : Push (s1);
2451 : 0 : return M2ALU_Equ (tokenno);
2452 : : /* static analysis guarentees a RETURN statement will be used before here. */
2453 : : __builtin_unreachable ();
2454 : : }
2455 : :
2456 : :
2457 : : /*
2458 : : IsSuperset - returns TRUE if the set as defined by, s1, is a superset of set, s2.
2459 : : */
2460 : :
2461 : 0 : static bool IsSuperset (unsigned int tokenno, M2ALU_PtrToValue s1, M2ALU_PtrToValue s2)
2462 : : {
2463 : 0 : M2ALU_PushFrom (s1);
2464 : 0 : M2ALU_PushFrom (s2);
2465 : 0 : M2ALU_SetAnd (tokenno);
2466 : 0 : M2ALU_PushFrom (s2);
2467 : 0 : return M2ALU_Equ (tokenno);
2468 : : /* static analysis guarentees a RETURN statement will be used before here. */
2469 : : __builtin_unreachable ();
2470 : : }
2471 : :
2472 : :
2473 : : /*
2474 : : cellTypeString - returns a string corresponding to, s.
2475 : : */
2476 : :
2477 : 0 : static DynamicStrings_String cellTypeString (M2ALU_cellType s)
2478 : : {
2479 : 0 : switch (s)
2480 : : {
2481 : 0 : case M2ALU_none:
2482 : 0 : return DynamicStrings_InitString ((const char *) "none", 4);
2483 : 0 : break;
2484 : :
2485 : 0 : case M2ALU_integer:
2486 : 0 : return DynamicStrings_InitString ((const char *) "integer", 7);
2487 : 0 : break;
2488 : :
2489 : 0 : case M2ALU_real:
2490 : 0 : return DynamicStrings_InitString ((const char *) "real", 4);
2491 : 0 : break;
2492 : :
2493 : 0 : case M2ALU_complex:
2494 : 0 : return DynamicStrings_InitString ((const char *) "complex", 7);
2495 : 0 : break;
2496 : :
2497 : 0 : case M2ALU_set:
2498 : 0 : return DynamicStrings_InitString ((const char *) "set", 3);
2499 : 0 : break;
2500 : :
2501 : 0 : case M2ALU_constructor:
2502 : 0 : return DynamicStrings_InitString ((const char *) "constructor", 11);
2503 : 0 : break;
2504 : :
2505 : 0 : case M2ALU_array:
2506 : 0 : return DynamicStrings_InitString ((const char *) "array", 5);
2507 : 0 : break;
2508 : :
2509 : 0 : case M2ALU_record:
2510 : 0 : return DynamicStrings_InitString ((const char *) "record", 6);
2511 : 0 : break;
2512 : :
2513 : :
2514 : 0 : default:
2515 : 0 : M2Error_InternalError ((const char *) "unexpected value of s", 21);
2516 : : break;
2517 : : }
2518 : : return static_cast<DynamicStrings_String> (NULL);
2519 : : /* static analysis guarentees a RETURN statement will be used before here. */
2520 : : __builtin_unreachable ();
2521 : : }
2522 : :
2523 : :
2524 : : /*
2525 : : ToSetValue - converts a list of fields into a list of ranges.
2526 : : In effect it turns a generic constructor into
2527 : : a set type.
2528 : : */
2529 : :
2530 : 17398 : static M2ALU_listOfRange ToSetValue (M2ALU_listOfFields f)
2531 : : {
2532 : 17398 : M2ALU_listOfFields g;
2533 : 17398 : M2ALU_listOfRange r;
2534 : 17398 : M2ALU_listOfRange s;
2535 : :
2536 : 17398 : g = f;
2537 : 17398 : r = NULL;
2538 : 17398 : while (f != NULL)
2539 : : {
2540 : 0 : NewRange (&s);
2541 : 0 : s->low = f->field;
2542 : 0 : s->high = s->low;
2543 : 0 : s->next = r;
2544 : 0 : if (r == NULL)
2545 : : {
2546 : 0 : r = s;
2547 : : }
2548 : 0 : f = f->next;
2549 : : }
2550 : 17398 : DisposeFields (&g);
2551 : 17398 : return r;
2552 : : /* static analysis guarentees a RETURN statement will be used before here. */
2553 : : __builtin_unreachable ();
2554 : : }
2555 : :
2556 : :
2557 : : /*
2558 : : ToArrayValue - converts a list of fields into an array initialiser.
2559 : : In effect it turns a generic constructor into
2560 : : an array type.
2561 : : */
2562 : :
2563 : 806 : static M2ALU_listOfElements ToArrayValue (unsigned int tok, M2ALU_listOfFields f)
2564 : : {
2565 : 806 : M2ALU_listOfFields g;
2566 : 806 : M2ALU_listOfElements r;
2567 : 806 : M2ALU_listOfElements s;
2568 : :
2569 : 806 : g = f;
2570 : 806 : r = NULL;
2571 : 806 : while (f != NULL)
2572 : : {
2573 : 0 : NewElement (&s);
2574 : 0 : s->element = f->field;
2575 : 0 : s->by = SymbolTable_MakeConstLit (tok, NameKey_MakeKey ((const char *) "1", 1), M2Base_ZType);
2576 : 0 : s->next = r;
2577 : 0 : if (r == NULL)
2578 : : {
2579 : 0 : r = s;
2580 : : }
2581 : 0 : f = f->next;
2582 : : }
2583 : 806 : DisposeFields (&g);
2584 : 806 : return r;
2585 : : /* static analysis guarentees a RETURN statement will be used before here. */
2586 : : __builtin_unreachable ();
2587 : : }
2588 : :
2589 : :
2590 : : /*
2591 : : CoerseTo - attempts to coerses a cellType, v, into, type, t.
2592 : : Normally this will be a generic constructors converting
2593 : : into set or array.
2594 : : */
2595 : :
2596 : 43969 : static M2ALU_PtrToValue CoerseTo (unsigned int tokenno, M2ALU_cellType t, M2ALU_PtrToValue v)
2597 : : {
2598 : 43969 : DynamicStrings_String s1;
2599 : 43969 : DynamicStrings_String s2;
2600 : 43969 : DynamicStrings_String s3;
2601 : :
2602 : 43969 : if (t == v->type)
2603 : : {
2604 : : return v;
2605 : : }
2606 : 20462 : else if ((v->type == M2ALU_constructor) && (t == M2ALU_set))
2607 : : {
2608 : : /* avoid dangling else. */
2609 : 17398 : v->type = M2ALU_set;
2610 : 17398 : v->setValue = ToSetValue (v->fieldValues);
2611 : 17398 : return v;
2612 : : }
2613 : 3064 : else if ((v->type == M2ALU_constructor) && (t == M2ALU_array))
2614 : : {
2615 : : /* avoid dangling else. */
2616 : 806 : v->type = M2ALU_array;
2617 : 806 : v->arrayValues = ToArrayValue (tokenno, v->fieldValues);
2618 : 806 : return v;
2619 : : }
2620 : 2258 : else if ((v->type == M2ALU_constructor) && (t == M2ALU_record))
2621 : : {
2622 : : /* avoid dangling else. */
2623 : : /* nothing to do other than change tag */
2624 : 2258 : v->type = M2ALU_record;
2625 : 2258 : return v;
2626 : : }
2627 : : else
2628 : : {
2629 : : /* avoid dangling else. */
2630 : 0 : s1 = cellTypeString (t);
2631 : 0 : s2 = cellTypeString (v->type);
2632 : 0 : s3 = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "cannot mix construction of a ", 29), DynamicStrings_Mark (DynamicStrings_ConCat (DynamicStrings_Mark (s1), DynamicStrings_Mark (DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) " with a ", 8), DynamicStrings_Mark (s2))))));
2633 : 0 : M2MetaError_MetaErrorStringT0 (tokenno, s3);
2634 : 0 : return v;
2635 : : }
2636 : : /* static analysis guarentees a RETURN statement will be used before here. */
2637 : : __builtin_unreachable ();
2638 : : }
2639 : :
2640 : :
2641 : : /*
2642 : : AddElementToEnd - appends, e, to the end of list, v.
2643 : : */
2644 : :
2645 : 4202 : static void AddElementToEnd (M2ALU_PtrToValue v, M2ALU_listOfElements e)
2646 : : {
2647 : 4202 : M2ALU_listOfElements a;
2648 : :
2649 : 0 : if (v->arrayValues == NULL)
2650 : : {
2651 : 466 : v->arrayValues = e;
2652 : : }
2653 : : else
2654 : : {
2655 : : a = v->arrayValues;
2656 : 51888 : while (a->next != NULL)
2657 : : {
2658 : : a = a->next;
2659 : : }
2660 : 3736 : a->next = e;
2661 : : }
2662 : 0 : }
2663 : :
2664 : :
2665 : : /*
2666 : : AddFieldToEnd - appends, f, to the end of list, v.
2667 : : */
2668 : :
2669 : 9432 : static void AddFieldToEnd (M2ALU_PtrToValue v, M2ALU_listOfFields f)
2670 : : {
2671 : 9432 : M2ALU_listOfFields a;
2672 : :
2673 : 0 : if (v->fieldValues == NULL)
2674 : : {
2675 : 2258 : v->fieldValues = f;
2676 : : }
2677 : : else
2678 : : {
2679 : : a = v->fieldValues;
2680 : 16242 : while (a->next != NULL)
2681 : : {
2682 : : a = a->next;
2683 : : }
2684 : 7174 : a->next = f;
2685 : : }
2686 : 0 : }
2687 : :
2688 : :
2689 : : /*
2690 : : ElementsSolved - returns TRUE if all ranges in the set have been solved.
2691 : : */
2692 : :
2693 : 7518 : static bool ElementsSolved (unsigned int tokenno, M2ALU_listOfRange r)
2694 : : {
2695 : 18657 : while (r != NULL)
2696 : : {
2697 : 11163 : if (! (SymbolTable_IsConst (r->low)))
2698 : : {
2699 : 0 : M2MetaError_MetaErrorT1 (tokenno, (const char *) "a constant set can only contain constant set elements, {%1Ead} is not a constant", 80, r->low);
2700 : : }
2701 : 11163 : if ((r->high != r->low) && (! (SymbolTable_IsConst (r->high))))
2702 : : {
2703 : 6 : M2MetaError_MetaErrorT1 (tokenno, (const char *) "a constant set can only contain constant set elements, {%1Ead} is not a constant", 80, r->high);
2704 : : }
2705 : 11163 : if (! ((IsSolvedGCC (r->low)) && (IsSolvedGCC (r->high))))
2706 : : {
2707 : 18 : return false;
2708 : : }
2709 : 11139 : r = r->next;
2710 : : }
2711 : : return true;
2712 : : /* static analysis guarentees a RETURN statement will be used before here. */
2713 : : __builtin_unreachable ();
2714 : : }
2715 : :
2716 : :
2717 : : /*
2718 : : ArrayElementsSolved - returns TRUE if all ranges in the set have been solved.
2719 : : */
2720 : :
2721 : 1558 : static bool ArrayElementsSolved (M2ALU_listOfElements e)
2722 : : {
2723 : 5706 : while (e != NULL)
2724 : : {
2725 : 5258 : if (! ((IsSolvedGCC (e->element)) && (IsSolvedGCC (e->by))))
2726 : : {
2727 : 1110 : return false;
2728 : : }
2729 : 4148 : e = e->next;
2730 : : }
2731 : : return true;
2732 : : /* static analysis guarentees a RETURN statement will be used before here. */
2733 : : __builtin_unreachable ();
2734 : : }
2735 : :
2736 : :
2737 : : /*
2738 : : EvalFieldValues - returns TRUE if all fields in the record have been solved.
2739 : : */
2740 : :
2741 : 2850 : static bool EvalFieldValues (M2ALU_listOfFields e)
2742 : : {
2743 : 12638 : while (e != NULL)
2744 : : {
2745 : 10398 : if (SymbolTable_IsConst (e->field))
2746 : : {
2747 : : /* avoid dangling else. */
2748 : 10254 : if (! (IsSolvedGCC (e->field)))
2749 : : {
2750 : : return false;
2751 : : }
2752 : : }
2753 : : /* RETURN( FALSE ) */
2754 : 9788 : e = e->next;
2755 : : }
2756 : : return true;
2757 : : /* static analysis guarentees a RETURN statement will be used before here. */
2758 : : __builtin_unreachable ();
2759 : : }
2760 : :
2761 : :
2762 : : /*
2763 : : Swap - swaps the contents of, i, and, j.
2764 : : */
2765 : :
2766 : 11599 : static void Swap (M2ALU_listOfRange i, M2ALU_listOfRange j)
2767 : : {
2768 : 11599 : unsigned int t;
2769 : :
2770 : 11599 : t = i->low;
2771 : 11599 : i->low = j->low;
2772 : 11599 : j->low = t;
2773 : 11599 : t = i->high;
2774 : 11599 : i->high = j->high;
2775 : 11599 : j->high = t;
2776 : 0 : }
2777 : :
2778 : :
2779 : : /*
2780 : : DisplayElements -
2781 : : */
2782 : :
2783 : 0 : static void DisplayElements (M2ALU_listOfRange i)
2784 : : {
2785 : 0 : while (i != NULL)
2786 : : {
2787 : 0 : SymbolTable_PushValue (i->low);
2788 : 0 : PrintValue ();
2789 : 0 : Reduce ();
2790 : 0 : SymbolTable_PushValue (i->high);
2791 : 0 : PrintValue ();
2792 : 0 : Reduce ();
2793 : 0 : i = i->next;
2794 : : }
2795 : 0 : }
2796 : :
2797 : :
2798 : : /*
2799 : : SortElements - sorts the list as defined by, h, into ascending range order.
2800 : : The low element is the sort key.
2801 : : */
2802 : :
2803 : 7706 : static void SortElements (unsigned int tokenno, M2ALU_listOfRange h)
2804 : : {
2805 : 7706 : M2ALU_listOfRange i;
2806 : 7706 : M2ALU_listOfRange j;
2807 : 7706 : M2ALU_listOfRange k;
2808 : :
2809 : 7706 : i = h;
2810 : 19305 : while (i != NULL)
2811 : : {
2812 : 11599 : j = i;
2813 : 11599 : k = i->next;
2814 : 28588 : while (k != NULL)
2815 : : {
2816 : 16989 : SymbolTable_PushValue (k->low);
2817 : 16989 : M2ALU_ConvertToInt ();
2818 : 16989 : SymbolTable_PushValue (j->low);
2819 : 16989 : M2ALU_ConvertToInt ();
2820 : 16989 : if (M2ALU_Less (tokenno))
2821 : : {
2822 : 5180 : j = k;
2823 : : }
2824 : 16989 : k = k->next;
2825 : : }
2826 : 11599 : Swap (i, j);
2827 : 11599 : i = i->next;
2828 : : }
2829 : 7706 : }
2830 : :
2831 : :
2832 : : /*
2833 : : CombineElements - given a sorted list determine whether there is any
2834 : : overlap in the low..high bounds. If overlap exists
2835 : : then remove it.
2836 : : */
2837 : :
2838 : 7706 : static void CombineElements (unsigned int tokenno, M2ALU_listOfRange r)
2839 : : {
2840 : 7706 : M2ALU_listOfRange t;
2841 : 7706 : M2ALU_listOfRange j;
2842 : :
2843 : 16219 : while (r != NULL)
2844 : : {
2845 : 8513 : j = r->next;
2846 : 13697 : while (j != NULL)
2847 : : {
2848 : 5184 : SymbolTable_PushValue (r->high);
2849 : 5184 : M2ALU_ConvertToInt ();
2850 : 5184 : M2ALU_PushCard (1);
2851 : 5184 : M2ALU_Addn ();
2852 : 5184 : SymbolTable_PushValue (j->low);
2853 : 5184 : M2ALU_ConvertToInt ();
2854 : 5184 : if (M2ALU_GreEqu (tokenno))
2855 : : {
2856 : 3086 : r->high = j->high;
2857 : 3086 : t = j->next;
2858 : 3086 : r->next = j->next;
2859 : 3086 : j->next = NULL;
2860 : 3086 : DisposeRange (&j);
2861 : 3086 : j = t;
2862 : : }
2863 : : else
2864 : : {
2865 : 2098 : j = NULL;
2866 : : }
2867 : : }
2868 : 8513 : r = r->next;
2869 : : }
2870 : 7706 : }
2871 : :
2872 : :
2873 : : /*
2874 : : EvalSetValues - returns TRUE if all elements in this set have been resolved.
2875 : : */
2876 : :
2877 : 7518 : static bool EvalSetValues (unsigned int tokenno, M2ALU_listOfRange r)
2878 : : {
2879 : 7518 : if (ElementsSolved (tokenno, r))
2880 : : {
2881 : 7494 : SortElements (tokenno, r);
2882 : 7494 : CombineElements (tokenno, r);
2883 : 7494 : return true;
2884 : : }
2885 : : else
2886 : : {
2887 : : return false;
2888 : : }
2889 : : /* static analysis guarentees a RETURN statement will be used before here. */
2890 : : __builtin_unreachable ();
2891 : : }
2892 : :
2893 : :
2894 : : /*
2895 : : Eval - attempts to solve a constructor type.
2896 : : */
2897 : :
2898 : 28853 : static void Eval (unsigned int tokenno, M2ALU_PtrToValue v)
2899 : : {
2900 : 28853 : CheckNotAlreadyOnFreeList (v);
2901 : 28853 : if (! v->solved)
2902 : : {
2903 : 12598 : if (SymbolTable_IsSet (SymbolTable_SkipType (v->constructorType)))
2904 : : {
2905 : 7686 : v = CoerseTo (tokenno, M2ALU_set, v);
2906 : : }
2907 : 4912 : else if (SymbolTable_IsRecord (SymbolTable_SkipType (v->constructorType)))
2908 : : {
2909 : : /* avoid dangling else. */
2910 : 2850 : v = CoerseTo (tokenno, M2ALU_record, v);
2911 : : }
2912 : 2062 : else if (SymbolTable_IsArray (SymbolTable_SkipType (v->constructorType)))
2913 : : {
2914 : : /* avoid dangling else. */
2915 : 2062 : v = CoerseTo (tokenno, M2ALU_array, v);
2916 : : }
2917 : 12598 : v->areAllConstants = DefinedByConstants (v);
2918 : 12598 : switch (v->type)
2919 : : {
2920 : 7686 : case M2ALU_set:
2921 : 15372 : M2Debug_Assert ((v->constructorType == SymbolTable_NulSym) || (SymbolTable_IsSet (SymbolTable_SkipType (v->constructorType))));
2922 : 7686 : v->solved = (M2GCCDeclare_CompletelyResolved (v->constructorType)) && (EvalSetValues (tokenno, v->setValue));
2923 : 7680 : break;
2924 : :
2925 : 2062 : case M2ALU_array:
2926 : 4124 : M2Debug_Assert ((v->constructorType == SymbolTable_NulSym) || (SymbolTable_IsArray (SymbolTable_SkipType (v->constructorType))));
2927 : 2062 : v->solved = (M2GCCDeclare_CompletelyResolved (v->constructorType)) && (ArrayElementsSolved (v->arrayValues));
2928 : 2062 : break;
2929 : :
2930 : 2850 : case M2ALU_record:
2931 : 5700 : M2Debug_Assert ((v->constructorType == SymbolTable_NulSym) || (SymbolTable_IsRecord (SymbolTable_SkipType (v->constructorType))));
2932 : 2850 : v->solved = (M2GCCDeclare_CompletelyResolved (v->constructorType)) && (EvalFieldValues (v->fieldValues));
2933 : 2850 : break;
2934 : :
2935 : :
2936 : : default:
2937 : : break;
2938 : : }
2939 : : }
2940 : : /* do nothing */
2941 : 28847 : }
2942 : :
2943 : :
2944 : : /*
2945 : : WalkSetValueDependants -
2946 : : */
2947 : :
2948 : 64923 : static void WalkSetValueDependants (M2ALU_listOfRange r, M2GCCDeclare_WalkAction p)
2949 : : {
2950 : 141967 : while (r != NULL)
2951 : : {
2952 : 77044 : (*p.proc) (r->low);
2953 : 77044 : (*p.proc) (r->high);
2954 : 77044 : r = r->next;
2955 : : }
2956 : 64923 : }
2957 : :
2958 : :
2959 : : /*
2960 : : IsSetValueDependants -
2961 : : */
2962 : :
2963 : 7814 : static bool IsSetValueDependants (M2ALU_listOfRange r, M2GCCDeclare_IsAction q)
2964 : : {
2965 : 7814 : bool result;
2966 : :
2967 : 7814 : result = true;
2968 : 16953 : while (r != NULL)
2969 : : {
2970 : 9139 : if (! ((*q.proc) (r->low)))
2971 : : {
2972 : 708 : result = false;
2973 : : }
2974 : 9139 : if (! ((*q.proc) (r->high)))
2975 : : {
2976 : 708 : result = false;
2977 : : }
2978 : 9139 : r = r->next;
2979 : : }
2980 : 7814 : return result;
2981 : : /* static analysis guarentees a RETURN statement will be used before here. */
2982 : : __builtin_unreachable ();
2983 : : }
2984 : :
2985 : :
2986 : : /*
2987 : : WalkFieldValueDependants -
2988 : : */
2989 : :
2990 : 101308 : static void WalkFieldValueDependants (M2ALU_listOfFields f, M2GCCDeclare_WalkAction p)
2991 : : {
2992 : 543544 : while (f != NULL)
2993 : : {
2994 : 442236 : (*p.proc) (f->field);
2995 : 442236 : f = f->next;
2996 : : }
2997 : 0 : }
2998 : :
2999 : :
3000 : : /*
3001 : : IsFieldValueDependants -
3002 : : */
3003 : :
3004 : 6294 : static bool IsFieldValueDependants (M2ALU_listOfFields f, M2GCCDeclare_IsAction q)
3005 : : {
3006 : 6294 : bool result;
3007 : :
3008 : 6294 : result = true;
3009 : 28806 : while (f != NULL)
3010 : : {
3011 : 22512 : if (! ((*q.proc) (f->field)))
3012 : : {
3013 : 9188 : result = false;
3014 : : }
3015 : 22512 : f = f->next;
3016 : : }
3017 : 6294 : return result;
3018 : : /* static analysis guarentees a RETURN statement will be used before here. */
3019 : : __builtin_unreachable ();
3020 : : }
3021 : :
3022 : :
3023 : : /*
3024 : : WalkArrayValueDependants -
3025 : : */
3026 : :
3027 : 18774 : static void WalkArrayValueDependants (M2ALU_listOfElements a, M2GCCDeclare_WalkAction p)
3028 : : {
3029 : 215582 : while (a != NULL)
3030 : : {
3031 : 196808 : (*p.proc) (a->element);
3032 : 196808 : (*p.proc) (a->by);
3033 : 196808 : a = a->next;
3034 : : }
3035 : 18774 : }
3036 : :
3037 : :
3038 : : /*
3039 : : IsArrayValueDependants -
3040 : : */
3041 : :
3042 : 2562 : static bool IsArrayValueDependants (M2ALU_listOfElements a, M2GCCDeclare_IsAction q)
3043 : : {
3044 : 2562 : bool result;
3045 : :
3046 : 2562 : result = true;
3047 : 41318 : while (a != NULL)
3048 : : {
3049 : 38756 : if (! ((*q.proc) (a->element)))
3050 : : {
3051 : 32334 : result = false;
3052 : : }
3053 : 38756 : if (! ((*q.proc) (a->by)))
3054 : : {
3055 : 30708 : result = false;
3056 : : }
3057 : 38756 : a = a->next;
3058 : : }
3059 : 2562 : return result;
3060 : : /* static analysis guarentees a RETURN statement will be used before here. */
3061 : : __builtin_unreachable ();
3062 : : }
3063 : :
3064 : :
3065 : : /*
3066 : : DefinedByConstants - returns TRUE if the value, v, is defined by constants.
3067 : : It assigns, v^.areAllConstants, with the result.
3068 : : */
3069 : :
3070 : 12598 : static bool DefinedByConstants (M2ALU_PtrToValue v)
3071 : : {
3072 : 12598 : switch (v->type)
3073 : : {
3074 : 0 : case M2ALU_none:
3075 : 0 : case M2ALU_integer:
3076 : 0 : case M2ALU_real:
3077 : 0 : case M2ALU_complex:
3078 : 0 : v->areAllConstants = true;
3079 : 0 : break;
3080 : :
3081 : 7686 : case M2ALU_set:
3082 : 7686 : v->areAllConstants = rangeConstant (v->setValue);
3083 : 7686 : break;
3084 : :
3085 : 2850 : case M2ALU_constructor:
3086 : 2850 : case M2ALU_record:
3087 : 2850 : v->areAllConstants = fieldsConstant (v->fieldValues);
3088 : 2850 : break;
3089 : :
3090 : 2062 : case M2ALU_array:
3091 : 2062 : v->areAllConstants = arrayConstant (v->arrayValues);
3092 : 2062 : break;
3093 : :
3094 : :
3095 : 0 : default:
3096 : 0 : M2Error_InternalError ((const char *) "unexpected type", 15);
3097 : 12598 : break;
3098 : : }
3099 : 12598 : return v->areAllConstants;
3100 : : /* static analysis guarentees a RETURN statement will be used before here. */
3101 : : __builtin_unreachable ();
3102 : : }
3103 : :
3104 : :
3105 : : /*
3106 : : rangeConstant - returns TRUE if all the range entities are constant.
3107 : : */
3108 : :
3109 : 7686 : static bool rangeConstant (M2ALU_listOfRange r)
3110 : : {
3111 : 19149 : while (r != NULL)
3112 : : {
3113 : 11469 : if ((! (SymbolTable_IsConst (r->low))) || (! (SymbolTable_IsConst (r->high))))
3114 : : {
3115 : 6 : return false;
3116 : : }
3117 : 11463 : r = r->next;
3118 : : }
3119 : : return true;
3120 : : /* static analysis guarentees a RETURN statement will be used before here. */
3121 : : __builtin_unreachable ();
3122 : : }
3123 : :
3124 : :
3125 : : /*
3126 : : fieldsConstant - returns TRUE if all the field entities are constant.
3127 : : */
3128 : :
3129 : 2850 : static bool fieldsConstant (M2ALU_listOfFields f)
3130 : : {
3131 : 13344 : while (f != NULL)
3132 : : {
3133 : 10566 : if (! (SymbolTable_IsConst (f->field)))
3134 : : {
3135 : : return false;
3136 : : }
3137 : 10494 : f = f->next;
3138 : : }
3139 : : return true;
3140 : : /* static analysis guarentees a RETURN statement will be used before here. */
3141 : : __builtin_unreachable ();
3142 : : }
3143 : :
3144 : :
3145 : : /*
3146 : : arrayConstant - returns TRUE if the, element, and, by, components
3147 : : of an array constructor are constant.
3148 : : */
3149 : :
3150 : 2062 : static bool arrayConstant (M2ALU_listOfElements e)
3151 : : {
3152 : 35016 : while (e != NULL)
3153 : : {
3154 : 32954 : if ((! (SymbolTable_IsConst (e->element))) && (! (SymbolTable_IsConst (e->by))))
3155 : : {
3156 : : return false;
3157 : : }
3158 : 32954 : e = e->next;
3159 : : }
3160 : : return true;
3161 : : /* static analysis guarentees a RETURN statement will be used before here. */
3162 : : __builtin_unreachable ();
3163 : : }
3164 : :
3165 : :
3166 : : /*
3167 : : FindValueEnum -
3168 : : */
3169 : :
3170 : 0 : static void FindValueEnum (unsigned int field)
3171 : : {
3172 : 0 : SymbolTable_PushValue (field);
3173 : 0 : M2ALU_PushIntegerTree (EnumerationValue);
3174 : 0 : if (M2ALU_Equ (CurrentTokenNo))
3175 : : {
3176 : 0 : EnumerationField = static_cast<unsigned int> (field);
3177 : : }
3178 : 0 : }
3179 : :
3180 : :
3181 : : /*
3182 : : Val - returns a GCC symbol enumeration or a GCC constant which has, value, and which is
3183 : : of type, type.
3184 : : */
3185 : :
3186 : 24 : static unsigned int Val (unsigned int tokenno, unsigned int type, m2tree_Tree value)
3187 : : {
3188 : 24 : unsigned int sym;
3189 : :
3190 : 24 : if (SymbolTable_IsEnumeration (type))
3191 : : {
3192 : 0 : EnumerationField = SymbolTable_NulSym;
3193 : 0 : EnumerationValue = value;
3194 : 0 : CurrentTokenNo = tokenno;
3195 : 0 : SymbolTable_ForeachFieldEnumerationDo (type, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) FindValueEnum});
3196 : 0 : if (EnumerationField == SymbolTable_NulSym)
3197 : : {
3198 : 0 : M2Error_InternalError ((const char *) "enumeration value exceeds range", 31);
3199 : : }
3200 : : return EnumerationField;
3201 : : }
3202 : : else
3203 : : {
3204 : 24 : sym = SymbolTable_MakeTemporary (tokenno, SymbolTable_ImmediateValue);
3205 : 24 : SymbolTable_PutVar (sym, type);
3206 : 24 : CheckOverflow (tokenno, value);
3207 : 24 : M2ALU_PushIntegerTree (value);
3208 : 24 : SymbolTable_PopValue (sym);
3209 : 24 : return sym;
3210 : : }
3211 : : /* static analysis guarentees a RETURN statement will be used before here. */
3212 : : __builtin_unreachable ();
3213 : : }
3214 : :
3215 : :
3216 : : /*
3217 : : DupConst - duplicates and returns a constant, sym, but adds, offset to its value.
3218 : : */
3219 : :
3220 : 24 : static unsigned int DupConst (unsigned int tokenno, unsigned int sym, int offset)
3221 : : {
3222 : 24 : SymbolTable_PushValue (sym);
3223 : 24 : M2ALU_PushInt (offset);
3224 : 24 : M2ALU_Addn ();
3225 : 24 : return Val (tokenno, SymbolTable_GetType (sym), M2ALU_PopIntegerTree ());
3226 : : /* static analysis guarentees a RETURN statement will be used before here. */
3227 : : __builtin_unreachable ();
3228 : : }
3229 : :
3230 : :
3231 : : /*
3232 : : DupConstAndAdd - duplicates and returns a constant, sym,
3233 : : but adds the symbol, extra.
3234 : : */
3235 : :
3236 : 0 : static unsigned int DupConstAndAdd (unsigned int tokenno, unsigned int sym, m2tree_Tree extra)
3237 : : {
3238 : 0 : SymbolTable_PushValue (sym);
3239 : 0 : M2ALU_PushIntegerTree (extra);
3240 : 0 : M2ALU_Addn ();
3241 : 0 : return Val (tokenno, SymbolTable_GetType (sym), M2ALU_PopIntegerTree ());
3242 : : /* static analysis guarentees a RETURN statement will be used before here. */
3243 : : __builtin_unreachable ();
3244 : : }
3245 : :
3246 : :
3247 : : /*
3248 : : DupConstAndAddMod - duplicates and returns a constant, sym,
3249 : : but adds the symbol, extra, and ensures that
3250 : : the result in within limits: min..max using
3251 : : modulo arithmetic.
3252 : : */
3253 : :
3254 : 0 : static unsigned int DupConstAndAddMod (unsigned int tokenno, unsigned int sym, m2tree_Tree extra, unsigned int l, unsigned int h)
3255 : : {
3256 : : /* result := (((sym-l) + extra) MOD (h-l)) + l) */
3257 : 0 : SymbolTable_PushValue (sym);
3258 : 0 : SymbolTable_PushValue (l);
3259 : 0 : M2ALU_Sub ();
3260 : 0 : M2ALU_PushIntegerTree (extra);
3261 : 0 : M2ALU_Addn ();
3262 : 0 : SymbolTable_PushValue (h);
3263 : 0 : SymbolTable_PushValue (l);
3264 : 0 : M2ALU_Sub ();
3265 : 0 : M2ALU_ModTrunc ();
3266 : 0 : SymbolTable_PushValue (l);
3267 : 0 : M2ALU_Addn ();
3268 : 0 : return Val (tokenno, SymbolTable_GetType (sym), M2ALU_PopIntegerTree ());
3269 : : /* static analysis guarentees a RETURN statement will be used before here. */
3270 : : __builtin_unreachable ();
3271 : : }
3272 : :
3273 : :
3274 : : /*
3275 : : Remove - removes, v, from list, h.
3276 : : */
3277 : :
3278 : 0 : static void Remove (M2ALU_listOfRange *h, M2ALU_listOfRange v)
3279 : : {
3280 : 0 : M2ALU_listOfRange i;
3281 : :
3282 : 0 : if ((*h) == v)
3283 : : {
3284 : 0 : (*h) = (*h)->next;
3285 : : }
3286 : : else
3287 : : {
3288 : : i = (*h);
3289 : 0 : while ((i != NULL) && (i->next != v))
3290 : : {
3291 : : i = i->next;
3292 : : }
3293 : 0 : if (i == NULL)
3294 : : {
3295 : 0 : M2Error_InternalError ((const char *) "expecting v to be on the list", 29);
3296 : : }
3297 : : else
3298 : : {
3299 : 0 : i = v->next;
3300 : : }
3301 : : }
3302 : 0 : v->next = NULL;
3303 : 0 : DisposeRange (&v);
3304 : 0 : }
3305 : :
3306 : :
3307 : : /*
3308 : : RemoveBit - remove bit, op1, from range, v, on list, h.
3309 : : */
3310 : :
3311 : 0 : static void RemoveBit (unsigned int tokenno, M2ALU_listOfRange *h, M2ALU_listOfRange v, unsigned int op1)
3312 : : {
3313 : 0 : SymbolTable_PushValue (v->low);
3314 : 0 : SymbolTable_PushValue (v->high);
3315 : 0 : if (M2ALU_Equ (tokenno))
3316 : : {
3317 : : /* avoid dangling else. */
3318 : : /* single bit in this range */
3319 : 0 : SymbolTable_PushValue (v->low);
3320 : 0 : SymbolTable_PushValue (op1);
3321 : 0 : if (M2ALU_Equ (tokenno))
3322 : : {
3323 : : /* remove entry */
3324 : 0 : Remove (h, v);
3325 : 0 : return ;
3326 : : }
3327 : : }
3328 : : else
3329 : : {
3330 : : /* is op1 equal to low? */
3331 : 0 : SymbolTable_PushValue (op1);
3332 : 0 : SymbolTable_PushValue (v->low);
3333 : 0 : if (M2ALU_Equ (tokenno))
3334 : : {
3335 : 0 : v->low = DupConst (tokenno, v->low, 1);
3336 : : }
3337 : : else
3338 : : {
3339 : 0 : SymbolTable_PushValue (op1);
3340 : 0 : SymbolTable_PushValue (v->high);
3341 : 0 : if (M2ALU_Equ (tokenno))
3342 : : {
3343 : 0 : v->high = DupConst (tokenno, v->high, -1);
3344 : : }
3345 : : else
3346 : : {
3347 : 0 : v->high = DupConst (tokenno, op1, -1);
3348 : 0 : (*h) = AddRange ((*h), DupConst (tokenno, op1, 1), v->high);
3349 : 0 : SortElements (tokenno, (*h));
3350 : : }
3351 : : }
3352 : : }
3353 : : }
3354 : :
3355 : :
3356 : : /*
3357 : : PerformSubBit -
3358 : : */
3359 : :
3360 : 0 : static void PerformSubBit (unsigned int tokenno, M2ALU_listOfRange *h, unsigned int op1)
3361 : : {
3362 : 0 : M2ALU_listOfRange v;
3363 : :
3364 : 0 : v = (*h);
3365 : 0 : while (v != NULL)
3366 : : {
3367 : 0 : SymbolTable_PushValue (v->low);
3368 : 0 : SymbolTable_PushValue (op1);
3369 : 0 : if (M2ALU_LessEqu (tokenno))
3370 : : {
3371 : 0 : SymbolTable_PushValue (op1);
3372 : 0 : SymbolTable_PushValue (v->high);
3373 : 0 : if (M2ALU_LessEqu (tokenno))
3374 : : {
3375 : 0 : RemoveBit (tokenno, h, v, op1);
3376 : 0 : return ;
3377 : : }
3378 : : }
3379 : 0 : v = v->next;
3380 : : }
3381 : : }
3382 : :
3383 : :
3384 : : /*
3385 : : PerformSetIn - returns TRUE if op1 is in set.
3386 : : */
3387 : :
3388 : 0 : static bool PerformSetIn (unsigned int tokenno, unsigned int op1, M2ALU_listOfRange h)
3389 : : {
3390 : 0 : while (h != NULL)
3391 : : {
3392 : 0 : SymbolTable_PushValue (op1);
3393 : 0 : M2ALU_ConvertToInt ();
3394 : 0 : SymbolTable_PushValue (h->low);
3395 : 0 : M2ALU_ConvertToInt ();
3396 : 0 : if (M2ALU_GreEqu (tokenno))
3397 : : {
3398 : : /* avoid dangling else. */
3399 : 0 : SymbolTable_PushValue (op1);
3400 : 0 : SymbolTable_PushValue (h->high);
3401 : 0 : if (M2ALU_LessEqu (tokenno))
3402 : : {
3403 : : return true;
3404 : : }
3405 : : }
3406 : : else
3407 : : {
3408 : : /* op1 is smaller than this and all subsequent ranges */
3409 : : return false;
3410 : : }
3411 : 0 : h = h->next;
3412 : : }
3413 : : return false;
3414 : : /* static analysis guarentees a RETURN statement will be used before here. */
3415 : : __builtin_unreachable ();
3416 : : }
3417 : :
3418 : :
3419 : : /*
3420 : : SetOp - perform the function doOp on the top two elements of the stack.
3421 : : */
3422 : :
3423 : 218 : static void SetOp (unsigned int tokenno, M2ALU_DoSetProcedure doOp)
3424 : : {
3425 : 218 : M2ALU_PtrToValue Result;
3426 : 218 : M2ALU_PtrToValue Set1;
3427 : 218 : M2ALU_PtrToValue Set2;
3428 : :
3429 : 218 : Set1 = Pop ();
3430 : 218 : Set2 = Pop ();
3431 : 218 : Eval (tokenno, Set1);
3432 : 218 : Eval (tokenno, Set2);
3433 : 218 : if (! (Set1->solved && Set2->solved))
3434 : : {
3435 : 0 : M2Error_InternalError ((const char *) "one or more operands have not been resolved", 43);
3436 : : }
3437 : 218 : if (Set1->type != M2ALU_set)
3438 : : {
3439 : 0 : M2Error_InternalError ((const char *) "expecting type of constant to be a set", 38);
3440 : : }
3441 : 218 : if (Set2->type != M2ALU_set)
3442 : : {
3443 : 0 : M2Error_InternalError ((const char *) "expecting type of constant to be a set", 38);
3444 : : }
3445 : 218 : Result = New ();
3446 : 218 : Result->type = M2ALU_set;
3447 : 218 : Result->setValue = static_cast<M2ALU_listOfRange> ((*doOp.proc) (tokenno, Set1->setValue, Set2->setValue));
3448 : 218 : Result->constructorType = M2Base_MixTypes (Set1->constructorType, Set2->constructorType, tokenno);
3449 : 218 : Result->solved = false;
3450 : : /* Set1 and Set2 have given their range lists to the Result */
3451 : 218 : Set1->setValue = NULL;
3452 : 218 : Set2->setValue = NULL;
3453 : 218 : Eval (tokenno, Result);
3454 : 218 : Push (Result);
3455 : 218 : Dispose (Set1);
3456 : 218 : Dispose (Set2);
3457 : 218 : }
3458 : :
3459 : :
3460 : : /*
3461 : : PerformOr - performs a logical OR between the two ranges.
3462 : : The ranges, r1, r2, are destroyed.
3463 : : */
3464 : :
3465 : 212 : static M2ALU_listOfRange PerformOr (unsigned int tokenno, M2ALU_listOfRange r1, M2ALU_listOfRange r2)
3466 : : {
3467 : 212 : M2ALU_listOfRange i;
3468 : :
3469 : 212 : i = r1;
3470 : 212 : while ((i != NULL) && (i->next != NULL))
3471 : : {
3472 : : i = i->next;
3473 : : }
3474 : 212 : if (i == NULL)
3475 : : {
3476 : : r1 = r2;
3477 : : }
3478 : : else
3479 : : {
3480 : 212 : i->next = r2;
3481 : : }
3482 : 212 : SortElements (tokenno, r1);
3483 : 212 : CombineElements (tokenno, r1);
3484 : 212 : return r1;
3485 : : /* static analysis guarentees a RETURN statement will be used before here. */
3486 : : __builtin_unreachable ();
3487 : : }
3488 : :
3489 : :
3490 : : /*
3491 : : Min - returns the symbol which has the least value.
3492 : : */
3493 : :
3494 : 6 : static unsigned int Min (unsigned int tokenno, unsigned int a, unsigned int b)
3495 : : {
3496 : 6 : SymbolTable_PushValue (a);
3497 : 6 : M2ALU_ConvertToInt ();
3498 : 6 : SymbolTable_PushValue (b);
3499 : 6 : M2ALU_ConvertToInt ();
3500 : 6 : if (M2ALU_Less (tokenno))
3501 : : {
3502 : : return a;
3503 : : }
3504 : : else
3505 : : {
3506 : 6 : return b;
3507 : : }
3508 : : /* static analysis guarentees a RETURN statement will be used before here. */
3509 : : __builtin_unreachable ();
3510 : : }
3511 : :
3512 : :
3513 : : /*
3514 : : Max - returns the symbol which has the greatest value.
3515 : : */
3516 : :
3517 : 6 : static unsigned int Max (unsigned int tokenno, unsigned int a, unsigned int b)
3518 : : {
3519 : 6 : SymbolTable_PushValue (a);
3520 : 6 : M2ALU_ConvertToInt ();
3521 : 6 : SymbolTable_PushValue (b);
3522 : 6 : M2ALU_ConvertToInt ();
3523 : 6 : if (M2ALU_Gre (tokenno))
3524 : : {
3525 : : return a;
3526 : : }
3527 : : else
3528 : : {
3529 : 6 : return b;
3530 : : }
3531 : : /* static analysis guarentees a RETURN statement will be used before here. */
3532 : : __builtin_unreachable ();
3533 : : }
3534 : :
3535 : :
3536 : : /*
3537 : : IsRangeIntersection - returns TRUE if ranges, r1, and, r2, intersect.
3538 : : */
3539 : :
3540 : 6 : static bool IsRangeIntersection (unsigned int tokenno, M2ALU_listOfRange r1, M2ALU_listOfRange r2)
3541 : : {
3542 : 6 : if ((r1 == NULL) || (r2 == NULL))
3543 : : {
3544 : : return false;
3545 : : }
3546 : : else
3547 : : {
3548 : : /* easier to prove NOT outside limits */
3549 : 6 : SymbolTable_PushValue (r1->low);
3550 : 6 : M2ALU_ConvertToInt ();
3551 : 6 : SymbolTable_PushValue (r2->high);
3552 : 6 : M2ALU_ConvertToInt ();
3553 : 6 : if (M2ALU_Gre (tokenno))
3554 : : {
3555 : : return false;
3556 : : }
3557 : : else
3558 : : {
3559 : 6 : SymbolTable_PushValue (r1->high);
3560 : 6 : M2ALU_ConvertToInt ();
3561 : 6 : SymbolTable_PushValue (r2->low);
3562 : 6 : M2ALU_ConvertToInt ();
3563 : 6 : if (M2ALU_Less (tokenno))
3564 : : {
3565 : : return false;
3566 : : }
3567 : : else
3568 : : {
3569 : : return true;
3570 : : }
3571 : : }
3572 : : }
3573 : : /* static analysis guarentees a RETURN statement will be used before here. */
3574 : : __builtin_unreachable ();
3575 : : }
3576 : :
3577 : :
3578 : : /*
3579 : : IsRangeLess - returns TRUE if r1^.low is < r2^.low
3580 : : */
3581 : :
3582 : 0 : static bool IsRangeLess (unsigned int tokenno, M2ALU_listOfRange r1, M2ALU_listOfRange r2)
3583 : : {
3584 : 0 : if ((r1 == NULL) || (r2 == NULL))
3585 : : {
3586 : 0 : M2Error_InternalError ((const char *) "not expecting NIL ranges", 24);
3587 : : }
3588 : 0 : SymbolTable_PushValue (r1->high);
3589 : 0 : M2ALU_ConvertToInt ();
3590 : 0 : SymbolTable_PushValue (r2->low);
3591 : 0 : M2ALU_ConvertToInt ();
3592 : 0 : return M2ALU_Less (tokenno);
3593 : : /* static analysis guarentees a RETURN statement will be used before here. */
3594 : : __builtin_unreachable ();
3595 : : }
3596 : :
3597 : :
3598 : : /*
3599 : : MinTree - returns the tree symbol which has the least value.
3600 : : */
3601 : :
3602 : 9063 : static m2tree_Tree MinTree (unsigned int tokenno, m2tree_Tree a, m2tree_Tree b)
3603 : : {
3604 : 9063 : M2ALU_PushIntegerTree (a);
3605 : 9063 : M2ALU_ConvertToInt ();
3606 : 9063 : M2ALU_PushIntegerTree (b);
3607 : 9063 : M2ALU_ConvertToInt ();
3608 : 9063 : if (M2ALU_Less (tokenno))
3609 : : {
3610 : : return a;
3611 : : }
3612 : : else
3613 : : {
3614 : 1036 : return b;
3615 : : }
3616 : : /* static analysis guarentees a RETURN statement will be used before here. */
3617 : : __builtin_unreachable ();
3618 : : }
3619 : :
3620 : :
3621 : : /*
3622 : : MaxTree - returns the symbol which has the greatest value.
3623 : : */
3624 : :
3625 : 9063 : static m2tree_Tree MaxTree (unsigned int tokenno, m2tree_Tree a, m2tree_Tree b)
3626 : : {
3627 : 9063 : M2ALU_PushIntegerTree (a);
3628 : 9063 : M2ALU_ConvertToInt ();
3629 : 9063 : M2ALU_PushIntegerTree (b);
3630 : 9063 : M2ALU_ConvertToInt ();
3631 : 9063 : if (M2ALU_Gre (tokenno))
3632 : : {
3633 : : return a;
3634 : : }
3635 : : else
3636 : : {
3637 : 1739 : return b;
3638 : : }
3639 : : /* static analysis guarentees a RETURN statement will be used before here. */
3640 : : __builtin_unreachable ();
3641 : : }
3642 : :
3643 : :
3644 : : /*
3645 : : IsIntersectionTree - returns TRUE if ranges, a..b, and, c..d, intersect.
3646 : : */
3647 : :
3648 : 38219 : static bool IsIntersectionTree (unsigned int tokenno, m2tree_Tree a, m2tree_Tree b, m2tree_Tree c, m2tree_Tree d)
3649 : : {
3650 : : /* easier to prove NOT outside limits */
3651 : 38219 : M2ALU_PushIntegerTree (a);
3652 : 38219 : M2ALU_ConvertToInt ();
3653 : 38219 : M2ALU_PushIntegerTree (d);
3654 : 38219 : M2ALU_ConvertToInt ();
3655 : 38219 : if (M2ALU_Gre (tokenno))
3656 : : {
3657 : : return false;
3658 : : }
3659 : : else
3660 : : {
3661 : 33063 : M2ALU_PushIntegerTree (b);
3662 : 33063 : M2ALU_ConvertToInt ();
3663 : 33063 : M2ALU_PushIntegerTree (c);
3664 : 33063 : M2ALU_ConvertToInt ();
3665 : 33063 : if (M2ALU_Less (tokenno))
3666 : : {
3667 : : return false;
3668 : : }
3669 : : else
3670 : : {
3671 : : return true;
3672 : : }
3673 : : }
3674 : : /* static analysis guarentees a RETURN statement will be used before here. */
3675 : : __builtin_unreachable ();
3676 : : }
3677 : :
3678 : :
3679 : : /*
3680 : : SubTree - returns the tree value containing (a-b)
3681 : : */
3682 : :
3683 : 18126 : static m2tree_Tree SubTree (m2tree_Tree a, m2tree_Tree b)
3684 : : {
3685 : 18126 : M2ALU_PushIntegerTree (a);
3686 : 18126 : M2ALU_PushIntegerTree (b);
3687 : 18126 : M2ALU_Sub ();
3688 : 18126 : return M2ALU_PopIntegerTree ();
3689 : : /* static analysis guarentees a RETURN statement will be used before here. */
3690 : : __builtin_unreachable ();
3691 : : }
3692 : :
3693 : :
3694 : : /*
3695 : : PerformAnd - performs a logical AND between the two ranges.
3696 : : The ranges, r1, r2, are unaltered.
3697 : : */
3698 : :
3699 : 6 : static M2ALU_listOfRange PerformAnd (unsigned int tokenno, M2ALU_listOfRange r1, M2ALU_listOfRange r2)
3700 : : {
3701 : 6 : M2ALU_listOfRange r;
3702 : :
3703 : 6 : r = NULL;
3704 : 12 : while ((r1 != NULL) && (r2 != NULL))
3705 : : {
3706 : 6 : if (IsRangeIntersection (tokenno, r1, r2))
3707 : : {
3708 : 6 : r = AddRange (r, Max (tokenno, r1->low, r2->low), Min (tokenno, r1->high, r2->high));
3709 : 6 : if (r->high == r1->high)
3710 : : {
3711 : 0 : r1 = r1->next;
3712 : : }
3713 : : else
3714 : : {
3715 : 6 : r2 = r2->next;
3716 : : }
3717 : : }
3718 : 0 : else if (IsRangeLess (tokenno, r1, r2))
3719 : : {
3720 : : /* avoid dangling else. */
3721 : : /* move r1 onto the next range */
3722 : 0 : r1 = r1->next;
3723 : : }
3724 : : else
3725 : : {
3726 : : /* avoid dangling else. */
3727 : : /* move r2 onto the next range */
3728 : 0 : r2 = r2->next;
3729 : : }
3730 : : }
3731 : 6 : return r;
3732 : : /* static analysis guarentees a RETURN statement will be used before here. */
3733 : : __builtin_unreachable ();
3734 : : }
3735 : :
3736 : :
3737 : : /*
3738 : : BuildStructBitset - v is the PtrToValue.
3739 : : low and high are the limits of the subrange.
3740 : : */
3741 : :
3742 : 1727 : static m2tree_Tree BuildStructBitset (unsigned int tokenno, M2ALU_PtrToValue v, m2tree_Tree low, m2tree_Tree high)
3743 : : {
3744 : 1727 : m2tree_Tree BitsInSet;
3745 : 1727 : unsigned int bpw;
3746 : 1727 : m2type_Constructor cons;
3747 : :
3748 : 1727 : M2ALU_PushIntegerTree (low);
3749 : 1727 : M2ALU_ConvertToInt ();
3750 : 1727 : low = M2ALU_PopIntegerTree ();
3751 : 1727 : M2ALU_PushIntegerTree (high);
3752 : 1727 : M2ALU_ConvertToInt ();
3753 : 1727 : high = M2ALU_PopIntegerTree ();
3754 : 1727 : bpw = m2decl_GetBitsPerBitset ();
3755 : 1727 : M2ALU_PushIntegerTree (high);
3756 : 1727 : M2ALU_PushIntegerTree (low);
3757 : 1727 : M2ALU_Sub ();
3758 : 1727 : M2ALU_PushCard (1);
3759 : 1727 : M2ALU_Addn ();
3760 : 1727 : BitsInSet = M2ALU_PopIntegerTree ();
3761 : 1727 : cons = m2type_BuildStartSetConstructor (SymbolConversion_Mod2Gcc (v->constructorType));
3762 : 1727 : M2ALU_PushIntegerTree (BitsInSet);
3763 : 1727 : M2ALU_PushCard (0);
3764 : 21740 : while (M2ALU_Gre (tokenno))
3765 : : {
3766 : 18286 : M2ALU_PushIntegerTree (BitsInSet);
3767 : 18286 : M2ALU_PushCard (bpw-1);
3768 : 18286 : if (M2ALU_GreEqu (tokenno))
3769 : : {
3770 : 18109 : M2ALU_PushIntegerTree (low);
3771 : 18109 : M2ALU_PushCard (bpw-1);
3772 : 18109 : M2ALU_Addn ();
3773 : 18109 : m2type_BuildSetConstructorElement (cons, BuildBitset (tokenno, v, low, M2ALU_PopIntegerTree ()));
3774 : 18109 : M2ALU_PushIntegerTree (low);
3775 : 18109 : M2ALU_PushCard (bpw);
3776 : 18109 : M2ALU_Addn ();
3777 : 18109 : low = M2ALU_PopIntegerTree ();
3778 : 18109 : M2ALU_PushIntegerTree (BitsInSet);
3779 : 18109 : M2ALU_PushCard (bpw);
3780 : 18109 : M2ALU_Sub ();
3781 : 18109 : BitsInSet = M2ALU_PopIntegerTree ();
3782 : : }
3783 : : else
3784 : : {
3785 : : /* printf2('range is %a..%a
3786 : : ', GetSymName(low), GetSymName(high)) ; */
3787 : 177 : m2type_BuildSetConstructorElement (cons, BuildBitset (tokenno, v, low, high));
3788 : 177 : M2ALU_PushCard (0);
3789 : 177 : BitsInSet = M2ALU_PopIntegerTree ();
3790 : : }
3791 : 18286 : M2ALU_PushIntegerTree (BitsInSet);
3792 : 18286 : M2ALU_PushCard (0);
3793 : : }
3794 : 1727 : return m2type_BuildEndSetConstructor (cons);
3795 : : /* static analysis guarentees a RETURN statement will be used before here. */
3796 : : __builtin_unreachable ();
3797 : : }
3798 : :
3799 : :
3800 : : /*
3801 : : ConstructLargeOrSmallSet - generates a constant representing the set value of the symbol, sym.
3802 : : We manufacture the constant by using a initialization
3803 : : structure of cardinals.
3804 : :
3805 : : { (cardinal), (cardinal) etc }
3806 : : */
3807 : :
3808 : 7940 : static m2tree_Tree ConstructLargeOrSmallSet (unsigned int tokenno, M2ALU_PtrToValue v, unsigned int low, unsigned int high)
3809 : : {
3810 : 7940 : SymbolTable_PushValue (high);
3811 : 7940 : M2ALU_ConvertToInt ();
3812 : 7940 : SymbolTable_PushValue (low);
3813 : 7940 : M2ALU_ConvertToInt ();
3814 : 7940 : M2ALU_Sub ();
3815 : 7940 : M2ALU_PushCard (static_cast<unsigned int> (m2decl_GetBitsPerBitset ()));
3816 : 7940 : if (M2ALU_Less (tokenno))
3817 : : {
3818 : : /* small set */
3819 : 6213 : return BuildBitset (tokenno, v, SymbolConversion_Mod2Gcc (low), SymbolConversion_Mod2Gcc (high));
3820 : : }
3821 : : else
3822 : : {
3823 : : /* large set */
3824 : 1727 : return BuildStructBitset (tokenno, v, SymbolConversion_Mod2Gcc (low), SymbolConversion_Mod2Gcc (high));
3825 : : }
3826 : : /* static analysis guarentees a RETURN statement will be used before here. */
3827 : : __builtin_unreachable ();
3828 : : }
3829 : :
3830 : :
3831 : : /*
3832 : : ConvertConstToType - returns a Tree containing an initialiser,
3833 : : init, ready to be assigned to a record or
3834 : : array constructor.
3835 : : */
3836 : :
3837 : 9624 : static m2tree_Tree ConvertConstToType (unsigned int tokenno, unsigned int field, unsigned int init)
3838 : : {
3839 : 9624 : m2tree_Tree initT;
3840 : 9624 : m2tree_Tree nBytes;
3841 : :
3842 : 9624 : if (((SymbolTable_IsConstString (init)) && (SymbolTable_IsArray (SymbolTable_SkipType (SymbolTable_GetType (field))))) && ((SymbolTable_SkipTypeAndSubrange (SymbolTable_GetType (SymbolTable_GetType (field)))) == M2Base_Char))
3843 : : {
3844 : 2700 : if (! (M2GenGCC_PrepareCopyString (tokenno, &nBytes, &initT, init, SymbolTable_GetType (field))))
3845 : : {
3846 : 0 : M2MetaError_MetaErrorT2 (tokenno, (const char *) "string constant {%1Ea} is too large to be assigned to the {%2d} {%2a}", 69, init, field);
3847 : : }
3848 : 2700 : return initT;
3849 : : }
3850 : : else
3851 : : {
3852 : 6924 : return m2convert_ConvertConstantAndCheck (M2LexBuf_TokenToLocation (tokenno), SymbolConversion_Mod2Gcc (SymbolTable_GetType (field)), SymbolConversion_Mod2Gcc (init));
3853 : : }
3854 : : /* static analysis guarentees a RETURN statement will be used before here. */
3855 : : __builtin_unreachable ();
3856 : : }
3857 : :
3858 : :
3859 : : /*
3860 : : ConstructRecordConstant - builds a struct initializer, as defined by, v.
3861 : : */
3862 : :
3863 : 2332 : static m2tree_Tree ConstructRecordConstant (unsigned int tokenno, M2ALU_PtrToValue v)
3864 : : {
3865 : 2332 : NameKey_Name n1;
3866 : 2332 : NameKey_Name n2;
3867 : 2332 : unsigned int i;
3868 : 2332 : unsigned int Field;
3869 : 2332 : unsigned int baseType;
3870 : 2332 : m2type_Constructor cons;
3871 : :
3872 : 2332 : if (v->constructorType == SymbolTable_NulSym)
3873 : : {
3874 : 0 : M2Error_InternalError ((const char *) "record type must be known in order to generate a constant", 57);
3875 : : }
3876 : : else
3877 : : {
3878 : 2332 : baseType = SymbolTable_SkipType (v->constructorType);
3879 : 2332 : if (Debugging)
3880 : : {
3881 : : n1 = SymbolTable_GetSymName (v->constructorType);
3882 : : n2 = SymbolTable_GetSymName (baseType);
3883 : : M2Printf_printf2 ((const char *) "ConstructRecordConstant of type %a and baseType %a\\n", 52, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
3884 : : }
3885 : 2332 : cons = m2type_BuildStartRecordConstructor (SymbolConversion_Mod2Gcc (baseType));
3886 : 2332 : i = 1;
3887 : 11956 : do {
3888 : 11956 : Field = SymbolTable_GetNth (baseType, i);
3889 : 11956 : if (Field != SymbolTable_NulSym)
3890 : : {
3891 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
3892 : 9624 : if (SymbolConversion_GccKnowsAbout (SymbolTable_GetType (Field)))
3893 : : {
3894 : 9624 : m2type_BuildRecordConstructorElement (cons, ConvertConstToType (tokenno, Field, GetConstructorField (v, i)));
3895 : : }
3896 : : else
3897 : : {
3898 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "trying to construct a compound literal and using a record field which does not exist", 84);
3899 : : }
3900 : : }
3901 : 11956 : i += 1;
3902 : 11956 : } while (! (Field == SymbolTable_NulSym));
3903 : 2332 : return m2type_BuildEndRecordConstructor (cons);
3904 : : }
3905 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2ALU.def", 20, 1);
3906 : : __builtin_unreachable ();
3907 : : }
3908 : :
3909 : :
3910 : : /*
3911 : : GetConstructorField - returns a symbol containing the constructor field, i.
3912 : : */
3913 : :
3914 : 9624 : static unsigned int GetConstructorField (M2ALU_PtrToValue v, unsigned int i)
3915 : : {
3916 : 9624 : unsigned int j;
3917 : 9624 : M2ALU_listOfFields f;
3918 : :
3919 : 9624 : if (v->type != M2ALU_record)
3920 : : {
3921 : 0 : M2Error_InternalError ((const char *) "constructor type must be a record in order to push a field", 58);
3922 : : }
3923 : : else
3924 : : {
3925 : 9624 : if (v->constructorType == SymbolTable_NulSym)
3926 : : {
3927 : 0 : M2Error_InternalError ((const char *) "constructor type must be a record in order to push a field", 58);
3928 : : }
3929 : : else
3930 : : {
3931 : 9624 : j = 1;
3932 : 9624 : f = v->fieldValues;
3933 : 26052 : while ((j < i) && (f != NULL))
3934 : : {
3935 : 16428 : f = f->next;
3936 : 16428 : j += 1;
3937 : : }
3938 : 9624 : if (f == NULL)
3939 : : {
3940 : 0 : M2MetaError_MetaError1 ((const char *) "the {%1EN} element does not exist in the constant compound literal", 66, i);
3941 : 0 : return SymbolTable_NulSym;
3942 : : }
3943 : : else
3944 : : {
3945 : 9624 : return f->field;
3946 : : }
3947 : : }
3948 : : }
3949 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2ALU.def", 20, 1);
3950 : : __builtin_unreachable ();
3951 : : }
3952 : :
3953 : :
3954 : : /*
3955 : : GetConstructorElement - returns a symbol containing the array constructor element, i.
3956 : : */
3957 : :
3958 : 305394 : static unsigned int GetConstructorElement (unsigned int tokenno, M2ALU_PtrToValue v, unsigned int i)
3959 : : {
3960 : 305394 : m2tree_Tree j;
3961 : 305394 : M2ALU_listOfElements e;
3962 : :
3963 : 305394 : if (v->type != M2ALU_array)
3964 : : {
3965 : 0 : M2Error_InternalError ((const char *) "constructor type must be an array", 33);
3966 : : }
3967 : : else
3968 : : {
3969 : 305394 : if (v->constructorType == SymbolTable_NulSym)
3970 : : {
3971 : 0 : M2Error_InternalError ((const char *) "constructor type must be an array", 33);
3972 : : }
3973 : : else
3974 : : {
3975 : 305394 : M2ALU_PushCard (i);
3976 : 305394 : j = M2ALU_PopIntegerTree ();
3977 : 305394 : e = v->arrayValues;
3978 : 687016 : while (e != NULL)
3979 : : {
3980 : 570292 : SymbolTable_PushValue (e->by);
3981 : 570292 : M2ALU_PushIntegerTree (j);
3982 : 570292 : if (M2ALU_GreEqu (tokenno))
3983 : : {
3984 : 188670 : return e->element;
3985 : : }
3986 : 381622 : M2ALU_PushIntegerTree (j);
3987 : 381622 : M2ALU_ConvertToInt ();
3988 : 381622 : SymbolTable_PushValue (e->by);
3989 : 381622 : M2ALU_ConvertToInt ();
3990 : 381622 : M2ALU_Sub ();
3991 : 381622 : j = M2ALU_PopIntegerTree ();
3992 : 381622 : e = e->next;
3993 : : }
3994 : 116724 : if (e == NULL)
3995 : : {
3996 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
3997 : 116724 : if ((SymbolTable_IsArray (SymbolTable_SkipType (v->constructorType))) && ((SymbolTable_GetType (SymbolTable_SkipType (v->constructorType))) == M2Base_Char))
3998 : : {
3999 : 116724 : return SymbolTable_MakeConstLit (tokenno, NameKey_MakeKey ((const char *) "0", 1), M2Base_Char);
4000 : : }
4001 : : else
4002 : : {
4003 : 0 : M2MetaError_MetaErrorT2 (tokenno, (const char *) "the {%1EN} element does not exist in the {%2ad} array declaration used by the compound literal", 94, i, v->constructorType);
4004 : : }
4005 : : }
4006 : : }
4007 : : }
4008 : 0 : return SymbolTable_NulSym;
4009 : : /* static analysis guarentees a RETURN statement will be used before here. */
4010 : : __builtin_unreachable ();
4011 : : }
4012 : :
4013 : :
4014 : : /*
4015 : : IsString - returns TRUE if sym is an ARRAY [..] OF CHAR
4016 : : */
4017 : :
4018 : 4448 : static bool IsString (unsigned int sym)
4019 : : {
4020 : 4448 : return (((SymbolTable_IsArray (sym)) && ((SymbolTable_SkipType (SymbolTable_GetType (sym))) == M2Base_Char)) || (SymbolTable_IsConstString (sym))) || ((SymbolTable_IsConst (sym)) && ((SymbolTable_SkipType (SymbolTable_GetType (sym))) == M2Base_Char));
4021 : : /* static analysis guarentees a RETURN statement will be used before here. */
4022 : : __builtin_unreachable ();
4023 : : }
4024 : :
4025 : :
4026 : : /*
4027 : : StringFitsArray -
4028 : : */
4029 : :
4030 : 456 : static bool StringFitsArray (unsigned int arrayType, unsigned int el, unsigned int tokenno)
4031 : : {
4032 : 456 : m2linemap_location_t location;
4033 : :
4034 : 456 : location = M2LexBuf_TokenToLocation (tokenno);
4035 : 456 : M2ALU_PushIntegerTree (m2type_BuildNumberOfArrayElements (location, SymbolConversion_Mod2Gcc (arrayType)));
4036 : 456 : if (SymbolTable_IsConstString (el))
4037 : : {
4038 : 456 : M2ALU_PushCard (SymbolTable_GetStringLength (tokenno, el));
4039 : : }
4040 : 0 : else if (((SymbolTable_IsConst (el)) && ((SymbolTable_SkipType (SymbolTable_GetType (el))) == M2Base_Char)) && (SymbolTable_IsValueSolved (el)))
4041 : : {
4042 : : /* avoid dangling else. */
4043 : 0 : M2ALU_PushCard (1);
4044 : : }
4045 : : else
4046 : : {
4047 : : /* avoid dangling else. */
4048 : 0 : M2ALU_PushCard (0);
4049 : 0 : M2MetaError_MetaError1 ((const char *) "cannot build a string using {%1Ead}", 35, el);
4050 : : }
4051 : 456 : return M2ALU_GreEqu (tokenno);
4052 : : /* static analysis guarentees a RETURN statement will be used before here. */
4053 : : __builtin_unreachable ();
4054 : : }
4055 : :
4056 : :
4057 : : /*
4058 : : GetArrayLimits -
4059 : : */
4060 : :
4061 : 1180 : static void GetArrayLimits (unsigned int array, unsigned int *low, unsigned int *high)
4062 : : {
4063 : 1180 : unsigned int Subscript;
4064 : 1180 : unsigned int Subrange;
4065 : :
4066 : 1180 : Subscript = SymbolTable_GetArraySubscript (array);
4067 : 1180 : Subrange = SymbolTable_SkipType (SymbolTable_GetType (Subscript));
4068 : 1180 : if (SymbolTable_IsEnumeration (Subrange))
4069 : : {
4070 : 32 : M2Base_GetBaseTypeMinMax (Subrange, low, high);
4071 : : }
4072 : : else
4073 : : {
4074 : 1148 : SymbolTable_GetSubrange (Subrange, high, low);
4075 : : }
4076 : 1180 : }
4077 : :
4078 : :
4079 : : /*
4080 : : InitialiseArrayOfCharWithString -
4081 : : */
4082 : :
4083 : 456 : static m2tree_Tree InitialiseArrayOfCharWithString (unsigned int tokenno, m2tree_Tree cons, unsigned int el, unsigned int baseType, unsigned int arrayType)
4084 : : {
4085 : 456 : bool isChar;
4086 : 456 : DynamicStrings_String s;
4087 : 456 : DynamicStrings_String letter;
4088 : 456 : unsigned int i;
4089 : 456 : unsigned int l;
4090 : 456 : unsigned int high;
4091 : 456 : unsigned int low;
4092 : 456 : m2tree_Tree value;
4093 : 456 : m2tree_Tree indice;
4094 : 456 : m2linemap_location_t location;
4095 : :
4096 : 456 : location = M2LexBuf_TokenToLocation (tokenno);
4097 : 456 : GetArrayLimits (baseType, &low, &high);
4098 : 456 : l = 0;
4099 : 456 : s = static_cast<DynamicStrings_String> (NULL);
4100 : 456 : if (SymbolTable_IsConstString (el))
4101 : : {
4102 : 456 : isChar = false;
4103 : 456 : s = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (SymbolTable_GetString (el)));
4104 : 456 : l = SymbolTable_GetStringLength (tokenno, el);
4105 : : }
4106 : 0 : else if (((SymbolTable_IsConst (el)) && ((SymbolTable_SkipType (SymbolTable_GetType (el))) == M2Base_Char)) && (SymbolTable_IsValueSolved (el)))
4107 : : {
4108 : : /* avoid dangling else. */
4109 : : isChar = true;
4110 : : }
4111 : : else
4112 : : {
4113 : : /* avoid dangling else. */
4114 : 0 : M2MetaError_MetaError1 ((const char *) "cannot build a string using {%1Ead}", 35, el);
4115 : 0 : isChar = false;
4116 : : }
4117 : 456 : i = 0;
4118 : 1824 : do {
4119 : 1824 : SymbolTable_PushValue (low);
4120 : 1824 : M2ALU_PushCard (i);
4121 : 1824 : M2ALU_Addn ();
4122 : 1824 : indice = M2ALU_PopIntegerTree ();
4123 : 1824 : letter = static_cast<DynamicStrings_String> (NULL);
4124 : 1824 : if (isChar)
4125 : : {
4126 : 0 : isChar = false;
4127 : 0 : SymbolTable_PushValue (el);
4128 : 0 : value = M2ALU_PopIntegerTree ();
4129 : : }
4130 : 1824 : else if (i < l)
4131 : : {
4132 : : /* avoid dangling else. */
4133 : 1368 : if ((i+1) < l)
4134 : : {
4135 : 912 : letter = DynamicStrings_Slice (s, static_cast<int> (i), static_cast<int> (i+1));
4136 : : }
4137 : : else
4138 : : {
4139 : 456 : letter = DynamicStrings_Slice (s, static_cast<int> (i), 0);
4140 : : }
4141 : 1368 : value = m2type_BuildCharConstant (location, DynamicStrings_string (letter));
4142 : : }
4143 : : else
4144 : : {
4145 : : /* avoid dangling else. */
4146 : 456 : letter = DynamicStrings_InitStringChar (ASCII_nul);
4147 : 456 : value = m2type_BuildCharConstant (location, DynamicStrings_string (letter));
4148 : : }
4149 : 1824 : value = m2convert_ConvertConstantAndCheck (location, SymbolConversion_Mod2Gcc (arrayType), value);
4150 : 1824 : letter = DynamicStrings_KillString (letter);
4151 : 1824 : m2type_BuildArrayConstructorElement (cons, value, indice);
4152 : 1824 : SymbolTable_PushValue (low);
4153 : 1824 : M2ALU_PushCard (i);
4154 : 1824 : M2ALU_Addn ();
4155 : 1824 : SymbolTable_PushValue (high);
4156 : 1824 : i += 1;
4157 : 1824 : } while (! (M2ALU_GreEqu (tokenno)));
4158 : 456 : s = DynamicStrings_KillString (s);
4159 : 456 : if (! (StringFitsArray (baseType, el, tokenno)))
4160 : : {
4161 : 0 : M2MetaError_MetaError2 ((const char *) "string {%1Ea} is too large to fit into array {%2ad}", 51, el, baseType);
4162 : : }
4163 : : /*
4164 : : IF v#NIL
4165 : : THEN
4166 : : el := GetConstructorElement(tokenno, v, 2) ;
4167 : : IF el#NulSym
4168 : : THEN
4169 : : MetaError1('not allowed to have multiple strings to initialise an array of characters {%1Ua}', el)
4170 : : END
4171 : : END ;
4172 : : */
4173 : 456 : return m2type_BuildEndArrayConstructor (cons);
4174 : : /* static analysis guarentees a RETURN statement will be used before here. */
4175 : : __builtin_unreachable ();
4176 : : }
4177 : :
4178 : :
4179 : : /*
4180 : : CheckElementString -
4181 : : */
4182 : :
4183 : 3992 : static m2tree_Tree CheckElementString (unsigned int el, unsigned int arrayType, unsigned int tokenno)
4184 : : {
4185 : 3992 : m2tree_Tree cons;
4186 : :
4187 : 3992 : if ((IsString (arrayType)) && (IsString (el)))
4188 : : {
4189 : 456 : cons = m2type_BuildStartArrayConstructor (SymbolConversion_Mod2Gcc (arrayType));
4190 : 456 : return InitialiseArrayOfCharWithString (tokenno, cons, el, arrayType, SymbolTable_SkipType (SymbolTable_GetType (arrayType)));
4191 : : }
4192 : : else
4193 : : {
4194 : 3536 : return SymbolConversion_Mod2Gcc (el);
4195 : : }
4196 : : /* static analysis guarentees a RETURN statement will be used before here. */
4197 : : __builtin_unreachable ();
4198 : : }
4199 : :
4200 : :
4201 : : /*
4202 : : InitialiseArrayWith -
4203 : : */
4204 : :
4205 : 514 : static m2tree_Tree InitialiseArrayWith (unsigned int tokenno, m2tree_Tree cons, M2ALU_PtrToValue v, unsigned int el, unsigned int high, unsigned int low, unsigned int arrayType)
4206 : : {
4207 : 514 : m2linemap_location_t location;
4208 : 514 : unsigned int i;
4209 : 514 : m2tree_Tree indice;
4210 : 514 : m2tree_Tree value;
4211 : :
4212 : 514 : location = M2LexBuf_TokenToLocation (tokenno);
4213 : 514 : i = 0;
4214 : 4506 : while (el != SymbolTable_NulSym)
4215 : : {
4216 : 3992 : SymbolTable_PushValue (low);
4217 : 3992 : M2ALU_ConvertToInt ();
4218 : 3992 : M2ALU_PushInt (static_cast<int> (i));
4219 : 3992 : M2ALU_Addn ();
4220 : 3992 : indice = M2ALU_PopIntegerTree ();
4221 : 3992 : value = CheckElementString (el, arrayType, tokenno);
4222 : 3992 : if (value == NULL)
4223 : : {
4224 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "{%W}too few characters found when trying to construct a compound literal array", 78);
4225 : 0 : value = m2expr_GetCardinalZero (location);
4226 : : }
4227 : 3992 : value = m2convert_ConvertConstantAndCheck (location, SymbolConversion_Mod2Gcc (arrayType), value);
4228 : 3992 : m2type_BuildArrayConstructorElement (cons, value, indice);
4229 : 3992 : SymbolTable_PushValue (low);
4230 : 3992 : M2ALU_ConvertToInt ();
4231 : 3992 : M2ALU_PushInt (static_cast<int> (i));
4232 : 3992 : M2ALU_Addn ();
4233 : 3992 : SymbolTable_PushValue (high);
4234 : 3992 : M2ALU_ConvertToInt ();
4235 : 3992 : if (M2ALU_GreEqu (tokenno))
4236 : : {
4237 : 514 : return m2type_BuildEndArrayConstructor (cons);
4238 : : }
4239 : 3478 : i += 1;
4240 : 3478 : el = GetConstructorElement (tokenno, v, i+1);
4241 : : }
4242 : 0 : return m2type_BuildEndArrayConstructor (cons);
4243 : : /* static analysis guarentees a RETURN statement will be used before here. */
4244 : : __builtin_unreachable ();
4245 : : }
4246 : :
4247 : :
4248 : : /*
4249 : : CheckGetCharFromString - return TRUE if a char from the position arrayIndex in the list of
4250 : : constDecl elements can be extracted. The character is returned
4251 : : in value.
4252 : : */
4253 : :
4254 : 6792 : static bool CheckGetCharFromString (m2linemap_location_t location, unsigned int tokenno, M2ALU_PtrToValue constDecl, unsigned int consType, unsigned int arrayIndex, m2tree_Tree *value)
4255 : : {
4256 : 6792 : unsigned int elementIndex;
4257 : 6792 : unsigned int element;
4258 : 6792 : unsigned int offset;
4259 : 6792 : unsigned int totalLength;
4260 : 6792 : NameKey_Name key;
4261 : :
4262 : 6792 : totalLength = 0;
4263 : 6792 : elementIndex = 1;
4264 : 300468 : do {
4265 : 300468 : element = GetConstructorElement (tokenno, constDecl, elementIndex);
4266 : 300468 : offset = totalLength;
4267 : 300468 : if (SymbolTable_IsConstString (element))
4268 : : {
4269 : : /* avoid dangling else. */
4270 : 183744 : totalLength += SymbolTable_GetStringLength (tokenno, element);
4271 : 183744 : if (totalLength > arrayIndex)
4272 : : {
4273 : 3864 : key = SymbolTable_GetString (element);
4274 : 3864 : arrayIndex -= offset;
4275 : 3864 : (*value) = m2type_BuildCharConstantChar (location, NameKey_CharKey (key, arrayIndex));
4276 : 3864 : return true;
4277 : : }
4278 : : }
4279 : 116724 : else if (((SymbolTable_IsConst (element)) && ((SymbolTable_SkipType (SymbolTable_GetType (element))) == M2Base_Char)) && (SymbolTable_IsValueSolved (element)))
4280 : : {
4281 : : /* avoid dangling else. */
4282 : 116664 : totalLength += 1;
4283 : 116664 : if (totalLength > arrayIndex)
4284 : : {
4285 : 2904 : SymbolTable_PushValue (element);
4286 : 2904 : (*value) = m2convert_ConvertConstantAndCheck (location, m2type_GetM2CharType (), M2ALU_PopIntegerTree ());
4287 : 2904 : return true;
4288 : : }
4289 : : }
4290 : : else
4291 : : {
4292 : : /* avoid dangling else. */
4293 : 60 : totalLength += 1;
4294 : 60 : if (totalLength > arrayIndex)
4295 : : {
4296 : 24 : M2MetaError_MetaErrorT3 (tokenno, (const char *) "expecting {%kCHAR} datatype and not {%1Ea} a {%1tad} in the {%2N} component of the {%3a} {%3d}", 94, element, arrayIndex, consType);
4297 : 24 : (*value) = m2expr_GetCardinalZero (location);
4298 : 24 : return false;
4299 : : }
4300 : : }
4301 : 293676 : elementIndex += 1;
4302 : 293676 : } while (! (element == SymbolTable_NulSym));
4303 : 0 : (*value) = m2expr_GetCardinalZero (location);
4304 : 0 : M2MetaError_MetaErrorT2 (tokenno, (const char *) "unable to obtain a {%kCHAR} at the {%1EN} position in {%2ad}", 60, arrayIndex, consType);
4305 : 0 : return false;
4306 : : /* static analysis guarentees a RETURN statement will be used before here. */
4307 : : __builtin_unreachable ();
4308 : : }
4309 : :
4310 : :
4311 : : /*
4312 : : InitialiseArrayOfCharWith -
4313 : : */
4314 : :
4315 : 210 : static m2tree_Tree InitialiseArrayOfCharWith (unsigned int tokenno, m2tree_Tree cons, M2ALU_PtrToValue constDecl, unsigned int el, unsigned int high, unsigned int low, unsigned int consType, unsigned int arrayType)
4316 : : {
4317 : 210 : m2linemap_location_t location;
4318 : 210 : unsigned int arrayIndex;
4319 : 210 : m2tree_Tree indice;
4320 : 210 : m2tree_Tree value;
4321 : :
4322 : 210 : location = M2LexBuf_TokenToLocation (tokenno); /* arrayIndex is the char position index of the final string. */
4323 : 210 : arrayIndex = 0;
4324 : 7002 : while (el != SymbolTable_NulSym)
4325 : : {
4326 : 6792 : SymbolTable_PushValue (low);
4327 : 6792 : M2ALU_ConvertToInt ();
4328 : 6792 : M2ALU_PushInt (static_cast<int> (arrayIndex));
4329 : 6792 : M2ALU_Addn ();
4330 : 6792 : indice = M2ALU_PopIntegerTree ();
4331 : 6792 : if (! (CheckGetCharFromString (location, tokenno, constDecl, consType, arrayIndex, &value)))
4332 : : {} /* empty. */
4333 : : /*
4334 : : MetaErrorT2 (tokenno,
4335 : : 'unable to obtain a {%kCHAR} at the {%1EN} position in {%2ad}',
4336 : : arrayIndex, consType) ;
4337 : : */
4338 : 6792 : value = m2convert_ConvertConstantAndCheck (location, SymbolConversion_Mod2Gcc (arrayType), value);
4339 : 6792 : m2type_BuildArrayConstructorElement (cons, value, indice);
4340 : 6792 : SymbolTable_PushValue (low);
4341 : 6792 : M2ALU_ConvertToInt ();
4342 : 6792 : M2ALU_PushInt (static_cast<int> (arrayIndex));
4343 : 6792 : M2ALU_Addn ();
4344 : 6792 : SymbolTable_PushValue (high);
4345 : 6792 : M2ALU_ConvertToInt ();
4346 : 6792 : if (M2ALU_GreEqu (tokenno))
4347 : : {
4348 : 210 : return m2type_BuildEndArrayConstructor (cons);
4349 : : }
4350 : 6582 : arrayIndex += 1;
4351 : : }
4352 : 0 : return m2type_BuildEndArrayConstructor (cons);
4353 : : /* static analysis guarentees a RETURN statement will be used before here. */
4354 : : __builtin_unreachable ();
4355 : : }
4356 : :
4357 : :
4358 : : /*
4359 : : ConstructArrayConstant - builds a struct initializer, as defined by, v.
4360 : : */
4361 : :
4362 : 724 : static m2tree_Tree ConstructArrayConstant (unsigned int tokenno, M2ALU_PtrToValue v)
4363 : : {
4364 : 724 : NameKey_Name n1;
4365 : 724 : NameKey_Name n2;
4366 : 724 : unsigned int el1;
4367 : 724 : unsigned int el2;
4368 : 724 : unsigned int baseType;
4369 : 724 : unsigned int arrayType;
4370 : 724 : unsigned int high;
4371 : 724 : unsigned int low;
4372 : 724 : m2type_Constructor cons;
4373 : :
4374 : 724 : if (v->constructorType == SymbolTable_NulSym)
4375 : : {
4376 : 0 : M2Error_InternalError ((const char *) "array type must be known in order to generate a constant", 56);
4377 : : }
4378 : : else
4379 : : {
4380 : 724 : baseType = SymbolTable_SkipType (v->constructorType);
4381 : 724 : if (Debugging)
4382 : : {
4383 : : n1 = SymbolTable_GetSymName (v->constructorType);
4384 : : n2 = SymbolTable_GetSymName (baseType);
4385 : : M2Printf_printf2 ((const char *) "ConstructArrayConstant of type %a and baseType %a\\n", 51, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
4386 : : }
4387 : 724 : cons = m2type_BuildStartArrayConstructor (SymbolConversion_Mod2Gcc (baseType));
4388 : 724 : GetArrayLimits (baseType, &low, &high);
4389 : 724 : arrayType = SymbolTable_GetType (baseType);
4390 : 724 : el1 = GetConstructorElement (tokenno, v, 1);
4391 : 724 : el2 = GetConstructorElement (tokenno, v, 2);
4392 : 724 : if (((el2 == SymbolTable_NulSym) && (IsString (baseType))) && (IsString (el1)))
4393 : : {
4394 : : /* constructorType is ARRAY [low..high] OF CHAR and using a string to initialise it */
4395 : 0 : return InitialiseArrayOfCharWithString (tokenno, cons, el1, baseType, arrayType);
4396 : : }
4397 : 724 : else if ((SymbolTable_SkipType (arrayType)) == M2Base_Char)
4398 : : {
4399 : : /* avoid dangling else. */
4400 : 210 : return InitialiseArrayOfCharWith (tokenno, cons, v, el1, high, low, baseType, arrayType);
4401 : : }
4402 : : else
4403 : : {
4404 : : /* avoid dangling else. */
4405 : 514 : return InitialiseArrayWith (tokenno, cons, v, el1, high, low, arrayType);
4406 : : }
4407 : : }
4408 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2ALU.def", 20, 1);
4409 : : __builtin_unreachable ();
4410 : : }
4411 : :
4412 : :
4413 : : /*
4414 : : BuildBitset - given a set, v, construct the bitmask for its
4415 : : constant value which lie in the range low..high.
4416 : : */
4417 : :
4418 : 24499 : static m2tree_Tree BuildBitset (unsigned int tokenno, M2ALU_PtrToValue v, m2tree_Tree low, m2tree_Tree high)
4419 : : {
4420 : 24499 : m2tree_Tree tl;
4421 : 24499 : m2tree_Tree th;
4422 : 24499 : m2tree_Tree t;
4423 : 24499 : unsigned int n;
4424 : 24499 : unsigned int r1;
4425 : 24499 : unsigned int r2;
4426 : 24499 : m2linemap_location_t location;
4427 : :
4428 : 24499 : location = M2LexBuf_TokenToLocation (tokenno);
4429 : 24499 : low = m2convert_ToInteger (location, low);
4430 : 24499 : high = m2convert_ToInteger (location, high);
4431 : 24499 : n = 1;
4432 : 24499 : t = m2expr_GetCardinalZero (location);
4433 : 87217 : while (M2ALU_GetRange (v, n, &r1, &r2))
4434 : : {
4435 : 38219 : SymbolTable_PushValue (r1);
4436 : 38219 : tl = m2convert_ToInteger (location, M2ALU_PopIntegerTree ());
4437 : 38219 : SymbolTable_PushValue (r2);
4438 : 38219 : th = m2convert_ToInteger (location, M2ALU_PopIntegerTree ());
4439 : 38219 : if (IsIntersectionTree (tokenno, tl, th, low, high))
4440 : : {
4441 : 9063 : tl = m2convert_ToCardinal (location, SubTree (MaxTree (tokenno, tl, low), low));
4442 : 9063 : th = m2convert_ToCardinal (location, SubTree (MinTree (tokenno, th, high), low));
4443 : 9063 : t = m2expr_BuildLogicalOr (location, t, M2ALU_BuildRange (tokenno, tl, th), false);
4444 : : }
4445 : 38219 : n += 1;
4446 : : }
4447 : 24499 : return m2convert_ToBitset (location, t);
4448 : : /* static analysis guarentees a RETURN statement will be used before here. */
4449 : : __builtin_unreachable ();
4450 : : }
4451 : :
4452 : :
4453 : : /*
4454 : : CheckOverflow - tests to see whether the tree, t, has caused
4455 : : an overflow error and if so it generates an
4456 : : error message.
4457 : : */
4458 : :
4459 : 344782 : static void CheckOverflow (unsigned int tokenno, m2tree_Tree t)
4460 : : {
4461 : 344782 : if (m2expr_TreeOverflow (t))
4462 : : {
4463 : 12 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "constant overflow error", 23);
4464 : 12 : M2Error_FlushErrors ();
4465 : : }
4466 : 344770 : }
4467 : :
4468 : :
4469 : : /*
4470 : : PushGCCArrayTree - pushes a gcc tree value onto the ALU stack.
4471 : : */
4472 : :
4473 : 0 : static void PushGCCArrayTree (m2tree_Tree gcc, unsigned int t)
4474 : : {
4475 : 0 : M2ALU_PtrToValue v;
4476 : :
4477 : 0 : v = New ();
4478 : 0 : v->constructorType = t;
4479 : 0 : v->type = M2ALU_array;
4480 : 0 : v->numberValue = gcc;
4481 : 0 : v->arrayValues = NULL;
4482 : 0 : v->areAllConstants = true;
4483 : 0 : v->solved = true;
4484 : 0 : Push (v);
4485 : 0 : }
4486 : :
4487 : :
4488 : : /*
4489 : : PushGCCSetTree - pushes a gcc tree value onto the ALU stack.
4490 : : */
4491 : :
4492 : 18 : static void PushGCCSetTree (m2tree_Tree gcc, unsigned int t)
4493 : : {
4494 : 18 : M2ALU_PtrToValue v;
4495 : :
4496 : 18 : v = New ();
4497 : 18 : v->constructorType = t;
4498 : 18 : v->type = M2ALU_set;
4499 : 18 : v->numberValue = gcc;
4500 : 18 : v->setValue = NULL;
4501 : 18 : v->areAllConstants = true;
4502 : 18 : v->solved = true;
4503 : 18 : Push (v);
4504 : 18 : }
4505 : :
4506 : :
4507 : : /*
4508 : : PushGCCRecordTree - pushes a gcc tree value onto the ALU stack.
4509 : : */
4510 : :
4511 : 0 : static void PushGCCRecordTree (m2tree_Tree gcc, unsigned int t)
4512 : : {
4513 : 0 : M2ALU_PtrToValue v;
4514 : :
4515 : 0 : v = New ();
4516 : 0 : v->constructorType = t;
4517 : 0 : v->type = M2ALU_record;
4518 : 0 : v->numberValue = gcc;
4519 : 0 : v->fieldValues = NULL;
4520 : 0 : v->areAllConstants = true;
4521 : 0 : v->solved = true;
4522 : 0 : Push (v);
4523 : 0 : }
4524 : :
4525 : :
4526 : : /*
4527 : : Init - initialises the stack and the free list.
4528 : : */
4529 : :
4530 : 16817 : static void Init (void)
4531 : : {
4532 : 16817 : FreeList = NULL;
4533 : 16817 : TopOfStack = NULL;
4534 : 16817 : RangeFreeList = NULL;
4535 : 16817 : FieldFreeList = NULL;
4536 : 16817 : ElementFreeList = NULL;
4537 : 0 : }
4538 : :
4539 : :
4540 : : /*
4541 : : InitValue - initializes and returns a memory cell.
4542 : : */
4543 : :
4544 : 34710935 : extern "C" M2ALU_PtrToValue M2ALU_InitValue (void)
4545 : : {
4546 : 34710935 : M2ALU_PtrToValue v;
4547 : :
4548 : 34710935 : v = New ();
4549 : 34710935 : if (v == NULL)
4550 : : {
4551 : 0 : M2Error_InternalError ((const char *) "out of memory error", 19);
4552 : : }
4553 : : else
4554 : : {
4555 : 34710935 : v->location = m2linemap_UnknownLocation ();
4556 : 34710935 : v->type = M2ALU_none;
4557 : 34710935 : v->areAllConstants = true;
4558 : 34710935 : v->solved = false;
4559 : 34710935 : v->next = NULL;
4560 : 34710935 : v->constructorType = SymbolTable_NulSym;
4561 : 34710935 : return v;
4562 : : }
4563 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2ALU.def", 20, 1);
4564 : : __builtin_unreachable ();
4565 : : }
4566 : :
4567 : :
4568 : : /*
4569 : : IsValueTypeNone - returns TRUE if the value on the top stack has no value.
4570 : : */
4571 : :
4572 : 234527 : extern "C" bool M2ALU_IsValueTypeNone (void)
4573 : : {
4574 : 234527 : M2ALU_PtrToValue v;
4575 : :
4576 : 234527 : v = Pop ();
4577 : 234527 : if (v->type == M2ALU_none)
4578 : : {
4579 : 32852 : Push (v);
4580 : 32852 : return true;
4581 : : }
4582 : : else
4583 : : {
4584 : 201675 : Push (v);
4585 : 201675 : return false;
4586 : : }
4587 : : /* static analysis guarentees a RETURN statement will be used before here. */
4588 : : __builtin_unreachable ();
4589 : : }
4590 : :
4591 : :
4592 : : /*
4593 : : IsValueTypeInteger - returns TRUE if the value on the top stack is an integer.
4594 : : */
4595 : :
4596 : 0 : extern "C" bool M2ALU_IsValueTypeInteger (void)
4597 : : {
4598 : 0 : M2ALU_PtrToValue v;
4599 : :
4600 : 0 : v = Pop ();
4601 : 0 : if (v->type == M2ALU_integer)
4602 : : {
4603 : 0 : Push (v);
4604 : 0 : return true;
4605 : : }
4606 : : else
4607 : : {
4608 : 0 : Push (v);
4609 : 0 : return false;
4610 : : }
4611 : : /* static analysis guarentees a RETURN statement will be used before here. */
4612 : : __builtin_unreachable ();
4613 : : }
4614 : :
4615 : :
4616 : : /*
4617 : : IsValueTypeReal - returns TRUE if the value on the top stack is a real.
4618 : : */
4619 : :
4620 : 247063 : extern "C" bool M2ALU_IsValueTypeReal (void)
4621 : : {
4622 : 247063 : M2ALU_PtrToValue v;
4623 : :
4624 : 247063 : v = Pop ();
4625 : 247063 : if (v->type == M2ALU_real)
4626 : : {
4627 : 432 : Push (v);
4628 : 432 : return true;
4629 : : }
4630 : : else
4631 : : {
4632 : 246631 : Push (v);
4633 : 246631 : return false;
4634 : : }
4635 : : /* static analysis guarentees a RETURN statement will be used before here. */
4636 : : __builtin_unreachable ();
4637 : : }
4638 : :
4639 : :
4640 : : /*
4641 : : IsValueTypeComplex - returns TRUE if the value on the top stack is a complex.
4642 : : */
4643 : :
4644 : 243191 : extern "C" bool M2ALU_IsValueTypeComplex (void)
4645 : : {
4646 : 243191 : M2ALU_PtrToValue v;
4647 : :
4648 : 243191 : v = Pop ();
4649 : 243191 : if (v->type == M2ALU_complex)
4650 : : {
4651 : 330 : Push (v);
4652 : 330 : return true;
4653 : : }
4654 : : else
4655 : : {
4656 : 242861 : Push (v);
4657 : 242861 : return false;
4658 : : }
4659 : : /* static analysis guarentees a RETURN statement will be used before here. */
4660 : : __builtin_unreachable ();
4661 : : }
4662 : :
4663 : :
4664 : : /*
4665 : : IsValueTypeSet - returns TRUE if the value on the top stack is a set.
4666 : : */
4667 : :
4668 : 269630 : extern "C" bool M2ALU_IsValueTypeSet (void)
4669 : : {
4670 : 269630 : M2ALU_PtrToValue v;
4671 : :
4672 : 269630 : v = Pop ();
4673 : 269630 : if (v->type == M2ALU_set)
4674 : : {
4675 : 3385 : Push (v);
4676 : 3385 : return true;
4677 : : }
4678 : : else
4679 : : {
4680 : 266245 : Push (v);
4681 : 266245 : return false;
4682 : : }
4683 : : /* static analysis guarentees a RETURN statement will be used before here. */
4684 : : __builtin_unreachable ();
4685 : : }
4686 : :
4687 : :
4688 : : /*
4689 : : IsValueTypeConstructor - returns TRUE if the value on the top
4690 : : stack is a constructor.
4691 : : */
4692 : :
4693 : 266564 : extern "C" bool M2ALU_IsValueTypeConstructor (void)
4694 : : {
4695 : 266564 : M2ALU_PtrToValue v;
4696 : :
4697 : 266564 : v = Pop ();
4698 : 266564 : if (v->type == M2ALU_constructor)
4699 : : {
4700 : 0 : Push (v);
4701 : 0 : return true;
4702 : : }
4703 : : else
4704 : : {
4705 : 266564 : Push (v);
4706 : 266564 : return false;
4707 : : }
4708 : : /* static analysis guarentees a RETURN statement will be used before here. */
4709 : : __builtin_unreachable ();
4710 : : }
4711 : :
4712 : :
4713 : : /*
4714 : : IsValueTypeArray - returns TRUE if the value on the top stack is
4715 : : an array.
4716 : : */
4717 : :
4718 : 266245 : extern "C" bool M2ALU_IsValueTypeArray (void)
4719 : : {
4720 : 266245 : M2ALU_PtrToValue v;
4721 : :
4722 : 266245 : v = Pop ();
4723 : 266245 : if (v->type == M2ALU_array)
4724 : : {
4725 : 464 : Push (v);
4726 : 464 : return true;
4727 : : }
4728 : : else
4729 : : {
4730 : 265781 : Push (v);
4731 : 265781 : return false;
4732 : : }
4733 : : /* static analysis guarentees a RETURN statement will be used before here. */
4734 : : __builtin_unreachable ();
4735 : : }
4736 : :
4737 : :
4738 : : /*
4739 : : IsValueTypeRecord - returns TRUE if the value on the top stack is
4740 : : a record.
4741 : : */
4742 : :
4743 : 265781 : extern "C" bool M2ALU_IsValueTypeRecord (void)
4744 : : {
4745 : 265781 : M2ALU_PtrToValue v;
4746 : :
4747 : 265781 : v = Pop ();
4748 : 265781 : if (v->type == M2ALU_record)
4749 : : {
4750 : 2122 : Push (v);
4751 : 2122 : return true;
4752 : : }
4753 : : else
4754 : : {
4755 : 263659 : Push (v);
4756 : 263659 : return false;
4757 : : }
4758 : : /* static analysis guarentees a RETURN statement will be used before here. */
4759 : : __builtin_unreachable ();
4760 : : }
4761 : :
4762 : :
4763 : : /*
4764 : : GetSetValueType - returns the set type on top of the ALU stack.
4765 : : */
4766 : :
4767 : 0 : extern "C" unsigned int M2ALU_GetSetValueType (void)
4768 : : {
4769 : 0 : M2ALU_PtrToValue v;
4770 : :
4771 : 0 : v = Pop ();
4772 : 0 : Push (v);
4773 : 0 : if (v->type == M2ALU_set)
4774 : : {
4775 : 0 : return v->constructorType;
4776 : : }
4777 : : else
4778 : : {
4779 : 0 : M2Error_InternalError ((const char *) "expecting set type", 18);
4780 : : }
4781 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2ALU.def", 20, 1);
4782 : : __builtin_unreachable ();
4783 : : }
4784 : :
4785 : :
4786 : : /*
4787 : : PushIntegerTree - pushes a gcc tree value onto the ALU stack.
4788 : : */
4789 : :
4790 : 7907825 : extern "C" void M2ALU_PushIntegerTree (m2tree_Tree t)
4791 : : {
4792 : 7907825 : M2ALU_PtrToValue v;
4793 : :
4794 : 7907825 : v = M2ALU_InitValue ();
4795 : 7907825 : v->type = M2ALU_integer;
4796 : 7907825 : v->numberValue = t;
4797 : 7907825 : v->areAllConstants = true;
4798 : 7907825 : v->solved = true;
4799 : 7907825 : Push (v);
4800 : 7907825 : }
4801 : :
4802 : :
4803 : : /*
4804 : : PopIntegerTree - pops a gcc tree value from the ALU stack.
4805 : : */
4806 : :
4807 : 2383988 : extern "C" m2tree_Tree M2ALU_PopIntegerTree (void)
4808 : : {
4809 : 2383988 : M2ALU_PtrToValue v;
4810 : 2383988 : m2tree_Tree t;
4811 : :
4812 : 2383988 : v = Pop ();
4813 : 2383988 : if (v->type == M2ALU_integer)
4814 : : {
4815 : 2383988 : t = v->numberValue;
4816 : : }
4817 : : else
4818 : : {
4819 : 0 : M2Error_InternalError ((const char *) "expecting type of constant to be a whole number", 47);
4820 : : }
4821 : 2383988 : Dispose (v);
4822 : 2383988 : return t;
4823 : : /* static analysis guarentees a RETURN statement will be used before here. */
4824 : : __builtin_unreachable ();
4825 : : }
4826 : :
4827 : :
4828 : : /*
4829 : : PushRealTree - pushes a gcc tree value onto the ALU stack.
4830 : : */
4831 : :
4832 : 108418 : extern "C" void M2ALU_PushRealTree (m2tree_Tree t)
4833 : : {
4834 : 108418 : M2ALU_PtrToValue v;
4835 : :
4836 : 108418 : v = New ();
4837 : 108418 : v->type = M2ALU_real;
4838 : 108418 : v->numberValue = t;
4839 : 108418 : v->areAllConstants = true;
4840 : 108418 : v->solved = true;
4841 : 108418 : Push (v);
4842 : 108418 : }
4843 : :
4844 : :
4845 : : /*
4846 : : PopRealTree - pops a gcc tree value from the ALU stack.
4847 : : */
4848 : :
4849 : 7228 : extern "C" m2tree_Tree M2ALU_PopRealTree (void)
4850 : : {
4851 : 7228 : M2ALU_PtrToValue v;
4852 : 7228 : m2tree_Tree t;
4853 : :
4854 : 7228 : v = Pop ();
4855 : 7228 : if (v->type == M2ALU_real)
4856 : : {
4857 : 7228 : t = v->numberValue;
4858 : : }
4859 : : else
4860 : : {
4861 : 0 : M2Error_InternalError ((const char *) "expecting type of constant to be a real number", 46);
4862 : : }
4863 : 7228 : Dispose (v);
4864 : 7228 : return t;
4865 : : /* static analysis guarentees a RETURN statement will be used before here. */
4866 : : __builtin_unreachable ();
4867 : : }
4868 : :
4869 : :
4870 : : /*
4871 : : PushComplexTree - pushes a gcc tree value onto the ALU stack.
4872 : : */
4873 : :
4874 : 708 : extern "C" void M2ALU_PushComplexTree (m2tree_Tree t)
4875 : : {
4876 : 708 : M2ALU_PtrToValue v;
4877 : :
4878 : 708 : v = New ();
4879 : 708 : v->type = M2ALU_complex;
4880 : 708 : v->numberValue = t;
4881 : 708 : v->areAllConstants = true;
4882 : 708 : v->solved = true;
4883 : 708 : Push (v);
4884 : 708 : }
4885 : :
4886 : :
4887 : : /*
4888 : : PopComplexTree - pops a gcc tree value from the ALU stack.
4889 : : */
4890 : :
4891 : 660 : extern "C" m2tree_Tree M2ALU_PopComplexTree (void)
4892 : : {
4893 : 660 : M2ALU_PtrToValue v;
4894 : 660 : m2tree_Tree t;
4895 : :
4896 : 660 : v = Pop ();
4897 : 660 : if (v->type == M2ALU_complex)
4898 : : {
4899 : 660 : t = v->numberValue;
4900 : : }
4901 : : else
4902 : : {
4903 : 0 : M2Error_InternalError ((const char *) "expecting type of constant to be a complex number", 49);
4904 : : }
4905 : 660 : Dispose (v);
4906 : 660 : return t;
4907 : : /* static analysis guarentees a RETURN statement will be used before here. */
4908 : : __builtin_unreachable ();
4909 : : }
4910 : :
4911 : :
4912 : : /*
4913 : : PushSetTree - pushes a gcc tree onto the ALU stack.
4914 : : The tree, t, is expected to contain a
4915 : : word value. It is converted into a set
4916 : : type (sym). Bit 0 maps onto MIN(sym).
4917 : : */
4918 : :
4919 : 0 : extern "C" void M2ALU_PushSetTree (unsigned int tokenno, m2tree_Tree t, unsigned int sym)
4920 : : {
4921 : 0 : M2ALU_PtrToValue v;
4922 : 0 : int c;
4923 : 0 : int i;
4924 : 0 : M2ALU_listOfRange r;
4925 : 0 : m2linemap_location_t l;
4926 : :
4927 : 0 : l = M2LexBuf_TokenToLocation (tokenno);
4928 : 0 : r = NULL;
4929 : 0 : i = 0;
4930 : 0 : while ((i < (m2decl_GetBitsPerBitset ())) && ((m2expr_CompareTrees (m2expr_GetIntegerZero (l), t)) != 0))
4931 : : {
4932 : 0 : if ((m2expr_CompareTrees (m2expr_GetIntegerOne (l), m2expr_BuildLogicalAnd (l, t, m2expr_GetIntegerOne (l), false))) == 0)
4933 : : {
4934 : 0 : M2ALU_PushCard (static_cast<unsigned int> (i));
4935 : 0 : c = Val (tokenno, SymbolTable_SkipType (sym), M2ALU_PopIntegerTree ());
4936 : 0 : M2GCCDeclare_DeclareConstant (tokenno, static_cast<unsigned int> (c));
4937 : 0 : r = AddRange (r, static_cast<unsigned int> (c), static_cast<unsigned int> (c));
4938 : : }
4939 : 0 : t = m2expr_BuildLSR (l, t, m2expr_GetIntegerOne (l), false);
4940 : 0 : i += 1;
4941 : : }
4942 : 0 : SortElements (tokenno, r);
4943 : 0 : CombineElements (tokenno, r);
4944 : 0 : v = New ();
4945 : 0 : v->location = l;
4946 : 0 : v->type = M2ALU_set;
4947 : 0 : v->constructorType = sym;
4948 : 0 : v->areAllConstants = false;
4949 : 0 : v->solved = false;
4950 : 0 : v->setValue = r;
4951 : 0 : Eval (tokenno, v);
4952 : 0 : Push (v);
4953 : 0 : }
4954 : :
4955 : :
4956 : : /*
4957 : : PopSetTree - pops a gcc tree from the ALU stack.
4958 : : */
4959 : :
4960 : 703 : extern "C" m2tree_Tree M2ALU_PopSetTree (unsigned int tokenno)
4961 : : {
4962 : 703 : M2ALU_PtrToValue v;
4963 : 703 : m2tree_Tree t;
4964 : :
4965 : 703 : v = Pop ();
4966 : 703 : if (v->type == M2ALU_set)
4967 : : {
4968 : 703 : Eval (tokenno, v);
4969 : 703 : if (! v->solved)
4970 : : {
4971 : 0 : M2Error_InternalError ((const char *) "the set has not been resolved", 29);
4972 : : }
4973 : 703 : if (! v->areAllConstants)
4974 : : {
4975 : 0 : M2Error_InternalError ((const char *) "the set must only contain constants", 35);
4976 : : }
4977 : 703 : t = M2ALU_ConstructSetConstant (tokenno, v);
4978 : : }
4979 : : else
4980 : : {
4981 : 0 : M2Error_InternalError ((const char *) "expecting type of constant to be a set", 38);
4982 : : }
4983 : 703 : Dispose (v);
4984 : 703 : return t;
4985 : : /* static analysis guarentees a RETURN statement will be used before here. */
4986 : : __builtin_unreachable ();
4987 : : }
4988 : :
4989 : :
4990 : : /*
4991 : : PopConstructorTree - returns a tree containing the compound literal.
4992 : : */
4993 : :
4994 : 10293 : extern "C" m2tree_Tree M2ALU_PopConstructorTree (unsigned int tokenno)
4995 : : {
4996 : 10293 : M2ALU_PtrToValue v;
4997 : 10293 : m2tree_Tree t;
4998 : :
4999 : 10293 : v = Pop ();
5000 : 10293 : Eval (tokenno, v);
5001 : 10293 : if (! v->solved)
5002 : : {
5003 : 0 : M2Error_InternalError ((const char *) "the constructor has not been resolved", 37);
5004 : : }
5005 : 10293 : switch (v->type)
5006 : : {
5007 : 0 : case M2ALU_constructor:
5008 : 0 : M2Error_InternalError ((const char *) "expecting constructor to be resolved into specific type", 55);
5009 : 724 : break;
5010 : :
5011 : 724 : case M2ALU_array:
5012 : 724 : t = ConstructArrayConstant (tokenno, v);
5013 : 724 : break;
5014 : :
5015 : 2332 : case M2ALU_record:
5016 : 2332 : t = ConstructRecordConstant (tokenno, v);
5017 : 2332 : break;
5018 : :
5019 : 7237 : case M2ALU_set:
5020 : 7237 : t = M2ALU_ConstructSetConstant (tokenno, v);
5021 : 7237 : break;
5022 : :
5023 : :
5024 : 0 : default:
5025 : 0 : M2Error_InternalError ((const char *) "expecting type to be a constructor", 34);
5026 : 10293 : break;
5027 : : }
5028 : 10293 : Dispose (v);
5029 : 10293 : return t;
5030 : : /* static analysis guarentees a RETURN statement will be used before here. */
5031 : : __builtin_unreachable ();
5032 : : }
5033 : :
5034 : :
5035 : : /*
5036 : : PushFrom - pushes a copy of the contents of, v, onto stack.
5037 : : */
5038 : :
5039 : 13555585 : extern "C" void M2ALU_PushFrom (M2ALU_PtrToValue v)
5040 : : {
5041 : 13555585 : M2ALU_PtrToValue t;
5042 : :
5043 : 13555585 : CheckNotAlreadyOnFreeList (v);
5044 : 13555585 : t = New (); /* as it is a copy */
5045 : 13555585 : (*t) = (*v); /* as it is a copy */
5046 : 13555585 : switch (v->type)
5047 : : {
5048 : 103951 : case M2ALU_set:
5049 : 103951 : t->setValue = DupRange (v->setValue);
5050 : 103951 : break;
5051 : :
5052 : 129930 : case M2ALU_constructor:
5053 : 129930 : case M2ALU_record:
5054 : 129930 : t->fieldValues = DupFields (v->fieldValues);
5055 : 129930 : break;
5056 : :
5057 : 29428 : case M2ALU_array:
5058 : 29428 : t->arrayValues = DupElements (v->arrayValues);
5059 : 29428 : break;
5060 : :
5061 : :
5062 : : default:
5063 : : break;
5064 : : }
5065 : 13555585 : Push (t);
5066 : 13555585 : }
5067 : :
5068 : :
5069 : : /*
5070 : : PopInto - pops the top element from the stack and places it into, v.
5071 : : */
5072 : :
5073 : 2969075 : extern "C" void M2ALU_PopInto (M2ALU_PtrToValue v)
5074 : : {
5075 : 2969075 : M2ALU_PtrToValue t;
5076 : :
5077 : 2969075 : t = Pop ();
5078 : 2969075 : (*v) = (*t);
5079 : 2969075 : switch (v->type)
5080 : : {
5081 : 40180 : case M2ALU_set:
5082 : 40180 : t->setValue = NULL;
5083 : 40180 : break;
5084 : :
5085 : 21650 : case M2ALU_record:
5086 : 21650 : case M2ALU_constructor:
5087 : 21650 : t->fieldValues = NULL;
5088 : 21650 : break;
5089 : :
5090 : 6560 : case M2ALU_array:
5091 : 6560 : t->arrayValues = NULL;
5092 : 6560 : break;
5093 : :
5094 : 2900685 : case M2ALU_none:
5095 : 2900685 : case M2ALU_integer:
5096 : 2900685 : case M2ALU_real:
5097 : 2900685 : case M2ALU_complex:
5098 : 2900685 : v->numberValue = m2block_RememberConstant (m2expr_FoldAndStrip (t->numberValue));
5099 : 2900685 : break;
5100 : :
5101 : :
5102 : 0 : default:
5103 : 0 : M2Error_InternalError ((const char *) "not expecting this value", 24);
5104 : 2969075 : break;
5105 : : }
5106 : 2969075 : Dispose (t);
5107 : 2969075 : }
5108 : :
5109 : :
5110 : : /*
5111 : : PushCard - pushes a cardinal onto the stack.
5112 : : */
5113 : :
5114 : 1003084 : extern "C" void M2ALU_PushCard (unsigned int c)
5115 : : {
5116 : 1003084 : M2ALU_PtrToValue v;
5117 : :
5118 : 1003084 : v = New ();
5119 : 1003084 : v->type = M2ALU_integer;
5120 : 1003084 : v->numberValue = m2decl_BuildIntegerConstant ((int ) (c));
5121 : 1003084 : v->areAllConstants = true;
5122 : 1003084 : v->solved = true;
5123 : 1003084 : Push (v);
5124 : 1003084 : }
5125 : :
5126 : :
5127 : : /*
5128 : : PushInt - pushes an integer onto the stack.
5129 : : */
5130 : :
5131 : 24680 : extern "C" void M2ALU_PushInt (int i)
5132 : : {
5133 : 24680 : M2ALU_PtrToValue v;
5134 : :
5135 : 24680 : v = New ();
5136 : 24680 : v->type = M2ALU_integer;
5137 : 24680 : v->numberValue = m2decl_BuildIntegerConstant (i);
5138 : 24680 : v->areAllConstants = true;
5139 : 24680 : v->solved = true;
5140 : 24680 : Push (v);
5141 : 24680 : }
5142 : :
5143 : :
5144 : : /*
5145 : : PushChar - pushes a char onto the stack.
5146 : : */
5147 : :
5148 : 12028 : extern "C" void M2ALU_PushChar (char c)
5149 : : {
5150 : 12028 : M2ALU_PtrToValue v;
5151 : :
5152 : 12028 : v = New ();
5153 : 12028 : v->type = M2ALU_integer;
5154 : 12028 : v->numberValue = m2decl_BuildIntegerConstant (static_cast<int> ( ((unsigned int) (c))));
5155 : 12028 : v->areAllConstants = true;
5156 : 12028 : v->solved = true;
5157 : 12028 : Push (v);
5158 : 12028 : }
5159 : :
5160 : :
5161 : : /*
5162 : : PopChar - pops a char from the stack.
5163 : : */
5164 : :
5165 : 1604 : extern "C" char M2ALU_PopChar (unsigned int tokenno)
5166 : : {
5167 : 1604 : M2ALU_PtrToValue v;
5168 : 1604 : char ch;
5169 : :
5170 : 1604 : v = Pop ();
5171 : 1604 : ch = (char) 0;
5172 : 1604 : if (v->type == M2ALU_integer)
5173 : : {
5174 : 1604 : ch = (char ) (m2expr_GetCstInteger (v->numberValue));
5175 : : }
5176 : : else
5177 : : {
5178 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "{%E}cannot convert constant to a CHAR", 37);
5179 : : }
5180 : 1604 : Push (v);
5181 : 1604 : return ch;
5182 : : /* static analysis guarentees a RETURN statement will be used before here. */
5183 : : __builtin_unreachable ();
5184 : : }
5185 : :
5186 : :
5187 : : /*
5188 : : PushString - pushes the numerical value of the string onto the stack.
5189 : : */
5190 : :
5191 : 546807 : extern "C" void M2ALU_PushString (unsigned int tokenno, NameKey_Name s, bool issueError)
5192 : : {
5193 : 546807 : char ch;
5194 : 546807 : DynamicStrings_String a;
5195 : 546807 : DynamicStrings_String b;
5196 : 546807 : unsigned int length;
5197 : 546807 : m2linemap_location_t location;
5198 : :
5199 : 546807 : a = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (s));
5200 : 546807 : b = static_cast<DynamicStrings_String> (NULL);
5201 : 546807 : length = DynamicStrings_Length (a);
5202 : 546807 : if (length > 0)
5203 : : {
5204 : 546807 : length -= 1;
5205 : 546807 : ch = DynamicStrings_char (a, static_cast<int> (length));
5206 : 546807 : location = M2LexBuf_TokenToLocation (tokenno);
5207 : 546807 : switch (ch)
5208 : : {
5209 : 742 : case 'H':
5210 : 742 : b = DynamicStrings_Slice (a, 0, -1); /* hexadecimal */
5211 : 742 : M2ALU_PushIntegerTree (m2decl_BuildConstLiteralNumber (location, DynamicStrings_string (b), 16, issueError));
5212 : 742 : break;
5213 : :
5214 : 24 : case 'A':
5215 : 24 : b = DynamicStrings_Slice (a, 0, -1); /* binary */
5216 : 24 : M2ALU_PushIntegerTree (m2decl_BuildConstLiteralNumber (location, DynamicStrings_string (b), 2, issueError));
5217 : 24 : break;
5218 : :
5219 : 117240 : case 'C':
5220 : 117240 : case 'B':
5221 : 117240 : b = DynamicStrings_Slice (a, 0, -1); /* octal */
5222 : 117240 : M2ALU_PushIntegerTree (m2decl_BuildConstLiteralNumber (location, DynamicStrings_string (b), 8, issueError));
5223 : 117240 : break;
5224 : :
5225 : :
5226 : 428801 : default:
5227 : 428801 : if (IsReal (a))
5228 : : {
5229 : 6406 : M2ALU_PushRealTree (m2type_RealToTree (NameKey_KeyToCharStar (s)));
5230 : : }
5231 : : else
5232 : : {
5233 : 422395 : M2ALU_PushIntegerTree (m2decl_BuildConstLiteralNumber (location, NameKey_KeyToCharStar (s), 10, issueError));
5234 : : }
5235 : : break;
5236 : : }
5237 : : }
5238 : : else
5239 : : {
5240 : 0 : M2Error_InternalError ((const char *) "expecting constant literal", 26);
5241 : : }
5242 : 546807 : a = DynamicStrings_KillString (a);
5243 : 546807 : b = DynamicStrings_KillString (b);
5244 : 546807 : }
5245 : :
5246 : :
5247 : : /*
5248 : : CoerseLongRealToCard - performs a coersion between a REAL to a CARDINAL
5249 : : */
5250 : :
5251 : 0 : extern "C" void M2ALU_CoerseLongRealToCard (void)
5252 : : {
5253 : 0 : M2ALU_PtrToValue v;
5254 : :
5255 : 0 : v = Pop ();
5256 : 0 : if (v->type == M2ALU_real)
5257 : : {
5258 : 0 : v->numberValue = m2convert_ConvertConstantAndCheck (v->location, m2type_GetIntegerType (), v->numberValue);
5259 : 0 : v->type = M2ALU_integer;
5260 : 0 : v->areAllConstants = true;
5261 : 0 : v->solved = true;
5262 : : }
5263 : : else
5264 : : {
5265 : 0 : M2Error_InternalError ((const char *) "expecting a REAL number", 23);
5266 : : }
5267 : 0 : Push (v);
5268 : 0 : }
5269 : :
5270 : :
5271 : : /*
5272 : : ConvertRealToInt - converts a REAL into an INTEGER
5273 : : */
5274 : :
5275 : 0 : extern "C" void M2ALU_ConvertRealToInt (void)
5276 : : {
5277 : 0 : M2ALU_PtrToValue v;
5278 : :
5279 : 0 : v = Pop ();
5280 : 0 : if (v->type == M2ALU_real)
5281 : : {
5282 : 0 : v->numberValue = m2convert_ConvertConstantAndCheck (v->location, m2type_GetIntegerType (), v->numberValue);
5283 : 0 : v->type = M2ALU_integer;
5284 : 0 : v->areAllConstants = true;
5285 : 0 : v->solved = true;
5286 : : }
5287 : : else
5288 : : {
5289 : 0 : M2Error_InternalError ((const char *) "expecting a REAL number", 23);
5290 : : }
5291 : 0 : Push (v);
5292 : 0 : }
5293 : :
5294 : :
5295 : : /*
5296 : : ConvertToInt - converts the value into an INTEGER. This should be used
5297 : : if we are computing the number of elements in a char set to
5298 : : avoid an overflow.
5299 : : */
5300 : :
5301 : 1038140 : extern "C" void M2ALU_ConvertToInt (void)
5302 : : {
5303 : 1038140 : M2ALU_PtrToValue v;
5304 : :
5305 : 1038140 : v = Pop ();
5306 : 1038140 : if (v->type == M2ALU_integer)
5307 : : {
5308 : 1038140 : v->numberValue = m2convert_ConvertConstantAndCheck (v->location, m2type_GetIntegerType (), v->numberValue);
5309 : 1038140 : v->solved = true;
5310 : 1038140 : v->areAllConstants = true;
5311 : : }
5312 : : else
5313 : : {
5314 : 0 : M2Error_InternalError ((const char *) "expecting an INTEGER number", 27);
5315 : : }
5316 : 1038140 : Push (v);
5317 : 1038140 : }
5318 : :
5319 : :
5320 : : /*
5321 : : ConvertToType - converts the top of stack to type, t.
5322 : : */
5323 : :
5324 : 9111 : extern "C" void M2ALU_ConvertToType (unsigned int t)
5325 : : {
5326 : 9111 : M2ALU_PtrToValue v;
5327 : :
5328 : 9111 : v = Pop ();
5329 : 9111 : if (t != SymbolTable_NulSym)
5330 : : {
5331 : 9111 : if (v->type == M2ALU_integer)
5332 : : {
5333 : 9111 : v->numberValue = m2convert_ConvertConstantAndCheck (v->location, SymbolConversion_Mod2Gcc (t), v->numberValue);
5334 : 9111 : v->solved = true;
5335 : 9111 : v->areAllConstants = true;
5336 : : }
5337 : : else
5338 : : {
5339 : 0 : M2Error_InternalError ((const char *) "expecting an INTEGER number", 27);
5340 : : }
5341 : : }
5342 : 9111 : Push (v);
5343 : 9111 : }
5344 : :
5345 : :
5346 : : /*
5347 : : IsSolved - returns true if the memory cell indicated by v
5348 : : has a known value.
5349 : : */
5350 : :
5351 : 3186276 : extern "C" bool M2ALU_IsSolved (M2ALU_PtrToValue v)
5352 : : {
5353 : 3186276 : if (v == NULL)
5354 : : {
5355 : 0 : M2Error_InternalError ((const char *) "uninitialized value", 19);
5356 : : }
5357 : : else
5358 : : {
5359 : 3186276 : return v->solved;
5360 : : }
5361 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2ALU.def", 20, 1);
5362 : : __builtin_unreachable ();
5363 : : }
5364 : :
5365 : :
5366 : : /*
5367 : : PutConstructorSolved - records that this constructor is solved.
5368 : : */
5369 : :
5370 : 2531 : extern "C" void M2ALU_PutConstructorSolved (unsigned int sym)
5371 : : {
5372 : 2531 : M2ALU_PtrToValue v;
5373 : :
5374 : 2531 : SymbolTable_PushValue (sym);
5375 : 2531 : v = Pop ();
5376 : 2531 : v->solved = true;
5377 : 2531 : Push (v);
5378 : 2531 : SymbolTable_PopValue (sym);
5379 : 2531 : }
5380 : :
5381 : :
5382 : : /*
5383 : : EvaluateValue - attempts to evaluate the symbol, sym, value.
5384 : : */
5385 : :
5386 : 5134 : extern "C" void M2ALU_EvaluateValue (unsigned int sym)
5387 : : {
5388 : 5134 : M2ALU_PtrToValue v;
5389 : :
5390 : 5134 : SymbolTable_PushValue (sym);
5391 : 5134 : v = Pop ();
5392 : 5134 : Eval (SymbolTable_GetDeclaredMod (sym), v);
5393 : 5134 : Push (v);
5394 : 5134 : SymbolTable_PopValue (sym);
5395 : 5134 : }
5396 : :
5397 : :
5398 : : /*
5399 : : TryEvaluateValue - attempts to evaluate the symbol, sym, value.
5400 : : */
5401 : :
5402 : 12033 : extern "C" void M2ALU_TryEvaluateValue (unsigned int sym)
5403 : : {
5404 : 12033 : M2ALU_PtrToValue v;
5405 : :
5406 : 12033 : SymbolTable_PushValue (sym);
5407 : 12033 : v = Pop ();
5408 : 12033 : switch (v->type)
5409 : : {
5410 : 11949 : case M2ALU_set:
5411 : 11949 : case M2ALU_array:
5412 : 11949 : case M2ALU_record:
5413 : 11949 : if (v->constructorType == SymbolTable_NulSym)
5414 : : {
5415 : : /* must wait */
5416 : : return ;
5417 : : }
5418 : : else
5419 : : {
5420 : 11949 : Eval (SymbolTable_GetDeclaredMod (sym), v);
5421 : : }
5422 : 11949 : break;
5423 : :
5424 : :
5425 : : default:
5426 : : break;
5427 : : }
5428 : : /* nothing to do */
5429 : 12027 : if (v->solved)
5430 : : {
5431 : 9533 : Push (v);
5432 : 9533 : SymbolTable_PopValue (sym);
5433 : : }
5434 : : }
5435 : :
5436 : 139189 : extern "C" void M2ALU_Addn (void)
5437 : : {
5438 : 139189 : M2ALU_PtrToValue Temp;
5439 : 139189 : M2ALU_PtrToValue Op1;
5440 : 139189 : M2ALU_PtrToValue Op2;
5441 : :
5442 : : /*
5443 : : Add - adds the top two elements on the stack.
5444 : :
5445 : : The Stack:
5446 : :
5447 : : Entry Exit
5448 : :
5449 : : Ptr ->
5450 : : +------------+
5451 : : | Op1 | <- Ptr
5452 : : |------------| +------------+
5453 : : | Op2 | | Op2 + Op1 |
5454 : : |------------| |------------|
5455 : : */
5456 : 139189 : Op1 = Pop ();
5457 : 139189 : Op2 = Pop ();
5458 : 139189 : if (EitherReal (Op1, Op2))
5459 : : {
5460 : 0 : RealAdd (Op1, Op2);
5461 : : }
5462 : 139189 : else if (EitherComplex (Op1, Op2))
5463 : : {
5464 : : /* avoid dangling else. */
5465 : 0 : ComplexAdd (Op1, Op2);
5466 : : }
5467 : : else
5468 : : {
5469 : : /* avoid dangling else. */
5470 : 139189 : Temp = New (); /* as it is a temp */
5471 : 139189 : Temp->location = Op1->location; /* as it is a temp */
5472 : 139189 : Temp->type = M2ALU_integer;
5473 : 139189 : Temp->numberValue = m2expr_BuildAdd (Temp->location, Op1->numberValue, Op2->numberValue, false);
5474 : 139189 : Temp->solved = true;
5475 : 139189 : Push (Temp);
5476 : : }
5477 : 139189 : Dispose (Op1);
5478 : 139189 : Dispose (Op2);
5479 : 139189 : }
5480 : :
5481 : :
5482 : : /*
5483 : : Sub - subtracts the top two elements on the stack.
5484 : :
5485 : : The Stack:
5486 : :
5487 : : Entry Exit
5488 : :
5489 : : Ptr ->
5490 : : +------------+
5491 : : | Op1 | <- Ptr
5492 : : |------------| +------------+
5493 : : | Op2 | | Op2 - Op1 |
5494 : : |------------| |------------|
5495 : : */
5496 : :
5497 : 458566 : extern "C" void M2ALU_Sub (void)
5498 : : {
5499 : 458566 : M2ALU_PtrToValue Temp;
5500 : 458566 : M2ALU_PtrToValue Op1;
5501 : 458566 : M2ALU_PtrToValue Op2;
5502 : :
5503 : 458566 : Op1 = Pop ();
5504 : 458566 : Op2 = Pop ();
5505 : 458566 : if (EitherReal (Op1, Op2))
5506 : : {
5507 : 0 : RealSub (Op1, Op2);
5508 : : }
5509 : 458566 : else if (EitherComplex (Op1, Op2))
5510 : : {
5511 : : /* avoid dangling else. */
5512 : 0 : ComplexSub (Op1, Op2);
5513 : : }
5514 : : else
5515 : : {
5516 : : /* avoid dangling else. */
5517 : 458566 : Temp = New (); /* as it is a temp */
5518 : 458566 : Temp->location = Op1->location; /* as it is a temp */
5519 : 458566 : Temp->type = M2ALU_integer;
5520 : 458566 : Temp->numberValue = m2expr_BuildSub (Temp->location, Op2->numberValue, Op1->numberValue, true);
5521 : 458566 : Temp->solved = true;
5522 : 458566 : Push (Temp);
5523 : : }
5524 : 458566 : Dispose (Op1);
5525 : 458566 : Dispose (Op2);
5526 : 458566 : }
5527 : :
5528 : 0 : extern "C" void M2ALU_Multn (void)
5529 : : {
5530 : 0 : M2ALU_PtrToValue Temp;
5531 : 0 : M2ALU_PtrToValue Op1;
5532 : 0 : M2ALU_PtrToValue Op2;
5533 : :
5534 : : /*
5535 : : Mult - multiplies the top two elements on the stack.
5536 : :
5537 : : The Stack:
5538 : :
5539 : : Entry Exit
5540 : :
5541 : : Ptr ->
5542 : : +------------+
5543 : : | Op1 | <- Ptr
5544 : : |------------| +------------+
5545 : : | Op2 | | Op2 * Op1 |
5546 : : |------------| |------------|
5547 : : */
5548 : 0 : Op1 = Pop ();
5549 : 0 : Op2 = Pop ();
5550 : 0 : if (EitherReal (Op1, Op2))
5551 : : {
5552 : 0 : RealMult (Op1, Op2);
5553 : : }
5554 : 0 : else if (EitherComplex (Op1, Op2))
5555 : : {
5556 : : /* avoid dangling else. */
5557 : 0 : ComplexMult (Op1, Op2);
5558 : : }
5559 : : else
5560 : : {
5561 : : /* avoid dangling else. */
5562 : 0 : Temp = New (); /* as it is a temp */
5563 : 0 : Temp->location = Op1->location; /* as it is a temp */
5564 : 0 : Temp->type = M2ALU_integer;
5565 : 0 : Temp->numberValue = m2expr_BuildMult (Temp->location, Op2->numberValue, Op1->numberValue, false);
5566 : 0 : Temp->solved = true;
5567 : 0 : Push (Temp);
5568 : : }
5569 : 0 : Dispose (Op1);
5570 : 0 : Dispose (Op2);
5571 : 0 : }
5572 : :
5573 : :
5574 : : /*
5575 : : DivFloor - divides the top two elements on the stack.
5576 : :
5577 : : The Stack:
5578 : :
5579 : : Entry Exit
5580 : :
5581 : : Ptr ->
5582 : : +------------+
5583 : : | Op1 | <- Ptr
5584 : : |------------| +--------------+
5585 : : | Op2 | | Op2 DIV Op1 |
5586 : : |------------| |--------------|
5587 : : */
5588 : :
5589 : 0 : extern "C" void M2ALU_DivFloor (void)
5590 : : {
5591 : 0 : M2ALU_PtrToValue Temp;
5592 : 0 : M2ALU_PtrToValue Op1;
5593 : 0 : M2ALU_PtrToValue Op2;
5594 : :
5595 : 0 : Op1 = Pop ();
5596 : 0 : Op2 = Pop ();
5597 : 0 : if (EitherReal (Op1, Op2))
5598 : : {
5599 : 0 : RealDiv (Op1, Op2);
5600 : : }
5601 : 0 : else if (EitherComplex (Op1, Op2))
5602 : : {
5603 : : /* avoid dangling else. */
5604 : 0 : ComplexDiv (Op1, Op2);
5605 : : }
5606 : : else
5607 : : {
5608 : : /* avoid dangling else. */
5609 : 0 : Temp = New (); /* as it is a temp */
5610 : 0 : Temp->location = Op1->location; /* as it is a temp */
5611 : 0 : Temp->type = M2ALU_integer;
5612 : 0 : Temp->numberValue = m2expr_BuildDivFloor (Temp->location, Op2->numberValue, Op1->numberValue, false);
5613 : 0 : Temp->solved = true;
5614 : 0 : Push (Temp);
5615 : : }
5616 : 0 : Dispose (Op1);
5617 : 0 : Dispose (Op2);
5618 : 0 : }
5619 : :
5620 : :
5621 : : /*
5622 : : ModFloor - modulus of the top two elements on the stack.
5623 : :
5624 : : The Stack:
5625 : :
5626 : : Entry Exit
5627 : :
5628 : : Ptr ->
5629 : : +------------+
5630 : : | Op1 | <- Ptr
5631 : : |------------| +--------------+
5632 : : | Op2 | | Op2 MOD Op1 |
5633 : : |------------| |--------------|
5634 : : */
5635 : :
5636 : 0 : extern "C" void M2ALU_ModFloor (void)
5637 : : {
5638 : 0 : M2ALU_PtrToValue Temp;
5639 : 0 : M2ALU_PtrToValue Op1;
5640 : 0 : M2ALU_PtrToValue Op2;
5641 : :
5642 : 0 : Op1 = Pop ();
5643 : 0 : Op2 = Pop ();
5644 : 0 : if (EitherReal (Op1, Op2))
5645 : : {
5646 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkMOD} on REAL types", 37);
5647 : : }
5648 : 0 : else if (EitherComplex (Op1, Op2))
5649 : : {
5650 : : /* avoid dangling else. */
5651 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkMOD} on COMPLEX types", 40);
5652 : : }
5653 : : else
5654 : : {
5655 : : /* avoid dangling else. */
5656 : 0 : Temp = New (); /* as it is a temp */
5657 : 0 : Temp->location = Op1->location; /* as it is a temp */
5658 : 0 : Temp->type = M2ALU_integer;
5659 : 0 : Temp->numberValue = m2expr_BuildModFloor (Temp->location, Op2->numberValue, Op1->numberValue, false);
5660 : 0 : Temp->solved = true;
5661 : 0 : Push (Temp);
5662 : : }
5663 : 0 : Dispose (Op1);
5664 : 0 : Dispose (Op2);
5665 : 0 : }
5666 : :
5667 : :
5668 : : /*
5669 : : DivTrunc - divides the top two elements on the stack.
5670 : :
5671 : : The Stack:
5672 : :
5673 : : Entry Exit
5674 : :
5675 : : Ptr ->
5676 : : +------------+
5677 : : | Op1 | <- Ptr
5678 : : |------------| +--------------+
5679 : : | Op2 | | Op2 DIV Op1 |
5680 : : |------------| |--------------|
5681 : : */
5682 : :
5683 : 0 : extern "C" void M2ALU_DivTrunc (void)
5684 : : {
5685 : 0 : M2ALU_PtrToValue Temp;
5686 : 0 : M2ALU_PtrToValue Op1;
5687 : 0 : M2ALU_PtrToValue Op2;
5688 : :
5689 : 0 : Op1 = Pop ();
5690 : 0 : Op2 = Pop ();
5691 : 0 : if (EitherReal (Op1, Op2))
5692 : : {
5693 : 0 : RealDiv (Op1, Op2);
5694 : : }
5695 : 0 : else if (EitherComplex (Op1, Op2))
5696 : : {
5697 : : /* avoid dangling else. */
5698 : 0 : ComplexDiv (Op1, Op2);
5699 : : }
5700 : : else
5701 : : {
5702 : : /* avoid dangling else. */
5703 : 0 : Temp = New (); /* as it is a temp */
5704 : 0 : Temp->location = Op1->location; /* as it is a temp */
5705 : 0 : Temp->type = M2ALU_integer;
5706 : 0 : Temp->numberValue = m2expr_BuildDivTrunc (Temp->location, Op2->numberValue, Op1->numberValue, false);
5707 : 0 : Temp->solved = true;
5708 : 0 : Push (Temp);
5709 : : }
5710 : 0 : Dispose (Op1);
5711 : 0 : Dispose (Op2);
5712 : 0 : }
5713 : :
5714 : :
5715 : : /*
5716 : : ModTrunc - modulus of the top two elements on the stack.
5717 : :
5718 : : The Stack:
5719 : :
5720 : : Entry Exit
5721 : :
5722 : : Ptr ->
5723 : : +------------+
5724 : : | Op1 | <- Ptr
5725 : : |------------| +--------------+
5726 : : | Op2 | | Op2 MOD Op1 |
5727 : : |------------| |--------------|
5728 : : */
5729 : :
5730 : 0 : extern "C" void M2ALU_ModTrunc (void)
5731 : : {
5732 : 0 : M2ALU_PtrToValue Temp;
5733 : 0 : M2ALU_PtrToValue Op1;
5734 : 0 : M2ALU_PtrToValue Op2;
5735 : :
5736 : 0 : Op1 = Pop ();
5737 : 0 : Op2 = Pop ();
5738 : 0 : if (EitherReal (Op1, Op2))
5739 : : {
5740 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkMOD} on REAL types", 37);
5741 : : }
5742 : 0 : else if (EitherComplex (Op1, Op2))
5743 : : {
5744 : : /* avoid dangling else. */
5745 : 0 : M2MetaError_MetaError0 ((const char *) "cannot perform {%EkMOD} on COMPLEX types", 40);
5746 : : }
5747 : : else
5748 : : {
5749 : : /* avoid dangling else. */
5750 : 0 : Temp = New (); /* as it is a temp */
5751 : 0 : Temp->location = Op1->location; /* as it is a temp */
5752 : 0 : Temp->type = M2ALU_integer;
5753 : 0 : Temp->numberValue = m2expr_BuildModTrunc (Temp->location, Op2->numberValue, Op1->numberValue, false);
5754 : 0 : Temp->solved = true;
5755 : 0 : Push (Temp);
5756 : : }
5757 : 0 : Dispose (Op1);
5758 : 0 : Dispose (Op2);
5759 : 0 : }
5760 : :
5761 : :
5762 : : /*
5763 : : Equ - returns true if the top two elements on the stack
5764 : : are identical.
5765 : :
5766 : : The Stack:
5767 : :
5768 : : Entry Exit
5769 : :
5770 : : Ptr ->
5771 : : +------------+
5772 : : | Op1 |
5773 : : |------------|
5774 : : | Op2 |
5775 : : |------------| Empty
5776 : :
5777 : : RETURN( Op2 = Op1 )
5778 : : */
5779 : :
5780 : 1327422 : extern "C" bool M2ALU_Equ (unsigned int tokenno)
5781 : : {
5782 : 1327422 : M2ALU_PtrToValue Op1;
5783 : 1327422 : M2ALU_PtrToValue Op2;
5784 : 1327422 : bool result;
5785 : :
5786 : 1327422 : Op1 = Pop ();
5787 : 1327422 : Op2 = Pop ();
5788 : 1327422 : if ((Op1->type == M2ALU_set) && (Op2->type == M2ALU_set))
5789 : : {
5790 : 0 : result = AreSetsEqual (tokenno, Op1, Op2);
5791 : : }
5792 : 1327422 : else if ((Op1->type == M2ALU_set) || (Op2->type == M2ALU_set))
5793 : : {
5794 : : /* avoid dangling else. */
5795 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "cannot perform a comparison between a number and a set", 54);
5796 : 0 : result = false;
5797 : : }
5798 : : else
5799 : : {
5800 : : /* avoid dangling else. */
5801 : 1327422 : if (Op1->type != Op2->type)
5802 : : {
5803 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "cannot perform a comparison between a different type constants", 62);
5804 : 0 : result = false;
5805 : : }
5806 : 1327422 : else if ((Op1->type == M2ALU_complex) || (Op1->type == M2ALU_real))
5807 : : {
5808 : : /* avoid dangling else. */
5809 : 54 : result = m2expr_AreRealOrComplexConstantsEqual (Op1->numberValue, Op2->numberValue);
5810 : : }
5811 : : else
5812 : : {
5813 : : /* avoid dangling else. */
5814 : 1327368 : result = m2expr_AreConstantsEqual (Op1->numberValue, Op2->numberValue);
5815 : : }
5816 : : }
5817 : 1327422 : Dispose (Op1);
5818 : 1327422 : Dispose (Op2);
5819 : 1327422 : return result;
5820 : : /* static analysis guarentees a RETURN statement will be used before here. */
5821 : : __builtin_unreachable ();
5822 : : }
5823 : :
5824 : :
5825 : : /*
5826 : : NotEqu - returns true if the top two elements on the stack
5827 : : are not identical.
5828 : :
5829 : : The Stack:
5830 : :
5831 : : Entry Exit
5832 : :
5833 : : Ptr ->
5834 : : +------------+
5835 : : | Op1 |
5836 : : |------------|
5837 : : | Op2 |
5838 : : |------------| Empty
5839 : :
5840 : : RETURN( Op2 # Op1 )
5841 : : */
5842 : :
5843 : 1307 : extern "C" bool M2ALU_NotEqu (unsigned int tokenno)
5844 : : {
5845 : 1307 : return ! (M2ALU_Equ (tokenno));
5846 : : /* static analysis guarentees a RETURN statement will be used before here. */
5847 : : __builtin_unreachable ();
5848 : : }
5849 : :
5850 : :
5851 : : /*
5852 : : Less - returns true if Op2 < Op1
5853 : :
5854 : : The Stack:
5855 : :
5856 : : Entry Exit
5857 : :
5858 : : Ptr ->
5859 : : +------------+
5860 : : | Op1 |
5861 : : |------------|
5862 : : | Op2 |
5863 : : |------------| Empty
5864 : :
5865 : : RETURN( Op2 < Op1 )
5866 : : */
5867 : :
5868 : 3099232 : extern "C" bool M2ALU_Less (unsigned int tokenno)
5869 : : {
5870 : 3099232 : M2ALU_PtrToValue v1;
5871 : 3099232 : M2ALU_PtrToValue v2;
5872 : 3099232 : bool result;
5873 : 3099232 : int res;
5874 : :
5875 : 3099232 : v1 = Pop ();
5876 : 3099232 : v2 = Pop ();
5877 : 3099232 : if ((v1->type == M2ALU_set) && (v2->type == M2ALU_set))
5878 : : {
5879 : 0 : result = ! (IsSuperset (tokenno, v2, v1));
5880 : : }
5881 : 3099232 : else if ((v1->type == M2ALU_set) || (v2->type == M2ALU_set))
5882 : : {
5883 : : /* avoid dangling else. */
5884 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "cannot perform a comparison between a number and a set", 54);
5885 : 0 : result = false;
5886 : : }
5887 : : else
5888 : : {
5889 : : /* avoid dangling else. */
5890 : 3099232 : res = m2expr_CompareTrees (v2->numberValue, v1->numberValue);
5891 : 3099232 : if (res == -1)
5892 : : {
5893 : : result = true;
5894 : : }
5895 : : else
5896 : : {
5897 : 1447963 : result = false;
5898 : : }
5899 : : }
5900 : : /* result := (CompareTrees(v2^.numberValue, v1^.numberValue)=-1) */
5901 : 3099232 : Dispose (v1);
5902 : 3099232 : Dispose (v2);
5903 : 3099232 : return result;
5904 : : /* static analysis guarentees a RETURN statement will be used before here. */
5905 : : __builtin_unreachable ();
5906 : : }
5907 : :
5908 : :
5909 : : /*
5910 : : Gre - returns true if Op2 > Op1
5911 : :
5912 : : The Stack:
5913 : :
5914 : : Entry Exit
5915 : :
5916 : : Ptr ->
5917 : : +------------+
5918 : : | Op1 |
5919 : : |------------|
5920 : : | Op2 |
5921 : : |------------| Empty
5922 : :
5923 : : RETURN( Op2 > Op1 )
5924 : : */
5925 : :
5926 : 3143931 : extern "C" bool M2ALU_Gre (unsigned int tokenno)
5927 : : {
5928 : 3143931 : M2ALU_PtrToValue v1;
5929 : 3143931 : M2ALU_PtrToValue v2;
5930 : 3143931 : bool result;
5931 : :
5932 : 3143931 : v1 = Pop ();
5933 : 3143931 : v2 = Pop ();
5934 : 3143931 : if ((v1->type == M2ALU_set) && (v2->type == M2ALU_set))
5935 : : {
5936 : 0 : result = ! (IsSubset (tokenno, v2, v1));
5937 : : }
5938 : 3143931 : else if ((v1->type == M2ALU_set) || (v2->type == M2ALU_set))
5939 : : {
5940 : : /* avoid dangling else. */
5941 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "cannot perform a comparison between a number and a set", 54);
5942 : 0 : M2Error_FlushErrors ();
5943 : 0 : result = false;
5944 : : }
5945 : : else
5946 : : {
5947 : : /* avoid dangling else. */
5948 : 3143931 : result = (m2expr_CompareTrees (v2->numberValue, v1->numberValue)) == 1;
5949 : : }
5950 : 3143931 : Dispose (v1);
5951 : 3143931 : Dispose (v2);
5952 : 3143931 : return result;
5953 : : /* static analysis guarentees a RETURN statement will be used before here. */
5954 : : __builtin_unreachable ();
5955 : : }
5956 : :
5957 : :
5958 : : /*
5959 : : LessEqu - returns true if Op2<Op1
5960 : :
5961 : : The Stack:
5962 : :
5963 : : Entry Exit
5964 : :
5965 : : Ptr ->
5966 : : +------------+
5967 : : | Op1 |
5968 : : |------------|
5969 : : | Op2 |
5970 : : |------------| Empty
5971 : :
5972 : : RETURN( Op2 <= Op1 )
5973 : : */
5974 : :
5975 : 40 : extern "C" bool M2ALU_LessEqu (unsigned int tokenno)
5976 : : {
5977 : 40 : M2ALU_PtrToValue v1;
5978 : 40 : M2ALU_PtrToValue v2;
5979 : 40 : bool result;
5980 : :
5981 : 40 : v1 = Pop ();
5982 : 40 : v2 = Pop ();
5983 : 40 : if ((v1->type == M2ALU_set) && (v2->type == M2ALU_set))
5984 : : {
5985 : 0 : result = IsSubset (tokenno, v2, v1);
5986 : : }
5987 : 40 : else if ((v1->type == M2ALU_set) || (v2->type == M2ALU_set))
5988 : : {
5989 : : /* avoid dangling else. */
5990 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "cannot perform a comparison between a number and a set", 54);
5991 : 0 : M2Error_FlushErrors ();
5992 : 0 : result = false;
5993 : : }
5994 : : else
5995 : : {
5996 : : /* avoid dangling else. */
5997 : 40 : result = (m2expr_CompareTrees (v2->numberValue, v1->numberValue)) <= 0;
5998 : : }
5999 : 40 : Dispose (v1);
6000 : 40 : Dispose (v2);
6001 : 40 : return result;
6002 : : /* static analysis guarentees a RETURN statement will be used before here. */
6003 : : __builtin_unreachable ();
6004 : : }
6005 : :
6006 : :
6007 : : /*
6008 : : GreEqu - returns true if Op2 >= Op1
6009 : : are not identical.
6010 : :
6011 : : The Stack:
6012 : :
6013 : : Entry Exit
6014 : :
6015 : : Ptr ->
6016 : : +------------+
6017 : : | Op1 |
6018 : : |------------|
6019 : : | Op2 |
6020 : : |------------| Empty
6021 : :
6022 : : RETURN( Op2 >= Op1 )
6023 : : */
6024 : :
6025 : 640551 : extern "C" bool M2ALU_GreEqu (unsigned int tokenno)
6026 : : {
6027 : 640551 : M2ALU_PtrToValue v1;
6028 : 640551 : M2ALU_PtrToValue v2;
6029 : 640551 : bool result;
6030 : :
6031 : 640551 : v1 = Pop ();
6032 : 640551 : v2 = Pop ();
6033 : 640551 : if ((v1->type == M2ALU_set) && (v2->type == M2ALU_set))
6034 : : {
6035 : 0 : result = IsSuperset (tokenno, v2, v1);
6036 : : }
6037 : 640551 : else if ((v1->type == M2ALU_set) || (v2->type == M2ALU_set))
6038 : : {
6039 : : /* avoid dangling else. */
6040 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "cannot perform a comparison between a number and a set", 54);
6041 : 0 : M2Error_FlushErrors ();
6042 : 0 : result = false;
6043 : : }
6044 : : else
6045 : : {
6046 : : /* avoid dangling else. */
6047 : 640551 : result = (m2expr_CompareTrees (v2->numberValue, v1->numberValue)) >= 0;
6048 : : }
6049 : 640551 : Dispose (v1);
6050 : 640551 : Dispose (v2);
6051 : 640551 : return result;
6052 : : /* static analysis guarentees a RETURN statement will be used before here. */
6053 : : __builtin_unreachable ();
6054 : : }
6055 : :
6056 : :
6057 : : /*
6058 : : IsNulSet - returns TRUE if the top element is the nul set constant, {}.
6059 : : */
6060 : :
6061 : 0 : extern "C" bool M2ALU_IsNulSet (void)
6062 : : {
6063 : 0 : M2ALU_PtrToValue v;
6064 : 0 : bool r;
6065 : :
6066 : 0 : v = Pop ();
6067 : 0 : r = (v->type == M2ALU_set) && (v->setValue == NULL);
6068 : 0 : Push (v);
6069 : 0 : return r;
6070 : : /* static analysis guarentees a RETURN statement will be used before here. */
6071 : : __builtin_unreachable ();
6072 : : }
6073 : :
6074 : :
6075 : : /*
6076 : : IsGenericNulSet - returns TRUE if the top element is the generic nul set constant, {}.
6077 : : */
6078 : :
6079 : 0 : extern "C" bool M2ALU_IsGenericNulSet (void)
6080 : : {
6081 : 0 : M2ALU_PtrToValue v;
6082 : 0 : bool r;
6083 : :
6084 : 0 : v = Pop ();
6085 : 0 : r = ((v->type == M2ALU_set) && (v->setValue == NULL)) && (v->constructorType == SymbolTable_NulSym);
6086 : 0 : Push (v);
6087 : 0 : return r;
6088 : : /* static analysis guarentees a RETURN statement will be used before here. */
6089 : : __builtin_unreachable ();
6090 : : }
6091 : :
6092 : :
6093 : : /*
6094 : : PushNulSet - pushes an empty set {} onto the ALU stack. The subrange type used
6095 : : to construct the set is defined by, constructorType.
6096 : : If this is NulSym then
6097 : : the set is generic and compatible with all sets.
6098 : :
6099 : : The Stack:
6100 : :
6101 : : Entry Exit
6102 : :
6103 : : <- Ptr
6104 : : +------------+
6105 : : | {} |
6106 : : Ptr -> |------------|
6107 : :
6108 : : */
6109 : :
6110 : 0 : extern "C" void M2ALU_PushNulSet (unsigned int settype)
6111 : : {
6112 : 0 : M2ALU_PtrToValue v;
6113 : :
6114 : 0 : v = M2ALU_InitValue ();
6115 : 0 : v->type = M2ALU_set;
6116 : 0 : v->constructorType = settype;
6117 : 0 : v->areAllConstants = true;
6118 : 0 : v->solved = M2GCCDeclare_CompletelyResolved (settype);
6119 : 0 : v->setValue = NULL;
6120 : 0 : v->next = NULL;
6121 : 0 : Push (v);
6122 : 0 : }
6123 : :
6124 : :
6125 : : /*
6126 : : AddBitRange - adds the range op1..op2 to the underlying set.
6127 : :
6128 : : Ptr ->
6129 : : <- Ptr
6130 : : +------------+ +------------+
6131 : : | Set | | Set |
6132 : : |------------| |------------|
6133 : :
6134 : : */
6135 : :
6136 : 10879 : extern "C" void M2ALU_AddBitRange (unsigned int tokenno, unsigned int op1, unsigned int op2)
6137 : : {
6138 : 10879 : M2ALU_PtrToValue v;
6139 : :
6140 : 10879 : v = Pop ();
6141 : 10879 : v = CoerseTo (tokenno, M2ALU_set, v);
6142 : 10879 : if (v->type == M2ALU_set)
6143 : : {
6144 : 10879 : v->setValue = AddRange (v->setValue, op1, op2);
6145 : 10879 : v->solved = (v->solved && (IsSolvedGCC (op1))) && (IsSolvedGCC (op2));
6146 : 10885 : v->areAllConstants = (v->areAllConstants && (SymbolTable_IsConst (op1))) && (SymbolTable_IsConst (op2));
6147 : : }
6148 : 10879 : Push (v);
6149 : 10879 : }
6150 : :
6151 : :
6152 : : /*
6153 : : AddBit - adds the bit op1 to the underlying set. INCL(Set, op1)
6154 : :
6155 : : Ptr ->
6156 : : <- Ptr
6157 : : +------------+ +------------+
6158 : : | Set | | Set |
6159 : : |------------| |------------|
6160 : : */
6161 : :
6162 : 10637 : extern "C" void M2ALU_AddBit (unsigned int tokenno, unsigned int op1)
6163 : : {
6164 : 10637 : M2ALU_AddBitRange (tokenno, op1, op1);
6165 : 10637 : }
6166 : :
6167 : :
6168 : : /*
6169 : : SubBit - removes a bit op1 from the underlying set. EXCL(Set, Op1)
6170 : :
6171 : : Ptr ->
6172 : : <- Ptr
6173 : : +------------+ +------------+
6174 : : | Set | | Set |
6175 : : |------------| |------------|
6176 : : */
6177 : :
6178 : 0 : extern "C" void M2ALU_SubBit (unsigned int tokenno, unsigned int op1)
6179 : : {
6180 : 0 : M2ALU_PtrToValue v;
6181 : :
6182 : 0 : v = Pop ();
6183 : 0 : if (v->type == M2ALU_set)
6184 : : {
6185 : 0 : Eval (tokenno, v);
6186 : 0 : if (v->solved)
6187 : : {
6188 : 0 : if (IsSolvedGCC (op1))
6189 : : {
6190 : 0 : PerformSubBit (tokenno, &v->setValue, op1);
6191 : 0 : v->solved = false;
6192 : : }
6193 : : else
6194 : : {
6195 : 0 : M2Error_InternalError ((const char *) "can only subtract a bit from a set when the bit value is known", 62);
6196 : : }
6197 : : }
6198 : : else
6199 : : {
6200 : 0 : M2Error_InternalError ((const char *) "can only subtract a bit from a set when the set value is known", 62);
6201 : : }
6202 : 0 : Eval (tokenno, v);
6203 : : }
6204 : : else
6205 : : {
6206 : 0 : M2Error_InternalError ((const char *) "expecting set type constant", 27);
6207 : : }
6208 : 0 : Push (v);
6209 : 0 : }
6210 : :
6211 : :
6212 : : /*
6213 : : SetIn - returns true if Op2 IN Op1
6214 : :
6215 : : The Stack:
6216 : :
6217 : : Entry Exit
6218 : :
6219 : : Ptr ->
6220 : : +------------+
6221 : : | Set |
6222 : : |------------| Empty
6223 : :
6224 : : RETURN( Op1 IN Set )
6225 : : */
6226 : :
6227 : 0 : extern "C" bool M2ALU_SetIn (unsigned int tokenno, unsigned int Op1)
6228 : : {
6229 : 0 : M2ALU_PtrToValue Set;
6230 : 0 : bool result;
6231 : :
6232 : 0 : Set = Pop ();
6233 : 0 : if (Set->type != M2ALU_set)
6234 : : {
6235 : 0 : M2Error_InternalError ((const char *) "expecting ALU operand to be a set", 33);
6236 : : }
6237 : 0 : Eval (tokenno, Set);
6238 : 0 : if ((IsSolvedGCC (Op1)) && Set->solved)
6239 : : {
6240 : 0 : result = PerformSetIn (tokenno, Op1, Set->setValue);
6241 : : }
6242 : : else
6243 : : {
6244 : 0 : M2Error_InternalError ((const char *) "one or more operands have not been resolved", 43);
6245 : : }
6246 : 0 : Dispose (Set);
6247 : 0 : return result;
6248 : : /* static analysis guarentees a RETURN statement will be used before here. */
6249 : : __builtin_unreachable ();
6250 : : }
6251 : :
6252 : :
6253 : : /*
6254 : : SetOr - performs an inclusive OR of the top two elements on the stack.
6255 : :
6256 : : The Stack:
6257 : :
6258 : : Entry Exit
6259 : :
6260 : : Ptr ->
6261 : : +------------+
6262 : : | Set1 | <- Ptr
6263 : : |------------| +------------+
6264 : : | Set2 | | Set1 + Set2|
6265 : : |------------| |------------|
6266 : :
6267 : : */
6268 : :
6269 : 212 : extern "C" void M2ALU_SetOr (unsigned int tokenno)
6270 : : {
6271 : 212 : SetOp (tokenno, (M2ALU_DoSetProcedure) {(M2ALU_DoSetProcedure_t) PerformOr});
6272 : 212 : }
6273 : :
6274 : :
6275 : : /*
6276 : : SetAnd - performs a set AND the top two elements on the stack.
6277 : :
6278 : : The Stack:
6279 : :
6280 : : Entry Exit
6281 : :
6282 : : Ptr ->
6283 : : +------------+
6284 : : | Op1 | <- Ptr
6285 : : |------------| +------------+
6286 : : | Op2 | | Op2 * Op1 |
6287 : : |------------| |------------|
6288 : : */
6289 : :
6290 : 6 : extern "C" void M2ALU_SetAnd (unsigned int tokenno)
6291 : : {
6292 : 6 : SetOp (tokenno, (M2ALU_DoSetProcedure) {(M2ALU_DoSetProcedure_t) PerformAnd});
6293 : 6 : }
6294 : :
6295 : :
6296 : : /*
6297 : : SetDifference - performs a set difference of the top two elements on the stack.
6298 : : For each member in the set
6299 : : if member in Op2 and not member in Op1
6300 : :
6301 : : The Stack:
6302 : :
6303 : : Entry Exit
6304 : :
6305 : : Ptr ->
6306 : : +------------+
6307 : : | Op1 | <- Ptr
6308 : : |------------| +-------------------+
6309 : : | Op2 | | Op2 and (not Op1) |
6310 : : |------------| |-------------------|
6311 : : */
6312 : :
6313 : 6 : extern "C" void M2ALU_SetDifference (unsigned int tokenno)
6314 : : {
6315 : 6 : M2ALU_PtrToValue Set1;
6316 : 6 : M2ALU_PtrToValue Set2;
6317 : :
6318 : 6 : Set1 = Pop ();
6319 : 6 : Set2 = Pop ();
6320 : 6 : Eval (tokenno, Set1);
6321 : 6 : Eval (tokenno, Set2);
6322 : 6 : if (! (Set1->solved && Set2->solved))
6323 : : {
6324 : 0 : M2Error_InternalError ((const char *) "one or more operands have not been resolved", 43);
6325 : : }
6326 : 6 : if (Set1->setValue == NULL)
6327 : : {
6328 : : /* null set, return Set2 */
6329 : 0 : Push (Set1);
6330 : : }
6331 : : else
6332 : : {
6333 : 6 : Push (Set1);
6334 : 6 : M2ALU_SetNegate (tokenno);
6335 : 6 : Push (Set2);
6336 : 6 : M2ALU_SetAnd (tokenno);
6337 : : }
6338 : 6 : }
6339 : :
6340 : :
6341 : : /*
6342 : : SetSymmetricDifference - performs a set difference of the top two elements on the stack.
6343 : :
6344 : : The Stack:
6345 : :
6346 : : Entry Exit
6347 : :
6348 : : Ptr ->
6349 : : +------------+
6350 : : | Op1 | <- Ptr
6351 : : |------------| +-------------+
6352 : : | Op2 | | Op2 xor Op1 |
6353 : : |------------| |-------------|
6354 : : */
6355 : :
6356 : 0 : extern "C" void M2ALU_SetSymmetricDifference (unsigned int tokenno)
6357 : : {
6358 : 0 : M2ALU_PtrToValue Set1;
6359 : 0 : M2ALU_PtrToValue Set2;
6360 : :
6361 : 0 : Set1 = Pop ();
6362 : 0 : Set2 = Pop ();
6363 : 0 : Eval (tokenno, Set1);
6364 : 0 : Eval (tokenno, Set2);
6365 : 0 : if (! (Set1->solved && Set2->solved))
6366 : : {
6367 : 0 : M2Error_InternalError ((const char *) "one or more operands have not been resolved", 43);
6368 : : }
6369 : 0 : if (Set1->setValue == NULL)
6370 : : {
6371 : 0 : Dispose (Set1);
6372 : 0 : Push (Set2);
6373 : : }
6374 : 0 : else if (Set2->setValue == NULL)
6375 : : {
6376 : : /* avoid dangling else. */
6377 : 0 : Dispose (Set2);
6378 : 0 : Push (Set1);
6379 : : }
6380 : : else
6381 : : {
6382 : : /* avoid dangling else. */
6383 : : /* Set1 or Set2 and (not (Set1 and Set2)) */
6384 : 0 : M2ALU_PushFrom (Set1);
6385 : 0 : M2ALU_PushFrom (Set2);
6386 : 0 : M2ALU_SetAnd (tokenno);
6387 : 0 : M2ALU_SetNegate (tokenno);
6388 : 0 : Push (Set1);
6389 : 0 : Push (Set2);
6390 : 0 : M2ALU_SetOr (tokenno);
6391 : 0 : M2ALU_SetAnd (tokenno);
6392 : : }
6393 : 0 : }
6394 : :
6395 : :
6396 : : /*
6397 : : SetNegate - negates the top set on the stack.
6398 : :
6399 : : Ptr -> <- Ptr
6400 : : +-----------+ +------------+
6401 : : | Set | | Set |
6402 : : |-----------| |------------|
6403 : : */
6404 : :
6405 : 10 : extern "C" void M2ALU_SetNegate (unsigned int tokenno)
6406 : : {
6407 : 10 : unsigned int min;
6408 : 10 : unsigned int max;
6409 : 10 : M2ALU_listOfRange r;
6410 : 10 : M2ALU_listOfRange s;
6411 : 10 : M2ALU_PtrToValue v;
6412 : 10 : unsigned int i;
6413 : :
6414 : 10 : v = Pop ();
6415 : 10 : Eval (tokenno, v);
6416 : 10 : if (v->constructorType == SymbolTable_NulSym)
6417 : : {
6418 : 0 : M2MetaError_MetaError0 ((const char *) "cannot negate a generic set, set should be prefixed by a simple type", 68);
6419 : : }
6420 : 10 : r = NULL;
6421 : 10 : min = M2GCCDeclare_GetTypeMin (SymbolTable_GetType (v->constructorType));
6422 : 10 : max = M2GCCDeclare_GetTypeMax (SymbolTable_GetType (v->constructorType));
6423 : 10 : i = min;
6424 : 10 : s = v->setValue;
6425 : 10 : if (Debugging)
6426 : : {
6427 : : M2Printf_printf0 ((const char *) "attempting to negate set\\n", 26);
6428 : : DisplayElements (s);
6429 : : }
6430 : 22 : while (s != NULL)
6431 : : {
6432 : 12 : SymbolTable_PushValue (s->low);
6433 : 12 : SymbolTable_PushValue (min);
6434 : 12 : if (M2ALU_Gre (tokenno))
6435 : : {
6436 : 12 : SymbolTable_PushValue (i);
6437 : 12 : SymbolTable_PushValue (max);
6438 : 12 : if (M2ALU_LessEqu (tokenno))
6439 : : {
6440 : 12 : r = AddRange (r, i, DupConst (tokenno, s->low, -1));
6441 : : }
6442 : : }
6443 : 12 : SymbolTable_PushValue (s->high);
6444 : 12 : SymbolTable_PushValue (max);
6445 : 12 : if (M2ALU_Less (tokenno))
6446 : : {
6447 : 12 : i = DupConst (tokenno, s->high, 1);
6448 : 12 : s = s->next;
6449 : : }
6450 : : else
6451 : : {
6452 : : s = NULL;
6453 : : }
6454 : : }
6455 : 10 : if (Debugging)
6456 : : {
6457 : : M2Printf_printf0 ((const char *) "negated set so far\\n", 20);
6458 : : DisplayElements (r);
6459 : : }
6460 : 10 : DisposeRange (&v->setValue);
6461 : 10 : SymbolTable_PushValue (i);
6462 : 10 : SymbolTable_PushValue (max);
6463 : 10 : if (M2ALU_LessEqu (tokenno))
6464 : : {
6465 : 10 : r = AddRange (r, i, max);
6466 : : }
6467 : 10 : if (Debugging)
6468 : : {
6469 : : M2Printf_printf0 ((const char *) "final negated set value\\n", 25);
6470 : : DisplayElements (r);
6471 : : }
6472 : 10 : v->solved = false;
6473 : 10 : v->setValue = r;
6474 : 10 : Eval (tokenno, v);
6475 : 10 : Push (v);
6476 : 10 : }
6477 : :
6478 : :
6479 : : /*
6480 : : SetShift - if op1 is positive
6481 : : then
6482 : : result := op2 << op1
6483 : : else
6484 : : result := op2 >> op1
6485 : : fi
6486 : :
6487 : :
6488 : : The Stack:
6489 : :
6490 : : Entry Exit
6491 : :
6492 : : Ptr ->
6493 : : +------------+
6494 : : | Op1 | <- Ptr
6495 : : |------------| +------------+
6496 : : | Op2 | | result |
6497 : : |------------| |------------|
6498 : :
6499 : : */
6500 : :
6501 : 0 : extern "C" void M2ALU_SetShift (unsigned int tokenno)
6502 : : {
6503 : 0 : M2ALU_PtrToValue res;
6504 : 0 : M2ALU_PtrToValue Shift;
6505 : 0 : M2ALU_PtrToValue Set;
6506 : 0 : unsigned int n;
6507 : 0 : unsigned int r1;
6508 : 0 : unsigned int r2;
6509 : :
6510 : 0 : if (! (M2ALU_IsValueTypeInteger ()))
6511 : : {
6512 : 0 : M2Error_InternalError ((const char *) "expecting integer type", 22);
6513 : : }
6514 : 0 : Shift = Pop ();
6515 : 0 : if (! (M2ALU_IsValueTypeSet ()))
6516 : : {
6517 : 0 : M2Error_InternalError ((const char *) "expecting set type", 18);
6518 : : }
6519 : 0 : Set = Pop ();
6520 : 0 : Eval (tokenno, Set);
6521 : 0 : if (! Set->solved)
6522 : : {
6523 : 0 : M2Error_InternalError ((const char *) "set has not been resolved", 25);
6524 : : }
6525 : 0 : if (Set->setValue == NULL)
6526 : : {
6527 : 0 : Push (Set);
6528 : : }
6529 : : else
6530 : : {
6531 : 0 : res = New ();
6532 : 0 : (*res) = (*Set);
6533 : 0 : res->setValue = NULL;
6534 : 0 : n = 1;
6535 : 0 : while (M2ALU_GetRange (Set, n, &r1, &r2))
6536 : : {
6537 : 0 : res->setValue = AddRange (res->setValue, DupConstAndAdd (tokenno, r1, reinterpret_cast<m2tree_Tree> (Shift)), DupConstAndAdd (tokenno, r2, reinterpret_cast<m2tree_Tree> (Shift)));
6538 : 0 : n += 1;
6539 : : }
6540 : 0 : Push (res);
6541 : 0 : if (res->constructorType != SymbolTable_NulSym)
6542 : : {
6543 : 0 : M2ALU_PushNulSet (res->constructorType);
6544 : 0 : M2ALU_SetNegate (tokenno);
6545 : 0 : M2ALU_SetAnd (tokenno);
6546 : : }
6547 : 0 : Dispose (Set);
6548 : : }
6549 : 0 : }
6550 : :
6551 : :
6552 : : /*
6553 : : SetRotate - if op1 is positive
6554 : : then
6555 : : result := ROTATERIGHT(op2, op1)
6556 : : else
6557 : : result := ROTATELEFT(op2, op1)
6558 : : fi
6559 : :
6560 : :
6561 : : The Stack:
6562 : :
6563 : : Entry Exit
6564 : :
6565 : : Ptr ->
6566 : : +------------+
6567 : : | Op1 | <- Ptr
6568 : : |------------| +------------+
6569 : : | Op2 | | result |
6570 : : |------------| |------------|
6571 : : */
6572 : :
6573 : 0 : extern "C" void M2ALU_SetRotate (unsigned int tokenno)
6574 : : {
6575 : 0 : M2ALU_PtrToValue res;
6576 : 0 : M2ALU_PtrToValue Rotate;
6577 : 0 : M2ALU_PtrToValue Set;
6578 : 0 : unsigned int n;
6579 : 0 : unsigned int l;
6580 : 0 : unsigned int h;
6581 : 0 : unsigned int type;
6582 : 0 : unsigned int r1;
6583 : 0 : unsigned int r2;
6584 : :
6585 : 0 : if (! (M2ALU_IsValueTypeInteger ()))
6586 : : {
6587 : 0 : M2Error_InternalError ((const char *) "expecting integer type", 22);
6588 : : }
6589 : 0 : Rotate = Pop ();
6590 : 0 : if (! (M2ALU_IsValueTypeSet ()))
6591 : : {
6592 : 0 : M2Error_InternalError ((const char *) "expecting set type", 18);
6593 : : }
6594 : 0 : Set = Pop ();
6595 : 0 : Eval (tokenno, Set);
6596 : 0 : if (! Set->solved)
6597 : : {
6598 : 0 : M2Error_InternalError ((const char *) "set has not been resolved", 25);
6599 : : }
6600 : 0 : if (Set->setValue == NULL)
6601 : : {
6602 : 0 : Push (Set);
6603 : : }
6604 : : else
6605 : : {
6606 : 0 : type = Set->constructorType;
6607 : 0 : if (type == SymbolTable_NulSym)
6608 : : {
6609 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "cannot perform a ROTATE on a generic set", 40);
6610 : 0 : Push (Set);
6611 : 0 : return ;
6612 : : }
6613 : 0 : l = M2GCCDeclare_GetTypeMin (type);
6614 : 0 : h = M2GCCDeclare_GetTypeMax (type);
6615 : 0 : res = New ();
6616 : 0 : (*res) = (*Set);
6617 : 0 : res->setValue = NULL;
6618 : 0 : n = 1;
6619 : 0 : while (M2ALU_GetRange (Set, n, &r1, &r2))
6620 : : {
6621 : 0 : res->setValue = AddRange (res->setValue, DupConstAndAddMod (tokenno, r1, reinterpret_cast<m2tree_Tree> (Rotate), l, h), DupConstAndAddMod (tokenno, r2, reinterpret_cast<m2tree_Tree> (Rotate), l, h));
6622 : 0 : n += 1;
6623 : : }
6624 : 0 : Push (res);
6625 : 0 : Dispose (Set);
6626 : : }
6627 : : }
6628 : :
6629 : :
6630 : : /*
6631 : : GetValue - returns and pops the value from the top of stack.
6632 : : */
6633 : :
6634 : 88 : extern "C" M2ALU_PtrToValue M2ALU_GetValue (unsigned int tokenno)
6635 : : {
6636 : 88 : M2ALU_PtrToValue v;
6637 : :
6638 : 88 : v = Pop ();
6639 : 88 : Eval (tokenno, v);
6640 : 88 : return v;
6641 : : /* static analysis guarentees a RETURN statement will be used before here. */
6642 : : __builtin_unreachable ();
6643 : : }
6644 : :
6645 : :
6646 : : /*
6647 : : GetRange - returns TRUE if range number, n, exists in the value, v.
6648 : : A non empty set is defined by having 1..N ranges
6649 : : */
6650 : :
6651 : 63036 : extern "C" bool M2ALU_GetRange (M2ALU_PtrToValue v, unsigned int n, unsigned int *low, unsigned int *high)
6652 : : {
6653 : 63036 : M2ALU_listOfRange l;
6654 : :
6655 : 63036 : if (v->type != M2ALU_set)
6656 : : {
6657 : 0 : M2Error_InternalError ((const char *) "expecting set constant", 22);
6658 : : }
6659 : 63036 : l = v->setValue;
6660 : 140743 : while (n > 1)
6661 : : {
6662 : 77707 : if (l == NULL)
6663 : : {
6664 : : return false;
6665 : : }
6666 : 77707 : l = l->next;
6667 : 77707 : n -= 1;
6668 : : }
6669 : 63036 : if (l == NULL)
6670 : : {
6671 : : return false;
6672 : : }
6673 : 38417 : (*low) = l->low;
6674 : 38417 : (*high) = l->high;
6675 : 38417 : return true;
6676 : : /* static analysis guarentees a RETURN statement will be used before here. */
6677 : : __builtin_unreachable ();
6678 : : }
6679 : :
6680 : :
6681 : : /*
6682 : : ConstructSetConstant - builds a struct of integers which represents the
6683 : : set const as defined by, v.
6684 : : */
6685 : :
6686 : 7940 : extern "C" m2tree_Tree M2ALU_ConstructSetConstant (unsigned int tokenno, M2ALU_PtrToValue v)
6687 : : {
6688 : 7940 : NameKey_Name n1;
6689 : 7940 : NameKey_Name n2;
6690 : 7940 : m2tree_Tree gccsym;
6691 : 7940 : unsigned int baseType;
6692 : 7940 : unsigned int high;
6693 : 7940 : unsigned int low;
6694 : :
6695 : 7940 : if (v->constructorType == SymbolTable_NulSym)
6696 : : {
6697 : 0 : M2Error_InternalError ((const char *) "set type must be known in order to generate a constant", 54);
6698 : : }
6699 : : else
6700 : : {
6701 : 7940 : baseType = SymbolTable_SkipType (SymbolTable_GetType (v->constructorType));
6702 : 7940 : if (Debugging)
6703 : : {
6704 : : n1 = SymbolTable_GetSymName (v->constructorType);
6705 : : n2 = SymbolTable_GetSymName (baseType);
6706 : : M2Printf_printf2 ((const char *) "ConstructSetConstant of type %a and baseType %a\\n", 49, (const unsigned char *) &n1, (sizeof (n1)-1), (const unsigned char *) &n2, (sizeof (n2)-1));
6707 : : }
6708 : 7940 : if (SymbolTable_IsSubrange (baseType))
6709 : : {
6710 : 3342 : SymbolTable_GetSubrange (baseType, &high, &low);
6711 : 3342 : gccsym = ConstructLargeOrSmallSet (tokenno, v, low, high);
6712 : : }
6713 : : else
6714 : : {
6715 : 4598 : gccsym = ConstructLargeOrSmallSet (tokenno, v, M2GCCDeclare_GetTypeMin (baseType), M2GCCDeclare_GetTypeMax (baseType));
6716 : : }
6717 : 7940 : return gccsym;
6718 : : }
6719 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2ALU.def", 20, 1);
6720 : : __builtin_unreachable ();
6721 : : }
6722 : :
6723 : :
6724 : : /*
6725 : : BuildRange - returns a integer sized constant which represents the
6726 : : value {e1..e2}.
6727 : : */
6728 : :
6729 : 9063 : extern "C" m2tree_Tree M2ALU_BuildRange (unsigned int tokenno, m2tree_Tree e1, m2tree_Tree e2)
6730 : : {
6731 : 9063 : m2tree_Tree c;
6732 : 9063 : m2tree_Tree i;
6733 : 9063 : m2tree_Tree t;
6734 : 9063 : m2linemap_location_t location;
6735 : :
6736 : 9063 : location = M2LexBuf_TokenToLocation (tokenno);
6737 : 9063 : M2ALU_PushIntegerTree (e1);
6738 : 9063 : M2ALU_PushIntegerTree (e2);
6739 : 9063 : if (M2ALU_Gre (tokenno))
6740 : : {
6741 : 0 : c = e1;
6742 : 0 : e1 = e2;
6743 : 0 : e2 = c;
6744 : : }
6745 : 9063 : t = (m2tree_Tree) (NULL);
6746 : 9063 : M2ALU_PushIntegerTree (e1);
6747 : 9063 : i = M2ALU_PopIntegerTree ();
6748 : 15417 : do {
6749 : 15417 : if (t == ((m2tree_Tree) (NULL)))
6750 : : {
6751 : 9063 : t = m2expr_BuildLSL (location, m2expr_GetWordOne (location), m2convert_ToWord (location, i), false);
6752 : : }
6753 : : else
6754 : : {
6755 : 6354 : t = m2expr_BuildLogicalOr (location, t, m2expr_BuildLSL (location, m2expr_GetWordOne (location), m2convert_ToWord (location, i), false), false);
6756 : : }
6757 : 15417 : M2ALU_PushIntegerTree (i);
6758 : 15417 : M2ALU_PushIntegerTree (m2expr_GetIntegerOne (location));
6759 : 15417 : M2ALU_Addn ();
6760 : 15417 : i = M2ALU_PopIntegerTree ();
6761 : 15417 : M2ALU_PushIntegerTree (i);
6762 : 15417 : M2ALU_PushIntegerTree (e2);
6763 : 15417 : } while (! (M2ALU_Gre (tokenno)));
6764 : 9063 : return t;
6765 : : /* static analysis guarentees a RETURN statement will be used before here. */
6766 : : __builtin_unreachable ();
6767 : : }
6768 : :
6769 : :
6770 : : /*
6771 : : IsConstructorDependants - return TRUE if all q(dependants) of,
6772 : : sym, return TRUE.
6773 : : */
6774 : :
6775 : 22670 : extern "C" bool M2ALU_IsConstructorDependants (unsigned int sym, M2GCCDeclare_IsAction q)
6776 : : {
6777 : 22670 : M2ALU_PtrToValue v;
6778 : 22670 : bool typeResult;
6779 : 22670 : bool result;
6780 : :
6781 : 22670 : SymbolTable_PushValue (sym);
6782 : 22670 : if (M2ALU_IsValueTypeNone ())
6783 : : {
6784 : 6000 : v = Pop ();
6785 : 6000 : result = false;
6786 : : }
6787 : : else
6788 : : {
6789 : 16670 : v = Pop ();
6790 : 16670 : typeResult = static_cast<bool> ((*q.proc) (v->constructorType));
6791 : 16670 : switch (v->type)
6792 : : {
6793 : : case M2ALU_none:
6794 : : result = false;
6795 : : break;
6796 : :
6797 : 7814 : case M2ALU_set:
6798 : 7814 : result = IsSetValueDependants (v->setValue, q);
6799 : 7814 : break;
6800 : :
6801 : 6294 : case M2ALU_constructor:
6802 : 6294 : case M2ALU_record:
6803 : 6294 : result = IsFieldValueDependants (v->fieldValues, q);
6804 : 6294 : break;
6805 : :
6806 : 2562 : case M2ALU_array:
6807 : 2562 : result = IsArrayValueDependants (v->arrayValues, q);
6808 : 2562 : break;
6809 : :
6810 : :
6811 : 0 : default:
6812 : 0 : M2Error_InternalError ((const char *) "not expecting this type", 23);
6813 : 16670 : break;
6814 : : }
6815 : 16670 : result = result && typeResult;
6816 : : }
6817 : 22670 : return result;
6818 : : /* static analysis guarentees a RETURN statement will be used before here. */
6819 : : __builtin_unreachable ();
6820 : : }
6821 : :
6822 : :
6823 : : /*
6824 : : WalkConstructorDependants - walk the constructor, sym, calling
6825 : : p for each dependant.
6826 : : */
6827 : :
6828 : 191389 : extern "C" void M2ALU_WalkConstructorDependants (unsigned int sym, M2GCCDeclare_WalkAction p)
6829 : : {
6830 : 191389 : M2ALU_PtrToValue v;
6831 : :
6832 : 191389 : SymbolTable_PushValue (sym);
6833 : 191389 : if (M2ALU_IsValueTypeNone ())
6834 : : {
6835 : 6384 : v = Pop ();
6836 : : }
6837 : : else
6838 : : {
6839 : 185005 : v = Pop ();
6840 : 185005 : (*p.proc) (v->constructorType);
6841 : 185005 : switch (v->type)
6842 : : {
6843 : : case M2ALU_none:
6844 : : break;
6845 : :
6846 : 64923 : case M2ALU_set:
6847 : 64923 : WalkSetValueDependants (v->setValue, p);
6848 : 64923 : break;
6849 : :
6850 : 101308 : case M2ALU_constructor:
6851 : 101308 : case M2ALU_record:
6852 : 101308 : WalkFieldValueDependants (v->fieldValues, p);
6853 : : break;
6854 : :
6855 : 18774 : case M2ALU_array:
6856 : 18774 : WalkArrayValueDependants (v->arrayValues, p);
6857 : 18774 : break;
6858 : :
6859 : :
6860 : 0 : default:
6861 : 0 : M2Error_InternalError ((const char *) "not expecting this type", 23);
6862 : 191389 : break;
6863 : : }
6864 : : }
6865 : 191389 : }
6866 : :
6867 : :
6868 : : /*
6869 : : IsValueAndTreeKnown - returns TRUE if the value is known and the gcc tree
6870 : : is defined.
6871 : :
6872 : : The Stack:
6873 : :
6874 : : Entry Exit
6875 : :
6876 : : Ptr ->
6877 : : +------------+
6878 : : | Op1 | <- Ptr
6879 : : |------------| +------------+
6880 : : */
6881 : :
6882 : 78 : extern "C" bool M2ALU_IsValueAndTreeKnown (void)
6883 : : {
6884 : 78 : M2ALU_PtrToValue v;
6885 : :
6886 : 78 : v = Pop ();
6887 : 78 : if (v != NULL)
6888 : : {
6889 : 78 : if (v->solved)
6890 : : {
6891 : 78 : switch (v->type)
6892 : : {
6893 : 78 : case M2ALU_integer:
6894 : 78 : case M2ALU_real:
6895 : 78 : case M2ALU_complex:
6896 : 78 : if (v->numberValue == NULL)
6897 : : {
6898 : 0 : Dispose (v);
6899 : 0 : return false;
6900 : : }
6901 : : break;
6902 : :
6903 : :
6904 : : default:
6905 : : break;
6906 : : }
6907 : : }
6908 : : else
6909 : : {
6910 : 0 : Dispose (v);
6911 : 0 : return false;
6912 : : }
6913 : 78 : Dispose (v);
6914 : : }
6915 : : return true;
6916 : : /* static analysis guarentees a RETURN statement will be used before here. */
6917 : : __builtin_unreachable ();
6918 : : }
6919 : :
6920 : :
6921 : : /*
6922 : : CheckOrResetOverflow - tests to see whether the tree, t, has caused
6923 : : an overflow error and if so it generates an
6924 : : error message.
6925 : : */
6926 : :
6927 : 363867 : extern "C" void M2ALU_CheckOrResetOverflow (unsigned int tokenno, m2tree_Tree t, bool check)
6928 : : {
6929 : 363867 : if (check)
6930 : : {
6931 : 344758 : CheckOverflow (tokenno, t);
6932 : : }
6933 : : else
6934 : : {
6935 : 19109 : t = m2expr_RemoveOverflow (t);
6936 : : }
6937 : 363855 : }
6938 : :
6939 : :
6940 : : /*
6941 : : AddElements - adds the elements, el BY, n, to the array constant.
6942 : :
6943 : : Ptr ->
6944 : : <- Ptr
6945 : : +------------+ +------------+
6946 : : | Array | | Array |
6947 : : |------------| |------------|
6948 : :
6949 : : */
6950 : :
6951 : 30 : extern "C" void M2ALU_AddElements (unsigned int tokenno, unsigned int el, unsigned int n)
6952 : : {
6953 : 30 : M2ALU_PtrToValue v;
6954 : 30 : M2ALU_listOfElements e;
6955 : :
6956 : 30 : v = Pop ();
6957 : 30 : v = CoerseTo (tokenno, M2ALU_array, v);
6958 : 30 : if (v->type == M2ALU_array)
6959 : : {
6960 : 30 : NewElement (&e);
6961 : 30 : e->element = el;
6962 : 30 : e->by = n;
6963 : 30 : e->next = NULL;
6964 : 30 : AddElementToEnd (v, e);
6965 : 30 : v->solved = (v->solved && (IsSolvedGCC (el))) && (IsSolvedGCC (n));
6966 : : }
6967 : : else
6968 : : {
6969 : 0 : M2Error_InternalError ((const char *) "expecting array type", 20);
6970 : : }
6971 : 30 : Push (v);
6972 : 30 : }
6973 : :
6974 : :
6975 : : /*
6976 : : AddField - adds the field op1 to the underlying constructor.
6977 : :
6978 : : Ptr ->
6979 : : <- Ptr
6980 : : +------------+ +------------+
6981 : : | const | | const |
6982 : : |------------| |------------|
6983 : :
6984 : : */
6985 : :
6986 : 13604 : extern "C" void M2ALU_AddField (unsigned int tokenno, unsigned int op1)
6987 : : {
6988 : 13604 : M2ALU_PtrToValue v;
6989 : 13604 : M2ALU_listOfFields f;
6990 : 13604 : M2ALU_listOfElements e;
6991 : :
6992 : 13604 : v = Pop ();
6993 : 13604 : switch (v->type)
6994 : : {
6995 : 0 : case M2ALU_set:
6996 : 0 : Push (v);
6997 : 0 : M2ALU_AddBit (tokenno, op1);
6998 : 0 : return ;
6999 : 4172 : break;
7000 : :
7001 : 4172 : case M2ALU_array:
7002 : 4172 : v->solved = v->solved && (IsSolvedGCC (op1));
7003 : 4172 : v->areAllConstants = v->areAllConstants && (SymbolTable_IsConst (op1));
7004 : 4172 : NewElement (&e);
7005 : 4172 : e->element = op1;
7006 : 4172 : e->by = SymbolTable_MakeConstLit (tokenno, NameKey_MakeKey ((const char *) "1", 1), M2Base_ZType);
7007 : 4172 : e->next = NULL;
7008 : 4172 : AddElementToEnd (v, e);
7009 : : break;
7010 : :
7011 : 9432 : case M2ALU_constructor:
7012 : 9432 : case M2ALU_record:
7013 : 9432 : v->solved = v->solved && (IsSolvedGCC (op1));
7014 : 9432 : v->areAllConstants = v->areAllConstants && (SymbolTable_IsConst (op1));
7015 : 9432 : NewField (&f);
7016 : 9432 : f->field = op1;
7017 : 9432 : f->next = NULL;
7018 : 9432 : AddFieldToEnd (v, f);
7019 : : break;
7020 : :
7021 : :
7022 : 0 : default:
7023 : 0 : M2Error_InternalError ((const char *) "not expecting this constant type", 32);
7024 : 13604 : break;
7025 : : }
7026 : 13604 : Push (v);
7027 : : }
7028 : :
7029 : :
7030 : : /*
7031 : : PushEmptyConstructor - pushes an empty constructor {} onto the ALU stack.
7032 : : This is expected to be filled in by subsequent
7033 : : calls to AddElements, AddRange or AddField.
7034 : :
7035 : : The Stack:
7036 : :
7037 : : Entry Exit
7038 : :
7039 : : <- Ptr
7040 : : +------------+
7041 : : | {} |
7042 : : Ptr -> |------------|
7043 : :
7044 : : */
7045 : :
7046 : 0 : extern "C" void M2ALU_PushEmptyConstructor (unsigned int constype)
7047 : : {
7048 : 0 : M2ALU_PtrToValue v;
7049 : :
7050 : 0 : v = M2ALU_InitValue ();
7051 : 0 : v->type = M2ALU_constructor;
7052 : 0 : v->constructorType = constype;
7053 : 0 : v->areAllConstants = true;
7054 : 0 : v->solved = M2GCCDeclare_CompletelyResolved (constype);
7055 : 0 : v->fieldValues = NULL;
7056 : 0 : v->next = NULL;
7057 : 0 : Push (v);
7058 : 0 : }
7059 : :
7060 : :
7061 : : /*
7062 : : PushEmptyArray - pushes an empty array {} onto the ALU stack.
7063 : : This is expected to be filled in by subsequent
7064 : : calls to AddElements.
7065 : :
7066 : : The Stack:
7067 : :
7068 : : Entry Exit
7069 : :
7070 : : <- Ptr
7071 : : +------------+
7072 : : | {} |
7073 : : Ptr -> |------------|
7074 : :
7075 : : */
7076 : :
7077 : 0 : extern "C" void M2ALU_PushEmptyArray (unsigned int arraytype)
7078 : : {
7079 : 0 : M2ALU_PtrToValue v;
7080 : :
7081 : 0 : v = M2ALU_InitValue ();
7082 : 0 : v->type = M2ALU_array;
7083 : 0 : v->constructorType = arraytype;
7084 : 0 : v->areAllConstants = true;
7085 : 0 : v->solved = M2GCCDeclare_CompletelyResolved (arraytype);
7086 : 0 : v->arrayValues = NULL;
7087 : 0 : v->next = NULL;
7088 : 0 : Push (v);
7089 : 0 : }
7090 : :
7091 : :
7092 : : /*
7093 : : PushEmptyRecord - pushes an empty record {} onto the ALU stack.
7094 : : This is expected to be filled in by subsequent
7095 : : calls to AddField.
7096 : :
7097 : : The Stack:
7098 : :
7099 : : Entry Exit
7100 : :
7101 : : <- Ptr
7102 : : +------------+
7103 : : | {} |
7104 : : Ptr -> |------------|
7105 : :
7106 : : */
7107 : :
7108 : 0 : extern "C" void M2ALU_PushEmptyRecord (unsigned int recordtype)
7109 : : {
7110 : 0 : M2ALU_PtrToValue v;
7111 : :
7112 : 0 : v = M2ALU_InitValue ();
7113 : 0 : v->type = M2ALU_record;
7114 : 0 : v->constructorType = recordtype;
7115 : 0 : v->areAllConstants = true;
7116 : 0 : v->solved = M2GCCDeclare_CompletelyResolved (recordtype);
7117 : 0 : v->arrayValues = NULL;
7118 : 0 : v->next = NULL;
7119 : 0 : Push (v);
7120 : 0 : }
7121 : :
7122 : :
7123 : : /*
7124 : : ChangeToConstructor - change the top of stack value to a constructor, type.
7125 : : (Constructor, Set, Array or Record).
7126 : : */
7127 : :
7128 : 22999 : extern "C" void M2ALU_ChangeToConstructor (unsigned int tokenno, unsigned int constype)
7129 : : {
7130 : 22999 : M2ALU_PtrToValue v;
7131 : :
7132 : 22999 : if ((((M2ALU_IsValueTypeConstructor ()) || (M2ALU_IsValueTypeSet ())) || (M2ALU_IsValueTypeArray ())) || (M2ALU_IsValueTypeRecord ()))
7133 : : {
7134 : 2531 : return ;
7135 : : }
7136 : 20468 : else if (M2ALU_IsValueTypeNone ())
7137 : : {
7138 : : /* avoid dangling else. */
7139 : 20468 : v = Pop ();
7140 : 20468 : v->type = M2ALU_constructor;
7141 : 20468 : v->constructorType = constype;
7142 : 20468 : v->solved = M2GCCDeclare_CompletelyResolved (constype);
7143 : 20468 : v->fieldValues = NULL;
7144 : 20468 : v->next = NULL;
7145 : 20468 : if (SymbolTable_IsSet (SymbolTable_SkipType (constype)))
7146 : : {
7147 : 17398 : v = CoerseTo (tokenno, M2ALU_set, v);
7148 : : }
7149 : 3070 : else if (SymbolTable_IsRecord (SymbolTable_SkipType (constype)))
7150 : : {
7151 : : /* avoid dangling else. */
7152 : 2258 : v = CoerseTo (tokenno, M2ALU_record, v);
7153 : : }
7154 : 812 : else if (SymbolTable_IsArray (SymbolTable_SkipType (constype)))
7155 : : {
7156 : : /* avoid dangling else. */
7157 : 806 : v = CoerseTo (tokenno, M2ALU_array, v);
7158 : : }
7159 : 20468 : Push (v);
7160 : : }
7161 : : else
7162 : : {
7163 : : /* avoid dangling else. */
7164 : 0 : M2Error_InternalError ((const char *) "cannot change constant to a constructor type", 44);
7165 : : }
7166 : : }
7167 : :
7168 : :
7169 : : /*
7170 : : IsValueConst - returns true if the memory cell indicated by v
7171 : : is only defined by constants. For example
7172 : : no variables are used in the constructor.
7173 : : */
7174 : :
7175 : 661127 : extern "C" bool M2ALU_IsValueConst (M2ALU_PtrToValue v)
7176 : : {
7177 : 661127 : if (v == NULL)
7178 : : {
7179 : 0 : M2Error_InternalError ((const char *) "uninitialized value", 19);
7180 : : }
7181 : : else
7182 : : {
7183 : 661127 : return v->areAllConstants;
7184 : : }
7185 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2ALU.def", 20, 1);
7186 : : __builtin_unreachable ();
7187 : : }
7188 : :
7189 : :
7190 : : /*
7191 : : PushTypeOfTree - pushes tree, gcc, to the stack and records the
7192 : : front end type.
7193 : : */
7194 : :
7195 : 350390 : extern "C" void M2ALU_PushTypeOfTree (unsigned int sym, m2tree_Tree gcc)
7196 : : {
7197 : 350390 : unsigned int t;
7198 : :
7199 : 350390 : t = SymbolTable_SkipType (SymbolTable_GetType (sym));
7200 : 350390 : if (t == SymbolTable_NulSym)
7201 : : {
7202 : 12 : M2ALU_PushIntegerTree (gcc);
7203 : : }
7204 : 350378 : else if (M2Base_IsComplexType (t))
7205 : : {
7206 : : /* avoid dangling else. */
7207 : 708 : M2ALU_PushComplexTree (gcc);
7208 : : }
7209 : 349670 : else if (SymbolTable_IsArray (t))
7210 : : {
7211 : : /* avoid dangling else. */
7212 : 0 : PushGCCArrayTree (gcc, t);
7213 : : }
7214 : 349670 : else if (SymbolTable_IsSet (t))
7215 : : {
7216 : : /* avoid dangling else. */
7217 : 18 : PushGCCSetTree (gcc, t);
7218 : : }
7219 : 349652 : else if (SymbolTable_IsRecord (t))
7220 : : {
7221 : : /* avoid dangling else. */
7222 : 0 : PushGCCRecordTree (gcc, t);
7223 : : }
7224 : 349652 : else if (M2Base_IsRealType (t))
7225 : : {
7226 : : /* avoid dangling else. */
7227 : 1074 : M2ALU_PushRealTree (gcc);
7228 : : }
7229 : : else
7230 : : {
7231 : : /* avoid dangling else. */
7232 : 348578 : M2ALU_PushIntegerTree (gcc);
7233 : : }
7234 : 350390 : }
7235 : :
7236 : 16817 : extern "C" void _M2_M2ALU_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
7237 : : {
7238 : 16817 : Init ();
7239 : 16817 : }
7240 : :
7241 : 0 : extern "C" void _M2_M2ALU_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
7242 : : {
7243 : 0 : }
|