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
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 -------------------------------------------------------------------------*/
32 #include "dbuf_string.h"
37 /*-----------------------------------------------------------------*/
38 /* newValue - allocates and returns a new value */
39 /*-----------------------------------------------------------------*/
45 val
= Safe_alloc (sizeof (value
));
50 /*-----------------------------------------------------------------*/
51 /* newiList - new initializer list */
52 /*-----------------------------------------------------------------*/
54 newiList (int type
, void *ilist
)
58 nilist
= Safe_alloc (sizeof (initList
));
61 nilist
->filename
= lexFilename
;
62 nilist
->lineno
= lexLineno
;
63 nilist
->designation
= NULL
;
68 nilist
->init
.node
= (struct ast
*) ilist
;
72 nilist
->init
.deep
= (struct initList
*) ilist
;
79 /*------------------------------------------------------------------*/
80 /* revinit - reverses the initial values for a value chain */
81 /*------------------------------------------------------------------*/
83 revinit (initList
* val
)
85 initList
*prev
, *curr
, *next
;
100 val
->next
= (void *) NULL
;
105 convertIListToConstList (initList
* src
, literalList
** lList
, int size
)
109 literalList
*head
, *last
, *newL
;
113 if (src
&& src
->type
!= INIT_DEEP
)
118 iLoop
= src
? src
->init
.deep
: NULL
;
122 if (iLoop
->designation
!= NULL
)
127 if (iLoop
->type
!= INIT_NODE
)
132 if (!IS_AST_LIT_VALUE (decorateType (resolveSymbols (iLoop
->init
.node
), RESULT_TYPE_NONE
, true)))
144 /* We've now established that the initializer list contains only literal values. */
146 iLoop
= src
? src
->init
.deep
: NULL
;
149 literalList ll
= {0};
150 value
*val
= iLoop
? AST_VALUE (iLoop
->init
.node
) : NULL
;
153 ll
.isFloat
= IS_FLOAT(val
->type
);
155 ll
.value
.f64
= floatFromVal(val
);
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
)))
167 newL
= Safe_alloc (sizeof (literalList
));
182 iLoop
= iLoop
? iLoop
->next
: NULL
;
195 copyLiteralList (literalList
* src
)
197 literalList
*head
, *prev
, *newL
;
203 newL
= Safe_alloc (sizeof (literalList
));
206 newL
->count
= src
->count
;
224 /*------------------------------------------------------------------*/
225 /* copyIlist - copy initializer list */
226 /*------------------------------------------------------------------*/
228 copyIlist (initList
* src
)
230 initList
*dest
= NULL
;
238 dest
= newiList (INIT_DEEP
, copyIlist (src
->init
.deep
));
239 dest
->lineno
= src
->lineno
;
242 dest
= newiList (INIT_NODE
, copyAst (src
->init
.node
));
243 dest
->lineno
= src
->lineno
;
247 if (src
->designation
)
248 dest
->designation
= copyDesignation (src
->designation
);
251 assert (dest
!= NULL
);
252 dest
->next
= copyIlist (src
->next
);
257 /*------------------------------------------------------------------*/
258 /* list2int - converts the first element of the list to value */
259 /*------------------------------------------------------------------*/
261 list2int (initList
* 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 /*------------------------------------------------------------------*/
277 list2val (initList
* val
, int check
)
282 if(val
->type
== INIT_HOLE
)
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 /*------------------------------------------------------------------*/
298 list2expr (initList
* ilist
)
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 /*------------------------------------------------------------------*/
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
));
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
);
334 /*-----------------------------------------------------------------*/
335 /* newDesignation - new designation */
336 /*-----------------------------------------------------------------*/
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
;
350 case DESIGNATOR_STRUCT
:
351 ndesignation
->designator
.tag
= (struct symbol
*) designator
;
354 case DESIGNATOR_ARRAY
:
355 ndesignation
->designator
.elemno
= * ((int *) designator
);
362 /*------------------------------------------------------------------*/
363 /* revDesignation - reverses the designation chain */
364 /*------------------------------------------------------------------*/
366 revDesignation (designation
* val
)
368 designation
*prev
, *curr
, *next
;
383 val
->next
= (void *) NULL
;
387 /*------------------------------------------------------------------*/
388 /* copyDesignation - copy designation list */
389 /*------------------------------------------------------------------*/
391 copyDesignation (designation
* src
)
393 designation
*dest
= NULL
;
400 case DESIGNATOR_STRUCT
:
401 dest
= newDesignation (DESIGNATOR_STRUCT
, copySymbol (src
->designator
.tag
));
403 case DESIGNATOR_ARRAY
:
404 dest
= newDesignation (DESIGNATOR_ARRAY
, &(src
->designator
.elemno
) );
408 dest
->lineno
= src
->lineno
;
409 dest
->filename
= src
->filename
;
412 dest
->next
= copyDesignation (src
->next
);
417 /*------------------------------------------------------------------*/
418 /* moveNestedInit - rewrites an initList node with a nested */
419 /* designator to remove one level of nesting. */
420 /*------------------------------------------------------------------*/
422 void moveNestedInit(initList
*deepParent
, initList
*src
)
424 initList
*dst
= NULL
, **eol
;
426 /** Create new initList element */
430 dst
= newiList(INIT_NODE
, src
->init
.node
);
433 dst
= newiList(INIT_DEEP
, src
->init
.deep
);
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>");
447 for (eol
= &(deepParent
->init
.deep
); *eol
; )
448 eol
= &((*eol
)->next
);
452 /*-----------------------------------------------------------------*/
453 /* findStructField - find a specific field in a struct definition */
454 /*-----------------------------------------------------------------*/
456 findStructField (symbol
*fields
, symbol
*target
)
460 for (i
=0 ; fields
; fields
= fields
->next
)
462 /* skip past unnamed bitfields */
463 if (IS_BITFIELD (fields
->type
) && SPEC_BUNNAMED (fields
->etype
))
466 if (strcmp(fields
->name
, target
->name
) == 0)
472 werrorfl (target
->fileDef
, target
->lineDef
, E_NOT_MEMBER
, target
->name
);
476 /*------------------------------------------------------------------*/
477 /* reorderIlist - expands an initializer list to match designated */
479 /*------------------------------------------------------------------*/
480 initList
*reorderIlist (sym_link
* type
, initList
* ilist
)
482 initList
*iloop
, *nlist
, **nlistArray
;
486 if (!IS_AGGREGATE (type
))
487 /* uninteresting: no designated initializers */
490 if (ilist
&& ilist
->type
== INIT_HOLE
)
491 /* ditto; just a uninitialized hole */
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. */
507 if (ilist
&& ilist
->type
!= INIT_DEEP
)
509 werrorfl (ilist
->filename
, ilist
->lineno
, E_INIT_STRUCT
, "<unknown>");
513 /* okay, allocate enough space */
516 size
= getNelements(type
, ilist
);
520 else if (IS_STRUCT (type
))
522 /* compute size from struct type. */
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
))
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
);
544 if (iloop
->designation
->type
== DESIGNATOR_ARRAY
)
545 idx
= iloop
->designation
->designator
.elemno
;
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
);
555 werrorfl (iloop
->filename
, iloop
->lineno
, E_BAD_DESIGNATOR
);
562 if (iloop
->designation
->next
)
566 if (nlistArray
[idx
] == NULL
)
567 nlistArray
[idx
] = newiList(INIT_DEEP
, NULL
);
568 moveNestedInit(nlistArray
[idx
], iloop
);
573 /* overwrite any existing entry with iloop */
574 if (iloop
->type
!= INIT_HOLE
)
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 */
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
;
601 dst
= newiList(INIT_NODE
, src
->init
.node
);
604 dst
= newiList(INIT_DEEP
, src
->init
.deep
);
607 dst
->filename
= src
->filename
;
608 dst
->lineno
= src
->lineno
;
612 /* advance to next field which is not an unnamed bitfield */
615 sflds
= sflds
? sflds
->next
: NULL
;
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
;
629 /*------------------------------------------------------------------*/
630 /* symbolVal - creates a value for a symbol */
631 /*------------------------------------------------------------------*/
633 symbolVal (symbol
* sym
)
645 val
->type
= sym
->type
;
646 val
->etype
= getSpec (val
->type
);
651 SNPRINTF (val
->name
, sizeof (val
->name
), "%s", sym
->rname
);
655 SNPRINTF (val
->name
, sizeof (val
->name
), "_%s", sym
->name
);
661 /*--------------------------------------------------------------------*/
662 /* cheapestVal - try to reduce 'signed int' to 'char' */
663 /*--------------------------------------------------------------------*/
665 cheapestVal (value
* val
)
667 /* only int can be reduced */
668 if (!IS_INT (val
->type
))
671 /* long must not be changed */
672 if (SPEC_LONG (val
->type
) || SPEC_LONGLONG (val
->type
))
675 /* unsigned must not be changed */
676 if (SPEC_USIGN (val
->type
))
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 */
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
;
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;
715 /*-----------------------------------------------------------------*/
716 /* double2ul - double to unsigned long conversion */
717 /*-----------------------------------------------------------------*/
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 /*-----------------------------------------------------------------*/
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 /*--------------------------------------------------------------------*/
747 checkConstantRange (sym_link
*var
, sym_link
*lit
, int op
, bool exchangeLeftRight
)
750 TYPE_TARGET_LONGLONG litVal
;
751 TYPE_TARGET_ULONGLONG ulitVal
;
752 TYPE_TARGET_ULONGLONG signExtMask
;
753 TYPE_TARGET_ULONGLONG signMask
;
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);
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
);
772 //return CCR_OK; /* EEP - debug for long long */
774 if (IS_FLOAT (var
) || IS_FIXED (var
))
777 return CCR_ALWAYS_FALSE
;
779 return CCR_ALWAYS_TRUE
;
781 /* special: assignment */
784 if (IS_BOOLEAN (var
))
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)
800 if ((ulitVal
& (signExtMask
| signMask
)) == 0)
805 if ((litVal
& (signExtMask
| signMask
)) == 0)
807 if ((litVal
& (signExtMask
| signMask
)) == (signExtMask
| signMask
))
815 /* ignore signedness, e.g. allow everything
816 from -127...+255 for (unsigned) char */
817 if ((litVal
& signExtMask
) == 0)
819 if ((litVal
& (signExtMask
| signMask
)) == (signExtMask
| signMask
))
825 if (exchangeLeftRight
)
845 return CCR_ALWAYS_FALSE
;
848 reType
= computeType (var
, lit
, RESULT_TYPE_NONE
, op
);
851 printf(" reType = ");
852 printTypeChain (reType
, 0);
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);
869 else if (SPEC_USIGN (lit
) && SPEC_USIGN (var
))
871 /* both operands are unsigned, this is easy */
873 maxValP
= ~signExtMask
;
874 /* there's only range, just copy it to 2nd set */
878 else if (SPEC_USIGN (var
))
880 /* lit is casted from signed to unsigned, e.g.:
886 maxValP
= ~signExtMask
;
887 /* there's only one range, just copy it to 2nd set */
891 /* it's an unsigned operation */
892 ulitVal
&= opBitsMask
;
894 else /* SPEC_USIGN (lit) */
896 /* var is casted from signed to unsigned, e.g.:
901 The possible values after casting var
902 split up in two, nonconsecutive ranges:
904 minValP = 0; positive range: 0...127
906 minValM = 0xff80; negative range: -128...-1
912 maxValP
= ~(signExtMask
| signMask
);
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
;
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
);
932 case EQ_OP
: /* var == lit */
933 if (ulitVal
<= maxValP
&& ulitVal
>= minValP
) /* 0 */
935 if (ulitVal
<= maxValM
&& ulitVal
>= minValM
)
937 return CCR_ALWAYS_FALSE
;
938 case NE_OP
: /* var != lit */
939 if (ulitVal
<= maxValP
&& ulitVal
>= minValP
) /* 0 */
941 if (ulitVal
<= maxValM
&& ulitVal
>= minValM
)
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
;
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
;
956 case '<': /* var < lit */
957 if (ulitVal
> maxValM
)
958 return CCR_ALWAYS_TRUE
;
959 if (ulitVal
<= minValP
) /* 0 */
960 return CCR_ALWAYS_FALSE
;
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
;
969 return CCR_ALWAYS_FALSE
;
974 /* signed operation */
975 TYPE_TARGET_LONGLONG minVal
, maxVal
;
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. */
988 maxVal
= ~signExtMask
;
993 minVal
= signExtMask
| signMask
;
994 maxVal
= ~(signExtMask
| signMask
);
999 case EQ_OP
: /* var == lit */
1000 if (litVal
> maxVal
|| litVal
< minVal
)
1001 return CCR_ALWAYS_FALSE
;
1003 case NE_OP
: /* var != lit */
1004 if (litVal
> maxVal
|| litVal
< minVal
)
1005 return CCR_ALWAYS_TRUE
;
1007 case '>': /* var > lit */
1008 if (litVal
>= maxVal
)
1009 return CCR_ALWAYS_FALSE
;
1010 if (litVal
< minVal
)
1011 return CCR_ALWAYS_TRUE
;
1013 case GE_OP
: /* var >= lit */
1014 if (litVal
> maxVal
)
1015 return CCR_ALWAYS_FALSE
;
1016 if (litVal
<= minVal
)
1017 return CCR_ALWAYS_TRUE
;
1019 case '<': /* var < lit */
1020 if (litVal
> maxVal
)
1021 return CCR_ALWAYS_TRUE
;
1022 if (litVal
<= minVal
)
1023 return CCR_ALWAYS_FALSE
;
1025 case LE_OP
: /* var <= lit */
1026 if (litVal
>= maxVal
)
1027 return CCR_ALWAYS_TRUE
;
1028 if (litVal
< minVal
)
1029 return CCR_ALWAYS_FALSE
;
1032 return CCR_ALWAYS_FALSE
;
1039 checkConstantRange (sym_link
* var
, sym_link
* lit
, int op
, bool exchangeLeftRight
)
1043 printf ("checkConstantRange:\n");
1045 printTypeChain (var
, NULL
);
1046 printf (" lit = 0x%lx: ",ullFromLit (lit
));
1047 printTypeChain (lit
, NULL
);
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
);
1061 result
= checkConstantRange2 (var
, lit
, op
, exchangeLeftRight
);
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
);
1075 /*-----------------------------------------------------------------*/
1076 /* valueFromLit - creates a value from a literal */
1077 /*-----------------------------------------------------------------*/
1079 valueFromLit (double lit
)
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
);
1093 dbuf_init (&dbuf
, 128);
1094 dbuf_printf (&dbuf
, "%f", lit
);
1095 ret
= constFloatVal (dbuf_c_str (&dbuf
));
1096 dbuf_destroy (&dbuf
);
1100 /*-----------------------------------------------------------------*/
1101 /* constFloatVal - converts a FLOAT constant to value */
1102 /*-----------------------------------------------------------------*/
1104 constFloatVal (const char *s
)
1106 value
*val
= newValue ();
1110 sval
= strtod (s
, &p
);
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
;
1126 /*-----------------------------------------------------------------*/
1127 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
1128 /*-----------------------------------------------------------------*/
1130 constFixed16x16Val (const char *s
)
1132 value
*val
= newValue ();
1136 sval
= strtod (s
, &p
);
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
);
1152 /*-----------------------------------------------------------------*/
1153 /* constVal - converts a constant into a cheap value type */
1154 /*-----------------------------------------------------------------*/
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
;
1170 SPEC_NOUN (val
->type
) = V_CHAR
;
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
;
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;
1205 // Skip digit separators
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')
1222 if (!(next
>= 0 && next
< base
))
1229 if(separated
&& !options
.std_c23
)
1230 werror (W_DIGIT_SEPARATOR_C23
);
1233 *endptr
= (char *)nptr
;
1238 /*-----------------------------------------------------------------*/
1239 /* constIntVal - converts an integer constant into correct type */
1240 /* See ISO C11, section 6.4.4.1 for the rules. */
1241 /*-----------------------------------------------------------------*/
1243 constIntVal (const char *s
)
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;
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);
1269 llval
= sepStrToUll (s
, &p
, 8);
1270 dval
= (double)(unsigned long long int) llval
;
1275 dval
= strtod (s
, &p
);
1278 llval
= sepStrToUll (s
, &p
, 10);
1279 dval
= (double)(unsigned long long int) llval
;
1283 llval
= sepStrToUll (s
+ 1, &p
, 10);
1285 dval
= (double) llval
;
1292 dval
= 4294967295.0;
1293 werror (W_INVALID_INT_CONST
, s
, dval
);
1297 if ((p2
= strchr (p
, 'u')) || (p2
= strchr (p
, 'U')))
1301 if (strchr (p2
, 'u') || strchr (p2
, 'U'))
1302 werror (E_INTEGERSUFFIX
, p
);
1305 if ((p2
= strstr (p
, "ll")) || (p2
= strstr (p
, "LL")))
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')))
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")))
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.
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
;
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
;
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;
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;
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
;
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
);
1441 SPEC_CVAL (val
->type
).v_long
= (TYPE_TARGET_LONG
) double2ul (dval
);
1446 if (SPEC_USIGN (val
->type
))
1448 SPEC_CVAL (val
->type
).v_uint
= (TYPE_TARGET_UINT
) double2ul (dval
);
1452 SPEC_CVAL (val
->type
).v_int
= (TYPE_TARGET_INT
) double2ul (dval
);
1459 /*-----------------------------------------------------------------*/
1460 /* constCharacterVal - converts a character constant to value */
1461 /*-----------------------------------------------------------------*/
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;
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
;
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
;
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
;
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
;
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
);
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
;
1517 /*-----------------------------------------------------------------*/
1518 /* constCharVal - converts a character constant to value */
1519 /*-----------------------------------------------------------------*/
1521 constCharVal (unsigned char v
)
1523 return constCharacterVal (v
, 0);
1526 /*-----------------------------------------------------------------*/
1527 /* constBoolVal - converts a BOOL constant to value */
1528 /*-----------------------------------------------------------------*/
1530 constBoolVal (bool v
, bool 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
;
1546 return constIntVal (v
? "1" : "0");
1550 /*-----------------------------------------------------------------*/
1551 /* constNullptrVal - a value of C23 nullptr_t */
1552 /*-----------------------------------------------------------------*/
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;
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
;
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));
1582 allocated
= *utf_32_len
+ 16;
1585 first_byte
= *utf_8
;
1587 if (first_byte
& 0x80)
1589 while (first_byte
& (0x80 >> 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
;
1600 for(; seqlen
; seqlen
--)
1603 codepoint
|= (*utf_8
& 0x3f);
1608 utf_32
[*utf_32_len
] = codepoint
;
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));
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
;
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;
1648 /*------------------------------------------------------------------*/
1649 /* strVal - converts a string constant to a value */
1650 /*------------------------------------------------------------------*/
1652 strVal (const char *s
)
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;
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
;
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
);
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
);
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
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
;
1721 /*------------------------------------------------------------------*/
1722 /* rawStrVal - converts a string to a value */
1723 /*------------------------------------------------------------------*/
1725 rawStrVal (const char *s
, size_t size
)
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
;
1749 /*------------------------------------------------------------------*/
1750 /* reverseValWithType - reverses value chain with type & etype */
1751 /*------------------------------------------------------------------*/
1753 reverseValWithType (value
* val
)
1761 /* save the type * etype chains */
1765 /* set the current one 2b null */
1766 val
->type
= val
->etype
= NULL
;
1767 val
= reverseVal (val
);
1769 /* restore type & etype */
1776 /*------------------------------------------------------------------*/
1777 /* reverseVal - reverses the values for a value chain */
1778 /*------------------------------------------------------------------*/
1780 reverseVal (value
* val
)
1782 value
*prev
, *curr
, *next
;
1797 val
->next
= (void *) NULL
;
1801 /*------------------------------------------------------------------*/
1802 /* copyValueChain - will copy a chain of values */
1803 /*------------------------------------------------------------------*/
1805 copyValueChain (value
* src
)
1812 dest
= copyValue (src
);
1813 dest
->next
= copyValueChain (src
->next
);
1818 /*------------------------------------------------------------------*/
1819 /* copyValue - copies contents of a value to a fresh one */
1820 /*------------------------------------------------------------------*/
1822 copyValue (value
* src
)
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
);
1835 /*------------------------------------------------------------------*/
1836 /* charVal - converts a character constant to a value */
1837 /*------------------------------------------------------------------*/
1839 charVal (const char *s
)
1843 if ((s
[0] == 'L' || s
[0] == 'u' || s
[0] == 'U') && s
[1] == '\'')
1845 else if (s
[0] == 'u' && s
[1] == '8' && s
[2] == '\'')
1848 werror (E_U8_CHAR_INVALID
);
1855 s
++; // Get rid of quotation.
1857 /* if \ then special processing */
1860 switch (*++s
) /* go beyond the backslash */
1863 return constCharacterVal ('\n', type
);
1865 return constCharacterVal ('\t', type
);
1867 return constCharacterVal ('\v', type
);
1869 return constCharacterVal ('\b', type
);
1871 return constCharacterVal ('\r', type
);
1873 return constCharacterVal ('\f', type
);
1875 return constCharacterVal ('\a', type
);
1877 return constCharacterVal ('\\', type
);
1879 return constCharacterVal ('\?', type
);
1881 return constCharacterVal ('\'', type
);
1883 return constCharacterVal ('\"', type
);
1893 return constCharacterVal (octalEscape (&s
), type
);
1896 return constCharacterVal (hexEscape (&s
), type
);
1899 return constCharacterVal (universalEscape (&s
, 4), type
);
1902 return constCharacterVal (universalEscape (&s
, 8), type
);
1905 return constCharacterVal (*s
, type
);
1908 else if (type
) // Wide character constant
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
);
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 /*------------------------------------------------------------------*/
1924 valFromType (sym_link
* type
)
1926 value
*val
= newValue ();
1927 val
->type
= copyLinkChain (type
);
1928 val
->etype
= getSpec (val
->type
);
1932 /*------------------------------------------------------------------*/
1933 /* floatFromVal - value to double float conversion */
1934 /*------------------------------------------------------------------*/
1936 floatFromVal (value
* val
)
1941 if (val
->etype
&& SPEC_SCLS (val
->etype
) != S_LITERAL
)
1943 werror (E_CONST_EXPECTED
, val
->name
);
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
;
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
;
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
;
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
;
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
;
2000 werror (E_INTERNAL_ERROR
, __FILE__
, __LINE__
, "floatFromVal: unknown value");
2004 /*------------------------------------------------------------------*/
2005 /* ulFromVal - value to unsigned long conversion */
2006 /*------------------------------------------------------------------*/
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 /*------------------------------------------------------------------*/
2020 byteOfVal (value
*val
, int offset
)
2023 int shift
= 8*offset
;
2025 wassert (offset
>= 0);
2030 if (val
->etype
&& SPEC_SCLS (val
->etype
) != S_LITERAL
)
2032 werror (E_CONST_EXPECTED
, val
->name
);
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
;
2048 p
= (unsigned char *)&f
;
2049 #ifdef WORDS_BIGENDIAN
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;
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;
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;
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;
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;
2100 werror (E_INTERNAL_ERROR
, __FILE__
, __LINE__
, "byteOfVal: unknown value");
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
);
2115 if (etype
&& SPEC_SCLS (etype
) != S_LITERAL
)
2117 werror (E_CONST_EXPECTED
, "");
2121 /* if it is not a specifier then we can assume that */
2122 /* it will be an unsigned long */
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
;
2137 return SPEC_CVAL (etype
).v_longlong
;
2140 if (SPEC_LONG (etype
))
2142 if (SPEC_USIGN (etype
))
2143 return SPEC_CVAL (etype
).v_ulong
;
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
;
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
;
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
;
2174 werror (E_INTERNAL_ERROR
, __FILE__
, __LINE__
, "ullFromLit: unknown value");
2178 /*------------------------------------------------------------------*/
2179 /* ullFromVal - value to unsigned long long conversion */
2180 /*------------------------------------------------------------------*/
2182 ullFromVal (const value
* val
)
2187 if (val
->etype
&& SPEC_SCLS (val
->etype
) != S_LITERAL
)
2189 werror (E_CONST_EXPECTED
, val
->name
);
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
;
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
;
2221 *csd_add
|= (1ull << bit
);
2223 *csd_sub
|= (1ull << bit
);
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 /*-----------------------------------------------------------------*/
2254 doubleFromFixed16x16 (TYPE_TARGET_ULONG value
)
2257 /* This version is incorrect negative values. */
2258 double tmp
= 0, exp
= 2;
2260 tmp
= (value
& 0xffff0000) >> 16;
2273 return ((double) (value
* 1.0) / (double) (1UL << 16));
2278 fixed16x16FromDouble (double value
)
2281 /* This version is incorrect negative values. */
2282 unsigned int tmp
= 0, pos
= 16;
2283 TYPE_TARGET_ULONG res
;
2285 tmp
= floor (value
);
2295 value
-= floor (value
);
2302 return double2ul (value
* (double) (1UL << 16));
2306 /*------------------------------------------------------------------*/
2307 /* valUnaryPM - does the unary +/- operation on a constant */
2308 /*------------------------------------------------------------------*/
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
;
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
;
2329 SPEC_CVAL (val
->etype
).v_long
= -SPEC_CVAL (val
->etype
).v_long
;
2333 if (SPEC_USIGN (val
->etype
))
2334 SPEC_CVAL (val
->etype
).v_uint
= 0 - SPEC_CVAL (val
->etype
).v_uint
;
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
;
2345 return cheapestVal (val
);
2350 /*------------------------------------------------------------------*/
2351 /* valueComplement - complements a constant */
2352 /*------------------------------------------------------------------*/
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
;
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
;
2369 SPEC_CVAL (val
->etype
).v_long
= ~SPEC_CVAL (val
->etype
).v_long
;
2373 if (SPEC_USIGN (val
->etype
))
2374 SPEC_CVAL (val
->etype
).v_uint
= ~SPEC_CVAL (val
->etype
).v_uint
;
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
;
2385 return cheapestVal (val
);
2390 /*------------------------------------------------------------------*/
2391 /* valueNot - complements a constant */
2392 /*------------------------------------------------------------------*/
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
;
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
;
2409 SPEC_CVAL (val
->etype
).v_int
= !SPEC_CVAL (val
->etype
).v_long
;
2413 if (SPEC_USIGN (val
->etype
))
2414 SPEC_CVAL (val
->etype
).v_int
= !SPEC_CVAL (val
->etype
).v_uint
;
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' */
2424 SPEC_USIGN (val
->etype
) = 1;
2425 SPEC_NOUN (val
->etype
) = V_CHAR
;
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;
2438 /*------------------------------------------------------------------*/
2439 /* valMult - multiply constants */
2440 /*------------------------------------------------------------------*/
2442 valMult (value
* lval
, value
* rval
, bool reduceType
)
2446 /* create a new value */
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
)
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
)
2484 return reduceType
? cheapestVal (val
) : val
;
2487 /*------------------------------------------------------------------*/
2488 /* valDiv - Divide constants */
2489 /*------------------------------------------------------------------*/
2491 valDiv (value
* lval
, value
* rval
, bool reduceType
)
2495 if (isEqualVal (rval
, 0) && !IS_FLOAT (computeType (lval
->etype
, rval
->etype
, RESULT_TYPE_INT
, '/')))
2497 werror (E_DIVIDE_BY_ZERO
);
2501 /* create a new value */
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
)));
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
);
2526 SPEC_CVAL (val
->type
).v_long
= (TYPE_TARGET_LONG
) ulFromVal (lval
) / (TYPE_TARGET_LONG
) ulFromVal (rval
);
2530 if (SPEC_USIGN (val
->type
))
2531 SPEC_CVAL (val
->type
).v_uint
= (TYPE_TARGET_UINT
) ulFromVal (lval
) / (TYPE_TARGET_UINT
) ulFromVal (rval
);
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 /*------------------------------------------------------------------*/
2542 valMod (value
* lval
, value
* rval
, bool reduceType
)
2546 if (isEqualVal (rval
, 0))
2548 werror (E_DIVIDE_BY_ZERO
);
2552 /* create a new value */
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
)));
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
);
2573 SPEC_CVAL (val
->type
).v_long
= (TYPE_TARGET_LONG
) ulFromVal (lval
) % (TYPE_TARGET_LONG
) ulFromVal (rval
);
2577 if (SPEC_USIGN (val
->type
))
2578 SPEC_CVAL (val
->type
).v_uint
= (TYPE_TARGET_UINT
) ulFromVal (lval
) % (TYPE_TARGET_UINT
) ulFromVal (rval
);
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 /*------------------------------------------------------------------*/
2589 valZeroResultFromOp (sym_link
* type1
, sym_link
* type2
, int op
, bool reduceType
)
2594 printf("valZeroResultFromOp %d ", op
); printTypeChain (type1
, stdout
); printf (" vs. "); printTypeChain (type2
, 0);
2597 /* create a new value */
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;
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;
2627 SPEC_CVAL (val
->type
).v_long
= 0;
2631 if (SPEC_USIGN (val
->type
))
2632 SPEC_CVAL (val
->type
).v_uint
= 0;
2634 SPEC_CVAL (val
->type
).v_int
= 0;
2636 return reduceType
? cheapestVal (val
) : val
;
2639 /*------------------------------------------------------------------*/
2640 /* valPlus - Addition constants */
2641 /*------------------------------------------------------------------*/
2643 valPlus (value
* lval
, value
* rval
, bool reduceType
)
2647 /* create a new value */
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
)));
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
));
2675 SPEC_CVAL (val
->type
).v_long
= (TYPE_TARGET_LONG
)(ulFromVal (lval
) + ulFromVal (rval
));
2679 if (SPEC_USIGN (val
->type
))
2680 SPEC_CVAL (val
->type
).v_uint
= (TYPE_TARGET_UINT
)(ulFromVal (lval
) + ulFromVal (rval
));
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 /*------------------------------------------------------------------*/
2691 valMinus (value
* lval
, value
* rval
, bool reduceType
)
2695 /* create a new value */
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
)));
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
);
2723 SPEC_CVAL (val
->type
).v_long
= (TYPE_TARGET_LONG
) ulFromVal (lval
) - (TYPE_TARGET_LONG
) ulFromVal (rval
);
2727 if (SPEC_USIGN (val
->type
))
2728 SPEC_CVAL (val
->type
).v_uint
= (TYPE_TARGET_UINT
) ulFromVal (lval
) - (TYPE_TARGET_UINT
) ulFromVal (rval
);
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 /*------------------------------------------------------------------*/
2739 valShift (value
* lval
, value
* rval
, int lr
, bool reduceType
)
2743 /* create a new value */
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
) &&
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
)));
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
);
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
);
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
);
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 /*------------------------------------------------------------------*/
2812 valCompare (value
* lval
, value
* rval
, int ctype
, bool reduceType
)
2816 /* create a new value */
2818 val
->type
= val
->etype
= newCharLink ();
2819 val
->type
->xclass
= SPECIFIER
;
2820 SPEC_SCLS (val
->type
) = S_LITERAL
; /* will remain literal */
2824 SPEC_NOUN (val
->type
) = V_CHAR
; /* type is char */
2825 SPEC_USIGN (val
->type
) = 1;
2829 SPEC_NOUN (val
->type
) = V_INT
;
2830 SPEC_USIGN (val
->type
) = 0;
2835 /* FIXME: need to add long long support to inequalities */
2837 SPEC_CVAL (val
->type
).v_int
= floatFromVal (lval
) < floatFromVal (rval
);
2841 SPEC_CVAL (val
->type
).v_int
= floatFromVal (lval
) > floatFromVal (rval
);
2845 SPEC_CVAL (val
->type
).v_int
= floatFromVal (lval
) <= floatFromVal (rval
);
2849 SPEC_CVAL (val
->type
).v_int
= floatFromVal (lval
) >= floatFromVal (rval
);
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
);
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
;
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
);
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
;
2926 /*------------------------------------------------------------------*/
2927 /* valBitwise - Bitwise operation */
2928 /*------------------------------------------------------------------*/
2930 valBitwise (value
* lval
, value
* rval
, int op
, bool reduceType
)
2934 /* create a new value */
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
;
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
);
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
);
2955 SPEC_CVAL (val
->type
).v_long
= (TYPE_TARGET_LONG
) ulFromVal (lval
) & (TYPE_TARGET_LONG
) ulFromVal (rval
);
2959 if (SPEC_USIGN (val
->type
))
2960 SPEC_CVAL (val
->type
).v_uint
= (TYPE_TARGET_UINT
) ulFromVal (lval
) & (TYPE_TARGET_UINT
) ulFromVal (rval
);
2962 SPEC_CVAL (val
->type
).v_int
= (TYPE_TARGET_INT
) ulFromVal (lval
) & (TYPE_TARGET_INT
) ulFromVal (rval
);
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
);
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
);
2979 SPEC_CVAL (val
->type
).v_long
= (TYPE_TARGET_LONG
) ulFromVal (lval
) | (TYPE_TARGET_LONG
) ulFromVal (rval
);
2983 if (SPEC_USIGN (val
->type
))
2984 SPEC_CVAL (val
->type
).v_uint
= (TYPE_TARGET_UINT
) ulFromVal (lval
) | (TYPE_TARGET_UINT
) ulFromVal (rval
);
2986 SPEC_CVAL (val
->type
).v_int
= (TYPE_TARGET_INT
) ulFromVal (lval
) | (TYPE_TARGET_INT
) ulFromVal (rval
);
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
);
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
);
3004 SPEC_CVAL (val
->type
).v_long
= (TYPE_TARGET_LONG
) ulFromVal (lval
) ^ (TYPE_TARGET_LONG
) ulFromVal (rval
);
3008 if (SPEC_USIGN (val
->type
))
3009 SPEC_CVAL (val
->type
).v_uint
= (TYPE_TARGET_UINT
) ulFromVal (lval
) ^ (TYPE_TARGET_UINT
) ulFromVal (rval
);
3011 SPEC_CVAL (val
->type
).v_int
= (TYPE_TARGET_INT
) ulFromVal (lval
) ^ (TYPE_TARGET_INT
) ulFromVal (rval
);
3016 return reduceType
? cheapestVal (val
) : val
;
3019 /*------------------------------------------------------------------*/
3020 /* valAndOr - Generates code for and / or operation */
3021 /*------------------------------------------------------------------*/
3023 valLogicAndOr (value
* lval
, value
* rval
, int op
, bool reduceType
)
3027 /* create a new value */
3029 val
->type
= val
->etype
= newCharLink ();
3030 val
->type
->xclass
= SPECIFIER
;
3031 SPEC_SCLS (val
->type
) = S_LITERAL
; /* will remain literal */
3034 SPEC_USIGN (val
->type
) = 1;
3037 SPEC_NOUN (val
->type
) = V_INT
;
3038 SPEC_USIGN (val
->type
) = 0;
3044 SPEC_CVAL (val
->type
).v_int
= !isEqualVal (lval
, 0) && !isEqualVal (rval
, 0);
3048 SPEC_CVAL (val
->type
).v_int
= !isEqualVal (lval
, 0) || !isEqualVal (rval
, 0);
3055 /*------------------------------------------------------------------*/
3056 /* valCastLiteral - casts a literal value to another type */
3057 /*------------------------------------------------------------------*/
3059 valCastLiteral (sym_link
*dtype
, double fval
, TYPE_TARGET_ULONGLONG llval
)
3062 unsigned long l
= double2ul (fval
);
3066 if ((fval
> 0x7ffffffful
) || (-fval
> 0x7ffffffful
))
3067 l
= (unsigned long)llval
;
3070 printf("valCastLiteral: %llx to ", (unsigned long long)llval
); printTypeChain (dtype
, stdout
); printf("\n");
3075 val
->etype
= getSpec (val
->type
= copyLinkChain (dtype
));
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
;
3091 switch (SPEC_NOUN (val
->etype
))
3094 SPEC_CVAL (val
->etype
).v_float
= fval
;
3098 SPEC_CVAL (val
->etype
).v_fixed16x16
= fixed16x16FromDouble (fval
);
3104 SPEC_CVAL (val
->etype
).v_uint
= fval
? 1 : 0;
3107 case V_BITINTBITFIELD
:
3108 llval
&= (0xffffffffffffffffull
>> (64 - SPEC_BLEN (val
->etype
)));
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
)));
3116 llval
&= (0xffffffffffffffffull
>> (64 - SPEC_BITINTWIDTH (val
->etype
) + 1));
3117 SPEC_CVAL (val
->etype
).v_longlong
= llval
;
3121 llval
&= (0xffffffffffffffffull
>> (64 - SPEC_BITINTWIDTH (val
->etype
)));
3122 SPEC_CVAL (val
->etype
).v_ulonglong
= llval
;
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
;
3131 SPEC_CVAL (val
->etype
).v_longlong
= (TYPE_TARGET_INT
) llval
;
3135 if (SPEC_USIGN (val
->etype
))
3136 SPEC_CVAL (val
->etype
).v_uint
= (TYPE_TARGET_UCHAR
) l
;
3138 SPEC_CVAL (val
->etype
).v_int
= (TYPE_TARGET_CHAR
) l
;
3142 if (SPEC_LONGLONG (val
->etype
))
3144 if (SPEC_USIGN (val
->etype
))
3145 SPEC_CVAL (val
->etype
).v_ulonglong
= (TYPE_TARGET_ULONGLONG
) llval
;
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
;
3154 SPEC_CVAL (val
->etype
).v_long
= (TYPE_TARGET_LONG
) l
;
3158 if (SPEC_USIGN (val
->etype
))
3159 SPEC_CVAL (val
->etype
).v_uint
= (TYPE_TARGET_UINT
) l
;
3161 SPEC_CVAL (val
->etype
).v_int
= (TYPE_TARGET_INT
) l
;
3168 /*-------------------------------------------------------------------*/
3169 /* valRecastLitVal - changes type of a literal value to another type */
3170 /*-------------------------------------------------------------------*/
3172 valRecastLitVal (sym_link
* dtype
, value
* val
)
3174 sym_link
* otype
= val
->type
;
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
;
3185 ull
= (TYPE_TARGET_ULONGLONG
) ullFromVal (val
);
3190 val
->etype
= getSpec (val
->type
= copyLinkChain (dtype
));
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
;
3206 switch (SPEC_NOUN (val
->etype
))
3209 SPEC_CVAL (val
->etype
).v_float
= fval
;
3213 SPEC_CVAL (val
->etype
).v_fixed16x16
= fixed16x16FromDouble (fval
);
3219 SPEC_CVAL (val
->etype
).v_uint
= fval
? 1 : 0;
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
;
3228 SPEC_CVAL (val
->etype
).v_longlong
= (TYPE_TARGET_LONGLONG
) ull
;
3232 if (SPEC_USIGN (val
->etype
))
3233 SPEC_CVAL (val
->etype
).v_uint
= (TYPE_TARGET_UCHAR
) ull
;
3235 SPEC_CVAL (val
->etype
).v_int
= (TYPE_TARGET_CHAR
) ull
;
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
;
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
;
3251 SPEC_CVAL (val
->etype
).v_long
= (TYPE_TARGET_LONG
) ull
;
3255 if (SPEC_USIGN (val
->etype
))
3256 SPEC_CVAL (val
->etype
).v_uint
= (TYPE_TARGET_UINT
) ull
;
3258 SPEC_CVAL (val
->etype
).v_int
= (TYPE_TARGET_INT
) ull
;
3265 /*------------------------------------------------------------------*/
3266 /* getNelements - determines # of elements from init list */
3267 /*------------------------------------------------------------------*/
3269 getNelements (sym_link
* type
, initList
* ilist
)
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
);
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
);
3306 i
= ilist
->designation
->designator
.elemno
;
3311 size
= i
+ 1; /* array size is one larger than array init element */
3314 ilist
= ilist
->next
;
3319 /*-----------------------------------------------------------------*/
3320 /* valForArray - returns a value with name of array index */
3321 /*-----------------------------------------------------------------*/
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
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
);
3346 else if (!IS_AST_SYM_VALUE (arrExpr
->left
))
3349 if (!IS_AST_LIT_VALUE (arrExpr
->right
))
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
));
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
));
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
;
3380 DCL_TYPE (val
->type
) = POINTER
;
3383 val
->type
->next
= arrExpr
->left
->ftype
->next
;
3384 val
->etype
= getSpec (val
->type
);
3388 /*-----------------------------------------------------------------*/
3389 /* valForStructElem - returns value with name of struct element */
3390 /*-----------------------------------------------------------------*/
3392 valForStructElem (ast
* structT
, ast
* elemT
)
3394 value
*val
, *lval
= 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
;
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
;
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
);
3442 if (!IS_AST_SYM_VALUE (elemT
))
3445 if (!structT
|| !IS_STRUCT (structT
->etype
))
3448 if ((sym
= getStructElement (SPEC_STRUCT (structT
->etype
), AST_SYMBOL (elemT
))) == NULL
)
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
));
3462 SNPRINTF (val
->name
, sizeof (val
->name
), "(%s + %d)", lval
->name
, (int) sym
->offset
);
3463 memcpy (val
->type
, lval
->type
, sizeof (sym_link
));
3468 SNPRINTF (val
->name
, sizeof (val
->name
), "(%s + (%d))", AST_SYMBOL (sast
)->rname
, ((int) sym
->offset
) + idxoff
);
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
;
3483 DCL_TYPE (val
->type
) = POINTER
;
3486 val
->type
->next
= sym
->type
;
3487 val
->etype
= getSpec (val
->type
);
3491 /*-----------------------------------------------------------------*/
3492 /* valForCastAggr - will return value for a cast of an aggregate */
3493 /* plus minus a constant */
3494 /*-----------------------------------------------------------------*/
3496 valForCastAggr (ast
* aexpr
, sym_link
* type
, ast
* cnst
, int op
)
3500 if (!IS_AST_SYM_VALUE (aexpr
))
3502 if (!IS_AST_LIT_VALUE (cnst
))
3507 SNPRINTF (val
->name
, sizeof (val
->name
), "(%s %c %d)",
3508 AST_SYMBOL (aexpr
)->rname
, op
, getSize (type
->next
) * AST_ULONG_VALUE (cnst
));
3511 val
->etype
= getSpec (val
->type
);
3515 /*-----------------------------------------------------------------*/
3516 /* valForCastArr - will return value for a cast of an aggregate */
3517 /* with no constant */
3518 /*-----------------------------------------------------------------*/
3520 valForCastArr (ast
* aexpr
, sym_link
* type
)
3524 if (!IS_AST_SYM_VALUE (aexpr
))
3529 SNPRINTF (val
->name
, sizeof (val
->name
), "(%s)", AST_SYMBOL (aexpr
)->rname
);
3532 val
->etype
= getSpec (val
->type
);