1 /*----------------------------------------------------------------------
2 SDCCval.c :- has routine to do all kinds of fun stuff with the
3 value wrapper & with initialiser lists.
4
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
25
26 #include "common.h"
27 #include <math.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <errno.h>
31 #include "newalloc.h"
32 #include "dbuf_string.h"
33
34 long cNestLevel;
35
36
37 /*-----------------------------------------------------------------*/
38 /* newValue - allocates and returns a new value */
39 /*-----------------------------------------------------------------*/
40 value *
newValue(void)41 newValue (void)
42 {
43 value *val;
44
45 val = Safe_alloc (sizeof (value));
46
47 return val;
48 }
49
50 /*-----------------------------------------------------------------*/
51 /* newiList - new initializer list */
52 /*-----------------------------------------------------------------*/
53 initList *
newiList(int type,void * ilist)54 newiList (int type, void *ilist)
55 {
56 initList *nilist;
57
58 nilist = Safe_alloc (sizeof (initList));
59
60 nilist->type = type;
61 nilist->filename = lexFilename;
62 nilist->lineno = lexLineno;
63 nilist->designation = NULL;
64
65 switch (type)
66 {
67 case INIT_NODE:
68 nilist->init.node = (struct ast *) ilist;
69 break;
70
71 case INIT_DEEP:
72 nilist->init.deep = (struct initList *) ilist;
73 break;
74 }
75
76 return nilist;
77 }
78
79 /*------------------------------------------------------------------*/
80 /* revinit - reverses the initial values for a value chain */
81 /*------------------------------------------------------------------*/
82 initList *
revinit(initList * val)83 revinit (initList * val)
84 {
85 initList *prev, *curr, *next;
86
87 if (!val)
88 return NULL;
89
90 prev = val;
91 curr = val->next;
92
93 while (curr)
94 {
95 next = curr->next;
96 curr->next = prev;
97 prev = curr;
98 curr = next;
99 }
100 val->next = (void *) NULL;
101 return prev;
102 }
103
104 bool
convertIListToConstList(initList * src,literalList ** lList,int size)105 convertIListToConstList (initList * src, literalList ** lList, int size)
106 {
107 int cnt = 0;
108 initList *iLoop;
109 literalList *head, *last, *newL;
110
111 head = last = NULL;
112
113 if (src && src->type != INIT_DEEP)
114 {
115 return FALSE;
116 }
117
118 iLoop = src ? src->init.deep : NULL;
119
120 while (iLoop)
121 {
122 if (iLoop->designation != NULL)
123 {
124 return FALSE;
125 }
126
127 if (iLoop->type != INIT_NODE)
128 {
129 return FALSE;
130 }
131
132 if (!IS_AST_LIT_VALUE (decorateType (resolveSymbols (iLoop->init.node), RESULT_TYPE_NONE)))
133 {
134 return FALSE;
135 }
136 iLoop = iLoop->next;
137 cnt++;
138 }
139 if (!size)
140 {
141 size = cnt;
142 }
143
144 /* We've now established that the initializer list contains only literal values. */
145
146 iLoop = src ? src->init.deep : NULL;
147 while (size--)
148 {
149 double val = iLoop ? AST_FLOAT_VALUE (iLoop->init.node) : 0;
150
151 if (last && last->literalValue == val)
152 {
153 last->count++;
154 }
155 else
156 {
157 newL = Safe_alloc (sizeof (literalList));
158 newL->literalValue = val;
159 newL->count = 1;
160 newL->next = NULL;
161
162 if (last)
163 {
164 last->next = newL;
165 }
166 else
167 {
168 head = newL;
169 }
170 last = newL;
171 }
172 iLoop = iLoop ? iLoop->next : NULL;
173 }
174
175 if (!head)
176 {
177 return FALSE;
178 }
179
180 *lList = head;
181 return TRUE;
182 }
183
184 literalList *
copyLiteralList(literalList * src)185 copyLiteralList (literalList * src)
186 {
187 literalList *head, *prev, *newL;
188
189 head = prev = NULL;
190
191 while (src)
192 {
193 newL = Safe_alloc (sizeof (literalList));
194
195 newL->literalValue = src->literalValue;
196 newL->count = src->count;
197 newL->next = NULL;
198
199 if (prev)
200 {
201 prev->next = newL;
202 }
203 else
204 {
205 head = newL;
206 }
207 prev = newL;
208 src = src->next;
209 }
210
211 return head;
212 }
213
214 /*------------------------------------------------------------------*/
215 /* copyIlist - copy initializer list */
216 /*------------------------------------------------------------------*/
217 initList *
copyIlist(initList * src)218 copyIlist (initList * src)
219 {
220 initList *dest = NULL;
221
222 if (!src)
223 return NULL;
224
225 switch (src->type)
226 {
227 case INIT_DEEP:
228 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
229 break;
230 case INIT_NODE:
231 dest = newiList (INIT_NODE, copyAst (src->init.node));
232 break;
233 }
234
235 if (src->designation)
236 dest->designation = copyDesignation (src->designation);
237
238 if (src->next)
239 assert (dest != NULL);
240 dest->next = copyIlist (src->next);
241
242 return dest;
243 }
244
245 /*------------------------------------------------------------------*/
246 /* list2int - converts the first element of the list to value */
247 /*------------------------------------------------------------------*/
248 double
list2int(initList * val)249 list2int (initList * val)
250 {
251 initList *i = val;
252
253 assert (i->type != INIT_HOLE);
254
255 if (i->type == INIT_DEEP)
256 return list2int (val->init.deep);
257
258 return floatFromVal (constExprValue (val->init.node, TRUE));
259 }
260
261 /*------------------------------------------------------------------*/
262 /* list2val - converts the first element of the list to value */
263 /*------------------------------------------------------------------*/
264 value *
list2val(initList * val,int check)265 list2val (initList * val, int check)
266 {
267 if (!val)
268 return NULL;
269
270 if(val->type == INIT_HOLE)
271 return NULL;
272
273 if (val->type == INIT_DEEP)
274 return list2val (val->init.deep, check);
275
276 if (val->type == INIT_NODE && val->init.node->opval.op == CAST)
277 return constExprValue (val->init.node->right, check);
278
279 return constExprValue (val->init.node, check);
280 }
281
282 /*------------------------------------------------------------------*/
283 /* list2expr - returns the first expression in the initializer list */
284 /*------------------------------------------------------------------*/
285 ast *
list2expr(initList * ilist)286 list2expr (initList * ilist)
287 {
288 if (!ilist)
289 return NULL;
290
291 assert (ilist->type != INIT_HOLE);
292
293 if (ilist->type == INIT_DEEP)
294 return list2expr (ilist->init.deep);
295 return ilist->init.node;
296 }
297
298 /*------------------------------------------------------------------*/
299 /* resolveIvalSym - resolve symbols in initial values */
300 /*------------------------------------------------------------------*/
301 void
resolveIvalSym(initList * ilist,sym_link * type)302 resolveIvalSym (initList *ilist, sym_link *type)
303 {
304 int is_ptr = IS_PTR (type) || (IS_ARRAY(type) && IS_PTR(type->next));
305 RESULT_TYPE resultType = getResultTypeFromType (getSpec (type));
306
307 while (ilist)
308 {
309 if (ilist->type == INIT_NODE)
310 {
311 ilist->init.node = decorateType (resolveSymbols (ilist->init.node), is_ptr ? RESULT_TYPE_INT : resultType);
312 }
313 else if (ilist->type == INIT_DEEP)
314 {
315 resolveIvalSym (ilist->init.deep, type);
316 }
317
318 ilist = ilist->next;
319 }
320 }
321
322 /*-----------------------------------------------------------------*/
323 /* newDesignation - new designation */
324 /*-----------------------------------------------------------------*/
325 designation *
newDesignation(int type,void * designator)326 newDesignation (int type, void *designator)
327 {
328 designation *ndesignation;
329
330 ndesignation = Safe_alloc (sizeof (designation));
331
332 ndesignation->type = type;
333 ndesignation->filename = lexFilename;
334 ndesignation->lineno = lexLineno;
335
336 switch (type)
337 {
338 case DESIGNATOR_STRUCT:
339 ndesignation->designator.tag = (struct symbol *) designator;
340 break;
341
342 case DESIGNATOR_ARRAY:
343 ndesignation->designator.elemno = * ((int *) designator);
344 break;
345 }
346
347 return ndesignation;
348 }
349
350 /*------------------------------------------------------------------*/
351 /* revDesignation - reverses the designation chain */
352 /*------------------------------------------------------------------*/
353 designation *
revDesignation(designation * val)354 revDesignation (designation * val)
355 {
356 designation *prev, *curr, *next;
357
358 if (!val)
359 return NULL;
360
361 prev = val;
362 curr = val->next;
363
364 while (curr)
365 {
366 next = curr->next;
367 curr->next = prev;
368 prev = curr;
369 curr = next;
370 }
371 val->next = (void *) NULL;
372 return prev;
373 }
374
375 /*------------------------------------------------------------------*/
376 /* copyDesignation - copy designation list */
377 /*------------------------------------------------------------------*/
378 designation *
copyDesignation(designation * src)379 copyDesignation (designation * src)
380 {
381 designation *dest = NULL;
382
383 if (!src)
384 return NULL;
385
386 switch (src->type)
387 {
388 case DESIGNATOR_STRUCT:
389 dest = newDesignation (DESIGNATOR_STRUCT, copySymbol (src->designator.tag));
390 break;
391 case DESIGNATOR_ARRAY:
392 dest = newDesignation (DESIGNATOR_ARRAY, &(src->designator.elemno) );
393 break;
394 }
395
396 dest->lineno = src->lineno;
397 dest->filename = src->filename;
398
399 if (src->next)
400 dest->next = copyDesignation (src->next);
401
402 return dest;
403 }
404
405 /*------------------------------------------------------------------*/
406 /* moveNestedInit - rewrites an initList node with a nested */
407 /* designator to remove one level of nesting. */
408 /*------------------------------------------------------------------*/
409 static
moveNestedInit(initList * deepParent,initList * src)410 void moveNestedInit(initList *deepParent, initList *src)
411 {
412 initList *dst = NULL, **eol;
413
414 /** Create new initList element */
415 switch (src->type)
416 {
417 case INIT_NODE:
418 dst = newiList(INIT_NODE, src->init.node);
419 break;
420 case INIT_DEEP:
421 dst = newiList(INIT_DEEP, src->init.deep);
422 break;
423 }
424 dst->filename = src->filename;
425 dst->lineno = src->lineno;
426 dst->designation = src->designation->next;
427
428 /* add dst to end of deepParent */
429 if (deepParent->type != INIT_DEEP)
430 {
431 werrorfl (deepParent->filename, deepParent->lineno,
432 E_INIT_STRUCT, "<unknown>");
433 return;
434 }
435 for (eol = &(deepParent->init.deep); *eol ; )
436 eol = &((*eol)->next);
437 *eol = dst;
438 }
439
440 /*-----------------------------------------------------------------*/
441 /* findStructField - find a specific field in a struct definition */
442 /*-----------------------------------------------------------------*/
443 static int
findStructField(symbol * fields,symbol * target)444 findStructField (symbol *fields, symbol *target)
445 {
446 int i;
447
448 for (i=0 ; fields; fields = fields->next)
449 {
450 /* skip past unnamed bitfields */
451 if (IS_BITFIELD (fields->type) && SPEC_BUNNAMED (fields->etype))
452 continue;
453 /* is this it? */
454 if (strcmp(fields->name, target->name) == 0)
455 return i;
456 i++;
457 }
458
459 /* not found */
460 werrorfl (target->fileDef, target->lineDef, E_NOT_MEMBER, target->name);
461 return 0;
462 }
463
464 /*------------------------------------------------------------------*/
465 /* reorderIlist - expands an initializer list to match designated */
466 /* initializers. */
467 /*------------------------------------------------------------------*/
reorderIlist(sym_link * type,initList * ilist)468 initList *reorderIlist (sym_link * type, initList * ilist)
469 {
470 initList *iloop, *nlist, **nlistArray;
471 symbol *sflds;
472 int size=0, idx;
473
474 if (!IS_AGGREGATE (type))
475 /* uninteresting: no designated initializers */
476 return ilist;
477
478 if (ilist && ilist->type == INIT_HOLE)
479 /* ditto; just a uninitialized hole */
480 return ilist;
481
482 /* special case: check for string initializer */
483 if (IS_ARRAY (type) && IS_CHAR (type->next) &&
484 ilist && ilist->type == INIT_NODE)
485 {
486 ast *iast = ilist->init.node;
487 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
488 if (v && IS_ARRAY (v->type) && IS_CHAR (v->etype))
489 {
490 /* yep, it's a string; no changes needed here. */
491 return ilist;
492 }
493 }
494
495 if (ilist && ilist->type != INIT_DEEP)
496 {
497 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, "<unknown>");
498 return NULL;
499 }
500
501 /* okay, allocate enough space */
502 if (IS_ARRAY (type))
503 size = getNelements(type, ilist);
504 else if (IS_STRUCT (type))
505 {
506 /* compute size from struct type. */
507 size = 0;
508 for (sflds = SPEC_STRUCT (type)->fields; sflds; sflds = sflds->next)
509 {
510 /* skip past unnamed bitfields */
511 if (IS_BITFIELD (sflds->type) && SPEC_BUNNAMED (sflds->etype))
512 continue;
513 size++;
514 }
515 }
516 nlistArray = Safe_calloc ( size, sizeof(initList *) );
517
518 /* pull together all the initializers into an ordered list */
519 iloop = ilist ? ilist->init.deep : NULL;
520 for (idx = 0 ; iloop ; iloop = iloop->next, idx++)
521 {
522 if (iloop->designation)
523 {
524 assert (iloop->type != INIT_HOLE);
525
526 if (IS_ARRAY (type))
527 {
528 if (iloop->designation->type == DESIGNATOR_ARRAY)
529 idx = iloop->designation->designator.elemno;
530 else
531 werrorfl (iloop->filename, iloop->lineno, E_BAD_DESIGNATOR);
532 }
533 else if (IS_STRUCT (type))
534 {
535 if (iloop->designation->type == DESIGNATOR_STRUCT)
536 idx = findStructField (SPEC_STRUCT (type)->fields,
537 iloop->designation->designator.tag);
538 else
539 werrorfl (iloop->filename, iloop->lineno, E_BAD_DESIGNATOR);
540 }
541 else
542 {
543 assert (0);
544 }
545
546 if (iloop->designation->next)
547 {
548 if (idx >= size)
549 continue;
550 if (nlistArray[idx] == NULL)
551 nlistArray[idx] = newiList(INIT_DEEP, NULL);
552 moveNestedInit(nlistArray[idx], iloop);
553 continue;
554 }
555 }
556
557 /* overwrite any existing entry with iloop */
558 if (iloop->type != INIT_HOLE)
559 {
560 if (idx >= size)
561 continue;
562 if (nlistArray[idx] != NULL)
563 werrorfl (iloop->filename, iloop->lineno, W_DUPLICATE_INIT, idx);
564 nlistArray[idx] = iloop;
565 }
566 }
567
568 /* create new list from nlistArray/size */
569 nlist = NULL;
570 sflds = IS_STRUCT (type) ? SPEC_STRUCT (type)->fields : NULL;
571 for ( idx=0; idx < size; idx++ )
572 {
573 initList *src = nlistArray[idx], *dst = NULL;
574 if (!src || src->type==INIT_HOLE)
575 {
576 dst = newiList(INIT_HOLE, NULL);
577 dst->filename = ilist->filename;
578 dst->lineno = ilist->lineno;
579 }
580 else
581 {
582 switch (src->type)
583 {
584 case INIT_NODE:
585 dst = newiList(INIT_NODE, src->init.node);
586 break;
587 case INIT_DEEP:
588 dst = newiList(INIT_DEEP, src->init.deep);
589 break;
590 }
591 dst->filename = src->filename;
592 dst->lineno = src->lineno;
593 }
594 dst->next = nlist;
595 nlist = dst;
596 /* advance to next field which is not an unnamed bitfield */
597 do
598 {
599 sflds = sflds ? sflds->next : NULL;
600 }
601 while (sflds &&
602 IS_BITFIELD (sflds->type) && SPEC_BUNNAMED (sflds->etype));
603 }
604
605 nlist = newiList(INIT_DEEP, revinit (nlist));
606 nlist->filename = ilist->filename;
607 nlist->lineno = ilist->lineno;
608 nlist->designation = ilist->designation;
609 nlist->next = ilist->next;
610 return nlist;
611 }
612
613 /*------------------------------------------------------------------*/
614 /* symbolVal - creates a value for a symbol */
615 /*------------------------------------------------------------------*/
616 value *
symbolVal(symbol * sym)617 symbolVal (symbol * sym)
618 {
619 value *val;
620
621 if (!sym)
622 return NULL;
623
624 val = newValue ();
625 val->sym = sym;
626
627 if (sym->type)
628 {
629 val->type = sym->type;
630 val->etype = getSpec (val->type);
631 }
632
633 if (*sym->rname)
634 {
635 SNPRINTF (val->name, sizeof (val->name), "%s", sym->rname);
636 }
637 else
638 {
639 SNPRINTF (val->name, sizeof (val->name), "_%s", sym->name);
640 }
641
642 return val;
643 }
644
645 /*--------------------------------------------------------------------*/
646 /* cheapestVal - try to reduce 'signed int' to 'char' */
647 /*--------------------------------------------------------------------*/
648 static value *
cheapestVal(value * val)649 cheapestVal (value * val)
650 {
651 /* only int can be reduced */
652 if (!IS_INT (val->type))
653 return val;
654
655 /* long must not be changed */
656 if (SPEC_LONG (val->type) || SPEC_LONGLONG (val->type))
657 return val;
658
659 /* unsigned must not be changed */
660 if (SPEC_USIGN (val->type))
661 return val;
662
663 /* the only possible reduction is from signed int to (un)signed char,
664 because it's automatically promoted back to signed int.
665
666 a reduction from unsigned int to unsigned char is a bug,
667 because an _unsigned_ char is promoted to _signed_ int! */
668 if (SPEC_CVAL (val->type).v_int < -128 || SPEC_CVAL (val->type).v_int > 255)
669 {
670 /* not in the range of (un)signed char */
671 return val;
672 }
673
674 SPEC_NOUN (val->type) = V_CHAR;
675
676 /* 'unsigned char' promotes to 'signed int', so that we can
677 reduce it the other way */
678 if (SPEC_CVAL (val->type).v_int >= 0)
679 {
680 /* 'bool' promotes to 'signed int' too */
681 if (SPEC_CVAL (val->type).v_int <= 1)
682 {
683 /* Do not use V_BIT here because in some contexts it also */
684 /* implies a storage class. */
685 SPEC_NOUN (val->type) = V_BOOL;
686 }
687 else
688 {
689 /* Boolean types are intrinsically unsigned, so only */
690 /* set the USIGN flag for char types to avoid triggering */
691 /* type checking errors/warnings. */
692 SPEC_USIGN (val->type) = 1;
693 }
694 }
695
696 return (val);
697 }
698
699 /*-----------------------------------------------------------------*/
700 /* double2ul - double to unsigned long conversion */
701 /*-----------------------------------------------------------------*/
702 unsigned long
double2ul(double val)703 double2ul (double val)
704 {
705 /*
706 * See ISO/IEC 9899, chapter 6.3.1.4 Real floating and integer:
707 * If the value of the integral part cannot be represented by the integer type, the behavior is undefined.
708 * This shows up on Mac OS X i386 platform which useus SSE unit instead of the x87 FPU for floating-point operations
709 */
710 /*
711 * on Mac OS X ppc (long) 2147483648.0 equals to 2147483647, so we explicitely convert it to 0x80000000
712 * on other known platforms (long) 2147483648.0 equals to -2147483648
713 */
714 return ((val) < 0) ? (((val) < -2147483647.0) ? 0x80000000UL : (unsigned long) -((long) -(val))) : (unsigned long) (val);
715 }
716
717 /*--------------------------------------------------------------------*/
718 /* checkConstantRange - check if constant fits in numeric range of */
719 /* var type in comparisons and assignments */
720 /*--------------------------------------------------------------------*/
721 CCR_RESULT
checkConstantRange(sym_link * var,sym_link * lit,int op,bool exchangeLeftRight)722 checkConstantRange (sym_link * var, sym_link * lit, int op, bool exchangeLeftRight)
723 {
724 sym_link *reType;
725 TYPE_TARGET_LONGLONG litVal;
726 TYPE_TARGET_ULONGLONG ulitVal;
727 TYPE_TARGET_ULONGLONG signExtMask;
728 TYPE_TARGET_ULONGLONG signMask;
729 bool litValUnsigned;
730 int varBits;
731
732 litVal = ullFromLit (lit);
733 ulitVal = (TYPE_TARGET_ULONGLONG) litVal;
734 litValUnsigned = SPEC_USIGN (lit);
735 varBits = bitsForType (var);
736 signMask = 1ull << (varBits-1);
737 signExtMask = varBits >= sizeof(TYPE_TARGET_ULONGLONG)*8 ? 0 : ~((1ull << varBits)-1);
738
739 #if 0
740 printf(" ulitVal = 0x%016lx\n", ulitVal);
741 printf(" signExtMask = 0x%016lx\n", signExtMask);
742 printf(" signMask = 0x%016lx\n",signMask);
743 #endif
744
745 //return CCR_OK; /* EEP - debug for long long */
746 /* sanity checks */
747 if (IS_FLOAT (var) || IS_FIXED (var))
748 return CCR_OK;
749 if (varBits < 1)
750 return CCR_ALWAYS_FALSE;
751 if (varBits > 64)
752 return CCR_ALWAYS_TRUE;
753
754 /* special: assignment */
755 if (op == '=')
756 {
757 if (IS_BOOLEAN (var))
758 return CCR_OK;
759
760 if (1) // Though the else branch is dead, I still would like to keep it.
761 //if (getenv ("SDCC_VERY_PEDANTIC"))
762 {
763 if (SPEC_USIGN (var))
764 {
765 if ((!litValUnsigned && litVal < 0) || (litVal & signExtMask) != 0)
766 return CCR_OVL;
767 return CCR_OK;
768 }
769 else
770 {
771 if (litValUnsigned)
772 {
773 if ((ulitVal & (signExtMask | signMask)) == 0)
774 return CCR_OK;
775 }
776 else
777 {
778 if ((litVal & (signExtMask | signMask)) == 0)
779 return CCR_OK;
780 if ((litVal & (signExtMask | signMask)) == (signExtMask | signMask))
781 return CCR_OK;
782 }
783 return CCR_OVL;
784 }
785 }
786 else
787 {
788 /* ignore signedness, e.g. allow everything
789 from -127...+255 for (unsigned) char */
790 if ((litVal & signExtMask) == 0)
791 return CCR_OK;
792 if ((litVal & (signExtMask | signMask)) == (signExtMask | signMask))
793 return CCR_OK;
794 return CCR_OVL;
795 }
796 }
797
798 if (exchangeLeftRight)
799 switch (op)
800 {
801 case EQ_OP:
802 break;
803 case NE_OP:
804 break;
805 case '>':
806 op = '<';
807 break;
808 case GE_OP:
809 op = LE_OP;
810 break;
811 case '<':
812 op = '>';
813 break;
814 case LE_OP:
815 op = GE_OP;
816 break;
817 default:
818 return CCR_ALWAYS_FALSE;
819 }
820
821 reType = computeType (var, lit, RESULT_TYPE_NONE, op);
822
823 if (SPEC_USIGN (reType))
824 {
825 /* unsigned operation */
826 int reBits = bitsForType (reType);
827 TYPE_TARGET_ULONGLONG minValP, maxValP, minValM, maxValM;
828 TYPE_TARGET_ULONGLONG opBitsMask = reBits >= sizeof(opBitsMask)*8 ? ~0ull : ((1ull << reBits)-1);
829
830 if (IS_BOOL (var))
831 {
832 minValP = 0;
833 maxValP = 1;
834 minValM = 0;
835 maxValM = 1;
836 }
837 else if (SPEC_USIGN (lit) && SPEC_USIGN (var))
838 {
839 /* both operands are unsigned, this is easy */
840 minValP = 0;
841 maxValP = ~signExtMask;
842 /* there's only range, just copy it to 2nd set */
843 minValM = minValP;
844 maxValM = maxValP;
845 }
846 else if (SPEC_USIGN (var))
847 {
848 /* lit is casted from signed to unsigned, e.g.:
849 unsigned u;
850 u == (char) -17
851 -> u == 0xffef'
852 */
853 minValP = 0;
854 maxValP = ~signExtMask;
855 /* there's only one range, just copy it to 2nd set */
856 minValM = minValP;
857 maxValM = maxValP;
858
859 /* it's an unsigned operation */
860 ulitVal &= opBitsMask;
861 }
862 else /* SPEC_USIGN (lit) */
863 {
864 /* var is casted from signed to unsigned, e.g.:
865 signed char c;
866 c == (unsigned) -17
867 -> c == 0xffef'
868
869 The possible values after casting var
870 split up in two, nonconsecutive ranges:
871
872 minValP = 0; positive range: 0...127
873 maxValP = 0x7f;
874 minValM = 0xff80; negative range: -128...-1
875 maxValM = 0xffff;
876 */
877
878 /* positive range */
879 minValP = 0;
880 maxValP = ~(signExtMask | signMask);
881
882 /* negative range */
883 minValM = signExtMask | signMask;
884 maxValM = (TYPE_TARGET_ULONGLONG)~0ull; /* -1 */
885 /* limit number of bits to size of return type */
886 minValM &= opBitsMask;
887 maxValM &= opBitsMask;
888 }
889 #if 0
890 printf(" reType = ");
891 printTypeChain (reType, NULL);
892 printf(" ulitVal = 0x%016lx\n", ulitVal);
893 printf(" opBitsMask = 0x%016lx\n", opBitsMask);
894 printf(" maxValP = 0x%016lx\n", maxValP);
895 printf(" minValP = 0x%016lx\n", minValP);
896 printf(" maxValM = 0x%016lx\n", maxValM);
897 printf(" minValM = 0x%016lx\n", minValM);
898 #endif
899
900 switch (op)
901 {
902 case EQ_OP: /* var == lit */
903 if (ulitVal <= maxValP && ulitVal >= minValP) /* 0 */
904 return CCR_OK;
905 if (ulitVal <= maxValM && ulitVal >= minValM)
906 return CCR_OK;
907 return CCR_ALWAYS_FALSE;
908 case NE_OP: /* var != lit */
909 if (ulitVal <= maxValP && ulitVal >= minValP) /* 0 */
910 return CCR_OK;
911 if (ulitVal <= maxValM && ulitVal >= minValM)
912 return CCR_OK;
913 return CCR_ALWAYS_TRUE;
914 case '>': /* var > lit */
915 if (ulitVal >= maxValM)
916 return CCR_ALWAYS_FALSE;
917 if (ulitVal < minValP) /* 0 */
918 return CCR_ALWAYS_TRUE;
919 return CCR_OK;
920 case GE_OP: /* var >= lit */
921 if (ulitVal > maxValM)
922 return CCR_ALWAYS_FALSE;
923 if (ulitVal <= minValP) /* 0 */
924 return CCR_ALWAYS_TRUE;
925 return CCR_OK;
926 case '<': /* var < lit */
927 if (ulitVal > maxValM)
928 return CCR_ALWAYS_TRUE;
929 if (ulitVal <= minValP) /* 0 */
930 return CCR_ALWAYS_FALSE;
931 return CCR_OK;
932 case LE_OP: /* var <= lit */
933 if (ulitVal >= maxValM)
934 return CCR_ALWAYS_TRUE;
935 if (ulitVal < minValP) /* 0 */
936 return CCR_ALWAYS_FALSE;
937 return CCR_OK;
938 default:
939 return CCR_ALWAYS_FALSE;
940 }
941 }
942 else
943 {
944 /* signed operation */
945 TYPE_TARGET_LONGLONG minVal, maxVal;
946
947 if (IS_BOOL (var))
948 {
949 minVal = 0;
950 maxVal = 1;
951 }
952 else if (SPEC_USIGN (var))
953 {
954 /* unsigned var, but signed operation. This happens
955 when var is promoted to signed int.
956 Set actual min/max values of var. */
957 minVal = 0;
958 maxVal = ~signExtMask;
959 }
960 else
961 {
962 /* signed var */
963 minVal = signExtMask | signMask;
964 maxVal = ~(signExtMask | signMask);
965 }
966
967 switch (op)
968 {
969 case EQ_OP: /* var == lit */
970 if (litVal > maxVal || litVal < minVal)
971 return CCR_ALWAYS_FALSE;
972 return CCR_OK;
973 case NE_OP: /* var != lit */
974 if (litVal > maxVal || litVal < minVal)
975 return CCR_ALWAYS_TRUE;
976 return CCR_OK;
977 case '>': /* var > lit */
978 if (litVal >= maxVal)
979 return CCR_ALWAYS_FALSE;
980 if (litVal < minVal)
981 return CCR_ALWAYS_TRUE;
982 return CCR_OK;
983 case GE_OP: /* var >= lit */
984 if (litVal > maxVal)
985 return CCR_ALWAYS_FALSE;
986 if (litVal <= minVal)
987 return CCR_ALWAYS_TRUE;
988 return CCR_OK;
989 case '<': /* var < lit */
990 if (litVal > maxVal)
991 return CCR_ALWAYS_TRUE;
992 if (litVal <= minVal)
993 return CCR_ALWAYS_FALSE;
994 return CCR_OK;
995 case LE_OP: /* var <= lit */
996 if (litVal >= maxVal)
997 return CCR_ALWAYS_TRUE;
998 if (litVal < minVal)
999 return CCR_ALWAYS_FALSE;
1000 return CCR_OK;
1001 default:
1002 return CCR_ALWAYS_FALSE;
1003 }
1004 }
1005 }
1006
1007 #if 0
1008 CCR_RESULT
1009 checkConstantRange (sym_link * var, sym_link * lit, int op, bool exchangeLeftRight)
1010 {
1011 CCR_RESULT result;
1012
1013 printf ("checkConstantRange:\n");
1014 printf (" var: ");
1015 printTypeChain (var, NULL);
1016 printf (" lit = 0x%lx: ",ullFromLit (lit));
1017 printTypeChain (lit, NULL);
1018 printf (" op: '");
1019 switch (op)
1020 {
1021 case '<': printf ("<"); break;
1022 case '=': printf ("="); break;
1023 case '>': printf (">"); break;
1024 case LE_OP: printf ("<="); break;
1025 case GE_OP: printf (">="); break;
1026 case EQ_OP: printf ("=="); break;
1027 case NE_OP: printf ("!="); break;
1028 default: printf ("%d",op);
1029 }
1030 printf("'\n");
1031 result = checkConstantRange2 (var, lit, op, exchangeLeftRight);
1032 switch (result)
1033 {
1034 case CCR_ALWAYS_TRUE: printf (" CCR_ALWAYS_TRUE\n"); break;
1035 case CCR_ALWAYS_FALSE: printf (" CCR_ALWAYS_FALSE\n"); break;
1036 case CCR_OK: printf (" CCR_OK\n"); break;
1037 case CCR_OVL: printf (" CCR_OVL\n"); break;
1038 default: printf(" CCR_%d\n",result);
1039 }
1040 return result;
1041 }
1042 #endif
1043
1044
1045 /*-----------------------------------------------------------------*/
1046 /* valueFromLit - creates a value from a literal */
1047 /*-----------------------------------------------------------------*/
1048 value *
valueFromLit(double lit)1049 valueFromLit (double lit)
1050 {
1051 struct dbuf_s dbuf;
1052 value *ret;
1053
1054 if ((((TYPE_TARGET_LONG) lit) - lit) == 0)
1055 {
1056 dbuf_init (&dbuf, 128);
1057 dbuf_printf (&dbuf, "%d", (TYPE_TARGET_LONG) lit);
1058 ret = constVal (dbuf_c_str (&dbuf));
1059 dbuf_destroy (&dbuf);
1060 return ret;
1061 }
1062
1063 dbuf_init (&dbuf, 128);
1064 dbuf_printf (&dbuf, "%f", lit);
1065 ret = constFloatVal (dbuf_c_str (&dbuf));
1066 dbuf_destroy (&dbuf);
1067 return ret;
1068 }
1069
1070 /*-----------------------------------------------------------------*/
1071 /* constFloatVal - converts a FLOAT constant to value */
1072 /*-----------------------------------------------------------------*/
1073 value *
constFloatVal(const char * s)1074 constFloatVal (const char *s)
1075 {
1076 value *val = newValue ();
1077 double sval;
1078 char *p;
1079
1080 sval = strtod (s, &p);
1081 if (p == s)
1082 {
1083 werror (E_INVALID_FLOAT_CONST, s);
1084 return constCharVal (0);
1085 }
1086
1087 val->type = val->etype = newLink (SPECIFIER);
1088 SPEC_NOUN (val->type) = V_FLOAT;
1089 SPEC_SCLS (val->type) = S_LITERAL;
1090 SPEC_CONST (val->type) = 1;
1091 SPEC_CVAL (val->type).v_float = sval;
1092
1093 return val;
1094 }
1095
1096 /*-----------------------------------------------------------------*/
1097 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
1098 /*-----------------------------------------------------------------*/
1099 value *
constFixed16x16Val(const char * s)1100 constFixed16x16Val (const char *s)
1101 {
1102 value *val = newValue ();
1103 double sval;
1104 char *p;
1105
1106 sval = strtod (s, &p);
1107 if (p == s)
1108 {
1109 werror (E_INVALID_FLOAT_CONST, s);
1110 return constCharVal (0);
1111 }
1112
1113 val->type = val->etype = newLink (SPECIFIER);
1114 SPEC_NOUN (val->type) = V_FLOAT;
1115 SPEC_SCLS (val->type) = S_LITERAL;
1116 SPEC_CONST (val->type) = 1;
1117 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (sval);
1118
1119 return val;
1120 }
1121
1122 /*-----------------------------------------------------------------*/
1123 /* constVal - converts a constant into a cheap value type */
1124 /*-----------------------------------------------------------------*/
1125 value *
constVal(const char * s)1126 constVal (const char *s)
1127 {
1128 value *val = constIntVal (s);
1129
1130 wassert (SPEC_NOUN (val->type) == V_INT);
1131
1132 if (SPEC_LONGLONG (val->type))
1133 ;
1134 else if (SPEC_LONG (val->type))
1135 ;
1136 else if (SPEC_USIGN (val->type))
1137 {
1138 unsigned int i = SPEC_CVAL (val->type).v_uint;
1139 if (i < 256)
1140 SPEC_NOUN (val->type) = V_CHAR;
1141 }
1142 else
1143 {
1144 int i = SPEC_CVAL (val->type).v_int;
1145 if (i >= 0 && i < 256)
1146 {
1147 SPEC_NOUN (val->type) = V_CHAR;
1148 SPEC_USIGN (val->type) = TRUE;
1149 SPEC_CVAL (val->type).v_uint = i;
1150 }
1151 else if (i >= -128 && i < 128)
1152 {
1153 SPEC_NOUN (val->type) = V_CHAR;
1154 }
1155 }
1156
1157 return val;
1158 }
1159
1160 /*-----------------------------------------------------------------*/
1161 /* constIntVal - converts an integer constant into correct type */
1162 /* See ISO C11, section 6.4.4.1 for the rules. */
1163 /*-----------------------------------------------------------------*/
1164 value *
constIntVal(const char * s)1165 constIntVal (const char *s)
1166 {
1167 char *p, *p2;
1168 double dval;
1169 long long int llval;
1170 value *val = newValue ();
1171 bool decimal, u_suffix = FALSE, l_suffix = FALSE, ll_suffix = FALSE;
1172
1173 val->type = val->etype = newLink (SPECIFIER);
1174 SPEC_SCLS (val->type) = S_LITERAL;
1175 SPEC_CONST (val->type) = 1;
1176 SPEC_USIGN (val->type) = 0;
1177
1178 errno = 0;
1179
1180 if (s[0] == '0')
1181 {
1182 if (s[1] == 'b' || s[1] == 'B')
1183 llval = strtoull (s + 2, &p, 2);
1184 else
1185 llval = strtoull (s, &p, 0);
1186 dval = (double)(unsigned long long int) llval;
1187 decimal = FALSE;
1188 }
1189 else
1190 {
1191 dval = strtod (s, &p);
1192 if (dval >= 0.0)
1193 llval = strtoull (s, &p, 0);
1194 else
1195 llval = strtoll (s, &p, 0);
1196 decimal = TRUE;
1197 }
1198
1199 if (errno)
1200 {
1201 dval = 4294967295.0;
1202 werror (W_INVALID_INT_CONST, s, dval);
1203 }
1204
1205 // Check suffixes
1206 if ((p2 = strchr (p, 'u')) || (p2 = strchr (p, 'U')))
1207 {
1208 u_suffix = TRUE;
1209 p2++;
1210 if (strchr (p2, 'u') || strchr (p2, 'U'))
1211 werror (E_INTEGERSUFFIX, p);
1212 }
1213
1214 if ((p2 = strstr (p, "ll")) || (p2 = strstr (p, "LL")))
1215 {
1216 ll_suffix = TRUE;
1217 p2 += 2;
1218 if (strchr (p2, 'l') || strchr (p2, 'L'))
1219 werror (E_INTEGERSUFFIX, p);
1220 }
1221 else if ((p2 = strchr (p, 'l')) || (p2 = strchr (p, 'L')))
1222 {
1223 l_suffix = TRUE;
1224 p2++;
1225 if (strchr (p2, 'l') || strchr (p2, 'L'))
1226 werror (E_INTEGERSUFFIX, p);
1227 }
1228
1229 SPEC_NOUN (val->type) = V_INT;
1230
1231 if (u_suffix) // Choose first of unsigned int, unsigned long int, unsigned long long int that fits.
1232 {
1233 SPEC_USIGN (val->type) = 1;
1234 if (ll_suffix || dval > 0xffffffff)
1235 SPEC_LONGLONG (val->type) = 1;
1236 else if(l_suffix || dval > 0xffff)
1237 SPEC_LONG (val->type) = 1;
1238 }
1239 else
1240 {
1241 if (decimal) // Choose first of int, long int, long long int that fits.
1242 {
1243 if (ll_suffix || dval > 0x7fffffff || dval < -0x80000000ll)
1244 {
1245 if (!options.std_c99) // C90 exception: Use unsigned long
1246 {
1247 SPEC_USIGN (val->type) = 1;
1248 SPEC_LONG (val->type) = 1;
1249 }
1250 else
1251 SPEC_LONGLONG (val->type) = 1;
1252 }
1253 else if(l_suffix || dval > 0x7fff || dval < -0x8000l)
1254 SPEC_LONG (val->type) = 1;
1255 }
1256 else // Choose first of int, unsigned int, long int, unsigned long int, long long int, unsigned long long int that fits.
1257 {
1258 if (dval > 0x7fffffffffffffff)
1259 {
1260 SPEC_USIGN (val->type) = 1;
1261 SPEC_LONGLONG (val->type) = 1;
1262 }
1263 else if (ll_suffix || dval > 0xffffffff || dval < -0x80000000ll)
1264 {
1265 SPEC_LONGLONG (val->type) = 1;
1266 }
1267 else if (dval > 0x7fffffff)
1268 {
1269 SPEC_USIGN (val->type) = 1;
1270 SPEC_LONG (val->type) = 1;
1271 }
1272 else if (l_suffix || dval > 0xffff || dval < -0x8000l)
1273 {
1274 SPEC_LONG (val->type) = 1;
1275 }
1276 else if (dval > 0x7fff)
1277 {
1278 SPEC_USIGN (val->type) = 1;
1279 }
1280 }
1281 }
1282
1283 /* check for out of range */
1284 if (!SPEC_LONGLONG (val->type))
1285 {
1286 if (dval < -2147483648.0)
1287 {
1288 dval = -2147483648.0;
1289 werror (W_INVALID_INT_CONST, s, dval);
1290 }
1291 if (dval > 2147483648.0 && !SPEC_USIGN (val->type))
1292 {
1293 dval = 2147483647.0;
1294 werror (W_INVALID_INT_CONST, s, dval);
1295 }
1296 if (dval > 4294967295.0)
1297 {
1298 dval = 4294967295.0;
1299 werror (W_INVALID_INT_CONST, s, dval);
1300 }
1301 }
1302
1303 if (SPEC_LONGLONG (val->type))
1304 {
1305 if (SPEC_USIGN (val->type))
1306 {
1307 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) llval;
1308 }
1309 else
1310 {
1311 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) llval;
1312 }
1313 }
1314 else if (SPEC_LONG (val->type))
1315 {
1316 if (SPEC_USIGN (val->type))
1317 {
1318 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) double2ul (dval);
1319 }
1320 else
1321 {
1322 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) double2ul (dval);
1323 }
1324 }
1325 else
1326 {
1327 if (SPEC_USIGN (val->type))
1328 {
1329 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) double2ul (dval);
1330 }
1331 else
1332 {
1333 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) double2ul (dval);
1334 }
1335 }
1336
1337 return val;
1338 }
1339
1340 /*-----------------------------------------------------------------*/
1341 /* constCharacterVal - converts a character constant to value */
1342 /*-----------------------------------------------------------------*/
1343 value *
constCharacterVal(unsigned long v,char type)1344 constCharacterVal (unsigned long v, char type)
1345 {
1346 value *val = newValue (); /* alloc space for value */
1347
1348 val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
1349 SPEC_SCLS (val->type) = S_LITERAL;
1350 SPEC_CONST (val->type) = 1;
1351
1352 switch (type)
1353 {
1354 case 0: // character constant
1355 SPEC_NOUN (val->type) = V_INT;
1356 SPEC_USIGN (val->type) = 0;
1357 SPEC_CVAL (val->type).v_int = options.signed_char ? (signed char) v : (unsigned char) v;
1358 break;
1359 case 'L': // wide character constant
1360 if (!options.std_c95)
1361 werror (E_WCHAR_CONST_C95);
1362 SPEC_NOUN (val->type) = V_INT;
1363 SPEC_USIGN (val->type) = 1;
1364 SPEC_LONG (val->etype) = 1;
1365 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) v;
1366 break;
1367 case 'u': // wide character constant
1368 if (!options.std_c11)
1369 werror (E_WCHAR_CONST_C11);
1370 SPEC_NOUN (val->type) = V_INT;
1371 SPEC_USIGN (val->type) = 1;
1372 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) v;
1373 break;
1374 case 'U': // wide character constant
1375 if (!options.std_c11)
1376 werror (E_WCHAR_CONST_C11);
1377 SPEC_NOUN (val->type) = V_INT;
1378 SPEC_USIGN (val->type) = 1;
1379 SPEC_LONG (val->etype) = 1;
1380 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) v;
1381 break;
1382 case '8':
1383 if (!options.std_c2x)
1384 werror (E_U8_CHAR_C2X);
1385 if (v >= 128)
1386 werror (E_U8_CHAR_INVALID);
1387 SPEC_NOUN (val->type) = V_CHAR;
1388 SPEC_USIGN (val->type) = 1;
1389 SPEC_CVAL (val->type).v_int = (unsigned char) v;
1390 break;
1391 default:
1392 wassert (0);
1393 }
1394
1395 return val;
1396 }
1397
1398 /*-----------------------------------------------------------------*/
1399 /* constCharVal - converts a character constant to value */
1400 /*-----------------------------------------------------------------*/
1401 value *
constCharVal(unsigned char v)1402 constCharVal (unsigned char v)
1403 {
1404 return constCharacterVal (v, 0);
1405 }
1406
1407 /*-----------------------------------------------------------------*/
1408 /* constBoolVal - converts a BOOL constant to value */
1409 /*-----------------------------------------------------------------*/
1410 value *
constBoolVal(bool v)1411 constBoolVal (bool v)
1412 {
1413 value *val = newValue (); /* alloc space for value */
1414
1415 val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
1416 SPEC_SCLS (val->type) = S_LITERAL;
1417 SPEC_CONST (val->type) = 1;
1418
1419 SPEC_NOUN (val->type) = (bit) ? V_BIT : V_BOOL;
1420
1421 SPEC_CVAL (val->type).v_uint = (unsigned int) v;
1422
1423 return val;
1424 }
1425
1426 // TODO: Move this function to SDCCutil?
utf_32_from_utf_8(size_t * utf_32_len,const char * utf_8,size_t utf_8_len)1427 static const TYPE_UDWORD *utf_32_from_utf_8 (size_t *utf_32_len, const char *utf_8, size_t utf_8_len)
1428 {
1429 size_t allocated = 0;
1430 TYPE_UDWORD *utf_32 = 0;
1431 unsigned char first_byte;
1432 TYPE_UDWORD codepoint;
1433 size_t seqlen;
1434
1435 for (*utf_32_len = 0; utf_8_len; (*utf_32_len)++)
1436 {
1437 if (allocated == *utf_32_len)
1438 {
1439 utf_32 = realloc (utf_32, sizeof(TYPE_UDWORD) * (*utf_32_len + 16));
1440 wassert (utf_32);
1441 allocated = *utf_32_len + 16;
1442 }
1443
1444 first_byte = *utf_8;
1445 seqlen = 1;
1446 if (first_byte & 0x80)
1447 {
1448 while (first_byte & (0x80 >> seqlen))
1449 seqlen++;
1450 first_byte &= (0xff >> (seqlen + 1));
1451 }
1452 wassert (seqlen <= 6); // seqlen 5 and 6 are deprecated in current unicode standard, but for now, allow them.
1453
1454 codepoint = first_byte;
1455 utf_8++;
1456 utf_8_len--;
1457 seqlen--;
1458
1459 for(; seqlen; seqlen--)
1460 {
1461 codepoint <<= 6;
1462 codepoint |= (*utf_8 & 0x3f);
1463 utf_8++;
1464 utf_8_len--;
1465 }
1466
1467 utf_32[*utf_32_len] = codepoint;
1468 }
1469 return (utf_32);
1470 }
1471
1472 // TODO: Move this function to SDCCutil?
utf_16_from_utf_32(size_t * utf_16_len,const TYPE_UDWORD * utf_32,size_t utf_32_len)1473 static const TYPE_UWORD *utf_16_from_utf_32 (size_t *utf_16_len, const TYPE_UDWORD *utf_32, size_t utf_32_len)
1474 {
1475 size_t allocated = 0;
1476 TYPE_UWORD *utf_16 = 0;
1477 TYPE_UDWORD codepoint;
1478
1479 for (*utf_16_len = 0; utf_32_len; utf_32_len--, utf_32++)
1480 {
1481 if (allocated <= *utf_16_len + 2)
1482 {
1483 utf_16 = realloc (utf_16, sizeof(TYPE_UWORD) * (*utf_16_len + 16));
1484 wassert (utf_16);
1485 allocated = *utf_16_len + 16;
1486 }
1487
1488 codepoint = *utf_32;
1489
1490 if (codepoint < 0xd7ff || codepoint >= 0xe000 && codepoint <= 0xffff) // Code in basic multilingual plane.
1491 {
1492 utf_16[(*utf_16_len)++] = codepoint;
1493 continue;
1494 }
1495
1496 // Code point in supplementary plane.
1497 wassert (codepoint >= 0x100000 && codepoint <= 0x10ffff);
1498 codepoint -= 0x100000;
1499
1500 utf_16[(*utf_16_len)++] = ((codepoint >> 10) & 0x3ff) + 0xd800;
1501 utf_16[(*utf_16_len)++] = (codepoint & 0x3ff) + 0xdc00;
1502 }
1503
1504 return (utf_16);
1505 }
1506
1507 /*------------------------------------------------------------------*/
1508 /* strVal - converts a string constant to a value */
1509 /*------------------------------------------------------------------*/
1510 value *
strVal(const char * s)1511 strVal (const char *s)
1512 {
1513 value *val;
1514 const char *utf_8;
1515 size_t utf_8_size;
1516
1517 val = newValue ();
1518
1519 /* get a declarator */
1520 val->type = newLink (DECLARATOR);
1521 DCL_TYPE (val->type) = ARRAY;
1522 val->type->next = val->etype = newLink (SPECIFIER);
1523 SPEC_SCLS (val->etype) = S_LITERAL;
1524 SPEC_CONST (val->etype) = 1;
1525
1526 // Convert input string (mixed UTF-8 and UTF-32) to UTF-8 first (handling all escape sequences, etc).
1527 utf_8 = copyStr (s[0] == '"' ? s : s + 1, &utf_8_size);
1528
1529 if (s[0] == '"') // UTF-8 string literal (any prefix u8 or L in the source would already have been stripped by earlier stages)
1530 {
1531 SPEC_NOUN (val->etype) = V_CHAR;
1532 SPEC_USIGN (val->etype) = !options.signed_char;
1533 val->etype->select.s.b_implicit_sign = true;
1534 SPEC_CVAL (val->etype).v_char = utf_8;
1535 DCL_ELEM (val->type) = utf_8_size;
1536 }
1537 else
1538 {
1539 size_t utf_32_size;
1540 // Convert to UTF-32 next, since converting UTF-32 to UTF-16 is easier than UTF-8 to UTF-16.
1541 const TYPE_UDWORD *utf_32 = utf_32_from_utf_8 (&utf_32_size, utf_8, utf_8_size);
1542
1543 dbuf_free (utf_8);
1544
1545 if (s[0] == 'U' || s[0] == 'L') // UTF-32 string literal
1546 {
1547 SPEC_NOUN (val->etype) = V_INT;
1548 SPEC_USIGN (val->etype) = 1;
1549 SPEC_LONG (val->etype) = 1;
1550 SPEC_CVAL (val->etype).v_char32 = utf_32;
1551 DCL_ELEM (val->type) = utf_32_size;
1552 }
1553 else if (s[0] == 'u') // UTF-16 string literal
1554 {
1555 size_t utf_16_size;
1556 const TYPE_UWORD *utf_16 = utf_16_from_utf_32 (&utf_16_size, utf_32, utf_32_size);
1557
1558 SPEC_NOUN (val->etype) = V_INT;
1559 SPEC_USIGN (val->etype) = 1;
1560 SPEC_CVAL (val->etype).v_char16 = utf_16;
1561 DCL_ELEM (val->type) = utf_16_size;
1562 }
1563 else
1564 wassert (0);
1565 }
1566
1567 return (val);
1568 }
1569
1570 /*------------------------------------------------------------------*/
1571 /* rawStrVal - converts a string to a value */
1572 /*------------------------------------------------------------------*/
1573 value *
rawStrVal(const char * s,size_t size)1574 rawStrVal (const char *s, size_t size)
1575 {
1576 struct dbuf_s dbuf;
1577 value *val = newValue ();
1578
1579 dbuf_init (&dbuf, size);
1580 wassert (dbuf_append (&dbuf, s, size));
1581
1582 /* get a declarator */
1583 val->type = newLink (DECLARATOR);
1584 DCL_TYPE (val->type) = ARRAY;
1585 val->type->next = val->etype = newLink (SPECIFIER);
1586 SPEC_SCLS (val->etype) = S_LITERAL;
1587 SPEC_CONST (val->etype) = 1;
1588
1589 SPEC_NOUN (val->etype) = V_CHAR;
1590 SPEC_USIGN (val->etype) = !options.signed_char;
1591 val->etype->select.s.b_implicit_sign = true;
1592 SPEC_CVAL (val->etype).v_char = dbuf_detach (&dbuf);
1593 DCL_ELEM (val->type) = size;
1594
1595 return (val);
1596 }
1597
1598 /*------------------------------------------------------------------*/
1599 /* reverseValWithType - reverses value chain with type & etype */
1600 /*------------------------------------------------------------------*/
1601 value *
reverseValWithType(value * val)1602 reverseValWithType (value * val)
1603 {
1604 sym_link *type;
1605 sym_link *etype;
1606
1607 if (!val)
1608 return NULL;
1609
1610 /* save the type * etype chains */
1611 type = val->type;
1612 etype = val->etype;
1613
1614 /* set the current one 2b null */
1615 val->type = val->etype = NULL;
1616 val = reverseVal (val);
1617
1618 /* restore type & etype */
1619 val->type = type;
1620 val->etype = etype;
1621
1622 return val;
1623 }
1624
1625 /*------------------------------------------------------------------*/
1626 /* reverseVal - reverses the values for a value chain */
1627 /*------------------------------------------------------------------*/
1628 value *
reverseVal(value * val)1629 reverseVal (value * val)
1630 {
1631 value *prev, *curr, *next;
1632
1633 if (!val)
1634 return NULL;
1635
1636 prev = val;
1637 curr = val->next;
1638
1639 while (curr)
1640 {
1641 next = curr->next;
1642 curr->next = prev;
1643 prev = curr;
1644 curr = next;
1645 }
1646 val->next = (void *) NULL;
1647 return prev;
1648 }
1649
1650 /*------------------------------------------------------------------*/
1651 /* copyValueChain - will copy a chain of values */
1652 /*------------------------------------------------------------------*/
1653 value *
copyValueChain(value * src)1654 copyValueChain (value * src)
1655 {
1656 value *dest;
1657
1658 if (!src)
1659 return NULL;
1660
1661 dest = copyValue (src);
1662 dest->next = copyValueChain (src->next);
1663
1664 return dest;
1665 }
1666
1667 /*------------------------------------------------------------------*/
1668 /* copyValue - copies contents of a value to a fresh one */
1669 /*------------------------------------------------------------------*/
1670 value *
copyValue(value * src)1671 copyValue (value * src)
1672 {
1673 value *dest;
1674
1675 dest = newValue ();
1676 dest->sym = copySymbol (src->sym);
1677 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
1678 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
1679 dest->etype = (src->type ? getSpec (dest->type) : NULL);
1680
1681 return dest;
1682 }
1683
1684 /*------------------------------------------------------------------*/
1685 /* charVal - converts a character constant to a value */
1686 /*------------------------------------------------------------------*/
1687 value *
charVal(const char * s)1688 charVal (const char *s)
1689 {
1690 char type;
1691
1692 if ((s[0] == 'L' || s[0] == 'u' || s[0] == 'U') && s[1] == '\'')
1693 type = *s++;
1694 else if (s[0] == 'u' && s[1] == '8' && s[2] == '\'')
1695 {
1696 if (s[4] != '\'')
1697 werror (E_U8_CHAR_INVALID);
1698 type = '8';
1699 s += 2;
1700 }
1701 else
1702 type = 0;
1703
1704 s++; // Get rid of quotation.
1705
1706 /* if \ then special processing */
1707 if (*s == '\\')
1708 {
1709 switch (*++s) /* go beyond the backslash */
1710 {
1711 case 'n':
1712 return constCharacterVal ('\n', type);
1713 case 't':
1714 return constCharacterVal ('\t', type);
1715 case 'v':
1716 return constCharacterVal ('\v', type);
1717 case 'b':
1718 return constCharacterVal ('\b', type);
1719 case 'r':
1720 return constCharacterVal ('\r', type);
1721 case 'f':
1722 return constCharacterVal ('\f', type);
1723 case 'a':
1724 return constCharacterVal ('\a', type);
1725 case '\\':
1726 return constCharacterVal ('\\', type);
1727 case '\?':
1728 return constCharacterVal ('\?', type);
1729 case '\'':
1730 return constCharacterVal ('\'', type);
1731 case '\"':
1732 return constCharacterVal ('\"', type);
1733
1734 case '0':
1735 case '1':
1736 case '2':
1737 case '3':
1738 case '4':
1739 case '5':
1740 case '6':
1741 case '7':
1742 return constCharacterVal (octalEscape (&s), type);
1743
1744 case 'x':
1745 return constCharacterVal (hexEscape (&s), type);
1746
1747 case 'u':
1748 return constCharacterVal (universalEscape (&s, 4), type);
1749
1750 case 'U':
1751 return constCharacterVal (universalEscape (&s, 8), type);
1752
1753 default:
1754 return constCharacterVal (*s, type);
1755 }
1756 }
1757 else if (type) // Wide character constant
1758 {
1759 size_t ulen;
1760 const TYPE_UDWORD *ustr = utf_32_from_utf_8 (&ulen, s, strlen(s) - 1);
1761 value *val = constCharacterVal (*ustr, type);
1762 free ((void *)ustr);
1763 return (val);
1764 }
1765 else // Character constant that is not wide - compability with legacy encodings.
1766 return constCharacterVal (*s, 0);
1767 }
1768
1769 /*------------------------------------------------------------------*/
1770 /* valFromType - creates a value from type given */
1771 /*------------------------------------------------------------------*/
1772 value *
valFromType(sym_link * type)1773 valFromType (sym_link * type)
1774 {
1775 value *val = newValue ();
1776 val->type = copyLinkChain (type);
1777 val->etype = getSpec (val->type);
1778 return val;
1779 }
1780
1781 /*------------------------------------------------------------------*/
1782 /* floatFromVal - value to double float conversion */
1783 /*------------------------------------------------------------------*/
1784 double
floatFromVal(value * val)1785 floatFromVal (value * val)
1786 {
1787 if (!val)
1788 return 0;
1789
1790 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1791 {
1792 werror (E_CONST_EXPECTED, val->name);
1793 return 0;
1794 }
1795
1796 /* if it is not a specifier then we can assume that */
1797 /* it will be an unsigned long */
1798 if (!IS_SPEC (val->type))
1799 return SPEC_CVAL (val->etype).v_ulong;
1800
1801 if (SPEC_NOUN (val->etype) == V_FLOAT)
1802 return SPEC_CVAL (val->etype).v_float;
1803
1804 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1805 return doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16);
1806
1807 if (SPEC_LONGLONG (val->etype))
1808 {
1809 if (SPEC_USIGN (val->etype))
1810 return (double)SPEC_CVAL (val->etype).v_ulonglong;
1811 else
1812 return (double)SPEC_CVAL (val->etype).v_longlong;
1813 }
1814
1815 if (SPEC_LONG (val->etype))
1816 {
1817 if (SPEC_USIGN (val->etype))
1818 return SPEC_CVAL (val->etype).v_ulong;
1819 else
1820 return SPEC_CVAL (val->etype).v_long;
1821 }
1822
1823 if (SPEC_NOUN (val->etype) == V_INT)
1824 {
1825 if (SPEC_USIGN (val->etype))
1826 return SPEC_CVAL (val->etype).v_uint;
1827 else
1828 return SPEC_CVAL (val->etype).v_int;
1829 }
1830
1831 if (SPEC_NOUN (val->etype) == V_CHAR)
1832 {
1833 if (SPEC_USIGN (val->etype))
1834 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1835 else
1836 return (signed char) SPEC_CVAL (val->etype).v_int;
1837 }
1838
1839 if (IS_BOOL (val->etype) || IS_BITVAR (val->etype))
1840 return SPEC_CVAL (val->etype).v_uint;
1841
1842 if (SPEC_NOUN (val->etype) == V_VOID)
1843 return SPEC_CVAL (val->etype).v_ulong;
1844
1845 if (SPEC_NOUN (val->etype) == V_STRUCT)
1846 return SPEC_CVAL (val->etype).v_ulong;
1847
1848 /* we are lost ! */
1849 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "floatFromVal: unknown value");
1850 return 0;
1851 }
1852
1853 /*------------------------------------------------------------------*/
1854 /* ulFromVal - value to unsigned long conversion */
1855 /*------------------------------------------------------------------*/
1856 unsigned long
ulFromVal(value * val)1857 ulFromVal (value *val)
1858 {
1859 if (!val)
1860 return 0;
1861
1862 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1863 {
1864 werror (E_CONST_EXPECTED, val->name);
1865 return 0;
1866 }
1867
1868 /* if it is not a specifier then we can assume that */
1869 /* it will be an unsigned long */
1870 if (!IS_SPEC (val->type))
1871 return SPEC_CVAL (val->etype).v_ulong;
1872
1873 if (SPEC_NOUN (val->etype) == V_FLOAT)
1874 return double2ul (SPEC_CVAL (val->etype).v_float);
1875
1876 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1877 return double2ul (doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16));
1878
1879 if (SPEC_LONGLONG (val->etype))
1880 {
1881 if (SPEC_USIGN (val->etype))
1882 return (unsigned long)SPEC_CVAL (val->etype).v_ulonglong;
1883 else
1884 return (unsigned long)SPEC_CVAL (val->etype).v_longlong;
1885 }
1886
1887 if (SPEC_LONG (val->etype))
1888 {
1889 if (SPEC_USIGN (val->etype))
1890 return SPEC_CVAL (val->etype).v_ulong;
1891 else
1892 return SPEC_CVAL (val->etype).v_long;
1893 }
1894
1895 if (SPEC_NOUN (val->etype) == V_INT)
1896 {
1897 if (SPEC_USIGN (val->etype))
1898 return SPEC_CVAL (val->etype).v_uint;
1899 else
1900 return SPEC_CVAL (val->etype).v_int;
1901 }
1902
1903 if (SPEC_NOUN (val->etype) == V_CHAR)
1904 {
1905 if (SPEC_USIGN (val->etype))
1906 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1907 else
1908 return (signed char) SPEC_CVAL (val->etype).v_int;
1909 }
1910
1911 if (IS_BOOL (val->etype) || IS_BITVAR (val->etype))
1912 return SPEC_CVAL (val->etype).v_uint;
1913
1914 if (SPEC_NOUN (val->etype) == V_VOID)
1915 return SPEC_CVAL (val->etype).v_ulong;
1916
1917 if (SPEC_NOUN (val->etype) == V_STRUCT)
1918 return SPEC_CVAL (val->etype).v_ulong;
1919
1920 /* we are lost ! */
1921 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ulFromVal: unknown value");
1922 return 0;
1923 }
1924
1925 /*------------------------------------------------------------------*/
1926 /* byteOfVal - extract a byte of a value */
1927 /* offset = 0 (LSB) ... n-1 (MSB) */
1928 /* higher offsets of signed ints will be sign extended, */
1929 /* other types will be extended with zero padding */
1930 /*------------------------------------------------------------------*/
1931 unsigned char
byteOfVal(value * val,int offset)1932 byteOfVal (value * val, int offset)
1933 {
1934 unsigned char *p;
1935 int shift = 8*offset;
1936
1937 wassert (offset >= 0);
1938
1939 if (!val)
1940 return 0;
1941
1942 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1943 {
1944 werror (E_CONST_EXPECTED, val->name);
1945 return 0;
1946 }
1947
1948 /* if it is not a specifier then we can assume that */
1949 /* it will be an unsigned long */
1950 /* 2012-Apr-30 EEP - Why is this true? */
1951 if (!IS_SPEC (val->type))
1952 return offset < 4 ? (SPEC_CVAL (val->etype).v_ulong >> shift) & 0xff : 0;
1953
1954 if (SPEC_NOUN (val->etype) == V_FLOAT)
1955 {
1956 float f = (float)SPEC_CVAL (val->etype).v_float;
1957
1958 if (offset > 3)
1959 return 0;
1960 p = (unsigned char *)&f;
1961 #ifdef WORDS_BIGENDIAN
1962 p += 3 - offset;
1963 #else
1964 p += offset;
1965 #endif
1966 return *p;
1967 }
1968
1969 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1970 return offset < 4 ? (SPEC_CVAL (val->etype).v_fixed16x16 >> shift) & 0xff : 0;
1971
1972 if (SPEC_LONGLONG (val->etype))
1973 {
1974 if (SPEC_USIGN (val->etype))
1975 return offset < 8 ? (SPEC_CVAL (val->etype).v_ulonglong >> shift) & 0xff : 0;
1976 else
1977 return offset < 8 ? (SPEC_CVAL (val->etype).v_longlong >> shift) & 0xff :
1978 (SPEC_CVAL (val->etype).v_longlong < 0 ? 0xff : 0);
1979 }
1980
1981 if (SPEC_LONG (val->etype))
1982 {
1983 if (SPEC_USIGN (val->etype))
1984 return offset < 4 ? (SPEC_CVAL (val->etype).v_ulong >> shift) & 0xff : 0;
1985 else
1986 return offset < 4 ? (SPEC_CVAL (val->etype).v_long >> shift) & 0xff :
1987 (SPEC_CVAL (val->etype).v_long < 0 ? 0xff : 0);
1988 }
1989
1990 if (SPEC_NOUN (val->etype) == V_INT)
1991 {
1992 if (SPEC_USIGN (val->etype))
1993 return offset < 2 ? (SPEC_CVAL (val->etype).v_uint >> shift) & 0xff : 0;
1994 else
1995 return offset < 2 ? (SPEC_CVAL (val->etype).v_int >> shift) & 0xff :
1996 (SPEC_CVAL (val->etype).v_int < 0 ? 0xff : 0);
1997 }
1998
1999 if (SPEC_NOUN (val->etype) == V_CHAR)
2000 {
2001 if (SPEC_USIGN (val->etype))
2002 return offset < 1 ? SPEC_CVAL (val->etype).v_uint & 0xff : 0;
2003 else
2004 return offset < 1 ? SPEC_CVAL (val->etype).v_int & 0xff :
2005 (SPEC_CVAL (val->etype).v_int < 0 ? 0xff : 0);
2006 }
2007
2008 if (IS_BOOL (val->etype) || IS_BITVAR (val->etype))
2009 return offset < 2 ? (SPEC_CVAL (val->etype).v_uint >> shift) & 0xff : 0;
2010
2011 /* we are lost ! */
2012 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "byteOfVal: unknown value");
2013 return 0;
2014 }
2015
2016 /*------------------------------------------------------------------*/
2017 /* ullFromLit - literal to unsigned long long conversion */
2018 /*------------------------------------------------------------------*/
2019 TYPE_TARGET_ULONGLONG
ullFromLit(sym_link * lit)2020 ullFromLit (sym_link * lit)
2021 {
2022 sym_link * etype = getSpec(lit);
2023
2024 if (!lit)
2025 return 0;
2026
2027 if (etype && SPEC_SCLS (etype) != S_LITERAL)
2028 {
2029 werror (E_CONST_EXPECTED, "");
2030 return 0;
2031 }
2032
2033 /* if it is not a specifier then we can assume that */
2034 /* it will be an unsigned long */
2035 if (!IS_SPEC (lit))
2036 return SPEC_CVAL (etype).v_ulong;
2037
2038 if (SPEC_NOUN (etype) == V_FLOAT)
2039 return double2ul (SPEC_CVAL (etype).v_float); /* FIXME: this loses bits */
2040
2041 if (SPEC_NOUN (etype) == V_FIXED16X16)
2042 return double2ul (doubleFromFixed16x16 (SPEC_CVAL (etype).v_fixed16x16)); /* FIXME: this loses bits */
2043
2044 if (SPEC_LONGLONG (etype))
2045 {
2046 if (SPEC_USIGN (etype))
2047 return SPEC_CVAL (etype).v_ulonglong;
2048 else
2049 return SPEC_CVAL (etype).v_longlong;
2050 }
2051
2052 if (SPEC_LONG (etype))
2053 {
2054 if (SPEC_USIGN (etype))
2055 return SPEC_CVAL (etype).v_ulong;
2056 else
2057 return SPEC_CVAL (etype).v_long;
2058 }
2059
2060 if (SPEC_NOUN (etype) == V_INT)
2061 {
2062 if (SPEC_USIGN (etype))
2063 return SPEC_CVAL (etype).v_uint;
2064 else
2065 return SPEC_CVAL (etype).v_int;
2066 }
2067
2068 if (SPEC_NOUN (etype) == V_CHAR)
2069 {
2070 if (SPEC_USIGN (etype))
2071 return (unsigned char) SPEC_CVAL (etype).v_uint;
2072 else
2073 return (signed char) SPEC_CVAL (etype).v_int;
2074 }
2075
2076 if (IS_BOOL (etype) || IS_BITVAR (etype))
2077 return SPEC_CVAL (etype).v_uint;
2078
2079 if (SPEC_NOUN (etype) == V_VOID)
2080 return SPEC_CVAL (etype).v_ulong;
2081
2082 if (SPEC_NOUN (etype) == V_STRUCT) /* ??? Why ??? EEP - 23 Nov 2012 */
2083 return SPEC_CVAL (etype).v_ulong;
2084
2085 /* we are lost ! */
2086 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ullFromLit: unknown value");
2087 return 0;
2088 }
2089
2090 /*------------------------------------------------------------------*/
2091 /* ullFromVal - value to unsigned long long conversion */
2092 /*------------------------------------------------------------------*/
2093 unsigned long long
ullFromVal(value * val)2094 ullFromVal (value * val)
2095 {
2096 if (!val)
2097 return 0;
2098
2099 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
2100 {
2101 werror (E_CONST_EXPECTED, val->name);
2102 return 0;
2103 }
2104 return (unsigned long long) ullFromLit (val->type);
2105 }
2106
2107 /*------------------------------------------------------------------*/
2108 /* csdOfVal - return 0 if the value can be represented as csd */
2109 /* topbit - highest nonzero bit in csd */
2110 /* nonzero - number of nonzero bits in csd */
2111 /* csd_add - positive bits in csd */
2112 /* csd_sub - negative bits in csd */
2113 /*------------------------------------------------------------------*/
csdOfVal(int * topbit,int * nonzero,unsigned long long * csd_add,unsigned long long * csd_sub,value * val)2114 int csdOfVal (int *topbit, int *nonzero, unsigned long long *csd_add, unsigned long long *csd_sub, value *val)
2115 {
2116 unsigned long long binary = ullFromVal (val);
2117 bool gamma, theta, a;
2118 int bit, next;
2119
2120 *topbit = 0;
2121 *nonzero = 0;
2122 *csd_add = 0;
2123 *csd_sub = 0;
2124
2125 for (a = 0, gamma = 0, bit = 0; bit < 61; bit++)
2126 {
2127 theta = a ^ (binary & 1);
2128 gamma = !gamma && theta;
2129 next = (1 - 2 * (bool)(binary & 2)) * gamma;
2130 if (next > 0)
2131 *csd_add |= (1ull << bit);
2132 else if (next < 0)
2133 *csd_sub |= (1ull << bit);
2134 if (next)
2135 {
2136 (*nonzero)++;
2137 *topbit = bit;
2138 }
2139 a = (binary & 1);
2140 binary >>= 1;
2141 }
2142 return((bool)binary);
2143 }
2144
2145 /*------------------------------------------------------------------*/
2146 /* isEqualVal - return 1 if value is equal to specified constant */
2147 /*------------------------------------------------------------------*/
2148 int
isEqualVal(value * val,int k)2149 isEqualVal (value * val, int k)
2150 {
2151 if (IS_SPEC (val->type))
2152 {
2153 if (SPEC_NOUN (val->type) == V_FLOAT || SPEC_NOUN (val->type) == V_FIXED16X16)
2154 return floatFromVal (val) == k;
2155 }
2156 return ((TYPE_TARGET_LONGLONG) ullFromVal (val)) == k;
2157 }
2158
2159
2160 /*-----------------------------------------------------------------*/
2161 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
2162 /*-----------------------------------------------------------------*/
2163 double
doubleFromFixed16x16(TYPE_TARGET_ULONG value)2164 doubleFromFixed16x16 (TYPE_TARGET_ULONG value)
2165 {
2166 #if 0
2167 /* This version is incorrect negative values. */
2168 double tmp = 0, exp = 2;
2169
2170 tmp = (value & 0xffff0000) >> 16;
2171
2172 while (value)
2173 {
2174 value &= 0xffff;
2175 if (value & 0x8000)
2176 tmp += 1 / exp;
2177 exp *= 2;
2178 value <<= 1;
2179 }
2180
2181 return (tmp);
2182 #else
2183 return ((double) (value * 1.0) / (double) (1UL << 16));
2184 #endif
2185 }
2186
2187 TYPE_TARGET_ULONG
fixed16x16FromDouble(double value)2188 fixed16x16FromDouble (double value)
2189 {
2190 #if 0
2191 /* This version is incorrect negative values. */
2192 unsigned int tmp = 0, pos = 16;
2193 TYPE_TARGET_ULONG res;
2194
2195 tmp = floor (value);
2196 res = tmp << 16;
2197 value -= tmp;
2198
2199 tmp = 0;
2200 while (pos--)
2201 {
2202 value *= 2;
2203 if (value >= 1.0)
2204 tmp |= (1 << pos);
2205 value -= floor (value);
2206 }
2207
2208 res |= tmp;
2209
2210 return (res);
2211 #else
2212 return double2ul (value * (double) (1UL << 16));
2213 #endif
2214 }
2215
2216 /*------------------------------------------------------------------*/
2217 /* valUnaryPM - does the unary +/- operation on a constant */
2218 /*------------------------------------------------------------------*/
2219 value *
valUnaryPM(value * val)2220 valUnaryPM (value * val)
2221 {
2222 /* depending on type */
2223 if (SPEC_NOUN (val->etype) == V_FLOAT)
2224 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
2225 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
2226 SPEC_CVAL (val->etype).v_fixed16x16 = (TYPE_TARGET_ULONG) - ((long) SPEC_CVAL (val->etype).v_fixed16x16);
2227 else if (SPEC_LONGLONG (val->etype))
2228 {
2229 if (SPEC_USIGN (val->etype))
2230 SPEC_CVAL (val->etype).v_ulonglong = 0 - SPEC_CVAL (val->etype).v_ulonglong;
2231 else
2232 SPEC_CVAL (val->etype).v_longlong = -SPEC_CVAL (val->etype).v_longlong;
2233 }
2234 else if (SPEC_LONG (val->etype))
2235 {
2236 if (SPEC_USIGN (val->etype))
2237 SPEC_CVAL (val->etype).v_ulong = 0 - SPEC_CVAL (val->etype).v_ulong;
2238 else
2239 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
2240 }
2241 else
2242 {
2243 if (SPEC_USIGN (val->etype))
2244 SPEC_CVAL (val->etype).v_uint = 0 - SPEC_CVAL (val->etype).v_uint;
2245 else
2246 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
2247
2248 if (SPEC_NOUN (val->etype) == V_CHAR)
2249 {
2250 /* promote to 'signed int', cheapestVal() might reduce it again */
2251 SPEC_USIGN (val->etype) = 0;
2252 SPEC_NOUN (val->etype) = V_INT;
2253 }
2254 return cheapestVal (val);
2255 }
2256 return val;
2257 }
2258
2259 /*------------------------------------------------------------------*/
2260 /* valueComplement - complements a constant */
2261 /*------------------------------------------------------------------*/
2262 value *
valComplement(value * val)2263 valComplement (value * val)
2264 {
2265 /* depending on type */
2266 if (SPEC_LONGLONG (val->etype))
2267 {
2268 if (SPEC_USIGN (val->etype))
2269 SPEC_CVAL (val->etype).v_ulonglong = ~SPEC_CVAL (val->etype).v_ulonglong;
2270 else
2271 SPEC_CVAL (val->etype).v_longlong = ~SPEC_CVAL (val->etype).v_longlong;
2272 }
2273 else if (SPEC_LONG (val->etype))
2274 {
2275 if (SPEC_USIGN (val->etype))
2276 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
2277 else
2278 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
2279 }
2280 else
2281 {
2282 if (SPEC_USIGN (val->etype))
2283 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
2284 else
2285 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
2286
2287 if (SPEC_NOUN (val->etype) == V_CHAR)
2288 {
2289 /* promote to 'signed int', cheapestVal() might reduce it again */
2290 SPEC_USIGN (val->etype) = 0;
2291 SPEC_NOUN (val->etype) = V_INT;
2292 }
2293 return cheapestVal (val);
2294 }
2295 return val;
2296 }
2297
2298 /*------------------------------------------------------------------*/
2299 /* valueNot - complements a constant */
2300 /*------------------------------------------------------------------*/
2301 value *
valNot(value * val)2302 valNot (value * val)
2303 {
2304 /* depending on type */
2305 if (SPEC_LONGLONG (val->etype))
2306 {
2307 if (SPEC_USIGN (val->etype))
2308 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulonglong;
2309 else
2310 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_longlong;
2311 }
2312 else if (SPEC_LONG (val->etype))
2313 {
2314 if (SPEC_USIGN (val->etype))
2315 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
2316 else
2317 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
2318 }
2319 else
2320 {
2321 if (SPEC_USIGN (val->etype))
2322 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
2323 else
2324 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
2325
2326 }
2327 /* ANSI: result type is int, value is 0 or 1 */
2328 /* sdcc will hold this in an 'unsigned char' */
2329 SPEC_USIGN (val->etype) = 1;
2330 SPEC_LONG (val->etype) = 0;
2331 SPEC_LONGLONG (val->type) = 0;
2332 SPEC_NOUN (val->etype) = V_CHAR;
2333 return val;
2334 }
2335
2336 /*------------------------------------------------------------------*/
2337 /* valMult - multiply constants */
2338 /*------------------------------------------------------------------*/
2339 value *
valMult(value * lval,value * rval)2340 valMult (value * lval, value * rval)
2341 {
2342 value *val;
2343
2344 /* create a new value */
2345 val = newValue ();
2346 val->type = val->etype = computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '*');
2347 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2348
2349 if (IS_FLOAT (val->type))
2350 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
2351 else if (IS_FIXED16X16 (val->type))
2352 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) * floatFromVal (rval));
2353 /* signed and unsigned mul are the same, as long as the precision of the
2354 result isn't bigger than the precision of the operands. */
2355 else if (SPEC_LONGLONG (val->type))
2356 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) * (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2357 else if (SPEC_LONG (val->type))
2358 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) * (TYPE_TARGET_ULONG) ulFromVal (rval);
2359 else if (SPEC_USIGN (val->type)) /* unsigned int */
2360 {
2361 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) ulFromVal (lval) * (TYPE_TARGET_UINT) ulFromVal (rval);
2362
2363 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
2364 if (ul != (TYPE_TARGET_UINT) ul)
2365 werror (W_INT_OVL);
2366 }
2367 else /* signed int */
2368 {
2369 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) * (TYPE_TARGET_INT) floatFromVal (rval);
2370
2371 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
2372 if (l != (TYPE_TARGET_INT) l)
2373 werror (W_INT_OVL);
2374 }
2375 return cheapestVal (val);
2376 }
2377
2378 /*------------------------------------------------------------------*/
2379 /* valDiv - Divide constants */
2380 /*------------------------------------------------------------------*/
2381 value *
valDiv(value * lval,value * rval)2382 valDiv (value * lval, value * rval)
2383 {
2384 value *val;
2385
2386 if (isEqualVal (rval, 0) && !IS_FLOAT (computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '/')))
2387 {
2388 werror (E_DIVIDE_BY_ZERO);
2389 return rval;
2390 }
2391
2392 /* create a new value */
2393 val = newValue ();
2394 val->type = val->etype = computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '/');
2395 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2396
2397 if (IS_FLOAT (val->type))
2398 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
2399 else if (IS_FIXED16X16 (val->type))
2400 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) / floatFromVal (rval));
2401 else if (SPEC_LONGLONG (val->type))
2402 {
2403 if (SPEC_USIGN (val->type))
2404 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) / (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2405 else
2406 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) / (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2407 }
2408 else if (SPEC_LONG (val->type))
2409 {
2410 if (SPEC_USIGN (val->type))
2411 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) / (TYPE_TARGET_ULONG) ulFromVal (rval);
2412 else
2413 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) / (TYPE_TARGET_LONG) ulFromVal (rval);
2414 }
2415 else
2416 {
2417 if (SPEC_USIGN (val->type))
2418 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) / (TYPE_TARGET_UINT) ulFromVal (rval);
2419 else
2420 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) / (TYPE_TARGET_INT) ulFromVal (rval);
2421 }
2422 return cheapestVal (val);
2423 }
2424
2425 /*------------------------------------------------------------------*/
2426 /* valMod - Modulus constants */
2427 /*------------------------------------------------------------------*/
2428 value *
valMod(value * lval,value * rval)2429 valMod (value * lval, value * rval)
2430 {
2431 value *val;
2432
2433 if (isEqualVal (rval, 0))
2434 {
2435 werror (E_DIVIDE_BY_ZERO);
2436 return rval;
2437 }
2438
2439 /* create a new value */
2440 val = newValue ();
2441 val->type = val->etype = computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '%');
2442 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2443
2444 if (SPEC_LONGLONG (val->type))
2445 {
2446 if (SPEC_USIGN (val->type))
2447 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) % (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2448 else
2449 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) % (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2450 }
2451 else if (SPEC_LONG (val->type))
2452 {
2453 if (SPEC_USIGN (val->type))
2454 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) % (TYPE_TARGET_ULONG) ulFromVal (rval);
2455 else
2456 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) % (TYPE_TARGET_LONG) ulFromVal (rval);
2457 }
2458 else
2459 {
2460 if (SPEC_USIGN (val->type))
2461 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) % (TYPE_TARGET_UINT) ulFromVal (rval);
2462 else
2463 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) % (TYPE_TARGET_INT) ulFromVal (rval);
2464 }
2465 return cheapestVal (val);
2466 }
2467
2468 /*------------------------------------------------------------------*/
2469 /* valPlus - Addition constants */
2470 /*------------------------------------------------------------------*/
2471 value *
valPlus(value * lval,value * rval)2472 valPlus (value * lval, value * rval)
2473 {
2474 value *val;
2475
2476 /* create a new value */
2477 val = newValue ();
2478 val->type = computeType (lval->type, rval->type, RESULT_TYPE_INT, '+');
2479 val->etype = getSpec (val->type);
2480 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2481
2482 if (!IS_SPEC (val->type))
2483 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) + (TYPE_TARGET_ULONG) ulFromVal (rval);
2484 else if (IS_FLOAT (val->type))
2485 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
2486 else if (IS_FIXED16X16 (val->type))
2487 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) + floatFromVal (rval));
2488 else if (SPEC_LONGLONG (val->type))
2489 {
2490 if (SPEC_USIGN (val->type))
2491 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) + (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2492 else
2493 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) + (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2494 }
2495 else if (SPEC_LONG (val->type))
2496 {
2497 if (SPEC_USIGN (val->type))
2498 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) + (TYPE_TARGET_ULONG) ulFromVal (rval);
2499 else
2500 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) + (TYPE_TARGET_LONG) ulFromVal (rval);
2501 }
2502 else
2503 {
2504 if (SPEC_USIGN (val->type))
2505 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) + (TYPE_TARGET_UINT) ulFromVal (rval);
2506 else
2507 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) + (TYPE_TARGET_INT) ulFromVal (rval);
2508 }
2509 return cheapestVal (val);
2510 }
2511
2512 /*------------------------------------------------------------------*/
2513 /* valMinus - Addition constants */
2514 /*------------------------------------------------------------------*/
2515 value *
valMinus(value * lval,value * rval)2516 valMinus (value * lval, value * rval)
2517 {
2518 value *val;
2519
2520 /* create a new value */
2521 val = newValue ();
2522 val->type = computeType (lval->type, rval->type, RESULT_TYPE_INT, '-');
2523 val->etype = getSpec (val->type);
2524 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2525
2526 if (!IS_SPEC (val->type))
2527 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) - (TYPE_TARGET_ULONG) ulFromVal (rval);
2528 else if (IS_FLOAT (val->type))
2529 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
2530 else if (IS_FIXED16X16 (val->type))
2531 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) - floatFromVal (rval));
2532 else if (SPEC_LONGLONG (val->type))
2533 {
2534 if (SPEC_USIGN (val->type))
2535 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) - (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2536 else
2537 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) - (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2538 }
2539 else if (SPEC_LONG (val->type))
2540 {
2541 if (SPEC_USIGN (val->type))
2542 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) - (TYPE_TARGET_ULONG) ulFromVal (rval);
2543 else
2544 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) - (TYPE_TARGET_LONG) ulFromVal (rval);
2545 }
2546 else
2547 {
2548 if (SPEC_USIGN (val->type))
2549 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) - (TYPE_TARGET_UINT) ulFromVal (rval);
2550 else
2551 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) - (TYPE_TARGET_INT) ulFromVal (rval);
2552 }
2553 return cheapestVal (val);
2554 }
2555
2556 /*------------------------------------------------------------------*/
2557 /* valShift - Shift left or right */
2558 /*------------------------------------------------------------------*/
2559 value *
valShift(value * lval,value * rval,int lr)2560 valShift (value * lval, value * rval, int lr)
2561 {
2562 value *val;
2563
2564 /* create a new value */
2565 val = newValue ();
2566 val->type = val->etype = computeType (lval->etype, NULL, RESULT_TYPE_INT, 'S');
2567 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2568
2569 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) ulFromVal (rval) &&
2570 /* left shift */
2571 (lr ||
2572 /* right shift and unsigned */
2573 (!lr && SPEC_USIGN (rval->type))) &&
2574 ((TYPE_TARGET_ULONG) ulFromVal (lval) != (TYPE_TARGET_ULONG) 0))
2575 {
2576 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
2577 }
2578
2579 if (SPEC_LONGLONG (val->type))
2580 {
2581 if (SPEC_USIGN (val->type))
2582 {
2583 SPEC_CVAL (val->type).v_ulonglong = lr ?
2584 (TYPE_TARGET_ULONGLONG) ullFromVal (lval) << (TYPE_TARGET_ULONGLONG) ullFromVal (rval) :
2585 (TYPE_TARGET_ULONGLONG) ullFromVal (lval) >> (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2586 }
2587 else
2588 {
2589 SPEC_CVAL (val->type).v_longlong = lr ?
2590 (TYPE_TARGET_LONGLONG) ullFromVal (lval) << (TYPE_TARGET_ULONGLONG) ullFromVal (rval) :
2591 (TYPE_TARGET_LONGLONG) ullFromVal (lval) >> (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2592 }
2593 }
2594 else if (SPEC_LONG (val->type))
2595 {
2596 if (SPEC_USIGN (val->type))
2597 {
2598 SPEC_CVAL (val->type).v_ulong = lr ?
2599 (TYPE_TARGET_ULONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) :
2600 (TYPE_TARGET_ULONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2601 }
2602 else
2603 {
2604 SPEC_CVAL (val->type).v_long = lr ?
2605 (TYPE_TARGET_LONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) :
2606 (TYPE_TARGET_LONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2607 }
2608 }
2609 else
2610 {
2611 if (SPEC_USIGN (val->type))
2612 {
2613 SPEC_CVAL (val->type).v_uint = lr ?
2614 (TYPE_TARGET_UINT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) :
2615 (TYPE_TARGET_UINT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2616 }
2617 else
2618 {
2619 SPEC_CVAL (val->type).v_int = lr ?
2620 (TYPE_TARGET_INT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) :
2621 (TYPE_TARGET_INT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2622 }
2623 }
2624 return cheapestVal (val);
2625 }
2626
2627 /*------------------------------------------------------------------*/
2628 /* valCompare - Compares two literal */
2629 /*------------------------------------------------------------------*/
2630 value *
valCompare(value * lval,value * rval,int ctype)2631 valCompare (value * lval, value * rval, int ctype)
2632 {
2633 value *val;
2634
2635 /* create a new value */
2636 val = newValue ();
2637 val->type = val->etype = newCharLink ();
2638 val->type->xclass = SPECIFIER;
2639 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
2640 SPEC_USIGN (val->type) = 1;
2641 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
2642
2643 switch (ctype)
2644 {
2645 /* FIXME: need to add long long support to inequalities */
2646 case '<':
2647 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
2648 break;
2649
2650 case '>':
2651 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
2652 break;
2653
2654 case LE_OP:
2655 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
2656 break;
2657
2658 case GE_OP:
2659 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
2660 break;
2661
2662 case EQ_OP:
2663 if (SPEC_NOUN (lval->type) == V_FLOAT || SPEC_NOUN (rval->type) == V_FLOAT)
2664 {
2665 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
2666 }
2667 else if (SPEC_NOUN (lval->type) == V_FIXED16X16 || SPEC_NOUN (rval->type) == V_FIXED16X16)
2668 {
2669 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
2670 }
2671 else
2672 {
2673 /* integrals: ignore signedness */
2674 TYPE_TARGET_ULONGLONG l, r;
2675
2676 l = (TYPE_TARGET_ULONGLONG) ullFromVal (lval);
2677 r = (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2678 /* In order to correctly compare 'signed int' and 'unsigned int' it's
2679 neccessary to strip them to 16 bit.
2680 Literals are reduced to their cheapest type, therefore left and
2681 right might have different types. It's neccessary to find a
2682 common type: int (used for char too) or long */
2683 if (!IS_LONGLONG (lval->etype) && !IS_LONGLONG (rval->etype))
2684 {
2685 r = (TYPE_TARGET_ULONG) r;
2686 l = (TYPE_TARGET_ULONG) l;
2687 }
2688 if (!IS_LONG (lval->etype) && !IS_LONG (rval->etype))
2689 {
2690 r = (TYPE_TARGET_UINT) r;
2691 l = (TYPE_TARGET_UINT) l;
2692 }
2693 SPEC_CVAL (val->type).v_int = l == r;
2694 }
2695 break;
2696 case NE_OP:
2697 if (SPEC_NOUN (lval->type) == V_FLOAT || SPEC_NOUN (rval->type) == V_FLOAT)
2698 {
2699 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
2700 }
2701 else if (SPEC_NOUN (lval->type) == V_FIXED16X16 || SPEC_NOUN (rval->type) == V_FIXED16X16)
2702 {
2703 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
2704 }
2705 else
2706 {
2707 /* integrals: ignore signedness */
2708 TYPE_TARGET_ULONGLONG l, r;
2709
2710 l = (TYPE_TARGET_ULONGLONG) ullFromVal (lval);
2711 r = (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2712 /* In order to correctly compare 'signed int' and 'unsigned int' it's
2713 neccessary to strip them to 16 bit.
2714 Literals are reduced to their cheapest type, therefore left and
2715 right might have different types. It's neccessary to find a
2716 common type: int (used for char too) or long */
2717 if (!IS_LONGLONG (lval->etype) && !IS_LONGLONG (rval->etype))
2718 {
2719 r = (TYPE_TARGET_ULONG) r;
2720 l = (TYPE_TARGET_ULONG) l;
2721 }
2722 if (!IS_LONG (lval->etype) && !IS_LONG (rval->etype))
2723 {
2724 r = (TYPE_TARGET_UINT) r;
2725 l = (TYPE_TARGET_UINT) l;
2726 }
2727 SPEC_CVAL (val->type).v_int = l != r;
2728 }
2729 break;
2730
2731 }
2732
2733 return val;
2734 }
2735
2736 /*------------------------------------------------------------------*/
2737 /* valBitwise - Bitwise operation */
2738 /*------------------------------------------------------------------*/
2739 value *
valBitwise(value * lval,value * rval,int op)2740 valBitwise (value * lval, value * rval, int op)
2741 {
2742 value *val;
2743
2744 /* create a new value */
2745 val = newValue ();
2746 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
2747 val->etype = getSpec (val->type);
2748 SPEC_SCLS (val->etype) = S_LITERAL;
2749
2750 switch (op)
2751 {
2752 case '&':
2753 if (SPEC_LONGLONG (val->type))
2754 {
2755 if (SPEC_USIGN (val->type))
2756 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) & (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2757 else
2758 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) & (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2759 }
2760 else if (SPEC_LONG (val->type))
2761 {
2762 if (SPEC_USIGN (val->type))
2763 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) & (TYPE_TARGET_ULONG) ulFromVal (rval);
2764 else
2765 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) & (TYPE_TARGET_LONG) ulFromVal (rval);
2766 }
2767 else
2768 {
2769 if (SPEC_USIGN (val->type))
2770 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) & (TYPE_TARGET_UINT) ulFromVal (rval);
2771 else
2772 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) & (TYPE_TARGET_INT) ulFromVal (rval);
2773 }
2774 break;
2775
2776 case '|':
2777 if (SPEC_LONGLONG (val->type))
2778 {
2779 if (SPEC_USIGN (val->type))
2780 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) | (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2781 else
2782 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) | (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2783 }
2784 else if (SPEC_LONG (val->type))
2785 {
2786 if (SPEC_USIGN (val->type))
2787 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) | (TYPE_TARGET_ULONG) ulFromVal (rval);
2788 else
2789 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) | (TYPE_TARGET_LONG) ulFromVal (rval);
2790 }
2791 else
2792 {
2793 if (SPEC_USIGN (val->type))
2794 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) | (TYPE_TARGET_UINT) ulFromVal (rval);
2795 else
2796 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) | (TYPE_TARGET_INT) ulFromVal (rval);
2797 }
2798
2799 break;
2800
2801 case '^':
2802 if (SPEC_LONGLONG (val->type))
2803 {
2804 if (SPEC_USIGN (val->type))
2805 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) ^ (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2806 else
2807 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) ^ (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2808 }
2809 else if (SPEC_LONG (val->type))
2810 {
2811 if (SPEC_USIGN (val->type))
2812 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) ^ (TYPE_TARGET_ULONG) ulFromVal (rval);
2813 else
2814 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) ^ (TYPE_TARGET_LONG) ulFromVal (rval);
2815 }
2816 else
2817 {
2818 if (SPEC_USIGN (val->type))
2819 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) ^ (TYPE_TARGET_UINT) ulFromVal (rval);
2820 else
2821 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) ^ (TYPE_TARGET_INT) ulFromVal (rval);
2822 }
2823 break;
2824 }
2825
2826 return cheapestVal (val);
2827 }
2828
2829 /*------------------------------------------------------------------*/
2830 /* valAndOr - Generates code for and / or operation */
2831 /*------------------------------------------------------------------*/
2832 value *
valLogicAndOr(value * lval,value * rval,int op)2833 valLogicAndOr (value * lval, value * rval, int op)
2834 {
2835 value *val;
2836
2837 /* create a new value */
2838 val = newValue ();
2839 val->type = val->etype = newCharLink ();
2840 val->type->xclass = SPECIFIER;
2841 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
2842 SPEC_USIGN (val->type) = 1;
2843
2844 switch (op)
2845 {
2846 case AND_OP:
2847 SPEC_CVAL (val->type).v_int = !isEqualVal (lval, 0) && !isEqualVal (rval, 0);
2848 break;
2849
2850 case OR_OP:
2851 SPEC_CVAL (val->type).v_int = !isEqualVal (lval, 0) || !isEqualVal (rval, 0);
2852 break;
2853 }
2854
2855 return val;
2856 }
2857
2858 /*------------------------------------------------------------------*/
2859 /* valCastLiteral - casts a literal value to another type */
2860 /*------------------------------------------------------------------*/
2861 value *
valCastLiteral(sym_link * dtype,double fval,TYPE_TARGET_ULONGLONG llval)2862 valCastLiteral (sym_link * dtype, double fval, TYPE_TARGET_ULONGLONG llval)
2863 {
2864 value *val;
2865 unsigned long l = double2ul (fval);
2866
2867 if (!dtype)
2868 return NULL;
2869
2870 val = newValue ();
2871 if (dtype)
2872 val->etype = getSpec (val->type = copyLinkChain (dtype));
2873 else
2874 {
2875 val->etype = val->type = newLink (SPECIFIER);
2876 SPEC_NOUN (val->etype) = V_VOID;
2877 }
2878 SPEC_SCLS (val->etype) = S_LITERAL;
2879
2880 /* if it is not a specifier then we can assume that */
2881 /* it will be an unsigned long */
2882 if (!IS_SPEC (val->type))
2883 {
2884 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
2885 return val;
2886 }
2887
2888 switch (SPEC_NOUN (val->etype))
2889 {
2890 case V_FLOAT:
2891 SPEC_CVAL (val->etype).v_float = fval;
2892 break;
2893
2894 case V_FIXED16X16:
2895 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
2896 break;
2897
2898 case V_BOOL:
2899 case V_BIT:
2900 case V_SBIT:
2901 SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
2902 break;
2903
2904 case V_BITFIELD:
2905 l &= (0xffffffffu >> (32 - SPEC_BLEN (val->etype)));
2906 if (SPEC_USIGN (val->etype))
2907 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
2908 else
2909 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
2910 break;
2911
2912 case V_CHAR:
2913 if (SPEC_USIGN (val->etype))
2914 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) l;
2915 else
2916 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
2917 break;
2918
2919 default:
2920 if (SPEC_LONGLONG (val->etype))
2921 {
2922 if (SPEC_USIGN (val->etype))
2923 SPEC_CVAL (val->etype).v_ulonglong = (TYPE_TARGET_ULONGLONG) llval;
2924 else
2925 SPEC_CVAL (val->etype).v_longlong = (TYPE_TARGET_LONGLONG) llval;
2926 }
2927 else if (SPEC_LONG (val->etype))
2928 {
2929 if (SPEC_USIGN (val->etype))
2930 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
2931 else
2932 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
2933 }
2934 else
2935 {
2936 if (SPEC_USIGN (val->etype))
2937 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
2938 else
2939 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
2940 }
2941 }
2942
2943 return val;
2944 }
2945
2946 /*-------------------------------------------------------------------*/
2947 /* valRecastLitVal - changes type of a literal value to another type */
2948 /*-------------------------------------------------------------------*/
2949 value *
valRecastLitVal(sym_link * dtype,value * val)2950 valRecastLitVal (sym_link * dtype, value * val)
2951 {
2952 sym_link * otype = val->type;
2953 double fval;
2954 TYPE_TARGET_ULONGLONG ull;
2955
2956 if (IS_SPEC (otype) && (SPEC_NOUN (otype) == V_FIXED16X16 || SPEC_NOUN (otype) == V_FLOAT))
2957 {
2958 fval = floatFromVal (val);
2959 ull = (TYPE_TARGET_ULONGLONG)fval;
2960 }
2961 else
2962 {
2963 ull = (TYPE_TARGET_ULONGLONG) ullFromVal (val);
2964 fval = (double)ull;
2965 }
2966
2967 if (dtype)
2968 val->etype = getSpec (val->type = copyLinkChain (dtype));
2969 else
2970 {
2971 val->etype = val->type = newLink (SPECIFIER);
2972 SPEC_NOUN (val->etype) = V_VOID;
2973 }
2974 SPEC_SCLS (val->etype) = S_LITERAL;
2975
2976 /* if it is not a specifier then we can assume that */
2977 /* it will be an unsigned long */
2978 if (!IS_SPEC (val->type))
2979 {
2980 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ull;
2981 return val;
2982 }
2983
2984 switch (SPEC_NOUN (val->etype))
2985 {
2986 case V_FLOAT:
2987 SPEC_CVAL (val->etype).v_float = fval;
2988 break;
2989
2990 case V_FIXED16X16:
2991 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
2992 break;
2993
2994 case V_BOOL:
2995 case V_BIT:
2996 case V_SBIT:
2997 SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
2998 break;
2999
3000 case V_BITFIELD:
3001 ull &= (0xffffffffu >> (32 - SPEC_BLEN (val->etype)));
3002 if (SPEC_USIGN (val->etype))
3003 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) ull;
3004 else
3005 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) ull;
3006 break;
3007
3008 case V_CHAR:
3009 if (SPEC_USIGN (val->etype))
3010 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) ull;
3011 else
3012 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) ull;
3013 break;
3014
3015 default:
3016 if (SPEC_LONGLONG (val->etype))
3017 {
3018 if (SPEC_USIGN (val->etype))
3019 SPEC_CVAL (val->etype).v_ulonglong = (TYPE_TARGET_ULONGLONG) ull;
3020 else
3021 SPEC_CVAL (val->etype).v_longlong = (TYPE_TARGET_LONGLONG) ull;
3022 }
3023 else if (SPEC_LONG (val->etype))
3024 {
3025 if (SPEC_USIGN (val->etype))
3026 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ull;
3027 else
3028 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) ull;
3029 }
3030 else
3031 {
3032 if (SPEC_USIGN (val->etype))
3033 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) ull;
3034 else
3035 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) ull;
3036 }
3037 }
3038
3039 return val;
3040 }
3041
3042 /*------------------------------------------------------------------*/
3043 /* getNelements - determines # of elements from init list */
3044 /*------------------------------------------------------------------*/
3045 int
getNelements(sym_link * type,initList * ilist)3046 getNelements (sym_link * type, initList * ilist)
3047 {
3048 int i, size;
3049
3050 if (!ilist)
3051 return 0;
3052
3053 if (ilist->type == INIT_DEEP)
3054 ilist = ilist->init.deep;
3055
3056 /* if type is a character array and there is only one
3057 (string) initialiser then get the length of the string */
3058 if (IS_ARRAY (type) && (IS_CHAR (type->next) || IS_INT (type->next) && IS_UNSIGNED (type->next)) && !ilist->next)
3059 {
3060 ast *iast = ilist->init.node;
3061 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
3062
3063 if (v && IS_ARRAY (v->type) && (IS_CHAR (v->etype) || IS_INT (v->etype) && IS_UNSIGNED (v->etype) && IS_LONG (type->next) == IS_LONG (v->etype)))
3064 /* yep, it's a string */
3065 {
3066 return DCL_ELEM (v->type);
3067 }
3068 }
3069
3070 size = 0;
3071 i = 0;
3072 while (ilist)
3073 {
3074 if (ilist->designation)
3075 {
3076 if (ilist->designation->type != DESIGNATOR_ARRAY)
3077 {
3078 // structure designator for array, boo.
3079 werrorfl (ilist->filename, ilist->lineno, E_BAD_DESIGNATOR);
3080 }
3081 else
3082 {
3083 i = ilist->designation->designator.elemno;
3084 }
3085 }
3086 if (size <= i)
3087 {
3088 size = i + 1; /* array size is one larger than array init element */
3089 }
3090 i++;
3091 ilist = ilist->next;
3092 }
3093 return size;
3094 }
3095
3096 /*-----------------------------------------------------------------*/
3097 /* valForArray - returns a value with name of array index */
3098 /*-----------------------------------------------------------------*/
3099 value *
valForArray(ast * arrExpr)3100 valForArray (ast * arrExpr)
3101 {
3102 value *val, *lval = NULL;
3103 int size = getSize (arrExpr->left->ftype->next);
3104
3105 /* if the right or left is an array
3106 resolve it first */
3107 if (IS_AST_OP (arrExpr->left))
3108 {
3109 if (arrExpr->left->opval.op == '[')
3110 lval = valForArray (arrExpr->left);
3111 else if (arrExpr->left->opval.op == '.')
3112 lval = valForStructElem (arrExpr->left->left, arrExpr->left->right);
3113 else if (arrExpr->left->opval.op == PTR_OP)
3114 {
3115 if (IS_ADDRESS_OF_OP (arrExpr->left->left))
3116 lval = valForStructElem (arrExpr->left->left->left, arrExpr->left->right);
3117 else if (IS_AST_VALUE (arrExpr->left->left) && IS_PTR (arrExpr->left->left->ftype))
3118 lval = valForStructElem (arrExpr->left->left, arrExpr->left->right);
3119 }
3120 else
3121 return NULL;
3122 }
3123 else if (!IS_AST_SYM_VALUE (arrExpr->left))
3124 return NULL;
3125
3126 if (!IS_AST_LIT_VALUE (arrExpr->right))
3127 return NULL;
3128
3129 val = newValue ();
3130 val->type = newLink (DECLARATOR);
3131 if (IS_AST_LIT_VALUE (arrExpr->left) && IS_PTR (arrExpr->left->ftype))
3132 {
3133 SNPRINTF (val->name, sizeof (val->name), "0x%X",
3134 AST_ULONG_VALUE (arrExpr->left) + AST_ULONG_VALUE (arrExpr->right) * size);
3135 memcpy (val->type, arrExpr->left->ftype, sizeof (sym_link));
3136 }
3137 else if (lval)
3138 {
3139 SNPRINTF (val->name, sizeof (val->name), "(%s + %d)", lval->name, AST_ULONG_VALUE (arrExpr->right) * size);
3140 memcpy (val->type, lval->type, sizeof (sym_link));
3141 }
3142 else
3143 {
3144 SNPRINTF (val->name, sizeof (val->name), "(%s + %d)",
3145 AST_SYMBOL (arrExpr->left)->rname, AST_ULONG_VALUE (arrExpr->right) * size);
3146 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
3147 DCL_TYPE (val->type) = CPOINTER;
3148 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
3149 DCL_TYPE (val->type) = FPOINTER;
3150 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
3151 DCL_TYPE (val->type) = PPOINTER;
3152 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
3153 DCL_TYPE (val->type) = IPOINTER;
3154 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
3155 DCL_TYPE (val->type) = EEPPOINTER;
3156 else
3157 DCL_TYPE (val->type) = POINTER;
3158 }
3159
3160 val->type->next = arrExpr->left->ftype->next;
3161 val->etype = getSpec (val->type);
3162 return val;
3163 }
3164
3165 /*-----------------------------------------------------------------*/
3166 /* valForStructElem - returns value with name of struct element */
3167 /*-----------------------------------------------------------------*/
3168 value *
valForStructElem(ast * structT,ast * elemT)3169 valForStructElem (ast * structT, ast * elemT)
3170 {
3171 value *val, *lval = NULL;
3172 symbol *sym;
3173 int idxoff = 0;
3174 ast *sast = NULL;
3175
3176 /* left could be further derefed */
3177 if (IS_AST_OP (structT))
3178 {
3179 if (structT->opval.op == '[')
3180 lval = valForArray (structT);
3181 else if (structT->opval.op == '+')
3182 {
3183 if (IS_AST_LIT_VALUE (structT->right) && !IS_AST_OP (structT->left))
3184 {
3185 idxoff = (int) (AST_ULONG_VALUE (structT->right) * getSize (structT->left->ftype->next));
3186 sast = structT->left;
3187 }
3188 else if (IS_AST_LIT_VALUE (structT->left) && !IS_AST_OP (structT->right))
3189 {
3190 idxoff = (int) (AST_ULONG_VALUE (structT->left) * getSize (structT->right->ftype->next));
3191 sast = structT->right;
3192 }
3193 else
3194 return NULL;
3195 }
3196 else if (structT->opval.op == '-')
3197 {
3198 if (IS_AST_LIT_VALUE (structT->right) && !IS_AST_OP (structT->left))
3199 {
3200 idxoff = 0 - (int) (AST_ULONG_VALUE (structT->right) * getSize (structT->left->ftype->next));
3201 sast = structT->left;
3202 }
3203 else
3204 return NULL;
3205 }
3206 else if (structT->opval.op == '.')
3207 lval = valForStructElem (structT->left, structT->right);
3208 else if (structT->opval.op == PTR_OP)
3209 {
3210 if (IS_ADDRESS_OF_OP (structT->left))
3211 lval = valForStructElem (structT->left->left, structT->right);
3212 else if (IS_AST_VALUE (structT->left) && IS_PTR (structT->left->ftype))
3213 lval = valForStructElem (structT->left, structT->right);
3214 }
3215 else
3216 return NULL;
3217 }
3218
3219 if (!IS_AST_SYM_VALUE (elemT))
3220 return NULL;
3221
3222 if (!structT || !IS_STRUCT (structT->etype))
3223 return NULL;
3224
3225 if ((sym = getStructElement (SPEC_STRUCT (structT->etype), AST_SYMBOL (elemT))) == NULL)
3226 {
3227 return NULL;
3228 }
3229
3230 val = newValue ();
3231 val->type = newLink (DECLARATOR);
3232 if (IS_AST_LIT_VALUE (structT) && IS_PTR (structT->ftype))
3233 {
3234 SNPRINTF (val->name, sizeof (val->name), "0x%X", AST_ULONG_VALUE (structT) + (int) sym->offset);
3235 memcpy (val->type, structT->ftype, sizeof (sym_link));
3236 }
3237 else if (lval)
3238 {
3239 SNPRINTF (val->name, sizeof (val->name), "(%s + %d)", lval->name, (int) sym->offset);
3240 memcpy (val->type, lval->type, sizeof (sym_link));
3241 }
3242 else
3243 {
3244 if (sast)
3245 SNPRINTF (val->name, sizeof (val->name), "(%s + (%d))", AST_SYMBOL (sast)->rname, ((int) sym->offset) + idxoff);
3246 else
3247 SNPRINTF (val->name, sizeof (val->name), "(%s + %d)", AST_SYMBOL (structT)->rname, (int) sym->offset);
3248
3249 if (SPEC_SCLS (structT->etype) == S_CODE)
3250 DCL_TYPE (val->type) = CPOINTER;
3251 else if (SPEC_SCLS (structT->etype) == S_XDATA)
3252 DCL_TYPE (val->type) = FPOINTER;
3253 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
3254 DCL_TYPE (val->type) = PPOINTER;
3255 else if (SPEC_SCLS (structT->etype) == S_IDATA)
3256 DCL_TYPE (val->type) = IPOINTER;
3257 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
3258 DCL_TYPE (val->type) = EEPPOINTER;
3259 else
3260 DCL_TYPE (val->type) = POINTER;
3261 }
3262
3263 val->type->next = sym->type;
3264 val->etype = getSpec (val->type);
3265 return val;
3266 }
3267
3268 /*-----------------------------------------------------------------*/
3269 /* valForCastAggr - will return value for a cast of an aggregate */
3270 /* plus minus a constant */
3271 /*-----------------------------------------------------------------*/
3272 value *
valForCastAggr(ast * aexpr,sym_link * type,ast * cnst,int op)3273 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
3274 {
3275 value *val;
3276
3277 if (!IS_AST_SYM_VALUE (aexpr))
3278 return NULL;
3279 if (!IS_AST_LIT_VALUE (cnst))
3280 return NULL;
3281
3282 val = newValue ();
3283
3284 SNPRINTF (val->name, sizeof (val->name), "(%s %c %d)",
3285 AST_SYMBOL (aexpr)->rname, op, getSize (type->next) * AST_ULONG_VALUE (cnst));
3286
3287 val->type = type;
3288 val->etype = getSpec (val->type);
3289 return val;
3290 }
3291
3292 /*-----------------------------------------------------------------*/
3293 /* valForCastArr - will return value for a cast of an aggregate */
3294 /* with no constant */
3295 /*-----------------------------------------------------------------*/
3296 value *
valForCastArr(ast * aexpr,sym_link * type)3297 valForCastArr (ast * aexpr, sym_link * type)
3298 {
3299 value *val;
3300
3301 if (!IS_AST_SYM_VALUE (aexpr))
3302 return NULL;
3303
3304 val = newValue ();
3305
3306 SNPRINTF (val->name, sizeof (val->name), "(%s)", AST_SYMBOL (aexpr)->rname);
3307
3308 val->type = type;
3309 val->etype = getSpec (val->type);
3310 return val;
3311 }
3312