Update svn merge history.
[sdcc.git] / sdcc / src / SDCCval.c
blob096cc2b452843f03d2d4e63f45720835106270f8
1 /*----------------------------------------------------------------------
2 SDCCval.c :- has routine to do all kinds of fun stuff with the
3 value wrapper & with initialiser lists.
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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.
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.
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.
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 -------------------------------------------------------------------------*/
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"
34 long cNestLevel;
37 /*-----------------------------------------------------------------*/
38 /* newValue - allocates and returns a new value */
39 /*-----------------------------------------------------------------*/
40 value *
41 newValue (void)
43 value *val;
45 val = Safe_alloc (sizeof (value));
47 return val;
50 /*-----------------------------------------------------------------*/
51 /* newiList - new initializer list */
52 /*-----------------------------------------------------------------*/
53 initList *
54 newiList (int type, void *ilist)
56 initList *nilist;
58 nilist = Safe_alloc (sizeof (initList));
60 nilist->type = type;
61 nilist->filename = lexFilename;
62 nilist->lineno = lexLineno;
63 nilist->designation = NULL;
65 switch (type)
67 case INIT_NODE:
68 nilist->init.node = (struct ast *) ilist;
69 break;
71 case INIT_DEEP:
72 nilist->init.deep = (struct initList *) ilist;
73 break;
76 return nilist;
79 /*------------------------------------------------------------------*/
80 /* revinit - reverses the initial values for a value chain */
81 /*------------------------------------------------------------------*/
82 initList *
83 revinit (initList * val)
85 initList *prev, *curr, *next;
87 if (!val)
88 return NULL;
90 prev = val;
91 curr = val->next;
93 while (curr)
95 next = curr->next;
96 curr->next = prev;
97 prev = curr;
98 curr = next;
100 val->next = (void *) NULL;
101 return prev;
104 bool
105 convertIListToConstList (initList * src, literalList ** lList, int size)
107 int cnt = 0;
108 initList *iLoop;
109 literalList *head, *last, *newL;
111 head = last = NULL;
113 if (src && src->type != INIT_DEEP)
115 return FALSE;
118 iLoop = src ? src->init.deep : NULL;
120 while (iLoop)
122 if (iLoop->designation != NULL)
124 return FALSE;
127 if (iLoop->type != INIT_NODE)
129 return FALSE;
132 if (!IS_AST_LIT_VALUE (decorateType (resolveSymbols (iLoop->init.node), RESULT_TYPE_NONE, true)))
134 return FALSE;
136 iLoop = iLoop->next;
137 cnt++;
139 if (!size)
141 size = cnt;
144 /* We've now established that the initializer list contains only literal values. */
146 iLoop = src ? src->init.deep : NULL;
147 while (size--)
149 literalList ll = {0};
150 value *val = iLoop ? AST_VALUE (iLoop->init.node) : NULL;
151 if (val)
153 ll.isFloat = IS_FLOAT(val->type);
154 if (ll.isFloat)
155 ll.value.f64 = floatFromVal(val);
156 else
157 ll.value.ull = ullFromVal(val);
160 if (last && ((!last->isFloat && last->value.ull == ll.value.ull) ||
161 (last->isFloat && last->value.f64 == ll.value.f64)))
163 last->count++;
165 else
167 newL = Safe_alloc (sizeof (literalList));
168 *newL = ll;
169 newL->count = 1;
170 newL->next = NULL;
172 if (last)
174 last->next = newL;
176 else
178 head = newL;
180 last = newL;
182 iLoop = iLoop ? iLoop->next : NULL;
185 if (!head)
187 return FALSE;
190 *lList = head;
191 return TRUE;
194 literalList *
195 copyLiteralList (literalList * src)
197 literalList *head, *prev, *newL;
199 head = prev = NULL;
201 while (src)
203 newL = Safe_alloc (sizeof (literalList));
205 *newL = *src;
206 newL->count = src->count;
207 newL->next = NULL;
209 if (prev)
211 prev->next = newL;
213 else
215 head = newL;
217 prev = newL;
218 src = src->next;
221 return head;
224 /*------------------------------------------------------------------*/
225 /* copyIlist - copy initializer list */
226 /*------------------------------------------------------------------*/
227 initList *
228 copyIlist (initList * src)
230 initList *dest = NULL;
232 if (!src)
233 return NULL;
235 switch (src->type)
237 case INIT_DEEP:
238 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
239 dest->lineno = src->lineno;
240 break;
241 case INIT_NODE:
242 dest = newiList (INIT_NODE, copyAst (src->init.node));
243 dest->lineno = src->lineno;
244 break;
247 if (src->designation)
248 dest->designation = copyDesignation (src->designation);
250 if (src->next)
251 assert (dest != NULL);
252 dest->next = copyIlist (src->next);
254 return dest;
257 /*------------------------------------------------------------------*/
258 /* list2int - converts the first element of the list to value */
259 /*------------------------------------------------------------------*/
260 double
261 list2int (initList * val)
263 initList *i = val;
265 assert (i->type != INIT_HOLE);
267 if (i->type == INIT_DEEP)
268 return list2int (val->init.deep);
270 return floatFromVal (constExprValue (val->init.node, TRUE));
273 /*------------------------------------------------------------------*/
274 /* list2val - converts the first element of the list to value */
275 /*------------------------------------------------------------------*/
276 value *
277 list2val (initList * val, int check)
279 if (!val)
280 return NULL;
282 if(val->type == INIT_HOLE)
283 return NULL;
285 if (val->type == INIT_DEEP)
286 return list2val (val->init.deep, check);
288 if (val->type == INIT_NODE && val->init.node->opval.op == CAST)
289 return constExprValue (val->init.node->right, check);
291 return constExprValue (val->init.node, check);
294 /*------------------------------------------------------------------*/
295 /* list2expr - returns the first expression in the initializer list */
296 /*------------------------------------------------------------------*/
297 ast *
298 list2expr (initList * ilist)
300 if (!ilist)
301 return NULL;
303 assert (ilist->type != INIT_HOLE);
305 if (ilist->type == INIT_DEEP)
306 return list2expr (ilist->init.deep);
307 return ilist->init.node;
310 /*------------------------------------------------------------------*/
311 /* resolveIvalSym - resolve symbols in initial values */
312 /*------------------------------------------------------------------*/
313 void
314 resolveIvalSym (initList *ilist, sym_link *type)
316 int is_ptr = IS_PTR (type) || (IS_ARRAY(type) && IS_PTR(type->next));
317 RESULT_TYPE resultType = getResultTypeFromType (getSpec (type));
319 while (ilist)
321 if (ilist->type == INIT_NODE)
323 ilist->init.node = decorateType (resolveSymbols (ilist->init.node), is_ptr ? RESULT_TYPE_INT : resultType, true);
325 else if (ilist->type == INIT_DEEP)
327 resolveIvalSym (ilist->init.deep, type);
330 ilist = ilist->next;
334 /*-----------------------------------------------------------------*/
335 /* newDesignation - new designation */
336 /*-----------------------------------------------------------------*/
337 designation *
338 newDesignation (int type, void *designator)
340 designation *ndesignation;
342 ndesignation = Safe_alloc (sizeof (designation));
344 ndesignation->type = type;
345 ndesignation->filename = lexFilename;
346 ndesignation->lineno = lexLineno;
348 switch (type)
350 case DESIGNATOR_STRUCT:
351 ndesignation->designator.tag = (struct symbol *) designator;
352 break;
354 case DESIGNATOR_ARRAY:
355 ndesignation->designator.elemno = * ((int *) designator);
356 break;
359 return ndesignation;
362 /*------------------------------------------------------------------*/
363 /* revDesignation - reverses the designation chain */
364 /*------------------------------------------------------------------*/
365 designation *
366 revDesignation (designation * val)
368 designation *prev, *curr, *next;
370 if (!val)
371 return NULL;
373 prev = val;
374 curr = val->next;
376 while (curr)
378 next = curr->next;
379 curr->next = prev;
380 prev = curr;
381 curr = next;
383 val->next = (void *) NULL;
384 return prev;
387 /*------------------------------------------------------------------*/
388 /* copyDesignation - copy designation list */
389 /*------------------------------------------------------------------*/
390 designation *
391 copyDesignation (designation * src)
393 designation *dest = NULL;
395 if (!src)
396 return NULL;
398 switch (src->type)
400 case DESIGNATOR_STRUCT:
401 dest = newDesignation (DESIGNATOR_STRUCT, copySymbol (src->designator.tag));
402 break;
403 case DESIGNATOR_ARRAY:
404 dest = newDesignation (DESIGNATOR_ARRAY, &(src->designator.elemno) );
405 break;
408 dest->lineno = src->lineno;
409 dest->filename = src->filename;
411 if (src->next)
412 dest->next = copyDesignation (src->next);
414 return dest;
417 /*------------------------------------------------------------------*/
418 /* moveNestedInit - rewrites an initList node with a nested */
419 /* designator to remove one level of nesting. */
420 /*------------------------------------------------------------------*/
421 static
422 void moveNestedInit(initList *deepParent, initList *src)
424 initList *dst = NULL, **eol;
426 /** Create new initList element */
427 switch (src->type)
429 case INIT_NODE:
430 dst = newiList(INIT_NODE, src->init.node);
431 break;
432 case INIT_DEEP:
433 dst = newiList(INIT_DEEP, src->init.deep);
434 break;
436 dst->filename = src->filename;
437 dst->lineno = src->lineno;
438 dst->designation = src->designation->next;
440 /* add dst to end of deepParent */
441 if (deepParent->type != INIT_DEEP)
443 werrorfl (deepParent->filename, deepParent->lineno,
444 E_INIT_STRUCT, "<unknown>");
445 return;
447 for (eol = &(deepParent->init.deep); *eol ; )
448 eol = &((*eol)->next);
449 *eol = dst;
452 /*-----------------------------------------------------------------*/
453 /* findStructField - find a specific field in a struct definition */
454 /*-----------------------------------------------------------------*/
455 static int
456 findStructField (symbol *fields, symbol *target)
458 int i;
460 for (i=0 ; fields; fields = fields->next)
462 /* skip past unnamed bitfields */
463 if (IS_BITFIELD (fields->type) && SPEC_BUNNAMED (fields->etype))
464 continue;
465 /* is this it? */
466 if (strcmp(fields->name, target->name) == 0)
467 return i;
468 i++;
471 /* not found */
472 werrorfl (target->fileDef, target->lineDef, E_NOT_MEMBER, target->name);
473 return 0;
476 /*------------------------------------------------------------------*/
477 /* reorderIlist - expands an initializer list to match designated */
478 /* initializers. */
479 /*------------------------------------------------------------------*/
480 initList *reorderIlist (sym_link * type, initList * ilist)
482 initList *iloop, *nlist, **nlistArray;
483 symbol *sflds;
484 int size=0, idx;
486 if (!IS_AGGREGATE (type))
487 /* uninteresting: no designated initializers */
488 return ilist;
490 if (ilist && ilist->type == INIT_HOLE)
491 /* ditto; just a uninitialized hole */
492 return ilist;
494 /* special case: check for string initializer */
495 if (IS_ARRAY (type) && IS_CHAR (type->next) &&
496 ilist && ilist->type == INIT_NODE)
498 ast *iast = ilist->init.node;
499 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
500 if (v && IS_ARRAY (v->type) && IS_CHAR (v->etype))
502 /* yep, it's a string; no changes needed here. */
503 return ilist;
507 if (ilist && ilist->type != INIT_DEEP)
509 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, "<unknown>");
510 return NULL;
513 /* okay, allocate enough space */
514 if (IS_ARRAY (type))
516 size = getNelements(type, ilist);
517 if (size == 0)
518 return NULL;
520 else if (IS_STRUCT (type))
522 /* compute size from struct type. */
523 size = 0;
524 for (sflds = SPEC_STRUCT (type)->fields; sflds; sflds = sflds->next)
526 /* skip past unnamed bitfields */
527 if (IS_BITFIELD (sflds->type) && SPEC_BUNNAMED (sflds->etype))
528 continue;
529 size++;
532 nlistArray = Safe_calloc ( size, sizeof(initList *) );
534 /* pull together all the initializers into an ordered list */
535 iloop = ilist ? ilist->init.deep : NULL;
536 for (idx = 0 ; iloop ; iloop = iloop->next, idx++)
538 if (iloop->designation)
540 assert (iloop->type != INIT_HOLE);
542 if (IS_ARRAY (type))
544 if (iloop->designation->type == DESIGNATOR_ARRAY)
545 idx = iloop->designation->designator.elemno;
546 else
547 werrorfl (iloop->filename, iloop->lineno, E_BAD_DESIGNATOR);
549 else if (IS_STRUCT (type))
551 if (iloop->designation->type == DESIGNATOR_STRUCT)
552 idx = findStructField (SPEC_STRUCT (type)->fields,
553 iloop->designation->designator.tag);
554 else
555 werrorfl (iloop->filename, iloop->lineno, E_BAD_DESIGNATOR);
557 else
559 assert (0);
562 if (iloop->designation->next)
564 if (idx >= size)
565 continue;
566 if (nlistArray[idx] == NULL)
567 nlistArray[idx] = newiList(INIT_DEEP, NULL);
568 moveNestedInit(nlistArray[idx], iloop);
569 continue;
573 /* overwrite any existing entry with iloop */
574 if (iloop->type != INIT_HOLE)
576 if (idx >= size)
577 continue;
578 if (nlistArray[idx] != NULL)
579 werrorfl (iloop->filename, iloop->lineno, W_DUPLICATE_INIT, idx);
580 nlistArray[idx] = iloop;
584 /* create new list from nlistArray/size */
585 nlist = NULL;
586 sflds = IS_STRUCT (type) ? SPEC_STRUCT (type)->fields : NULL;
587 for ( idx=0; idx < size; idx++ )
589 initList *src = nlistArray[idx], *dst = NULL;
590 if (!src || src->type==INIT_HOLE)
592 dst = newiList(INIT_HOLE, NULL);
593 dst->filename = ilist->filename;
594 dst->lineno = ilist->lineno;
596 else
598 switch (src->type)
600 case INIT_NODE:
601 dst = newiList(INIT_NODE, src->init.node);
602 break;
603 case INIT_DEEP:
604 dst = newiList(INIT_DEEP, src->init.deep);
605 break;
607 dst->filename = src->filename;
608 dst->lineno = src->lineno;
610 dst->next = nlist;
611 nlist = dst;
612 /* advance to next field which is not an unnamed bitfield */
615 sflds = sflds ? sflds->next : NULL;
617 while (sflds &&
618 IS_BITFIELD (sflds->type) && SPEC_BUNNAMED (sflds->etype));
621 nlist = newiList(INIT_DEEP, revinit (nlist));
622 nlist->filename = ilist->filename;
623 nlist->lineno = ilist->lineno;
624 nlist->designation = ilist->designation;
625 nlist->next = ilist->next;
626 return nlist;
629 /*------------------------------------------------------------------*/
630 /* symbolVal - creates a value for a symbol */
631 /*------------------------------------------------------------------*/
632 value *
633 symbolVal (symbol * sym)
635 value *val;
637 if (!sym)
638 return NULL;
640 val = newValue ();
641 val->sym = sym;
643 if (sym->type)
645 val->type = sym->type;
646 val->etype = getSpec (val->type);
649 if (*sym->rname)
651 SNPRINTF (val->name, sizeof (val->name), "%s", sym->rname);
653 else
655 SNPRINTF (val->name, sizeof (val->name), "_%s", sym->name);
658 return val;
661 /*--------------------------------------------------------------------*/
662 /* cheapestVal - try to reduce 'signed int' to 'char' */
663 /*--------------------------------------------------------------------*/
664 static value *
665 cheapestVal (value * val)
667 /* only int can be reduced */
668 if (!IS_INT (val->type))
669 return val;
671 /* long must not be changed */
672 if (SPEC_LONG (val->type) || SPEC_LONGLONG (val->type))
673 return val;
675 /* unsigned must not be changed */
676 if (SPEC_USIGN (val->type))
677 return val;
679 /* the only possible reduction is from signed int to (un)signed char,
680 because it's automatically promoted back to signed int.
682 a reduction from unsigned int to unsigned char is a bug,
683 because an _unsigned_ char is promoted to _signed_ int! */
684 if (SPEC_CVAL (val->type).v_int < -128 || SPEC_CVAL (val->type).v_int > 255)
686 /* not in the range of (un)signed char */
687 return val;
690 SPEC_NOUN (val->type) = V_CHAR;
692 /* 'unsigned char' promotes to 'signed int', so that we can
693 reduce it the other way */
694 if (SPEC_CVAL (val->type).v_int >= 0)
696 /* 'bool' promotes to 'signed int' too */
697 if (SPEC_CVAL (val->type).v_int <= 1)
699 /* Do not use V_BIT here because in some contexts it also */
700 /* implies a storage class. */
701 SPEC_NOUN (val->type) = V_BOOL;
703 else
705 /* Boolean types are intrinsically unsigned, so only */
706 /* set the USIGN flag for char types to avoid triggering */
707 /* type checking errors/warnings. */
708 SPEC_USIGN (val->type) = 1;
712 return (val);
715 /*-----------------------------------------------------------------*/
716 /* double2ul - double to unsigned long conversion */
717 /*-----------------------------------------------------------------*/
718 unsigned long
719 double2ul (double val)
722 * See ISO/IEC 9899, chapter 6.3.1.4 Real floating and integer (still the same in ISO C 23):
723 * If the value of the integral part cannot be represented by the integer type, the behavior is undefined.
724 * This shows up on Mac OS X i386 platform which uses SSE unit instead of the x87 FPU for floating-point operations
727 * on Mac OS X ppc (long) 2147483648.0 equals to 2147483647, so we explicitly convert it to 0x80000000
728 * on other known platforms (long) 2147483648.0 equals to -2147483648
730 return ((val) < 0) ? (((val) < -2147483647.0) ? 0x80000000UL : (unsigned long) -((long) -(val))) : (unsigned long) (val);
733 /*-----------------------------------------------------------------*/
734 /* double2ull - double to unsigned long long conversion */
735 /*-----------------------------------------------------------------*/
736 unsigned long long
737 double2ull (double val)
739 return ((val) < 0) ? (((val) < -9223372036854775807.0) ? 0x8000000000000000ull : (unsigned long long) -((long long) -(val))) : (unsigned long long) (val);
742 /*--------------------------------------------------------------------*/
743 /* checkConstantRange - check if constant fits in numeric range of */
744 /* var type in comparisons and assignments */
745 /*--------------------------------------------------------------------*/
746 CCR_RESULT
747 checkConstantRange (sym_link *var, sym_link *lit, int op, bool exchangeLeftRight)
749 sym_link *reType;
750 TYPE_TARGET_LONGLONG litVal;
751 TYPE_TARGET_ULONGLONG ulitVal;
752 TYPE_TARGET_ULONGLONG signExtMask;
753 TYPE_TARGET_ULONGLONG signMask;
754 bool litValUnsigned;
755 int varBits;
757 litVal = ullFromLit (lit);
758 ulitVal = (TYPE_TARGET_ULONGLONG) litVal;
759 litValUnsigned = SPEC_USIGN (lit);
760 varBits = bitsForType (var);
761 signMask = 1ull << (varBits-1);
762 signExtMask = varBits >= sizeof(TYPE_TARGET_ULONGLONG)*8 ? 0 : ~((1ull << varBits)-1);
764 #if 0
765 printf("checkConstantRange\n");
766 printf(" varBits = %d\n", varBits);
767 printf(" ulitVal = 0x%016lx\n", ulitVal);
768 printf(" signExtMask = 0x%016lx\n", signExtMask);
769 printf(" signMask = 0x%016lx\n", signMask);
770 #endif
772 //return CCR_OK; /* EEP - debug for long long */
773 /* sanity checks */
774 if (IS_FLOAT (var) || IS_FIXED (var))
775 return CCR_OK;
776 if (varBits < 1)
777 return CCR_ALWAYS_FALSE;
778 if (varBits > 64)
779 return CCR_ALWAYS_TRUE;
781 /* special: assignment */
782 if (op == '=')
784 if (IS_BOOLEAN (var))
785 return CCR_OK;
787 if (1) // Though the else branch is dead, I still would like to keep it.
788 //if (getenv ("SDCC_VERY_PEDANTIC"))
790 if (SPEC_USIGN (var))
792 if ((!litValUnsigned && litVal < 0) || (litVal & signExtMask) != 0)
793 return CCR_OVL;
794 return CCR_OK;
796 else
798 if (litValUnsigned)
800 if ((ulitVal & (signExtMask | signMask)) == 0)
801 return CCR_OK;
803 else
805 if ((litVal & (signExtMask | signMask)) == 0)
806 return CCR_OK;
807 if ((litVal & (signExtMask | signMask)) == (signExtMask | signMask))
808 return CCR_OK;
810 return CCR_OVL;
813 else
815 /* ignore signedness, e.g. allow everything
816 from -127...+255 for (unsigned) char */
817 if ((litVal & signExtMask) == 0)
818 return CCR_OK;
819 if ((litVal & (signExtMask | signMask)) == (signExtMask | signMask))
820 return CCR_OK;
821 return CCR_OVL;
825 if (exchangeLeftRight)
826 switch (op)
828 case EQ_OP:
829 break;
830 case NE_OP:
831 break;
832 case '>':
833 op = '<';
834 break;
835 case GE_OP:
836 op = LE_OP;
837 break;
838 case '<':
839 op = '>';
840 break;
841 case LE_OP:
842 op = GE_OP;
843 break;
844 default:
845 return CCR_ALWAYS_FALSE;
848 reType = computeType (var, lit, RESULT_TYPE_NONE, op);
850 #if 0
851 printf(" reType = ");
852 printTypeChain (reType, 0);
853 #endif
855 if (SPEC_USIGN (reType))
857 /* unsigned operation */
858 int reBits = bitsForType (reType);
859 TYPE_TARGET_ULONGLONG minValP, maxValP, minValM, maxValM;
860 TYPE_TARGET_ULONGLONG opBitsMask = reBits >= sizeof(opBitsMask)*8 ? ~0ull : ((1ull << reBits)-1);
862 if (IS_BOOL (var))
864 minValP = 0;
865 maxValP = 1;
866 minValM = 0;
867 maxValM = 1;
869 else if (SPEC_USIGN (lit) && SPEC_USIGN (var))
871 /* both operands are unsigned, this is easy */
872 minValP = 0;
873 maxValP = ~signExtMask;
874 /* there's only range, just copy it to 2nd set */
875 minValM = minValP;
876 maxValM = maxValP;
878 else if (SPEC_USIGN (var))
880 /* lit is casted from signed to unsigned, e.g.:
881 unsigned u;
882 u == (char) -17
883 -> u == 0xffef'
885 minValP = 0;
886 maxValP = ~signExtMask;
887 /* there's only one range, just copy it to 2nd set */
888 minValM = minValP;
889 maxValM = maxValP;
891 /* it's an unsigned operation */
892 ulitVal &= opBitsMask;
894 else /* SPEC_USIGN (lit) */
896 /* var is casted from signed to unsigned, e.g.:
897 signed char c;
898 c == (unsigned) -17
899 -> c == 0xffef'
901 The possible values after casting var
902 split up in two, nonconsecutive ranges:
904 minValP = 0; positive range: 0...127
905 maxValP = 0x7f;
906 minValM = 0xff80; negative range: -128...-1
907 maxValM = 0xffff;
910 /* positive range */
911 minValP = 0;
912 maxValP = ~(signExtMask | signMask);
914 /* negative range */
915 minValM = signExtMask | signMask;
916 maxValM = (TYPE_TARGET_ULONGLONG)~0ull; /* -1 */
917 /* limit number of bits to size of return type */
918 minValM &= opBitsMask;
919 maxValM &= opBitsMask;
921 #if 0
922 printf(" ulitVal = 0x%016lx\n", ulitVal);
923 printf(" opBitsMask = 0x%016lx\n", opBitsMask);
924 printf(" maxValP = 0x%016lx\n", maxValP);
925 printf(" minValP = 0x%016lx\n", minValP);
926 printf(" maxValM = 0x%016lx\n", maxValM);
927 printf(" minValM = 0x%016lx\n", minValM);
928 #endif
930 switch (op)
932 case EQ_OP: /* var == lit */
933 if (ulitVal <= maxValP && ulitVal >= minValP) /* 0 */
934 return CCR_OK;
935 if (ulitVal <= maxValM && ulitVal >= minValM)
936 return CCR_OK;
937 return CCR_ALWAYS_FALSE;
938 case NE_OP: /* var != lit */
939 if (ulitVal <= maxValP && ulitVal >= minValP) /* 0 */
940 return CCR_OK;
941 if (ulitVal <= maxValM && ulitVal >= minValM)
942 return CCR_OK;
943 return CCR_ALWAYS_TRUE;
944 case '>': /* var > lit */
945 if (ulitVal >= maxValM)
946 return CCR_ALWAYS_FALSE;
947 if (ulitVal < minValP) /* 0 */
948 return CCR_ALWAYS_TRUE;
949 return CCR_OK;
950 case GE_OP: /* var >= lit */
951 if (ulitVal > maxValM)
952 return CCR_ALWAYS_FALSE;
953 if (ulitVal <= minValP) /* 0 */
954 return CCR_ALWAYS_TRUE;
955 return CCR_OK;
956 case '<': /* var < lit */
957 if (ulitVal > maxValM)
958 return CCR_ALWAYS_TRUE;
959 if (ulitVal <= minValP) /* 0 */
960 return CCR_ALWAYS_FALSE;
961 return CCR_OK;
962 case LE_OP: /* var <= lit */
963 if (ulitVal >= maxValM)
964 return CCR_ALWAYS_TRUE;
965 if (ulitVal < minValP) /* 0 */
966 return CCR_ALWAYS_FALSE;
967 return CCR_OK;
968 default:
969 return CCR_ALWAYS_FALSE;
972 else
974 /* signed operation */
975 TYPE_TARGET_LONGLONG minVal, maxVal;
977 if (IS_BOOL (var))
979 minVal = 0;
980 maxVal = 1;
982 else if (SPEC_USIGN (var))
984 /* unsigned var, but signed operation. This happens
985 when var is promoted to signed int.
986 Set actual min/max values of var. */
987 minVal = 0;
988 maxVal = ~signExtMask;
990 else
992 /* signed var */
993 minVal = signExtMask | signMask;
994 maxVal = ~(signExtMask | signMask);
997 switch (op)
999 case EQ_OP: /* var == lit */
1000 if (litVal > maxVal || litVal < minVal)
1001 return CCR_ALWAYS_FALSE;
1002 return CCR_OK;
1003 case NE_OP: /* var != lit */
1004 if (litVal > maxVal || litVal < minVal)
1005 return CCR_ALWAYS_TRUE;
1006 return CCR_OK;
1007 case '>': /* var > lit */
1008 if (litVal >= maxVal)
1009 return CCR_ALWAYS_FALSE;
1010 if (litVal < minVal)
1011 return CCR_ALWAYS_TRUE;
1012 return CCR_OK;
1013 case GE_OP: /* var >= lit */
1014 if (litVal > maxVal)
1015 return CCR_ALWAYS_FALSE;
1016 if (litVal <= minVal)
1017 return CCR_ALWAYS_TRUE;
1018 return CCR_OK;
1019 case '<': /* var < lit */
1020 if (litVal > maxVal)
1021 return CCR_ALWAYS_TRUE;
1022 if (litVal <= minVal)
1023 return CCR_ALWAYS_FALSE;
1024 return CCR_OK;
1025 case LE_OP: /* var <= lit */
1026 if (litVal >= maxVal)
1027 return CCR_ALWAYS_TRUE;
1028 if (litVal < minVal)
1029 return CCR_ALWAYS_FALSE;
1030 return CCR_OK;
1031 default:
1032 return CCR_ALWAYS_FALSE;
1037 #if 0
1038 CCR_RESULT
1039 checkConstantRange (sym_link * var, sym_link * lit, int op, bool exchangeLeftRight)
1041 CCR_RESULT result;
1043 printf ("checkConstantRange:\n");
1044 printf (" var: ");
1045 printTypeChain (var, NULL);
1046 printf (" lit = 0x%lx: ",ullFromLit (lit));
1047 printTypeChain (lit, NULL);
1048 printf (" op: '");
1049 switch (op)
1051 case '<': printf ("<"); break;
1052 case '=': printf ("="); break;
1053 case '>': printf (">"); break;
1054 case LE_OP: printf ("<="); break;
1055 case GE_OP: printf (">="); break;
1056 case EQ_OP: printf ("=="); break;
1057 case NE_OP: printf ("!="); break;
1058 default: printf ("%d",op);
1060 printf("'\n");
1061 result = checkConstantRange2 (var, lit, op, exchangeLeftRight);
1062 switch (result)
1064 case CCR_ALWAYS_TRUE: printf (" CCR_ALWAYS_TRUE\n"); break;
1065 case CCR_ALWAYS_FALSE: printf (" CCR_ALWAYS_FALSE\n"); break;
1066 case CCR_OK: printf (" CCR_OK\n"); break;
1067 case CCR_OVL: printf (" CCR_OVL\n"); break;
1068 default: printf(" CCR_%d\n",result);
1070 return result;
1072 #endif
1075 /*-----------------------------------------------------------------*/
1076 /* valueFromLit - creates a value from a literal */
1077 /*-----------------------------------------------------------------*/
1078 value *
1079 valueFromLit (double lit)
1081 struct dbuf_s dbuf;
1082 value *ret;
1084 if ((((TYPE_TARGET_LONG) lit) - lit) == 0)
1086 dbuf_init (&dbuf, 128);
1087 dbuf_printf (&dbuf, "%d", (TYPE_TARGET_LONG) lit);
1088 ret = constVal (dbuf_c_str (&dbuf));
1089 dbuf_destroy (&dbuf);
1090 return ret;
1093 dbuf_init (&dbuf, 128);
1094 dbuf_printf (&dbuf, "%f", lit);
1095 ret = constFloatVal (dbuf_c_str (&dbuf));
1096 dbuf_destroy (&dbuf);
1097 return ret;
1100 /*-----------------------------------------------------------------*/
1101 /* constFloatVal - converts a FLOAT constant to value */
1102 /*-----------------------------------------------------------------*/
1103 value *
1104 constFloatVal (const char *s)
1106 value *val = newValue ();
1107 double sval;
1108 char *p;
1110 sval = strtod (s, &p);
1111 if (p == s)
1113 werror (E_INVALID_FLOAT_CONST, s);
1114 return constCharVal (0);
1117 val->type = val->etype = newLink (SPECIFIER);
1118 SPEC_NOUN (val->type) = V_FLOAT;
1119 SPEC_SCLS (val->type) = S_LITERAL;
1120 SPEC_CONST (val->type) = 1;
1121 SPEC_CVAL (val->type).v_float = sval;
1123 return val;
1126 /*-----------------------------------------------------------------*/
1127 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
1128 /*-----------------------------------------------------------------*/
1129 value *
1130 constFixed16x16Val (const char *s)
1132 value *val = newValue ();
1133 double sval;
1134 char *p;
1136 sval = strtod (s, &p);
1137 if (p == s)
1139 werror (E_INVALID_FLOAT_CONST, s);
1140 return constCharVal (0);
1143 val->type = val->etype = newLink (SPECIFIER);
1144 SPEC_NOUN (val->type) = V_FLOAT;
1145 SPEC_SCLS (val->type) = S_LITERAL;
1146 SPEC_CONST (val->type) = 1;
1147 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (sval);
1149 return val;
1152 /*-----------------------------------------------------------------*/
1153 /* constVal - converts a constant into a cheap value type */
1154 /*-----------------------------------------------------------------*/
1155 value *
1156 constVal (const char *s)
1158 value *val = constIntVal (s);
1160 wassert (SPEC_NOUN (val->type) == V_INT);
1162 if (SPEC_LONGLONG (val->type))
1164 else if (SPEC_LONG (val->type))
1166 else if (SPEC_USIGN (val->type))
1168 unsigned int i = SPEC_CVAL (val->type).v_uint;
1169 if (i < 256)
1170 SPEC_NOUN (val->type) = V_CHAR;
1172 else
1174 int i = SPEC_CVAL (val->type).v_int;
1175 if (i >= 0 && i < 256)
1177 SPEC_NOUN (val->type) = V_CHAR;
1178 SPEC_USIGN (val->type) = TRUE;
1179 SPEC_CVAL (val->type).v_uint = i;
1181 else if (i >= -128 && i < 128)
1183 SPEC_NOUN (val->type) = V_CHAR;
1187 return val;
1190 /*-----------------------------------------------------------------*/
1191 /* sepStrToUll - like stroull, but also handles digit separators */
1192 /*-----------------------------------------------------------------*/
1193 static unsigned long long
1194 sepStrToUll (const char *nptr, char **endptr, int base)
1196 wassert (base >= 2 && base <= 16);
1198 unsigned long long ret = 0ull;
1199 bool separated = false;
1201 for(;;nptr++)
1203 int next = nptr[0];
1205 // Skip digit separators
1206 if (next == '\'')
1208 separated = true;
1209 continue;
1212 // Assumes 0-9, a-f and A-F are consecutive in character set.
1213 if (next >= 'a' && next <= 'f')
1214 next = next - 'a' + 10;
1215 else if (next >= 'A' && next <= 'F')
1216 next = next - 'A' + 10;
1217 else if (next >= '0' && next <= '9')
1218 next = next - '0';
1219 else
1220 break;
1222 if (!(next >= 0 && next < base))
1223 break;
1225 ret *= base;
1226 ret += next;
1229 if(separated && !options.std_c23)
1230 werror (W_DIGIT_SEPARATOR_C23);
1232 if (endptr)
1233 *endptr = (char *)nptr;
1235 return(ret);
1238 /*-----------------------------------------------------------------*/
1239 /* constIntVal - converts an integer constant into correct type */
1240 /* See ISO C11, section 6.4.4.1 for the rules. */
1241 /*-----------------------------------------------------------------*/
1242 value *
1243 constIntVal (const char *s)
1245 char *p, *p2;
1246 double dval;
1247 long long int llval;
1248 value *val = newValue ();
1249 bool decimal, u_suffix = false, l_suffix = false, ll_suffix = false, wb_suffix = false;
1251 val->type = val->etype = newLink (SPECIFIER);
1252 SPEC_SCLS (val->type) = S_LITERAL;
1253 SPEC_CONST (val->type) = 1;
1254 SPEC_USIGN (val->type) = 0;
1256 errno = 0;
1258 if (s[0] == '0')
1260 if (s[1] == 'b' || s[1] == 'B')
1262 if (!options.std_sdcc && !options.std_c23)
1263 werror (W_BINARY_INTEGER_CONSTANT_C23);
1264 llval = sepStrToUll (s + 2, &p, 2);
1266 else if (s[1] == 'x' || s[1] == 'X')
1267 llval = sepStrToUll (s + 2, &p, 16);
1268 else
1269 llval = sepStrToUll (s, &p, 8);
1270 dval = (double)(unsigned long long int) llval;
1271 decimal = FALSE;
1273 else
1275 dval = strtod (s, &p);
1276 if (dval >= 0.0)
1278 llval = sepStrToUll (s, &p, 10);
1279 dval = (double)(unsigned long long int) llval;
1281 else
1283 llval = sepStrToUll (s + 1, &p, 10);
1284 llval = -llval;
1285 dval = (double) llval;
1287 decimal = true;
1290 if (errno)
1292 dval = 4294967295.0;
1293 werror (W_INVALID_INT_CONST, s, dval);
1296 // Check suffixes
1297 if ((p2 = strchr (p, 'u')) || (p2 = strchr (p, 'U')))
1299 u_suffix = TRUE;
1300 p2++;
1301 if (strchr (p2, 'u') || strchr (p2, 'U'))
1302 werror (E_INTEGERSUFFIX, p);
1305 if ((p2 = strstr (p, "ll")) || (p2 = strstr (p, "LL")))
1307 ll_suffix = TRUE;
1308 p2 += 2;
1309 if (strchr (p2, 'l') || strchr (p2, 'L') || strstr (p, "wb") || strstr (p, "WB"))
1310 werror (E_INTEGERSUFFIX, p);
1312 else if ((p2 = strchr (p, 'l')) || (p2 = strchr (p, 'L')))
1314 l_suffix = TRUE;
1315 p2++;
1316 if (strchr (p2, 'l') || strchr (p2, 'L') || strstr (p, "wb") || strstr (p, "WB"))
1317 werror (E_INTEGERSUFFIX, p);
1319 else if ((p2 = strstr (p, "wb")) || (p2 = strstr (p, "WB")))
1321 wb_suffix = true;
1322 p2 += 2;
1323 if (strchr (p2, 'l') || strchr (p2, 'L'))
1324 werror (E_INTEGERSUFFIX, p);
1325 else if (!options.std_c23)
1326 werror (W_BITINTCONST_C23);
1329 SPEC_NOUN (val->type) = wb_suffix ? V_BITINT : V_INT;
1331 if (wb_suffix) // Choose narrowest.
1333 int width;
1334 if (u_suffix)
1336 SPEC_USIGN (val->type) = 1;
1337 for (width = 1; width <= port->s.bitint_maxwidth && (1ull << width) - 1 < llval; width++);
1338 SPEC_CVAL (val->type).v_ulonglong = llval;
1340 else
1342 for (width = 2; width <= port->s.bitint_maxwidth && (-(1ll << (width - 1)) > llval || (1ull << (width - 1)) - 1 < llval); width++);
1343 SPEC_CVAL (val->type).v_longlong = llval;
1345 if (width > port->s.bitint_maxwidth)
1346 werror (E_INVALID_BITINTWIDTH);
1347 SPEC_BITINTWIDTH(val->type) = width;
1348 return val;
1350 else if (u_suffix) // Choose first of unsigned int, unsigned long int, unsigned long long int that fits.
1352 SPEC_USIGN (val->type) = 1;
1353 if (ll_suffix || dval > 0xffffffff)
1354 SPEC_LONGLONG (val->type) = 1;
1355 else if(l_suffix || dval > 0xffff)
1356 SPEC_LONG (val->type) = 1;
1358 else
1360 if (decimal) // Choose first of int, long int, long long int that fits.
1362 if (ll_suffix || dval > 0x7fffffff || dval < -0x80000000ll)
1364 if (!options.std_c99) // C90 exception: Use unsigned long
1366 SPEC_USIGN (val->type) = 1;
1367 SPEC_LONG (val->type) = 1;
1369 else
1370 SPEC_LONGLONG (val->type) = 1;
1372 else if(l_suffix || dval > 0x7fff || dval < -0x8000l)
1373 SPEC_LONG (val->type) = 1;
1375 else // Choose first of int, unsigned int, long int, unsigned long int, long long int, unsigned long long int that fits.
1377 if (dval > 0x7fffffffffffffffull || dval >= 0 && (unsigned long long int)llval > 0x7fffffffffffffffull)
1379 SPEC_USIGN (val->type) = 1;
1380 SPEC_LONGLONG (val->type) = 1;
1382 else if (ll_suffix || dval > 0xffffffff || dval < -0x80000000ll)
1384 SPEC_LONGLONG (val->type) = 1;
1386 else if (dval > 0x7fffffff)
1388 SPEC_USIGN (val->type) = 1;
1389 SPEC_LONG (val->type) = 1;
1391 else if (l_suffix || dval > 0xffff || dval < -0x8000l)
1393 SPEC_LONG (val->type) = 1;
1395 else if (dval > 0x7fff)
1397 SPEC_USIGN (val->type) = 1;
1402 /* check for out of range */
1403 if (!SPEC_LONGLONG (val->type))
1405 if (dval < -2147483648.0)
1407 dval = -2147483648.0;
1408 werror (W_INVALID_INT_CONST, s, dval);
1410 if (dval > 2147483648.0 && !SPEC_USIGN (val->type))
1412 dval = 2147483647.0;
1413 werror (W_INVALID_INT_CONST, s, dval);
1415 if (dval > 4294967295.0)
1417 dval = 4294967295.0;
1418 werror (W_INVALID_INT_CONST, s, dval);
1422 if (SPEC_LONGLONG (val->type))
1424 if (SPEC_USIGN (val->type))
1426 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) llval;
1428 else
1430 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) llval;
1433 else if (SPEC_LONG (val->type))
1435 if (SPEC_USIGN (val->type))
1437 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) double2ul (dval);
1439 else
1441 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) double2ul (dval);
1444 else
1446 if (SPEC_USIGN (val->type))
1448 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) double2ul (dval);
1450 else
1452 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) double2ul (dval);
1456 return val;
1459 /*-----------------------------------------------------------------*/
1460 /* constCharacterVal - converts a character constant to value */
1461 /*-----------------------------------------------------------------*/
1462 value *
1463 constCharacterVal (unsigned long v, char type)
1465 value *val = newValue (); /* alloc space for value */
1467 val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
1468 SPEC_SCLS (val->type) = S_LITERAL;
1469 SPEC_CONST (val->type) = 1;
1471 switch (type)
1473 case 0: // character constant
1474 SPEC_NOUN (val->type) = V_INT;
1475 SPEC_USIGN (val->type) = 0;
1476 SPEC_CVAL (val->type).v_int = options.signed_char ? (signed char) v : (unsigned char) v;
1477 break;
1478 case 'L': // wide character constant
1479 if (!options.std_c95)
1480 werror (E_WCHAR_CONST_C95);
1481 SPEC_NOUN (val->type) = V_INT;
1482 SPEC_USIGN (val->type) = 1;
1483 SPEC_LONG (val->etype) = 1;
1484 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) v;
1485 break;
1486 case 'u': // wide character constant
1487 if (!options.std_c11)
1488 werror (E_WCHAR_CONST_C11);
1489 SPEC_NOUN (val->type) = V_INT;
1490 SPEC_USIGN (val->type) = 1;
1491 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) v;
1492 break;
1493 case 'U': // wide character constant
1494 if (!options.std_c11)
1495 werror (E_WCHAR_CONST_C11);
1496 SPEC_NOUN (val->type) = V_INT;
1497 SPEC_USIGN (val->type) = 1;
1498 SPEC_LONG (val->etype) = 1;
1499 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) v;
1500 break;
1501 case '8': // u8 character constant of type char8_t, a typedef for unsigned char.
1502 if (!options.std_c23)
1503 werror (E_U8_CHAR_C23);
1504 if (v >= 128)
1505 werror (E_U8_CHAR_INVALID);
1506 SPEC_NOUN (val->type) = V_CHAR;
1507 SPEC_USIGN (val->type) = 1;
1508 SPEC_CVAL (val->type).v_int = (unsigned char) v;
1509 break;
1510 default:
1511 wassert (0);
1514 return val;
1517 /*-----------------------------------------------------------------*/
1518 /* constCharVal - converts a character constant to value */
1519 /*-----------------------------------------------------------------*/
1520 value *
1521 constCharVal (unsigned char v)
1523 return constCharacterVal (v, 0);
1526 /*-----------------------------------------------------------------*/
1527 /* constBoolVal - converts a BOOL constant to value */
1528 /*-----------------------------------------------------------------*/
1529 value *
1530 constBoolVal (bool v, bool reduceType)
1532 if (reduceType)
1534 value *val = newValue (); /* alloc space for value */
1535 val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
1536 SPEC_SCLS (val->type) = S_LITERAL;
1537 SPEC_CONST (val->type) = 1;
1539 SPEC_NOUN (val->type) = (bit) ? V_BIT : V_BOOL;
1541 SPEC_CVAL (val->type).v_uint = (unsigned int) v;
1542 return val;
1544 else
1546 return constIntVal (v ? "1" : "0");
1550 /*-----------------------------------------------------------------*/
1551 /* constNullptrVal - a value of C23 nullptr_t */
1552 /*-----------------------------------------------------------------*/
1553 value *
1554 constNullptrVal (void)
1556 value *val = newValue (); /* alloc space for value */
1557 val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
1558 SPEC_SCLS (val->type) = S_LITERAL;
1559 SPEC_CONST (val->type) = 1;
1561 SPEC_NOUN (val->type) = V_NULLPTR;
1563 SPEC_CVAL (val->type).v_uint = 0;
1564 return val;
1567 // TODO: Move this function to SDCCutil?
1568 static const TYPE_UDWORD *utf_32_from_utf_8 (size_t *utf_32_len, const char *utf_8, size_t utf_8_len)
1570 size_t allocated = 0;
1571 TYPE_UDWORD *utf_32 = 0;
1572 unsigned char first_byte;
1573 TYPE_UDWORD codepoint;
1574 size_t seqlen;
1576 for (*utf_32_len = 0; utf_8_len; (*utf_32_len)++)
1578 if (allocated == *utf_32_len)
1580 utf_32 = realloc (utf_32, sizeof(TYPE_UDWORD) * (*utf_32_len + 16));
1581 wassert (utf_32);
1582 allocated = *utf_32_len + 16;
1585 first_byte = *utf_8;
1586 seqlen = 1;
1587 if (first_byte & 0x80)
1589 while (first_byte & (0x80 >> seqlen))
1590 seqlen++;
1591 first_byte &= (0xff >> (seqlen + 1));
1593 wassert (seqlen <= 6); // seqlen 5 and 6 are deprecated in current unicode standard, but for now, allow them.
1595 codepoint = first_byte;
1596 utf_8++;
1597 utf_8_len--;
1598 seqlen--;
1600 for(; seqlen; seqlen--)
1602 codepoint <<= 6;
1603 codepoint |= (*utf_8 & 0x3f);
1604 utf_8++;
1605 utf_8_len--;
1608 utf_32[*utf_32_len] = codepoint;
1610 return (utf_32);
1613 // TODO: Move this function to SDCCutil?
1614 static const TYPE_UWORD *utf_16_from_utf_32 (size_t *utf_16_len, const TYPE_UDWORD *utf_32, size_t utf_32_len)
1616 size_t allocated = 0;
1617 TYPE_UWORD *utf_16 = 0;
1618 TYPE_UDWORD codepoint;
1620 for (*utf_16_len = 0; utf_32_len; utf_32_len--, utf_32++)
1622 if (allocated <= *utf_16_len + 2)
1624 utf_16 = realloc (utf_16, sizeof(TYPE_UWORD) * (*utf_16_len + 16));
1625 wassert (utf_16);
1626 allocated = *utf_16_len + 16;
1629 codepoint = *utf_32;
1631 if (codepoint < 0xd7ff || codepoint >= 0xe000 && codepoint <= 0xffff) // Code in basic multilingual plane.
1633 utf_16[(*utf_16_len)++] = codepoint;
1634 continue;
1637 // Code point in supplementary plane.
1638 wassert (codepoint >= 0x100000 && codepoint <= 0x10ffff);
1639 codepoint -= 0x100000;
1641 utf_16[(*utf_16_len)++] = ((codepoint >> 10) & 0x3ff) + 0xd800;
1642 utf_16[(*utf_16_len)++] = (codepoint & 0x3ff) + 0xdc00;
1645 return (utf_16);
1648 /*------------------------------------------------------------------*/
1649 /* strVal - converts a string constant to a value */
1650 /*------------------------------------------------------------------*/
1651 value *
1652 strVal (const char *s)
1654 value *val;
1655 const char *utf_8;
1656 size_t utf_8_size;
1658 val = newValue ();
1660 /* get a declarator */
1661 val->type = newLink (DECLARATOR);
1662 DCL_TYPE (val->type) = ARRAY;
1663 val->type->next = val->etype = newLink (SPECIFIER);
1664 SPEC_SCLS (val->etype) = S_LITERAL;
1665 SPEC_CONST (val->etype) = 1;
1667 bool explicit_u8 = s[0] == 'u' && s[1] == '8' && s[2] == '"';
1669 if (s[0] == '"' || explicit_u8) // UTF-8 string literal
1671 // Convert input string (mixed UTF-8 and UTF-32) to UTF-8 (handling all escape sequences, etc).
1672 utf_8 = copyStr (s[0] == '"' ? s : s + 2, &utf_8_size);
1674 SPEC_NOUN (val->etype) = V_CHAR;
1675 if (options.std_c23 && explicit_u8) // In C23, u8-prefixed string literals are of type char8_t *, ad char8_t is a typedef for unsigned char.
1676 SPEC_USIGN (val->etype) = true;
1677 else
1679 SPEC_USIGN (val->etype) = !options.signed_char;
1680 val->etype->select.s.b_implicit_sign = true;
1682 SPEC_CVAL (val->etype).v_char = utf_8;
1683 DCL_ELEM (val->type) = utf_8_size;
1685 else
1687 // Convert input string (mixed UTF-8 and UTF-32) to UTF-8 first (handling all escape sequences, etc).
1688 utf_8 = copyStr (s + 1, &utf_8_size);
1690 size_t utf_32_size;
1691 // Convert to UTF-32 next, since converting UTF-32 to UTF-16 is easier than UTF-8 to UTF-16.
1692 const TYPE_UDWORD *utf_32 = utf_32_from_utf_8 (&utf_32_size, utf_8, utf_8_size);
1694 dbuf_free (utf_8);
1696 if (s[0] == 'U' || s[0] == 'L') // UTF-32 string literal
1698 SPEC_NOUN (val->etype) = V_INT;
1699 SPEC_USIGN (val->etype) = 1;
1700 SPEC_LONG (val->etype) = 1;
1701 SPEC_CVAL (val->etype).v_char32 = utf_32;
1702 DCL_ELEM (val->type) = utf_32_size;
1704 else if (s[0] == 'u') // UTF-16 string literal
1706 size_t utf_16_size;
1707 const TYPE_UWORD *utf_16 = utf_16_from_utf_32 (&utf_16_size, utf_32, utf_32_size);
1709 SPEC_NOUN (val->etype) = V_INT;
1710 SPEC_USIGN (val->etype) = 1;
1711 SPEC_CVAL (val->etype).v_char16 = utf_16;
1712 DCL_ELEM (val->type) = utf_16_size;
1714 else
1715 wassert (0);
1718 return (val);
1721 /*------------------------------------------------------------------*/
1722 /* rawStrVal - converts a string to a value */
1723 /*------------------------------------------------------------------*/
1724 value *
1725 rawStrVal (const char *s, size_t size)
1727 struct dbuf_s dbuf;
1728 value *val = newValue ();
1730 dbuf_init (&dbuf, size);
1731 wassert (dbuf_append (&dbuf, s, size));
1733 /* get a declarator */
1734 val->type = newLink (DECLARATOR);
1735 DCL_TYPE (val->type) = ARRAY;
1736 val->type->next = val->etype = newLink (SPECIFIER);
1737 SPEC_SCLS (val->etype) = S_LITERAL;
1738 SPEC_CONST (val->etype) = 1;
1740 SPEC_NOUN (val->etype) = V_CHAR;
1741 SPEC_USIGN (val->etype) = !options.signed_char;
1742 val->etype->select.s.b_implicit_sign = true;
1743 SPEC_CVAL (val->etype).v_char = dbuf_detach (&dbuf);
1744 DCL_ELEM (val->type) = size;
1746 return (val);
1749 /*------------------------------------------------------------------*/
1750 /* reverseValWithType - reverses value chain with type & etype */
1751 /*------------------------------------------------------------------*/
1752 value *
1753 reverseValWithType (value * val)
1755 sym_link *type;
1756 sym_link *etype;
1758 if (!val)
1759 return NULL;
1761 /* save the type * etype chains */
1762 type = val->type;
1763 etype = val->etype;
1765 /* set the current one 2b null */
1766 val->type = val->etype = NULL;
1767 val = reverseVal (val);
1769 /* restore type & etype */
1770 val->type = type;
1771 val->etype = etype;
1773 return val;
1776 /*------------------------------------------------------------------*/
1777 /* reverseVal - reverses the values for a value chain */
1778 /*------------------------------------------------------------------*/
1779 value *
1780 reverseVal (value * val)
1782 value *prev, *curr, *next;
1784 if (!val)
1785 return NULL;
1787 prev = val;
1788 curr = val->next;
1790 while (curr)
1792 next = curr->next;
1793 curr->next = prev;
1794 prev = curr;
1795 curr = next;
1797 val->next = (void *) NULL;
1798 return prev;
1801 /*------------------------------------------------------------------*/
1802 /* copyValueChain - will copy a chain of values */
1803 /*------------------------------------------------------------------*/
1804 value *
1805 copyValueChain (value * src)
1807 value *dest;
1809 if (!src)
1810 return NULL;
1812 dest = copyValue (src);
1813 dest->next = copyValueChain (src->next);
1815 return dest;
1818 /*------------------------------------------------------------------*/
1819 /* copyValue - copies contents of a value to a fresh one */
1820 /*------------------------------------------------------------------*/
1821 value *
1822 copyValue (value * src)
1824 value *dest;
1826 dest = newValue ();
1827 dest->sym = copySymbol (src->sym);
1828 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
1829 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
1830 dest->etype = (src->type ? getSpec (dest->type) : NULL);
1832 return dest;
1835 /*------------------------------------------------------------------*/
1836 /* charVal - converts a character constant to a value */
1837 /*------------------------------------------------------------------*/
1838 value *
1839 charVal (const char *s)
1841 char type;
1843 if ((s[0] == 'L' || s[0] == 'u' || s[0] == 'U') && s[1] == '\'')
1844 type = *s++;
1845 else if (s[0] == 'u' && s[1] == '8' && s[2] == '\'')
1847 if (s[4] != '\'')
1848 werror (E_U8_CHAR_INVALID);
1849 type = '8';
1850 s += 2;
1852 else
1853 type = 0;
1855 s++; // Get rid of quotation.
1857 /* if \ then special processing */
1858 if (*s == '\\')
1860 switch (*++s) /* go beyond the backslash */
1862 case 'n':
1863 return constCharacterVal ('\n', type);
1864 case 't':
1865 return constCharacterVal ('\t', type);
1866 case 'v':
1867 return constCharacterVal ('\v', type);
1868 case 'b':
1869 return constCharacterVal ('\b', type);
1870 case 'r':
1871 return constCharacterVal ('\r', type);
1872 case 'f':
1873 return constCharacterVal ('\f', type);
1874 case 'a':
1875 return constCharacterVal ('\a', type);
1876 case '\\':
1877 return constCharacterVal ('\\', type);
1878 case '\?':
1879 return constCharacterVal ('\?', type);
1880 case '\'':
1881 return constCharacterVal ('\'', type);
1882 case '\"':
1883 return constCharacterVal ('\"', type);
1885 case '0':
1886 case '1':
1887 case '2':
1888 case '3':
1889 case '4':
1890 case '5':
1891 case '6':
1892 case '7':
1893 return constCharacterVal (octalEscape (&s), type);
1895 case 'x':
1896 return constCharacterVal (hexEscape (&s), type);
1898 case 'u':
1899 return constCharacterVal (universalEscape (&s, 4), type);
1901 case 'U':
1902 return constCharacterVal (universalEscape (&s, 8), type);
1904 default:
1905 return constCharacterVal (*s, type);
1908 else if (type) // Wide character constant
1910 size_t ulen;
1911 const TYPE_UDWORD *ustr = utf_32_from_utf_8 (&ulen, s, strlen(s) - 1);
1912 value *val = constCharacterVal (*ustr, type);
1913 free ((void *)ustr);
1914 return (val);
1916 else // Character constant that is not wide - compatibility with legacy encodings.
1917 return constCharacterVal (*s, 0);
1920 /*------------------------------------------------------------------*/
1921 /* valFromType - creates a value from type given */
1922 /*------------------------------------------------------------------*/
1923 value *
1924 valFromType (sym_link * type)
1926 value *val = newValue ();
1927 val->type = copyLinkChain (type);
1928 val->etype = getSpec (val->type);
1929 return val;
1932 /*------------------------------------------------------------------*/
1933 /* floatFromVal - value to double float conversion */
1934 /*------------------------------------------------------------------*/
1935 double
1936 floatFromVal (value * val)
1938 if (!val)
1939 return 0;
1941 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1943 werror (E_CONST_EXPECTED, val->name);
1944 return 0;
1947 /* if it is not a specifier then we can assume that */
1948 /* it will be an unsigned long */
1949 if (!IS_SPEC (val->type))
1950 return SPEC_CVAL (val->etype).v_ulong;
1952 if (SPEC_NOUN (val->etype) == V_FLOAT)
1953 return SPEC_CVAL (val->etype).v_float;
1955 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1956 return doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16);
1958 if (SPEC_LONGLONG (val->etype) || SPEC_NOUN (val->etype) == V_BITINT)
1960 if (SPEC_USIGN (val->etype))
1961 return (double)SPEC_CVAL (val->etype).v_ulonglong;
1962 else
1963 return (double)SPEC_CVAL (val->etype).v_longlong;
1966 if (SPEC_LONG (val->etype))
1968 if (SPEC_USIGN (val->etype))
1969 return SPEC_CVAL (val->etype).v_ulong;
1970 else
1971 return SPEC_CVAL (val->etype).v_long;
1974 if (SPEC_NOUN (val->etype) == V_INT)
1976 if (SPEC_USIGN (val->etype))
1977 return SPEC_CVAL (val->etype).v_uint;
1978 else
1979 return SPEC_CVAL (val->etype).v_int;
1982 if (SPEC_NOUN (val->etype) == V_CHAR)
1984 if (SPEC_USIGN (val->etype))
1985 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1986 else
1987 return (signed char) SPEC_CVAL (val->etype).v_int;
1990 if (IS_BOOL (val->etype) || IS_NULLPTR (val->etype) || IS_BITVAR (val->etype))
1991 return SPEC_CVAL (val->etype).v_uint;
1993 if (SPEC_NOUN (val->etype) == V_VOID)
1994 return SPEC_CVAL (val->etype).v_ulong;
1996 if (SPEC_NOUN (val->etype) == V_STRUCT)
1997 return SPEC_CVAL (val->etype).v_ulong;
1999 /* we are lost ! */
2000 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "floatFromVal: unknown value");
2001 return 0;
2004 /*------------------------------------------------------------------*/
2005 /* ulFromVal - value to unsigned long conversion */
2006 /*------------------------------------------------------------------*/
2007 unsigned long
2008 ulFromVal (const value *val)
2010 return ullFromVal (val);
2013 /*------------------------------------------------------------------*/
2014 /* byteOfVal - extract a byte of a value */
2015 /* offset = 0 (LSB) ... n-1 (MSB) */
2016 /* higher offsets of signed ints will be sign extended, */
2017 /* other types will be extended with zero padding */
2018 /*------------------------------------------------------------------*/
2019 unsigned char
2020 byteOfVal (value *val, int offset)
2022 unsigned char *p;
2023 int shift = 8*offset;
2025 wassert (offset >= 0);
2027 if (!val)
2028 return 0;
2030 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
2032 werror (E_CONST_EXPECTED, val->name);
2033 return 0;
2036 /* if it is not a specifier then we can assume that */
2037 /* it will be an unsigned long */
2038 /* 2012-Apr-30 EEP - Why is this true? */
2039 if (!IS_SPEC (val->type))
2040 return offset < 4 ? (SPEC_CVAL (val->etype).v_ulong >> shift) & 0xff : 0;
2042 if (SPEC_NOUN (val->etype) == V_FLOAT)
2044 float f = (float)SPEC_CVAL (val->etype).v_float;
2046 if (offset > 3)
2047 return 0;
2048 p = (unsigned char *)&f;
2049 #ifdef WORDS_BIGENDIAN
2050 p += 3 - offset;
2051 #else
2052 p += offset;
2053 #endif
2054 return *p;
2057 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
2058 return offset < 4 ? (SPEC_CVAL (val->etype).v_fixed16x16 >> shift) & 0xff : 0;
2060 if (SPEC_LONGLONG (val->etype) || SPEC_NOUN (val->etype) == V_BITINT || SPEC_NOUN (val->etype) == V_BITFIELD || SPEC_NOUN (val->etype) == V_BITINTBITFIELD)
2062 if (SPEC_USIGN (val->etype))
2063 return offset < 8 ? (SPEC_CVAL (val->etype).v_ulonglong >> shift) & 0xff : 0;
2064 else
2065 return offset < 8 ? (SPEC_CVAL (val->etype).v_longlong >> shift) & 0xff :
2066 (SPEC_CVAL (val->etype).v_longlong < 0 ? 0xff : 0);
2069 if (SPEC_LONG (val->etype))
2071 if (SPEC_USIGN (val->etype))
2072 return offset < 4 ? (SPEC_CVAL (val->etype).v_ulong >> shift) & 0xff : 0;
2073 else
2074 return offset < 4 ? (SPEC_CVAL (val->etype).v_long >> shift) & 0xff :
2075 (SPEC_CVAL (val->etype).v_long < 0 ? 0xff : 0);
2078 if (SPEC_NOUN (val->etype) == V_INT)
2080 if (SPEC_USIGN (val->etype))
2081 return offset < 2 ? (SPEC_CVAL (val->etype).v_uint >> shift) & 0xff : 0;
2082 else
2083 return offset < 2 ? (SPEC_CVAL (val->etype).v_int >> shift) & 0xff :
2084 (SPEC_CVAL (val->etype).v_int < 0 ? 0xff : 0);
2087 if (SPEC_NOUN (val->etype) == V_CHAR)
2089 if (SPEC_USIGN (val->etype))
2090 return offset < 1 ? SPEC_CVAL (val->etype).v_uint & 0xff : 0;
2091 else
2092 return offset < 1 ? SPEC_CVAL (val->etype).v_int & 0xff :
2093 (SPEC_CVAL (val->etype).v_int < 0 ? 0xff : 0);
2096 if (IS_BOOL (val->etype) || IS_NULLPTR (val->etype) || IS_BITVAR (val->etype))
2097 return offset < 2 ? (SPEC_CVAL (val->etype).v_uint >> shift) & 0xff : 0;
2099 /* we are lost ! */
2100 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "byteOfVal: unknown value");
2101 return 0;
2104 /*------------------------------------------------------------------*/
2105 /* ullFromLit - literal to unsigned long long conversion */
2106 /*------------------------------------------------------------------*/
2107 TYPE_TARGET_ULONGLONG
2108 ullFromLit (sym_link * lit)
2110 sym_link * etype = getSpec(lit);
2112 if (!lit)
2113 return 0;
2115 if (etype && SPEC_SCLS (etype) != S_LITERAL)
2117 werror (E_CONST_EXPECTED, "");
2118 return 0;
2121 /* if it is not a specifier then we can assume that */
2122 /* it will be an unsigned long */
2123 if (!IS_SPEC (lit))
2124 return SPEC_CVAL (etype).v_ulong;
2126 if (SPEC_NOUN (etype) == V_FLOAT)
2127 return double2ull (SPEC_CVAL (etype).v_float);
2129 if (SPEC_NOUN (etype) == V_FIXED16X16)
2130 return double2ul (doubleFromFixed16x16 (SPEC_CVAL (etype).v_fixed16x16)); /* FIXME: this loses bits */
2132 if (SPEC_LONGLONG (etype) || SPEC_NOUN (etype) == V_BITINT || SPEC_NOUN (etype) == V_BITFIELD || SPEC_NOUN (etype) == V_BITINTBITFIELD)
2134 if (SPEC_USIGN (etype))
2135 return SPEC_CVAL (etype).v_ulonglong;
2136 else
2137 return SPEC_CVAL (etype).v_longlong;
2140 if (SPEC_LONG (etype))
2142 if (SPEC_USIGN (etype))
2143 return SPEC_CVAL (etype).v_ulong;
2144 else
2145 return SPEC_CVAL (etype).v_long;
2148 if (SPEC_NOUN (etype) == V_INT)
2150 if (SPEC_USIGN (etype))
2151 return SPEC_CVAL (etype).v_uint;
2152 else
2153 return SPEC_CVAL (etype).v_int;
2156 if (SPEC_NOUN (etype) == V_CHAR)
2158 if (SPEC_USIGN (etype))
2159 return (unsigned char) SPEC_CVAL (etype).v_uint;
2160 else
2161 return (signed char) SPEC_CVAL (etype).v_int;
2164 if (IS_BOOL (etype) || IS_NULLPTR (etype) || IS_BITVAR (etype))
2165 return SPEC_CVAL (etype).v_uint;
2167 if (SPEC_NOUN (etype) == V_VOID)
2168 return SPEC_CVAL (etype).v_ulong;
2170 if (SPEC_NOUN (etype) == V_STRUCT) /* ??? Why ??? EEP - 23 Nov 2012 */
2171 return SPEC_CVAL (etype).v_ulong;
2173 /* we are lost ! */
2174 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ullFromLit: unknown value");
2175 return 0;
2178 /*------------------------------------------------------------------*/
2179 /* ullFromVal - value to unsigned long long conversion */
2180 /*------------------------------------------------------------------*/
2181 unsigned long long
2182 ullFromVal (const value * val)
2184 if (!val)
2185 return 0;
2187 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
2189 werror (E_CONST_EXPECTED, val->name);
2190 return 0;
2192 return (unsigned long long) ullFromLit (val->type);
2195 /*------------------------------------------------------------------*/
2196 /* csdOfVal - return 0 if the value can be represented as */
2197 /* canonical signed digit. Useful for generating */
2198 /* shift / add / sub code sequences for multiplication by literals. */
2199 /* topbit - highest nonzero bit in csd */
2200 /* nonzero - number of nonzero bits in csd */
2201 /* csd_add - positive bits in csd */
2202 /* csd_sub - negative bits in csd */
2203 /*------------------------------------------------------------------*/
2204 int csdOfVal (int *topbit, int *nonzero, unsigned long long *csd_add, unsigned long long *csd_sub, value *val, unsigned long long mask)
2206 unsigned long long binary = ullFromVal (val) & mask;
2207 bool gamma, theta, a;
2208 int bit, next;
2210 *topbit = 0;
2211 *nonzero = 0;
2212 *csd_add = 0;
2213 *csd_sub = 0;
2215 for (a = 0, gamma = 0, bit = 0; bit < 61; bit++)
2217 theta = a ^ (binary & 1);
2218 gamma = !gamma && theta;
2219 next = (1 - 2 * (bool)(binary & 2)) * gamma;
2220 if (next > 0)
2221 *csd_add |= (1ull << bit);
2222 else if (next < 0)
2223 *csd_sub |= (1ull << bit);
2224 if (next)
2226 (*nonzero)++;
2227 *topbit = bit;
2229 a = (binary & 1);
2230 binary >>= 1;
2232 return((bool)binary);
2235 /*------------------------------------------------------------------*/
2236 /* isEqualVal - return 1 if value is equal to specified constant */
2237 /*------------------------------------------------------------------*/
2239 isEqualVal (value * val, int k)
2241 if (IS_SPEC (val->type))
2243 if (SPEC_NOUN (val->type) == V_FLOAT || SPEC_NOUN (val->type) == V_FIXED16X16)
2244 return floatFromVal (val) == k;
2246 return ((TYPE_TARGET_LONGLONG) ullFromVal (val)) == k;
2250 /*-----------------------------------------------------------------*/
2251 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
2252 /*-----------------------------------------------------------------*/
2253 double
2254 doubleFromFixed16x16 (TYPE_TARGET_ULONG value)
2256 #if 0
2257 /* This version is incorrect negative values. */
2258 double tmp = 0, exp = 2;
2260 tmp = (value & 0xffff0000) >> 16;
2262 while (value)
2264 value &= 0xffff;
2265 if (value & 0x8000)
2266 tmp += 1 / exp;
2267 exp *= 2;
2268 value <<= 1;
2271 return (tmp);
2272 #else
2273 return ((double) (value * 1.0) / (double) (1UL << 16));
2274 #endif
2277 TYPE_TARGET_ULONG
2278 fixed16x16FromDouble (double value)
2280 #if 0
2281 /* This version is incorrect negative values. */
2282 unsigned int tmp = 0, pos = 16;
2283 TYPE_TARGET_ULONG res;
2285 tmp = floor (value);
2286 res = tmp << 16;
2287 value -= tmp;
2289 tmp = 0;
2290 while (pos--)
2292 value *= 2;
2293 if (value >= 1.0)
2294 tmp |= (1 << pos);
2295 value -= floor (value);
2298 res |= tmp;
2300 return (res);
2301 #else
2302 return double2ul (value * (double) (1UL << 16));
2303 #endif
2306 /*------------------------------------------------------------------*/
2307 /* valUnaryPM - does the unary +/- operation on a constant */
2308 /*------------------------------------------------------------------*/
2309 value *
2310 valUnaryPM (value * val, bool reduceType)
2312 /* depending on type */
2313 if (SPEC_NOUN (val->etype) == V_FLOAT)
2314 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
2315 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
2316 SPEC_CVAL (val->etype).v_fixed16x16 = (TYPE_TARGET_ULONG) - ((long) SPEC_CVAL (val->etype).v_fixed16x16);
2317 else if (SPEC_LONGLONG (val->etype) || SPEC_NOUN (val->etype) == V_BITINT)
2319 if (SPEC_USIGN (val->etype))
2320 SPEC_CVAL (val->etype).v_ulonglong = 0 - SPEC_CVAL (val->etype).v_ulonglong;
2321 else
2322 SPEC_CVAL (val->etype).v_longlong = -SPEC_CVAL (val->etype).v_longlong;
2324 else if (SPEC_LONG (val->etype))
2326 if (SPEC_USIGN (val->etype))
2327 SPEC_CVAL (val->etype).v_ulong = 0 - SPEC_CVAL (val->etype).v_ulong;
2328 else
2329 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
2331 else
2333 if (SPEC_USIGN (val->etype))
2334 SPEC_CVAL (val->etype).v_uint = 0 - SPEC_CVAL (val->etype).v_uint;
2335 else
2336 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
2338 if (SPEC_NOUN (val->etype) == V_CHAR)
2340 /* promote to 'signed int', cheapestVal() might reduce it again */
2341 SPEC_USIGN (val->etype) = 0;
2342 SPEC_NOUN (val->etype) = V_INT;
2344 if (reduceType)
2345 return cheapestVal (val);
2347 return val;
2350 /*------------------------------------------------------------------*/
2351 /* valueComplement - complements a constant */
2352 /*------------------------------------------------------------------*/
2353 value *
2354 valComplement (value * val, bool reduceType)
2356 /* depending on type */
2357 if (SPEC_LONGLONG (val->etype))
2359 if (SPEC_USIGN (val->etype))
2360 SPEC_CVAL (val->etype).v_ulonglong = ~SPEC_CVAL (val->etype).v_ulonglong;
2361 else
2362 SPEC_CVAL (val->etype).v_longlong = ~SPEC_CVAL (val->etype).v_longlong;
2364 else if (SPEC_LONG (val->etype))
2366 if (SPEC_USIGN (val->etype))
2367 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
2368 else
2369 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
2371 else
2373 if (SPEC_USIGN (val->etype))
2374 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
2375 else
2376 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
2378 if (SPEC_NOUN (val->etype) == V_CHAR)
2380 /* promote to 'signed int', cheapestVal() might reduce it again */
2381 SPEC_USIGN (val->etype) = 0;
2382 SPEC_NOUN (val->etype) = V_INT;
2384 if (reduceType)
2385 return cheapestVal (val);
2387 return val;
2390 /*------------------------------------------------------------------*/
2391 /* valueNot - complements a constant */
2392 /*------------------------------------------------------------------*/
2393 value *
2394 valNot (value * val, bool reduceType)
2396 /* depending on type */
2397 if (SPEC_LONGLONG (val->etype))
2399 if (SPEC_USIGN (val->etype))
2400 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulonglong;
2401 else
2402 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_longlong;
2404 else if (SPEC_LONG (val->etype))
2406 if (SPEC_USIGN (val->etype))
2407 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
2408 else
2409 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
2411 else
2413 if (SPEC_USIGN (val->etype))
2414 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
2415 else
2416 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
2420 /* ANSI: result type is int, value is 0 or 1 */
2421 /* If reduction is allowed SDCC will hold this in an 'unsigned char' */
2422 if (reduceType)
2424 SPEC_USIGN (val->etype) = 1;
2425 SPEC_NOUN (val->etype) = V_CHAR;
2427 else
2429 SPEC_USIGN (val->etype) = 0;
2430 SPEC_NOUN (val->etype) = V_INT;
2432 SPEC_LONG (val->etype) = 0;
2433 SPEC_LONGLONG (val->type) = 0;
2435 return val;
2438 /*------------------------------------------------------------------*/
2439 /* valMult - multiply constants */
2440 /*------------------------------------------------------------------*/
2441 value *
2442 valMult (value * lval, value * rval, bool reduceType)
2444 value *val;
2446 /* create a new value */
2447 val = newValue ();
2448 val->type = val->etype = computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '*');
2449 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2451 if (IS_FLOAT (val->type))
2452 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
2453 else if (IS_FIXED16X16 (val->type))
2454 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) * floatFromVal (rval));
2455 /* signed and unsigned mul are the same, as long as the precision of the
2456 result isn't bigger than the precision of the operands. */
2457 else if (IS_BITINT (val->type))
2459 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) * (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2460 if (SPEC_USIGN (val->type))
2461 SPEC_CVAL (val->type).v_ulonglong &= (0xffffffffffffffffull >> (64 - SPEC_BITINTWIDTH (val->type)));
2463 else if (SPEC_LONGLONG (val->type))
2464 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) * (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2465 else if (SPEC_LONG (val->type))
2466 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) * (TYPE_TARGET_ULONG) ulFromVal (rval);
2467 else if (SPEC_USIGN (val->type)) /* unsigned int */
2469 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) ulFromVal (lval) * (TYPE_TARGET_UINT) ulFromVal (rval);
2471 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
2472 if (ul != (TYPE_TARGET_UINT) ul)
2473 werror (W_INT_OVL);
2475 else /* signed int */
2477 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) * (TYPE_TARGET_INT) floatFromVal (rval);
2479 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
2480 if (l != (TYPE_TARGET_INT) l)
2481 werror (W_INT_OVL);
2484 return reduceType ? cheapestVal (val) : val;
2487 /*------------------------------------------------------------------*/
2488 /* valDiv - Divide constants */
2489 /*------------------------------------------------------------------*/
2490 value *
2491 valDiv (value * lval, value * rval, bool reduceType)
2493 value *val;
2495 if (isEqualVal (rval, 0) && !IS_FLOAT (computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '/')))
2497 werror (E_DIVIDE_BY_ZERO);
2498 return rval;
2501 /* create a new value */
2502 val = newValue ();
2503 val->type = val->etype = computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '/');
2504 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2506 if (IS_FLOAT (val->type))
2507 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
2508 else if (IS_FIXED16X16 (val->type))
2509 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) / floatFromVal (rval));
2510 else if (SPEC_LONGLONG (val->type) || IS_BITINT (val->type))
2512 if (SPEC_USIGN (val->type))
2514 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) / (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2515 if (IS_BITINT (val->type)) // unsigned wrap-around
2516 SPEC_CVAL (val->type).v_ulonglong &= (0xffffffffffffffffull >> (64 - SPEC_BITINTWIDTH (val->type)));
2518 else
2519 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) / (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2521 else if (SPEC_LONG (val->type))
2523 if (SPEC_USIGN (val->type))
2524 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) / (TYPE_TARGET_ULONG) ulFromVal (rval);
2525 else
2526 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) / (TYPE_TARGET_LONG) ulFromVal (rval);
2528 else
2530 if (SPEC_USIGN (val->type))
2531 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) / (TYPE_TARGET_UINT) ulFromVal (rval);
2532 else
2533 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) / (TYPE_TARGET_INT) ulFromVal (rval);
2535 return reduceType ? cheapestVal (val) : val;
2538 /*------------------------------------------------------------------*/
2539 /* valMod - Modulus constants */
2540 /*------------------------------------------------------------------*/
2541 value *
2542 valMod (value * lval, value * rval, bool reduceType)
2544 value *val;
2546 if (isEqualVal (rval, 0))
2548 werror (E_DIVIDE_BY_ZERO);
2549 return rval;
2552 /* create a new value */
2553 val = newValue ();
2554 val->type = val->etype = computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '%');
2555 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2557 if (SPEC_LONGLONG (val->type) || IS_BITINT (val->type))
2559 if (SPEC_USIGN (val->type))
2561 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) % (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2562 if (IS_BITINT (val->type)) // unsigned wrap-around
2563 SPEC_CVAL (val->type).v_ulonglong &= (0xffffffffffffffffull >> (64 - SPEC_BITINTWIDTH (val->type)));
2565 else
2566 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) % (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2568 else if (SPEC_LONG (val->type))
2570 if (SPEC_USIGN (val->type))
2571 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) % (TYPE_TARGET_ULONG) ulFromVal (rval);
2572 else
2573 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) % (TYPE_TARGET_LONG) ulFromVal (rval);
2575 else
2577 if (SPEC_USIGN (val->type))
2578 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) % (TYPE_TARGET_UINT) ulFromVal (rval);
2579 else
2580 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) % (TYPE_TARGET_INT) ulFromVal (rval);
2582 return reduceType ? cheapestVal (val) : val;
2585 /*------------------------------------------------------------------*/
2586 /* valZeroResult - constant zero with type from two values */
2587 /*------------------------------------------------------------------*/
2588 value *
2589 valZeroResultFromOp (sym_link * type1, sym_link * type2, int op, bool reduceType)
2591 value *val;
2593 #if 0
2594 printf("valZeroResultFromOp %d ", op); printTypeChain (type1, stdout); printf (" vs. "); printTypeChain (type2, 0);
2595 #endif
2597 /* create a new value */
2598 val = newValue ();
2599 val->type = computeType (type1, type2, RESULT_TYPE_INT, op);
2600 val->etype = getSpec (val->type);
2601 // If type reduction is not allowed, make sure we get integer promotion for smaller types
2602 if(!reduceType && IS_INTEGRAL (val->etype) && bitsForType (val->etype) < INTSIZE * 8)
2604 SPEC_NOUN (val->etype) = V_INT;
2605 SPEC_USIGN (val->etype) = 0;
2607 SPEC_SCLS (val->etype) = S_LITERAL;
2609 if (!IS_SPEC (val->type))
2610 SPEC_CVAL (val->etype).v_ulong = 0;
2611 else if (IS_FLOAT (val->type))
2612 SPEC_CVAL (val->type).v_float = 0;
2613 else if (IS_FIXED16X16 (val->type))
2614 SPEC_CVAL (val->type).v_fixed16x16 = 0;
2615 else if (SPEC_LONGLONG (val->type) || IS_BITINT (val->type))
2617 if (SPEC_USIGN (val->type))
2618 SPEC_CVAL (val->type).v_ulonglong = 0;
2619 else
2620 SPEC_CVAL (val->type).v_longlong = 0;
2622 else if (SPEC_LONG (val->type))
2624 if (SPEC_USIGN (val->type))
2625 SPEC_CVAL (val->type).v_ulong = 0;
2626 else
2627 SPEC_CVAL (val->type).v_long = 0;
2629 else
2631 if (SPEC_USIGN (val->type))
2632 SPEC_CVAL (val->type).v_uint = 0;
2633 else
2634 SPEC_CVAL (val->type).v_int = 0;
2636 return reduceType ? cheapestVal (val) : val;
2639 /*------------------------------------------------------------------*/
2640 /* valPlus - Addition constants */
2641 /*------------------------------------------------------------------*/
2642 value *
2643 valPlus (value * lval, value * rval, bool reduceType)
2645 value *val;
2647 /* create a new value */
2648 val = newValue ();
2649 val->type = computeType (lval->type, rval->type, RESULT_TYPE_INT, '+');
2650 val->etype = getSpec (val->type);
2651 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2653 if (!IS_SPEC (val->type))
2654 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) + (TYPE_TARGET_ULONG) ulFromVal (rval);
2655 else if (IS_FLOAT (val->type))
2656 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
2657 else if (IS_FIXED16X16 (val->type))
2658 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) + floatFromVal (rval));
2659 else if (SPEC_LONGLONG (val->type) || IS_BITINT (val->type))
2661 if (SPEC_USIGN (val->type))
2663 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG)(ullFromVal (lval) + ullFromVal (rval));
2664 if (IS_BITINT (val->type)) // unsigned wrap-around
2665 SPEC_CVAL (val->type).v_ulonglong &= (0xffffffffffffffffull >> (64 - SPEC_BITINTWIDTH (val->type)));
2667 else
2668 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG)(ullFromVal (lval) + ullFromVal (rval));
2670 else if (SPEC_LONG (val->type))
2672 if (SPEC_USIGN (val->type))
2673 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG)(ulFromVal (lval) + ulFromVal (rval));
2674 else
2675 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG)(ulFromVal (lval) + ulFromVal (rval));
2677 else
2679 if (SPEC_USIGN (val->type))
2680 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT)(ulFromVal (lval) + ulFromVal (rval));
2681 else
2682 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT)(ulFromVal (lval) + ulFromVal (rval));
2684 return reduceType ? cheapestVal (val) : val;
2687 /*------------------------------------------------------------------*/
2688 /* valMinus - Addition constants */
2689 /*------------------------------------------------------------------*/
2690 value *
2691 valMinus (value * lval, value * rval, bool reduceType)
2693 value *val;
2695 /* create a new value */
2696 val = newValue ();
2697 val->type = computeType (lval->type, rval->type, RESULT_TYPE_INT, '-');
2698 val->etype = getSpec (val->type);
2699 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2701 if (!IS_SPEC (val->type))
2702 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) - (TYPE_TARGET_ULONG) ulFromVal (rval);
2703 else if (IS_FLOAT (val->type))
2704 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
2705 else if (IS_FIXED16X16 (val->type))
2706 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) - floatFromVal (rval));
2707 else if (SPEC_LONGLONG (val->type) || IS_BITINT (val->type))
2709 if (SPEC_USIGN (val->type))
2711 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) - (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2712 if (IS_BITINT (val->type)) // unsigned wrap-around
2713 SPEC_CVAL (val->type).v_ulonglong &= (0xffffffffffffffffull >> (64 - SPEC_BITINTWIDTH (val->type)));
2715 else
2716 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) - (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2718 else if (SPEC_LONG (val->type))
2720 if (SPEC_USIGN (val->type))
2721 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) - (TYPE_TARGET_ULONG) ulFromVal (rval);
2722 else
2723 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) - (TYPE_TARGET_LONG) ulFromVal (rval);
2725 else
2727 if (SPEC_USIGN (val->type))
2728 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) - (TYPE_TARGET_UINT) ulFromVal (rval);
2729 else
2730 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) - (TYPE_TARGET_INT) ulFromVal (rval);
2732 return reduceType ? cheapestVal (val) : val;
2735 /*------------------------------------------------------------------*/
2736 /* valShift - Shift left or right */
2737 /*------------------------------------------------------------------*/
2738 value *
2739 valShift (value * lval, value * rval, int lr, bool reduceType)
2741 value *val;
2743 /* create a new value */
2744 val = newValue ();
2745 val->type = val->etype = computeType (lval->etype, NULL, RESULT_TYPE_INT, 'S');
2746 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
2748 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) ulFromVal (rval) &&
2749 /* left shift */
2750 (lr ||
2751 /* right shift and unsigned */
2752 (!lr && SPEC_USIGN (rval->type))) &&
2753 ((TYPE_TARGET_ULONG) ulFromVal (lval) != (TYPE_TARGET_ULONG) 0))
2755 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
2758 if (SPEC_LONGLONG (val->type) || IS_BITINT (val->type))
2760 if (SPEC_USIGN (val->type))
2762 SPEC_CVAL (val->type).v_ulonglong = lr ?
2763 (TYPE_TARGET_ULONGLONG) ullFromVal (lval) << (TYPE_TARGET_ULONGLONG) ullFromVal (rval) :
2764 (TYPE_TARGET_ULONGLONG) ullFromVal (lval) >> (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2765 if (IS_BITINT (val->type)) // unsigned wrap-around
2766 SPEC_CVAL (val->type).v_ulonglong &= (0xffffffffffffffffull >> (64 - SPEC_BITINTWIDTH (val->type)));
2768 else
2770 SPEC_CVAL (val->type).v_longlong = lr ?
2771 (TYPE_TARGET_LONGLONG) (ullFromVal (lval) << (TYPE_TARGET_ULONGLONG) ullFromVal (rval)) :
2772 (TYPE_TARGET_LONGLONG) ullFromVal (lval) >> (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2775 else if (SPEC_LONG (val->type))
2777 if (SPEC_USIGN (val->type))
2779 SPEC_CVAL (val->type).v_ulong = lr ?
2780 (TYPE_TARGET_ULONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) :
2781 (TYPE_TARGET_ULONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2783 else
2785 SPEC_CVAL (val->type).v_long = lr ?
2786 (TYPE_TARGET_LONG) (ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval)) :
2787 (TYPE_TARGET_LONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2790 else
2792 if (SPEC_USIGN (val->type))
2794 SPEC_CVAL (val->type).v_uint = lr ?
2795 (TYPE_TARGET_UINT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) :
2796 (TYPE_TARGET_UINT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2798 else
2800 SPEC_CVAL (val->type).v_int = lr ?
2801 (TYPE_TARGET_INT) (ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval)) :
2802 (TYPE_TARGET_INT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2805 return reduceType ? cheapestVal (val) : val;
2808 /*------------------------------------------------------------------*/
2809 /* valCompare - Compares two literal */
2810 /*------------------------------------------------------------------*/
2811 value *
2812 valCompare (value * lval, value * rval, int ctype, bool reduceType)
2814 value *val;
2816 /* create a new value */
2817 val = newValue ();
2818 val->type = val->etype = newCharLink ();
2819 val->type->xclass = SPECIFIER;
2820 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
2822 if (reduceType)
2824 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
2825 SPEC_USIGN (val->type) = 1;
2827 else
2829 SPEC_NOUN (val->type) = V_INT;
2830 SPEC_USIGN (val->type) = 0;
2833 switch (ctype)
2835 /* FIXME: need to add long long support to inequalities */
2836 case '<':
2837 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
2838 break;
2840 case '>':
2841 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
2842 break;
2844 case LE_OP:
2845 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
2846 break;
2848 case GE_OP:
2849 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
2850 break;
2852 case EQ_OP:
2853 if (SPEC_NOUN (lval->type) == V_FLOAT || SPEC_NOUN (rval->type) == V_FLOAT)
2855 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
2857 else if (SPEC_NOUN (lval->type) == V_FIXED16X16 || SPEC_NOUN (rval->type) == V_FIXED16X16)
2859 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
2861 else
2863 /* integrals: ignore signedness */
2864 TYPE_TARGET_ULONGLONG l, r;
2866 l = (TYPE_TARGET_ULONGLONG) ullFromVal (lval);
2867 r = (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2868 /* In order to correctly compare 'signed int' and 'unsigned int' it's
2869 necessary to strip them to 16 bit.
2870 Literals are reduced to their cheapest type, therefore left and
2871 right might have different types. It's necessary to find a
2872 common type: int (used for char too) or long */
2873 if (!IS_LONGLONG (lval->etype) && !IS_BITINT (lval->etype) && !IS_LONGLONG (rval->etype) && !IS_BITINT (rval->etype))
2875 r = (TYPE_TARGET_ULONG) r;
2876 l = (TYPE_TARGET_ULONG) l;
2878 if (!IS_LONG (lval->etype) && !IS_LONG (rval->etype))
2880 r = (TYPE_TARGET_UINT) r;
2881 l = (TYPE_TARGET_UINT) l;
2883 SPEC_CVAL (val->type).v_int = l == r;
2885 break;
2886 case NE_OP:
2887 if (SPEC_NOUN (lval->type) == V_FLOAT || SPEC_NOUN (rval->type) == V_FLOAT)
2889 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
2891 else if (SPEC_NOUN (lval->type) == V_FIXED16X16 || SPEC_NOUN (rval->type) == V_FIXED16X16)
2893 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
2895 else
2897 /* integrals: ignore signedness */
2898 TYPE_TARGET_ULONGLONG l, r;
2900 l = (TYPE_TARGET_ULONGLONG) ullFromVal (lval);
2901 r = (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2902 /* In order to correctly compare 'signed int' and 'unsigned int' it's
2903 necessary to strip them to 16 bit.
2904 Literals are reduced to their cheapest type, therefore left and
2905 right might have different types. It's necessary to find a
2906 common type: int (used for char too) or long */
2907 if (!IS_LONGLONG (lval->etype) && !IS_BITINT (lval->etype) && !IS_LONGLONG (rval->etype) && !IS_BITINT (rval->etype))
2909 r = (TYPE_TARGET_ULONG) r;
2910 l = (TYPE_TARGET_ULONG) l;
2912 if (!IS_LONG (lval->etype) && !IS_LONG (rval->etype))
2914 r = (TYPE_TARGET_UINT) r;
2915 l = (TYPE_TARGET_UINT) l;
2917 SPEC_CVAL (val->type).v_int = l != r;
2919 break;
2923 return val;
2926 /*------------------------------------------------------------------*/
2927 /* valBitwise - Bitwise operation */
2928 /*------------------------------------------------------------------*/
2929 value *
2930 valBitwise (value * lval, value * rval, int op, bool reduceType)
2932 value *val;
2934 /* create a new value */
2935 val = newValue ();
2936 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
2937 val->etype = getSpec (val->type);
2938 SPEC_SCLS (val->etype) = S_LITERAL;
2940 switch (op)
2942 case '&':
2943 if (SPEC_LONGLONG (val->type) || IS_BITINT (val->type))
2945 if (SPEC_USIGN (val->type))
2946 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) & (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2947 else
2948 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) & (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2950 else if (SPEC_LONG (val->type))
2952 if (SPEC_USIGN (val->type))
2953 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) & (TYPE_TARGET_ULONG) ulFromVal (rval);
2954 else
2955 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) & (TYPE_TARGET_LONG) ulFromVal (rval);
2957 else
2959 if (SPEC_USIGN (val->type))
2960 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) & (TYPE_TARGET_UINT) ulFromVal (rval);
2961 else
2962 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) & (TYPE_TARGET_INT) ulFromVal (rval);
2964 break;
2966 case '|':
2967 if (SPEC_LONGLONG (val->type) || IS_BITINT (val->type))
2969 if (SPEC_USIGN (val->type))
2970 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) | (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2971 else
2972 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) | (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2974 else if (SPEC_LONG (val->type))
2976 if (SPEC_USIGN (val->type))
2977 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) | (TYPE_TARGET_ULONG) ulFromVal (rval);
2978 else
2979 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) | (TYPE_TARGET_LONG) ulFromVal (rval);
2981 else
2983 if (SPEC_USIGN (val->type))
2984 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) | (TYPE_TARGET_UINT) ulFromVal (rval);
2985 else
2986 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) | (TYPE_TARGET_INT) ulFromVal (rval);
2989 break;
2991 case '^':
2992 if (SPEC_LONGLONG (val->type) || IS_BITINT (val->type))
2994 if (SPEC_USIGN (val->type))
2995 SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) ^ (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2996 else
2997 SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) ^ (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2999 else if (SPEC_LONG (val->type))
3001 if (SPEC_USIGN (val->type))
3002 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) ^ (TYPE_TARGET_ULONG) ulFromVal (rval);
3003 else
3004 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) ^ (TYPE_TARGET_LONG) ulFromVal (rval);
3006 else
3008 if (SPEC_USIGN (val->type))
3009 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) ^ (TYPE_TARGET_UINT) ulFromVal (rval);
3010 else
3011 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) ^ (TYPE_TARGET_INT) ulFromVal (rval);
3013 break;
3016 return reduceType ? cheapestVal (val) : val;
3019 /*------------------------------------------------------------------*/
3020 /* valAndOr - Generates code for and / or operation */
3021 /*------------------------------------------------------------------*/
3022 value *
3023 valLogicAndOr (value * lval, value * rval, int op, bool reduceType)
3025 value *val;
3027 /* create a new value */
3028 val = newValue ();
3029 val->type = val->etype = newCharLink ();
3030 val->type->xclass = SPECIFIER;
3031 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
3033 if (reduceType)
3034 SPEC_USIGN (val->type) = 1;
3035 else
3037 SPEC_NOUN (val->type) = V_INT;
3038 SPEC_USIGN (val->type) = 0;
3041 switch (op)
3043 case AND_OP:
3044 SPEC_CVAL (val->type).v_int = !isEqualVal (lval, 0) && !isEqualVal (rval, 0);
3045 break;
3047 case OR_OP:
3048 SPEC_CVAL (val->type).v_int = !isEqualVal (lval, 0) || !isEqualVal (rval, 0);
3049 break;
3052 return val;
3055 /*------------------------------------------------------------------*/
3056 /* valCastLiteral - casts a literal value to another type */
3057 /*------------------------------------------------------------------*/
3058 value *
3059 valCastLiteral (sym_link *dtype, double fval, TYPE_TARGET_ULONGLONG llval)
3061 value *val;
3062 unsigned long l = double2ul (fval);
3064 if (!dtype)
3065 return NULL;
3066 if ((fval > 0x7ffffffful) || (-fval > 0x7ffffffful))
3067 l = (unsigned long)llval;
3069 #if 0
3070 printf("valCastLiteral: %llx to ", (unsigned long long)llval); printTypeChain (dtype, stdout); printf("\n");
3071 #endif
3073 val = newValue ();
3074 if (dtype)
3075 val->etype = getSpec (val->type = copyLinkChain (dtype));
3076 else
3078 val->etype = val->type = newLink (SPECIFIER);
3079 SPEC_NOUN (val->etype) = V_VOID;
3081 SPEC_SCLS (val->etype) = S_LITERAL;
3083 /* if it is not a specifier then we can assume that */
3084 /* it will be an unsigned long */
3085 if (!IS_SPEC (val->type))
3087 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
3088 return val;
3091 switch (SPEC_NOUN (val->etype))
3093 case V_FLOAT:
3094 SPEC_CVAL (val->etype).v_float = fval;
3095 break;
3097 case V_FIXED16X16:
3098 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
3099 break;
3101 case V_BOOL:
3102 case V_BIT:
3103 case V_SBIT:
3104 SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
3105 break;
3107 case V_BITINTBITFIELD:
3108 llval &= (0xffffffffffffffffull >> (64 - SPEC_BLEN (val->etype)));
3109 case V_BITINT:
3110 wassert (SPEC_BITINTWIDTH (val->etype) >= 1);
3111 if (!SPEC_USIGN (val->etype)) // Sign-extend
3113 if (llval & ((1ull << (SPEC_BITINTWIDTH (val->etype) - 1))))
3114 llval |= ~(0xffffffffffffffffull >> (64 - SPEC_BITINTWIDTH (val->etype)));
3115 else
3116 llval &= (0xffffffffffffffffull >> (64 - SPEC_BITINTWIDTH (val->etype) + 1));
3117 SPEC_CVAL (val->etype).v_longlong = llval;
3119 else
3121 llval &= (0xffffffffffffffffull >> (64 - SPEC_BITINTWIDTH (val->etype)));
3122 SPEC_CVAL (val->etype).v_ulonglong = llval;
3124 break;
3126 case V_BITFIELD:
3127 llval &= (0xffffffffffffffffull >> (64 - SPEC_BLEN (val->etype)));
3128 if (SPEC_USIGN (val->etype))
3129 SPEC_CVAL (val->etype).v_ulonglong = (TYPE_TARGET_UINT) llval;
3130 else
3131 SPEC_CVAL (val->etype).v_longlong = (TYPE_TARGET_INT) llval;
3132 break;
3134 case V_CHAR:
3135 if (SPEC_USIGN (val->etype))
3136 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) l;
3137 else
3138 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
3139 break;
3141 default:
3142 if (SPEC_LONGLONG (val->etype))
3144 if (SPEC_USIGN (val->etype))
3145 SPEC_CVAL (val->etype).v_ulonglong = (TYPE_TARGET_ULONGLONG) llval;
3146 else
3147 SPEC_CVAL (val->etype).v_longlong = (TYPE_TARGET_LONGLONG) llval;
3149 else if (SPEC_LONG (val->etype))
3151 if (SPEC_USIGN (val->etype))
3152 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
3153 else
3154 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
3156 else
3158 if (SPEC_USIGN (val->etype))
3159 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
3160 else
3161 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
3165 return val;
3168 /*-------------------------------------------------------------------*/
3169 /* valRecastLitVal - changes type of a literal value to another type */
3170 /*-------------------------------------------------------------------*/
3171 value *
3172 valRecastLitVal (sym_link * dtype, value * val)
3174 sym_link * otype = val->type;
3175 double fval;
3176 TYPE_TARGET_ULONGLONG ull;
3178 if (IS_SPEC (otype) && (SPEC_NOUN (otype) == V_FIXED16X16 || SPEC_NOUN (otype) == V_FLOAT))
3180 fval = floatFromVal (val);
3181 ull = (TYPE_TARGET_ULONGLONG)fval;
3183 else
3185 ull = (TYPE_TARGET_ULONGLONG) ullFromVal (val);
3186 fval = (double)ull;
3189 if (dtype)
3190 val->etype = getSpec (val->type = copyLinkChain (dtype));
3191 else
3193 val->etype = val->type = newLink (SPECIFIER);
3194 SPEC_NOUN (val->etype) = V_VOID;
3196 SPEC_SCLS (val->etype) = S_LITERAL;
3198 /* if it is not a specifier then we can assume that */
3199 /* it will be an unsigned long */
3200 if (!IS_SPEC (val->type))
3202 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ull;
3203 return val;
3206 switch (SPEC_NOUN (val->etype))
3208 case V_FLOAT:
3209 SPEC_CVAL (val->etype).v_float = fval;
3210 break;
3212 case V_FIXED16X16:
3213 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
3214 break;
3216 case V_BOOL:
3217 case V_BIT:
3218 case V_SBIT:
3219 SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
3220 break;
3222 case V_BITFIELD:
3223 case V_BITINTBITFIELD:
3224 ull &= (0xffffffffffffffffull >> (64 - SPEC_BLEN (val->etype)));
3225 if (SPEC_USIGN (val->etype))
3226 SPEC_CVAL (val->etype).v_ulonglong = (TYPE_TARGET_ULONGLONG) ull;
3227 else
3228 SPEC_CVAL (val->etype).v_longlong = (TYPE_TARGET_LONGLONG) ull;
3229 break;
3231 case V_CHAR:
3232 if (SPEC_USIGN (val->etype))
3233 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) ull;
3234 else
3235 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) ull;
3236 break;
3238 default:
3239 if (SPEC_LONGLONG (val->etype) || SPEC_NOUN (val->etype) == V_BITINT)
3241 if (SPEC_USIGN (val->etype))
3242 SPEC_CVAL (val->etype).v_ulonglong = (TYPE_TARGET_ULONGLONG) ull;
3243 else
3244 SPEC_CVAL (val->etype).v_longlong = (TYPE_TARGET_LONGLONG) ull;
3246 else if (SPEC_LONG (val->etype))
3248 if (SPEC_USIGN (val->etype))
3249 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ull;
3250 else
3251 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) ull;
3253 else
3255 if (SPEC_USIGN (val->etype))
3256 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) ull;
3257 else
3258 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) ull;
3262 return val;
3265 /*------------------------------------------------------------------*/
3266 /* getNelements - determines # of elements from init list */
3267 /*------------------------------------------------------------------*/
3269 getNelements (sym_link * type, initList * ilist)
3271 int i, size;
3273 if (!ilist)
3274 return 0;
3276 if (ilist->type == INIT_DEEP)
3277 ilist = ilist->init.deep;
3279 /* if type is a character array and there is only one
3280 (string) initialiser then get the length of the string */
3281 if (IS_ARRAY (type) && (IS_CHAR (type->next) || IS_INT (type->next) && IS_UNSIGNED (type->next)) && !ilist->next)
3283 ast *iast = ilist->init.node;
3284 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
3286 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)))
3287 /* yep, it's a string */
3289 return DCL_ELEM (v->type);
3293 size = 0;
3294 i = 0;
3295 while (ilist)
3297 if (ilist->designation)
3299 if (ilist->designation->type != DESIGNATOR_ARRAY)
3301 // structure designator for array, boo.
3302 werrorfl (ilist->filename, ilist->lineno, E_BAD_DESIGNATOR);
3304 else
3306 i = ilist->designation->designator.elemno;
3309 if (size <= i)
3311 size = i + 1; /* array size is one larger than array init element */
3313 i++;
3314 ilist = ilist->next;
3316 return size;
3319 /*-----------------------------------------------------------------*/
3320 /* valForArray - returns a value with name of array index */
3321 /*-----------------------------------------------------------------*/
3322 value *
3323 valForArray (ast * arrExpr)
3325 value *val, *lval = NULL;
3326 int size = getSize (arrExpr->left->ftype->next);
3328 /* if the right or left is an array
3329 resolve it first */
3330 if (IS_AST_OP (arrExpr->left))
3332 if (arrExpr->left->opval.op == '[')
3333 lval = valForArray (arrExpr->left);
3334 else if (arrExpr->left->opval.op == '.')
3335 lval = valForStructElem (arrExpr->left->left, arrExpr->left->right);
3336 else if (arrExpr->left->opval.op == PTR_OP)
3338 if (IS_ADDRESS_OF_OP (arrExpr->left->left))
3339 lval = valForStructElem (arrExpr->left->left->left, arrExpr->left->right);
3340 else if (IS_AST_VALUE (arrExpr->left->left) && IS_PTR (arrExpr->left->left->ftype))
3341 lval = valForStructElem (arrExpr->left->left, arrExpr->left->right);
3343 else
3344 return NULL;
3346 else if (!IS_AST_SYM_VALUE (arrExpr->left))
3347 return NULL;
3349 if (!IS_AST_LIT_VALUE (arrExpr->right))
3350 return NULL;
3352 val = newValue ();
3353 val->type = newLink (DECLARATOR);
3354 if (IS_AST_LIT_VALUE (arrExpr->left) && IS_PTR (arrExpr->left->ftype))
3356 SNPRINTF (val->name, sizeof (val->name), "0x%X",
3357 AST_ULONG_VALUE (arrExpr->left) + AST_ULONG_VALUE (arrExpr->right) * size);
3358 memcpy (val->type, arrExpr->left->ftype, sizeof (sym_link));
3360 else if (lval)
3362 SNPRINTF (val->name, sizeof (val->name), "(%s + %d)", lval->name, AST_ULONG_VALUE (arrExpr->right) * size);
3363 memcpy (val->type, lval->type, sizeof (sym_link));
3365 else
3367 SNPRINTF (val->name, sizeof (val->name), "(%s + %d)",
3368 AST_SYMBOL (arrExpr->left)->rname, AST_ULONG_VALUE (arrExpr->right) * size);
3369 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
3370 DCL_TYPE (val->type) = CPOINTER;
3371 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
3372 DCL_TYPE (val->type) = FPOINTER;
3373 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
3374 DCL_TYPE (val->type) = PPOINTER;
3375 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
3376 DCL_TYPE (val->type) = IPOINTER;
3377 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
3378 DCL_TYPE (val->type) = EEPPOINTER;
3379 else
3380 DCL_TYPE (val->type) = POINTER;
3383 val->type->next = arrExpr->left->ftype->next;
3384 val->etype = getSpec (val->type);
3385 return val;
3388 /*-----------------------------------------------------------------*/
3389 /* valForStructElem - returns value with name of struct element */
3390 /*-----------------------------------------------------------------*/
3391 value *
3392 valForStructElem (ast * structT, ast * elemT)
3394 value *val, *lval = NULL;
3395 symbol *sym;
3396 int idxoff = 0;
3397 ast *sast = NULL;
3399 /* left could be further derefed */
3400 if (IS_AST_OP (structT))
3402 if (structT->opval.op == '[')
3403 lval = valForArray (structT);
3404 else if (structT->opval.op == '+')
3406 if (IS_AST_LIT_VALUE (structT->right) && !IS_AST_OP (structT->left))
3408 idxoff = (int) (AST_ULONG_VALUE (structT->right) * getSize (structT->left->ftype->next));
3409 sast = structT->left;
3411 else if (IS_AST_LIT_VALUE (structT->left) && !IS_AST_OP (structT->right))
3413 idxoff = (int) (AST_ULONG_VALUE (structT->left) * getSize (structT->right->ftype->next));
3414 sast = structT->right;
3416 else
3417 return NULL;
3419 else if (structT->opval.op == '-')
3421 if (IS_AST_LIT_VALUE (structT->right) && !IS_AST_OP (structT->left))
3423 idxoff = 0 - (int) (AST_ULONG_VALUE (structT->right) * getSize (structT->left->ftype->next));
3424 sast = structT->left;
3426 else
3427 return NULL;
3429 else if (structT->opval.op == '.')
3430 lval = valForStructElem (structT->left, structT->right);
3431 else if (structT->opval.op == PTR_OP)
3433 if (IS_ADDRESS_OF_OP (structT->left))
3434 lval = valForStructElem (structT->left->left, structT->right);
3435 else if (IS_AST_VALUE (structT->left) && IS_PTR (structT->left->ftype))
3436 lval = valForStructElem (structT->left, structT->right);
3438 else
3439 return NULL;
3442 if (!IS_AST_SYM_VALUE (elemT))
3443 return NULL;
3445 if (!structT || !IS_STRUCT (structT->etype))
3446 return NULL;
3448 if ((sym = getStructElement (SPEC_STRUCT (structT->etype), AST_SYMBOL (elemT))) == NULL)
3450 return NULL;
3453 val = newValue ();
3454 val->type = newLink (DECLARATOR);
3455 if (IS_AST_LIT_VALUE (structT) && IS_PTR (structT->ftype))
3457 SNPRINTF (val->name, sizeof (val->name), "0x%X", AST_ULONG_VALUE (structT) + (int) sym->offset);
3458 memcpy (val->type, structT->ftype, sizeof (sym_link));
3460 else if (lval)
3462 SNPRINTF (val->name, sizeof (val->name), "(%s + %d)", lval->name, (int) sym->offset);
3463 memcpy (val->type, lval->type, sizeof (sym_link));
3465 else
3467 if (sast)
3468 SNPRINTF (val->name, sizeof (val->name), "(%s + (%d))", AST_SYMBOL (sast)->rname, ((int) sym->offset) + idxoff);
3469 else
3470 SNPRINTF (val->name, sizeof (val->name), "(%s + %d)", AST_SYMBOL (structT)->rname, (int) sym->offset);
3472 if (SPEC_SCLS (structT->etype) == S_CODE)
3473 DCL_TYPE (val->type) = CPOINTER;
3474 else if (SPEC_SCLS (structT->etype) == S_XDATA)
3475 DCL_TYPE (val->type) = FPOINTER;
3476 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
3477 DCL_TYPE (val->type) = PPOINTER;
3478 else if (SPEC_SCLS (structT->etype) == S_IDATA)
3479 DCL_TYPE (val->type) = IPOINTER;
3480 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
3481 DCL_TYPE (val->type) = EEPPOINTER;
3482 else
3483 DCL_TYPE (val->type) = POINTER;
3486 val->type->next = sym->type;
3487 val->etype = getSpec (val->type);
3488 return val;
3491 /*-----------------------------------------------------------------*/
3492 /* valForCastAggr - will return value for a cast of an aggregate */
3493 /* plus minus a constant */
3494 /*-----------------------------------------------------------------*/
3495 value *
3496 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
3498 value *val;
3500 if (!IS_AST_SYM_VALUE (aexpr))
3501 return NULL;
3502 if (!IS_AST_LIT_VALUE (cnst))
3503 return NULL;
3505 val = newValue ();
3507 SNPRINTF (val->name, sizeof (val->name), "(%s %c %d)",
3508 AST_SYMBOL (aexpr)->rname, op, getSize (type->next) * AST_ULONG_VALUE (cnst));
3510 val->type = type;
3511 val->etype = getSpec (val->type);
3512 return val;
3515 /*-----------------------------------------------------------------*/
3516 /* valForCastArr - will return value for a cast of an aggregate */
3517 /* with no constant */
3518 /*-----------------------------------------------------------------*/
3519 value *
3520 valForCastArr (ast * aexpr, sym_link * type)
3522 value *val;
3524 if (!IS_AST_SYM_VALUE (aexpr))
3525 return NULL;
3527 val = newValue ();
3529 SNPRINTF (val->name, sizeof (val->name), "(%s)", AST_SYMBOL (aexpr)->rname);
3531 val->type = type;
3532 val->etype = getSpec (val->type);
3533 return val;