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 -------------------------------------------------------------------------*/
35 /*-----------------------------------------------------------------*/
36 /* newValue - allocates and returns a new value */
37 /*-----------------------------------------------------------------*/
43 val = Safe_alloc (sizeof (value));
48 /*-----------------------------------------------------------------*/
49 /* newiList - new initializer list */
50 /*-----------------------------------------------------------------*/
52 newiList (int type, void *ilist)
57 nilist = Safe_alloc (sizeof (initList));
60 nilist->lineno = lexLineno;
61 nilist->filename = lexFilename;
66 nilist->init.node = (struct ast *) ilist;
70 nilist->init.deep = (struct initList *) ilist;
77 /*------------------------------------------------------------------*/
78 /* revinit - reverses the initial values for a value chain */
79 /*------------------------------------------------------------------*/
81 revinit (initList * val)
83 initList *prev, *curr, *next;
98 val->next = (void *) NULL;
103 convertIListToConstList(initList *src, literalList **lList)
106 literalList *head, *last, *newL;
110 if (!src || src->type != INIT_DEEP)
115 iLoop = src->init.deep;
119 if (iLoop->type != INIT_NODE)
124 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_TYPE_NONE)))
131 // We've now established that the initializer list contains only literal values.
133 iLoop = src->init.deep;
136 double val = AST_LIT_VALUE(iLoop->init.node);
138 if (last && last->literalValue == val)
144 newL = Safe_alloc(sizeof(literalList));
145 newL->literalValue = val;
172 copyLiteralList(literalList *src)
174 literalList *head, *prev, *newL;
180 newL = Safe_alloc(sizeof(literalList));
182 newL->literalValue = src->literalValue;
183 newL->count = src->count;
203 /*------------------------------------------------------------------*/
204 /* copyIlist - copy initializer list */
205 /*------------------------------------------------------------------*/
207 copyIlist (initList * src)
209 initList *dest = NULL;
217 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
220 dest = newiList (INIT_NODE, copyAst (src->init.node));
225 dest->next = copyIlist (src->next);
230 /*------------------------------------------------------------------*/
231 /* list2int - converts the first element of the list to value */
232 /*------------------------------------------------------------------*/
234 list2int (initList * val)
238 if (i->type == INIT_DEEP)
239 return list2int (val->init.deep);
241 return floatFromVal (constExprValue (val->init.node, TRUE));
244 /*------------------------------------------------------------------*/
245 /* list2val - converts the first element of the list to value */
246 /*------------------------------------------------------------------*/
248 list2val (initList * val)
253 if (val->type == INIT_DEEP)
254 return list2val (val->init.deep);
256 return constExprValue (val->init.node, TRUE);
259 /*------------------------------------------------------------------*/
260 /* list2expr - returns the first expression in the initializer list */
261 /*------------------------------------------------------------------*/
263 list2expr (initList * ilist)
265 if (ilist->type == INIT_DEEP)
266 return list2expr (ilist->init.deep);
267 return ilist->init.node;
270 /*------------------------------------------------------------------*/
271 /* resolveIvalSym - resolve symbols in initial values */
272 /*------------------------------------------------------------------*/
274 resolveIvalSym (initList * ilist, sym_link * type)
276 int is_ptr = IS_PTR (type);
277 RESULT_TYPE resultType = getResultTypeFromType (getSpec (type));
281 if (ilist->type == INIT_NODE)
283 ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
284 is_ptr ? RESULT_TYPE_INT : resultType);
286 else if (ilist->type == INIT_DEEP)
288 resolveIvalSym (ilist->init.deep, type);
295 /*------------------------------------------------------------------*/
296 /* symbolVal - creates a value for a symbol */
297 /*------------------------------------------------------------------*/
299 symbolVal (symbol * sym)
311 val->type = sym->type;
312 val->etype = getSpec (val->type);
317 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
321 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
327 /*--------------------------------------------------------------------*/
328 /* cheapestVal - try to reduce 'signed int' to 'char' */
329 /*--------------------------------------------------------------------*/
331 cheapestVal (value *val)
333 /* only int can be reduced */
334 if (!IS_INT(val->type))
337 /* long must not be changed */
338 if (SPEC_LONG(val->type))
341 /* unsigned must not be changed */
342 if (SPEC_USIGN(val->type))
345 /* the only possible reduction is from signed int to (un)signed char,
346 because it's automatically promoted back to signed int.
348 a reduction from unsigned int to unsigned char is a bug,
349 because an _unsigned_ char is promoted to _signed_ int! */
350 if (SPEC_CVAL(val->type).v_int < -128 ||
351 SPEC_CVAL(val->type).v_int > 255)
353 /* not in the range of (un)signed char */
357 SPEC_NOUN(val->type) = V_CHAR;
359 /* 'unsigned char' promotes to 'signed int', so that we can
360 reduce it the other way */
361 if (SPEC_CVAL(val->type).v_int >= 0)
363 SPEC_USIGN(val->type) = 1;
368 /*--------------------------------------------------------------------*/
369 /* checkConstantRange - check if constant fits in numeric range of */
370 /* var type in comparisons and assignments */
371 /*--------------------------------------------------------------------*/
373 checkConstantRange (sym_link *var, sym_link *lit, int op, bool exchangeLeftRight)
379 litVal = floatFromVal (valFromType (lit));
380 varBits = bitsForType (var);
387 return CCR_ALWAYS_FALSE;
389 return CCR_ALWAYS_TRUE;
391 /* special: assignment */
397 if (getenv ("SDCC_VERY_PEDANTIC"))
399 if (SPEC_USIGN (var))
401 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
410 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
411 TYPE_TARGET_LONG maxVal = 0x7fffffff >> (32 - varBits);
421 /* ignore signedness, e.g. allow everything
422 from -127...+255 for (unsigned) char */
423 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
424 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
433 if (exchangeLeftRight)
438 case '>': op = '<'; break;
439 case GE_OP: op = LE_OP; break;
440 case '<': op = '>'; break;
441 case LE_OP: op = GE_OP; break;
442 default: return CCR_ALWAYS_FALSE;
445 reType = computeType (var, lit, RESULT_TYPE_NONE, op);
447 if (SPEC_USIGN (reType))
449 /* unsigned operation */
450 TYPE_TARGET_ULONG minValP, maxValP, minValM, maxValM;
451 TYPE_TARGET_ULONG opBitsMask = 0xffffffffu >> (32 - bitsForType (reType));
453 if (SPEC_USIGN (lit) && SPEC_USIGN (var))
455 /* both operands are unsigned, this is easy */
457 maxValP = 0xffffffffu >> (32 - varBits);
458 /* there's only range, just copy it to 2nd set */
462 else if (SPEC_USIGN (var))
464 /* lit is casted from signed to unsigned, e.g.:
470 maxValP = 0xffffffffu >> (32 - varBits);
471 /* there's only one range, just copy it to 2nd set */
475 /* it's an unsigned operation */
476 if ( IS_CHAR (reType)
479 /* make signed literal unsigned and
480 limit no of bits to size of return type */
481 litVal = (TYPE_TARGET_ULONG) double2ul (litVal) & opBitsMask;
484 else /* SPEC_USIGN (lit) */
486 /* var is casted from signed to unsigned, e.g.:
491 The possible values after casting var
492 split up in two, nonconsecutive ranges:
494 minValP = 0; positive range: 0...127
496 minValM = 0xff80; negative range: -128...-1
502 maxValP = 0x7fffffffu >> (32 - varBits);
505 minValM = 0xffffffff << (varBits - 1);
506 maxValM = 0xffffffffu; /* -1 */
507 /* limit no of bits to size of return type */
508 minValM &= opBitsMask;
509 maxValM &= opBitsMask;
514 case EQ_OP: /* var == lit */
515 if ( litVal <= maxValP
516 && litVal >= minValP) /* 0 */
518 if ( litVal <= maxValM
519 && litVal >= minValM)
521 return CCR_ALWAYS_FALSE;
522 case NE_OP: /* var != lit */
523 if ( litVal <= maxValP
524 && litVal >= minValP) /* 0 */
526 if ( litVal <= maxValM
527 && litVal >= minValM)
529 return CCR_ALWAYS_TRUE;
530 case '>': /* var > lit */
531 if (litVal >= maxValM)
532 return CCR_ALWAYS_FALSE;
533 if (litVal < minValP) /* 0 */
534 return CCR_ALWAYS_TRUE;
536 case GE_OP: /* var >= lit */
537 if (litVal > maxValM)
538 return CCR_ALWAYS_FALSE;
539 if (litVal <= minValP) /* 0 */
540 return CCR_ALWAYS_TRUE;
542 case '<': /* var < lit */
543 if (litVal > maxValM)
544 return CCR_ALWAYS_TRUE;
545 if (litVal <= minValP) /* 0 */
546 return CCR_ALWAYS_FALSE;
548 case LE_OP: /* var <= lit */
549 if (litVal >= maxValM)
550 return CCR_ALWAYS_TRUE;
551 if (litVal < minValP) /* 0 */
552 return CCR_ALWAYS_FALSE;
555 return CCR_ALWAYS_FALSE;
560 /* signed operation */
561 TYPE_TARGET_LONG minVal, maxVal;
563 if (SPEC_USIGN (var))
565 /* unsigned var, but signed operation. This happens
566 when var is promoted to signed int.
567 Set actual min/max values of var. */
569 maxVal = 0xffffffff >> (32 - varBits);
574 minVal = 0xffffffff << (varBits - 1);
575 maxVal = 0x7fffffff >> (32 - varBits);
580 case EQ_OP: /* var == lit */
583 return CCR_ALWAYS_FALSE;
585 case NE_OP: /* var != lit */
588 return CCR_ALWAYS_TRUE;
590 case '>': /* var > lit */
591 if (litVal >= maxVal)
592 return CCR_ALWAYS_FALSE;
594 return CCR_ALWAYS_TRUE;
596 case GE_OP: /* var >= lit */
598 return CCR_ALWAYS_FALSE;
599 if (litVal <= minVal)
600 return CCR_ALWAYS_TRUE;
602 case '<': /* var < lit */
604 return CCR_ALWAYS_TRUE;
605 if (litVal <= minVal)
606 return CCR_ALWAYS_FALSE;
608 case LE_OP: /* var <= lit */
609 if (litVal >= maxVal)
610 return CCR_ALWAYS_TRUE;
612 return CCR_ALWAYS_FALSE;
615 return CCR_ALWAYS_FALSE;
620 /*-----------------------------------------------------------------*/
621 /* valueFromLit - creates a value from a literal */
622 /*-----------------------------------------------------------------*/
624 valueFromLit (double lit)
628 if ((((TYPE_TARGET_LONG) lit) - lit) == 0)
630 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_TARGET_LONG) lit);
631 return constVal (buffer);
634 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
635 return constFloatVal (buffer);
638 /*-----------------------------------------------------------------*/
639 /* constFloatVal - converts a FLOAT constant to value */
640 /*-----------------------------------------------------------------*/
642 constFloatVal (char *s)
644 value *val = newValue ();
648 sval = strtod(s, &p);
651 werror (E_INVALID_FLOAT_CONST, s);
652 return constVal ("0");
655 val->type = val->etype = newLink (SPECIFIER);
656 SPEC_NOUN (val->type) = V_FLOAT;
657 SPEC_SCLS (val->type) = S_LITERAL;
658 SPEC_CVAL (val->type).v_float = sval;
663 /*-----------------------------------------------------------------*/
664 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
665 /*-----------------------------------------------------------------*/
667 constFixed16x16Val (char *s)
669 value *val = newValue ();
673 sval = strtod(s, &p);
676 werror (E_INVALID_FLOAT_CONST, s);
677 return constVal ("0");
680 val->type = val->etype = newLink (SPECIFIER);
681 SPEC_NOUN (val->type) = V_FLOAT;
682 SPEC_SCLS (val->type) = S_LITERAL;
683 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
688 /*-----------------------------------------------------------------*/
689 /* constVal - converts an INTEGER constant into a cheapest value */
690 /*-----------------------------------------------------------------*/
691 value *constVal (const char *s)
694 short hex = 0, octal = 0;
697 val = newValue (); /* alloc space for value */
699 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
700 SPEC_SCLS (val->type) = S_LITERAL;
701 // let's start with a signed char
702 SPEC_NOUN (val->type) = V_CHAR;
703 SPEC_USIGN (val->type) = 0;
705 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
707 /* set the octal flag */
708 if (!hex && *s == '0' && *(s + 1))
714 sval = strtoul (s, NULL, 0);
718 werror (W_INVALID_INT_CONST, s, dval);
721 dval = strtod(s, NULL);
724 /* Setup the flags first */
725 /* set the unsigned flag if 'uU' is found */
726 if (strchr (s, 'u') || strchr (s, 'U')) {
727 SPEC_USIGN (val->type) = 1;
730 /* set the b_long flag if 'lL' is found */
731 if (strchr (s, 'l') || strchr (s, 'L')) {
732 SPEC_NOUN (val->type) = V_INT;
733 SPEC_LONG (val->type) = 1;
735 if (dval<0) { // "-28u" will still be signed and negative
736 if (dval<-128) { // check if we have to promote to int
737 SPEC_NOUN (val->type) = V_INT;
739 if (dval<-32768) { // check if we have to promote to long int
740 SPEC_LONG (val->type) = 1;
743 if (dval>0xff || /* check if we have to promote to int */
744 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
745 char. After an integral promotion it will
746 be a signed int; this certainly isn't what
747 the programer wants */
748 SPEC_NOUN (val->type) = V_INT;
750 else { /* store char's always as unsigned; this helps other optimizations */
751 SPEC_USIGN (val->type) = 1;
753 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
754 SPEC_LONG (val->type) = 1;
756 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
757 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
759 SPEC_USIGN (val->type) = 1;
761 SPEC_LONG (val->type) = 1;
762 if (dval>0x7fffffff) {
763 SPEC_USIGN (val->type) = 1;
770 /* check for out of range */
771 if (dval<-2147483648.0) {
772 dval = -2147483648.0;
773 werror (W_INVALID_INT_CONST, s, dval);
775 if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
777 werror (W_INVALID_INT_CONST, s, dval);
779 if (dval>4294967295.0) {
781 werror (W_INVALID_INT_CONST, s, dval);
784 if (SPEC_LONG (val->type))
786 if (SPEC_USIGN (val->type))
788 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) double2ul (dval);
792 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) double2ul (dval);
797 if (SPEC_USIGN (val->type))
799 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) double2ul (dval);
803 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) double2ul (dval);
810 /*------------------------------------------------------------------*/
811 /* strVal - converts a string constant to a value */
812 /*------------------------------------------------------------------*/
814 strVal (const char *s)
818 val = newValue (); /* get a new one */
820 /* get a declarator */
821 val->type = newLink (DECLARATOR);
822 DCL_TYPE (val->type) = ARRAY;
823 val->type->next = val->etype = newLink (SPECIFIER);
824 SPEC_NOUN (val->etype) = V_CHAR;
825 SPEC_SCLS (val->etype) = S_LITERAL;
827 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
828 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
834 /*------------------------------------------------------------------*/
835 /* reverseValWithType - reverses value chain with type & etype */
836 /*------------------------------------------------------------------*/
838 reverseValWithType (value * val)
846 /* save the type * etype chains */
850 /* set the current one 2b null */
851 val->type = val->etype = NULL;
852 val = reverseVal (val);
854 /* restore type & etype */
861 /*------------------------------------------------------------------*/
862 /* reverseVal - reverses the values for a value chain */
863 /*------------------------------------------------------------------*/
865 reverseVal (value * val)
867 value *prev, *curr, *next;
882 val->next = (void *) NULL;
886 /*------------------------------------------------------------------*/
887 /* copyValueChain - will copy a chain of values */
888 /*------------------------------------------------------------------*/
890 copyValueChain (value * src)
897 dest = copyValue (src);
898 dest->next = copyValueChain (src->next);
903 /*------------------------------------------------------------------*/
904 /* copyValue - copies contents of a value to a fresh one */
905 /*------------------------------------------------------------------*/
907 copyValue (value * src)
912 dest->sym = copySymbol (src->sym);
913 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
914 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
915 dest->etype = (src->type ? getSpec (dest->type) : NULL);
920 /*------------------------------------------------------------------*/
921 /* charVal - converts a character constant to a value */
922 /*------------------------------------------------------------------*/
924 charVal (const char *s)
930 val->type = val->etype = newLink (SPECIFIER);
931 SPEC_NOUN (val->type) = V_CHAR;
932 SPEC_USIGN(val->type) = 1;
933 SPEC_SCLS (val->type) = S_LITERAL;
935 s++; /* get rid of quotation */
936 /* if \ then special processing */
939 s++; /* go beyond the backslash */
943 SPEC_CVAL (val->type).v_uint = '\n';
946 SPEC_CVAL (val->type).v_uint = '\t';
949 SPEC_CVAL (val->type).v_uint = '\v';
952 SPEC_CVAL (val->type).v_uint = '\b';
955 SPEC_CVAL (val->type).v_uint = '\r';
958 SPEC_CVAL (val->type).v_uint = '\f';
961 SPEC_CVAL (val->type).v_uint = '\a';
964 SPEC_CVAL (val->type).v_uint = '\\';
967 SPEC_CVAL (val->type).v_uint = '\?';
970 SPEC_CVAL (val->type).v_uint = '\'';
973 SPEC_CVAL (val->type).v_uint = '\"';
984 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
988 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
992 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
996 else /* not a backslash */
997 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
1002 /*------------------------------------------------------------------*/
1003 /* valFromType - creates a value from type given */
1004 /*------------------------------------------------------------------*/
1006 valFromType (sym_link * type)
1008 value *val = newValue ();
1009 val->type = copyLinkChain (type);
1010 val->etype = getSpec (val->type);
1014 /*------------------------------------------------------------------*/
1015 /* floatFromVal - value to double float conversion */
1016 /*------------------------------------------------------------------*/
1019 floatFromVal (value * val)
1026 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1028 werror (E_CONST_EXPECTED, val->name);
1032 /* if it is not a specifier then we can assume that */
1033 /* it will be an unsigned long */
1034 if (!IS_SPEC (val->type)) {
1035 //return (double) SPEC_CVAL (val->etype).v_ulong;
1036 res =SPEC_CVAL (val->etype).v_ulong;
1040 if (SPEC_NOUN (val->etype) == V_FLOAT) {
1041 //return (double) SPEC_CVAL (val->etype).v_float;
1042 res =SPEC_CVAL (val->etype).v_float;
1046 if (SPEC_NOUN (val->etype) == V_FIXED16X16) {
1047 res =doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
1051 if (SPEC_LONG (val->etype))
1053 if (SPEC_USIGN (val->etype)) {
1054 //return (double) SPEC_CVAL (val->etype).v_ulong;
1055 res =SPEC_CVAL (val->etype).v_ulong;
1059 //return (double) SPEC_CVAL (val->etype).v_long;
1060 res =SPEC_CVAL (val->etype).v_long;
1065 if (SPEC_NOUN (val->etype) == V_INT) {
1066 if (SPEC_USIGN (val->etype)) {
1067 //return (double) SPEC_CVAL (val->etype).v_uint;
1068 res =SPEC_CVAL (val->etype).v_uint;
1072 //return (double) SPEC_CVAL (val->etype).v_int;
1073 res =SPEC_CVAL (val->etype).v_int;
1078 if (SPEC_NOUN (val->etype) == V_CHAR) {
1079 if (SPEC_USIGN (val->etype)) {
1080 //return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
1081 res =(unsigned char)SPEC_CVAL (val->etype).v_uint;
1086 res = (signed char)SPEC_CVAL (val->etype).v_int;
1091 if (IS_BITVAR(val->etype)) {
1092 //return (double) SPEC_CVAL (val->etype).v_uint;
1093 res =SPEC_CVAL (val->etype).v_uint;
1097 if (SPEC_NOUN (val->etype) == V_VOID) {
1098 //return (double) SPEC_CVAL (val->etype).v_ulong;
1099 res = SPEC_CVAL (val->etype).v_ulong;
1104 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1105 "floatFromVal: unknown value");
1109 printf("floatFromVal(%f)\n", res);
1115 floatFromVal (value * val)
1120 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1122 werror (E_CONST_EXPECTED, val->name);
1126 /* if it is not a specifier then we can assume that */
1127 /* it will be an unsigned long */
1128 if (!IS_SPEC (val->type))
1129 return SPEC_CVAL (val->etype).v_ulong;
1131 if (SPEC_NOUN (val->etype) == V_FLOAT)
1132 return SPEC_CVAL (val->etype).v_float;
1134 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1135 return doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
1137 if (SPEC_LONG (val->etype))
1139 if (SPEC_USIGN (val->etype))
1140 return SPEC_CVAL (val->etype).v_ulong;
1142 return SPEC_CVAL (val->etype).v_long;
1145 if (SPEC_NOUN (val->etype) == V_INT) {
1146 if (SPEC_USIGN (val->etype))
1147 return SPEC_CVAL (val->etype).v_uint;
1149 return SPEC_CVAL (val->etype).v_int;
1152 if (SPEC_NOUN (val->etype) == V_CHAR) {
1153 if (SPEC_USIGN (val->etype))
1154 return (unsigned char)SPEC_CVAL (val->etype).v_uint;
1156 return (signed char)SPEC_CVAL (val->etype).v_int;
1159 if (IS_BITVAR(val->etype))
1160 return SPEC_CVAL (val->etype).v_uint;
1162 if (SPEC_NOUN (val->etype) == V_VOID)
1163 return SPEC_CVAL (val->etype).v_ulong;
1166 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "floatFromVal: unknown value");
1170 /*------------------------------------------------------------------*/
1171 /* ulFromVal - value to unsigned long conversion */
1172 /*------------------------------------------------------------------*/
1174 ulFromVal (value * val)
1179 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1181 werror (E_CONST_EXPECTED, val->name);
1185 /* if it is not a specifier then we can assume that */
1186 /* it will be an unsigned long */
1187 if (!IS_SPEC (val->type))
1188 return SPEC_CVAL (val->etype).v_ulong;
1190 if (SPEC_NOUN (val->etype) == V_FLOAT)
1191 return double2ul (SPEC_CVAL (val->etype).v_float);
1193 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1194 return double2ul (doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 ));
1196 if (SPEC_LONG (val->etype))
1198 if (SPEC_USIGN (val->etype))
1199 return SPEC_CVAL (val->etype).v_ulong;
1201 return SPEC_CVAL (val->etype).v_long;
1204 if (SPEC_NOUN (val->etype) == V_INT) {
1205 if (SPEC_USIGN (val->etype))
1206 return SPEC_CVAL (val->etype).v_uint;
1208 return SPEC_CVAL (val->etype).v_int;
1211 if (SPEC_NOUN (val->etype) == V_CHAR) {
1212 if (SPEC_USIGN (val->etype))
1213 return (unsigned char)SPEC_CVAL (val->etype).v_uint;
1215 return (signed char)SPEC_CVAL (val->etype).v_int;
1218 if (IS_BITVAR(val->etype)) {
1219 return SPEC_CVAL (val->etype).v_uint;
1222 if (SPEC_NOUN (val->etype) == V_VOID) {
1223 return SPEC_CVAL (val->etype).v_ulong;
1227 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ulFromVal: unknown value");
1231 /*-----------------------------------------------------------------*/
1232 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
1233 /*-----------------------------------------------------------------*/
1234 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1237 /* This version is incorrect negative values. */
1238 double tmp=0, exp=2;
1240 tmp = (value & 0xffff0000) >> 16;
1244 if(value & 0x8000)tmp += 1/exp;
1251 return ((double)(value * 1.0) / (double)(1UL << 16));
1255 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1258 /* This version is incorrect negative values. */
1259 unsigned int tmp=0, pos=16;
1260 TYPE_TARGET_ULONG res;
1262 tmp = floor( value );
1269 if(value >= 1.0)tmp |= (1 << pos);
1270 value -= floor( value );
1277 return double2ul (value * (double)(1UL << 16));
1281 /*------------------------------------------------------------------*/
1282 /* valUnaryPM - does the unary +/- operation on a constant */
1283 /*------------------------------------------------------------------*/
1285 valUnaryPM (value * val)
1287 /* depending on type */
1288 if (SPEC_NOUN (val->etype) == V_FLOAT)
1289 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1290 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1291 SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
1294 if (SPEC_LONG (val->etype))
1296 if (SPEC_USIGN (val->etype))
1297 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1299 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1303 if (SPEC_USIGN (val->etype))
1304 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1306 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1308 if (SPEC_NOUN(val->etype) == V_CHAR)
1310 /* promote to 'signed int', cheapestVal() might reduce it again */
1311 SPEC_USIGN(val->etype) = 0;
1312 SPEC_NOUN(val->etype) = V_INT;
1314 return cheapestVal (val);
1320 /*------------------------------------------------------------------*/
1321 /* valueComplement - complements a constant */
1322 /*------------------------------------------------------------------*/
1324 valComplement (value * val)
1326 /* depending on type */
1327 if (SPEC_LONG (val->etype))
1329 if (SPEC_USIGN (val->etype))
1330 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1332 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1336 if (SPEC_USIGN (val->etype))
1337 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1339 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1341 if (SPEC_NOUN(val->etype) == V_CHAR)
1343 /* promote to 'signed int', cheapestVal() might reduce it again */
1344 SPEC_USIGN(val->etype) = 0;
1345 SPEC_NOUN(val->etype) = V_INT;
1347 return cheapestVal (val);
1352 /*------------------------------------------------------------------*/
1353 /* valueNot - complements a constant */
1354 /*------------------------------------------------------------------*/
1356 valNot (value * val)
1358 /* depending on type */
1359 if (SPEC_LONG (val->etype))
1361 if (SPEC_USIGN (val->etype))
1362 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1364 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1368 if (SPEC_USIGN (val->etype))
1369 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1371 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1374 /* ANSI: result type is int, value is 0 or 1 */
1375 /* sdcc will hold this in an 'unsigned char' */
1376 SPEC_USIGN(val->etype) = 1;
1377 SPEC_LONG (val->etype) = 0;
1378 SPEC_NOUN(val->etype) = V_CHAR;
1382 /*------------------------------------------------------------------*/
1383 /* valMult - multiply constants */
1384 /*------------------------------------------------------------------*/
1386 valMult (value * lval, value * rval)
1390 /* create a new value */
1392 val->type = val->etype = computeType (lval->etype,
1396 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1398 if (IS_FLOAT (val->type))
1399 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1401 if (IS_FIXED16X16 (val->type))
1402 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1403 /* signed and unsigned mul are the same, as long as the precision of the
1404 result isn't bigger than the precision of the operands. */
1405 else if (SPEC_LONG (val->type))
1406 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) *
1407 (TYPE_TARGET_ULONG) ulFromVal (rval);
1408 else if (SPEC_USIGN (val->type)) /* unsigned int */
1410 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) ulFromVal (lval) *
1411 (TYPE_TARGET_UINT) ulFromVal (rval);
1413 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1414 if (ul != (TYPE_TARGET_UINT) ul)
1417 else /* signed int */
1419 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1420 (TYPE_TARGET_INT) floatFromVal (rval);
1422 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1423 if (l != (TYPE_TARGET_INT) l)
1426 return cheapestVal (val);
1429 /*------------------------------------------------------------------*/
1430 /* valDiv - Divide constants */
1431 /*------------------------------------------------------------------*/
1433 valDiv (value * lval, value * rval)
1437 if (floatFromVal (rval) == 0)
1439 werror (E_DIVIDE_BY_ZERO);
1443 /* create a new value */
1445 val->type = val->etype = computeType (lval->etype,
1449 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1451 if (IS_FLOAT (val->type))
1452 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1454 if (IS_FIXED16X16 (val->type))
1455 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1456 else if (SPEC_LONG (val->type))
1458 if (SPEC_USIGN (val->type))
1459 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) /
1460 (TYPE_TARGET_ULONG) ulFromVal (rval);
1462 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) /
1463 (TYPE_TARGET_LONG) ulFromVal (rval);
1467 if (SPEC_USIGN (val->type))
1468 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) /
1469 (TYPE_TARGET_UINT) ulFromVal (rval);
1471 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) /
1472 (TYPE_TARGET_INT) ulFromVal (rval);
1474 return cheapestVal (val);
1477 /*------------------------------------------------------------------*/
1478 /* valMod - Modulus constants */
1479 /*------------------------------------------------------------------*/
1481 valMod (value * lval, value * rval)
1485 /* create a new value */
1487 val->type = val->etype = computeType (lval->etype,
1491 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1493 if (SPEC_LONG (val->type))
1495 if (SPEC_USIGN (val->type))
1496 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) %
1497 (TYPE_TARGET_ULONG) ulFromVal (rval);
1499 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) %
1500 (TYPE_TARGET_LONG) ulFromVal (rval);
1504 if (SPEC_USIGN (val->type))
1505 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) %
1506 (TYPE_TARGET_UINT) ulFromVal (rval);
1508 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) %
1509 (TYPE_TARGET_INT) ulFromVal (rval);
1511 return cheapestVal (val);
1514 /*------------------------------------------------------------------*/
1515 /* valPlus - Addition constants */
1516 /*------------------------------------------------------------------*/
1518 valPlus (value * lval, value * rval)
1522 /* create a new value */
1524 val->type = val->etype = computeType (lval->etype,
1528 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1530 if (IS_FLOAT (val->type))
1531 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1533 if (IS_FIXED16X16 (val->type))
1534 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1535 else if (SPEC_LONG (val->type))
1537 if (SPEC_USIGN (val->type))
1538 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) +
1539 (TYPE_TARGET_ULONG) ulFromVal (rval);
1541 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) +
1542 (TYPE_TARGET_LONG) ulFromVal (rval);
1546 if (SPEC_USIGN (val->type))
1547 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) +
1548 (TYPE_TARGET_UINT) ulFromVal (rval);
1550 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) +
1551 (TYPE_TARGET_INT) ulFromVal (rval);
1553 return cheapestVal (val);
1556 /*------------------------------------------------------------------*/
1557 /* valMinus - Addition constants */
1558 /*------------------------------------------------------------------*/
1560 valMinus (value * lval, value * rval)
1564 /* create a new value */
1566 val->type = val->etype = computeType (lval->etype,
1570 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1572 if (IS_FLOAT (val->type))
1573 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1575 if (IS_FIXED16X16 (val->type))
1576 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1577 else if (SPEC_LONG (val->type))
1579 if (SPEC_USIGN (val->type))
1580 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) -
1581 (TYPE_TARGET_ULONG) ulFromVal (rval);
1583 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) -
1584 (TYPE_TARGET_LONG) ulFromVal (rval);
1588 if (SPEC_USIGN (val->type))
1589 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) -
1590 (TYPE_TARGET_UINT) ulFromVal (rval);
1592 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) -
1593 (TYPE_TARGET_INT) ulFromVal (rval);
1595 return cheapestVal (val);
1598 /*------------------------------------------------------------------*/
1599 /* valShift - Shift left or right */
1600 /*------------------------------------------------------------------*/
1602 valShift (value * lval, value * rval, int lr)
1606 /* create a new value */
1608 val->type = val->etype = computeType (lval->etype,
1612 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1614 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) ulFromVal (rval) &&
1617 /* right shift and unsigned */
1618 (!lr && SPEC_USIGN (rval->type))))
1620 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1623 if (SPEC_LONG (val->type))
1625 if (SPEC_USIGN (val->type))
1627 SPEC_CVAL (val->type).v_ulong = lr ?
1628 (TYPE_TARGET_ULONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1629 (TYPE_TARGET_ULONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1633 SPEC_CVAL (val->type).v_long = lr ?
1634 (TYPE_TARGET_LONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1635 (TYPE_TARGET_LONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1640 if (SPEC_USIGN (val->type))
1642 SPEC_CVAL (val->type).v_uint = lr ?
1643 (TYPE_TARGET_UINT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1644 (TYPE_TARGET_UINT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1648 SPEC_CVAL (val->type).v_int = lr ?
1649 (TYPE_TARGET_INT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1650 (TYPE_TARGET_INT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1653 return cheapestVal (val);
1656 /*------------------------------------------------------------------*/
1657 /* valCompare- Compares two literal */
1658 /*------------------------------------------------------------------*/
1660 valCompare (value * lval, value * rval, int ctype)
1664 /* create a new value */
1666 val->type = val->etype = newCharLink ();
1667 val->type->class = SPECIFIER;
1668 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1669 SPEC_USIGN (val->type) = 1;
1670 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1675 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1679 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1683 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1687 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1691 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1692 SPEC_NOUN(rval->type) == V_FLOAT)
1694 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1697 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1698 SPEC_NOUN(rval->type) == V_FIXED16X16)
1700 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1704 /* integrals: ignore signedness */
1705 TYPE_TARGET_ULONG l, r;
1707 l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1708 r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1709 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1710 neccessary to strip them to 16 bit.
1711 Literals are reduced to their cheapest type, therefore left and
1712 right might have different types. It's neccessary to find a
1713 common type: int (used for char too) or long */
1714 if (!IS_LONG (lval->etype) &&
1715 !IS_LONG (rval->etype))
1717 r = (TYPE_TARGET_UINT) r;
1718 l = (TYPE_TARGET_UINT) l;
1720 SPEC_CVAL (val->type).v_int = l == r;
1724 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1725 SPEC_NOUN(rval->type) == V_FLOAT)
1727 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1730 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1731 SPEC_NOUN(rval->type) == V_FIXED16X16)
1733 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1737 /* integrals: ignore signedness */
1738 TYPE_TARGET_ULONG l, r;
1740 l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1741 r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1742 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1743 neccessary to strip them to 16 bit.
1744 Literals are reduced to their cheapest type, therefore left and
1745 right might have different types. It's neccessary to find a
1746 common type: int (used for char too) or long */
1747 if (!IS_LONG (lval->etype) &&
1748 !IS_LONG (rval->etype))
1750 r = (TYPE_TARGET_UINT) r;
1751 l = (TYPE_TARGET_UINT) l;
1753 SPEC_CVAL (val->type).v_int = l != r;
1762 /*------------------------------------------------------------------*/
1763 /* valBitwise - Bitwise operation */
1764 /*------------------------------------------------------------------*/
1766 valBitwise (value * lval, value * rval, int op)
1770 /* create a new value */
1772 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1773 val->etype = getSpec (val->type);
1774 SPEC_SCLS (val->etype) = S_LITERAL;
1779 if (SPEC_LONG (val->type))
1781 if (SPEC_USIGN (val->type))
1782 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) &
1783 (TYPE_TARGET_ULONG) ulFromVal (rval);
1785 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) &
1786 (TYPE_TARGET_LONG) ulFromVal (rval);
1790 if (SPEC_USIGN (val->type))
1791 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) &
1792 (TYPE_TARGET_UINT) ulFromVal (rval);
1794 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) &
1795 (TYPE_TARGET_INT) ulFromVal (rval);
1800 if (SPEC_LONG (val->type))
1802 if (SPEC_USIGN (val->type))
1803 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) |
1804 (TYPE_TARGET_ULONG) ulFromVal (rval);
1806 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) |
1807 (TYPE_TARGET_LONG) ulFromVal (rval);
1811 if (SPEC_USIGN (val->type))
1812 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) |
1813 (TYPE_TARGET_UINT) ulFromVal (rval);
1815 SPEC_CVAL (val->type).v_int =
1816 (TYPE_TARGET_INT) ulFromVal (lval) | (TYPE_TARGET_INT) ulFromVal (rval);
1822 if (SPEC_LONG (val->type))
1824 if (SPEC_USIGN (val->type))
1825 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) ^
1826 (TYPE_TARGET_ULONG) ulFromVal (rval);
1828 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) ^
1829 (TYPE_TARGET_LONG) ulFromVal (rval);
1833 if (SPEC_USIGN (val->type))
1834 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) ^
1835 (TYPE_TARGET_UINT) ulFromVal (rval);
1837 SPEC_CVAL (val->type).v_int =
1838 (TYPE_TARGET_INT) ulFromVal (lval) ^ (TYPE_TARGET_INT) ulFromVal (rval);
1843 return cheapestVal(val);
1846 /*------------------------------------------------------------------*/
1847 /* valAndOr - Generates code for and / or operation */
1848 /*------------------------------------------------------------------*/
1850 valLogicAndOr (value * lval, value * rval, int op)
1854 /* create a new value */
1856 val->type = val->etype = newCharLink ();
1857 val->type->class = SPECIFIER;
1858 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1859 SPEC_USIGN (val->type) = 1;
1864 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1868 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1876 /*------------------------------------------------------------------*/
1877 /* valCastLiteral - casts a literal value to another type */
1878 /*------------------------------------------------------------------*/
1881 valCastLiteral (sym_link * dtype, double fval)
1884 unsigned long l = double2ul (fval);
1891 val->etype = getSpec (val->type = copyLinkChain (dtype));
1894 val->etype = val->type = newLink (SPECIFIER);
1895 SPEC_NOUN (val->etype) = V_VOID;
1897 SPEC_SCLS (val->etype) = S_LITERAL;
1899 /* if it is not a specifier then we can assume that */
1900 /* it will be an unsigned long */
1901 if (!IS_SPEC (val->type)) {
1902 SPEC_CVAL (val->etype).v_ulong = l;
1906 if (SPEC_NOUN (val->etype) == V_FLOAT)
1907 SPEC_CVAL (val->etype).v_float = fval;
1908 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1909 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1910 else if (SPEC_NOUN (val->etype) == V_BIT ||
1911 SPEC_NOUN (val->etype) == V_SBIT)
1912 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1913 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1914 SPEC_CVAL (val->etype).v_uint = l &
1915 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1916 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1917 if (SPEC_USIGN (val->etype))
1918 SPEC_CVAL (val->etype).v_uint= (TYPE_TARGET_UCHAR) l;
1920 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
1922 if (SPEC_LONG (val->etype)) {
1923 if (SPEC_USIGN (val->etype))
1924 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1926 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1928 if (SPEC_USIGN (val->etype))
1929 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
1931 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
1939 valCastLiteral (sym_link * dtype, double fval)
1942 unsigned long l = double2ul (fval);
1949 val->etype = getSpec (val->type = copyLinkChain (dtype));
1952 val->etype = val->type = newLink (SPECIFIER);
1953 SPEC_NOUN (val->etype) = V_VOID;
1955 SPEC_SCLS (val->etype) = S_LITERAL;
1957 /* if it is not a specifier then we can assume that */
1958 /* it will be an unsigned long */
1959 if (!IS_SPEC (val->type))
1961 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1965 switch (SPEC_NOUN (val->etype))
1968 SPEC_CVAL (val->etype).v_float = fval;
1972 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
1977 SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
1981 SPEC_CVAL (val->etype).v_uint = ((TYPE_TARGET_UINT) l) &
1982 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1986 if (SPEC_USIGN (val->etype))
1987 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) l;
1989 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
1993 if (SPEC_LONG (val->etype))
1995 if (SPEC_USIGN (val->etype))
1996 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1998 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
2002 if (SPEC_USIGN (val->etype))
2003 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
2005 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
2012 /*------------------------------------------------------------------*/
2013 /* getNelements - determines # of elements from init list */
2014 /*------------------------------------------------------------------*/
2016 getNelements (sym_link * type, initList * ilist)
2023 if (ilist->type == INIT_DEEP)
2024 ilist = ilist->init.deep;
2026 /* if type is a character array and there is only one
2027 (string) initialiser then get the length of the string */
2028 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
2030 ast *iast = ilist->init.node;
2031 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
2034 werror (E_CONST_EXPECTED);
2038 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
2039 // yep, it's a string
2041 return DCL_ELEM (v->type);
2049 ilist = ilist->next;
2054 /*-----------------------------------------------------------------*/
2055 /* valForArray - returns a value with name of array index */
2056 /*-----------------------------------------------------------------*/
2058 valForArray (ast * arrExpr)
2060 value *val, *lval = NULL;
2062 int size = getSize (arrExpr->left->ftype->next);
2063 /* if the right or left is an array
2065 if (IS_AST_OP (arrExpr->left))
2067 if (arrExpr->left->opval.op == '[')
2068 lval = valForArray (arrExpr->left);
2069 else if (arrExpr->left->opval.op == '.')
2070 lval = valForStructElem (arrExpr->left->left,
2071 arrExpr->left->right);
2072 else if (arrExpr->left->opval.op == PTR_OP &&
2073 IS_ADDRESS_OF_OP (arrExpr->left->left))
2074 lval = valForStructElem (arrExpr->left->left->left,
2075 arrExpr->left->right);
2080 else if (!IS_AST_SYM_VALUE (arrExpr->left))
2083 if (!IS_AST_LIT_VALUE (arrExpr->right))
2089 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
2093 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2096 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2097 (int) AST_LIT_VALUE (arrExpr->right) * size);
2099 val->type = newLink (DECLARATOR);
2100 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
2101 DCL_TYPE (val->type) = CPOINTER;
2102 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
2103 DCL_TYPE (val->type) = FPOINTER;
2104 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
2105 DCL_TYPE (val->type) = PPOINTER;
2106 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
2107 DCL_TYPE (val->type) = IPOINTER;
2108 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
2109 DCL_TYPE (val->type) = EEPPOINTER;
2111 DCL_TYPE (val->type) = POINTER;
2112 val->type->next = arrExpr->left->ftype->next;
2113 val->etype = getSpec (val->type);
2117 /*-----------------------------------------------------------------*/
2118 /* valForStructElem - returns value with name of struct element */
2119 /*-----------------------------------------------------------------*/
2121 valForStructElem (ast * structT, ast * elemT)
2123 value *val, *lval = NULL;
2127 /* left could be furthur derefed */
2128 if (IS_AST_OP (structT))
2130 if (structT->opval.op == '[')
2131 lval = valForArray (structT);
2132 else if (structT->opval.op == '.')
2133 lval = valForStructElem (structT->left, structT->right);
2134 else if (structT->opval.op == PTR_OP &&
2135 IS_ADDRESS_OF_OP (structT->left))
2136 lval = valForStructElem (structT->left->left,
2142 if (!IS_AST_SYM_VALUE (elemT))
2145 if (!IS_STRUCT (structT->etype))
2148 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
2149 AST_SYMBOL (elemT))) == NULL)
2157 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
2161 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2164 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2167 val->type = newLink (DECLARATOR);
2168 if (SPEC_SCLS (structT->etype) == S_CODE)
2169 DCL_TYPE (val->type) = CPOINTER;
2170 else if (SPEC_SCLS (structT->etype) == S_XDATA)
2171 DCL_TYPE (val->type) = FPOINTER;
2172 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
2173 DCL_TYPE (val->type) = PPOINTER;
2174 else if (SPEC_SCLS (structT->etype) == S_IDATA)
2175 DCL_TYPE (val->type) = IPOINTER;
2176 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
2177 DCL_TYPE (val->type) = EEPPOINTER;
2179 DCL_TYPE (val->type) = POINTER;
2180 val->type->next = sym->type;
2181 val->etype = getSpec (val->type);
2185 /*-----------------------------------------------------------------*/
2186 /* valForCastAggr - will return value for a cast of an aggregate */
2187 /* plus minus a constant */
2188 /*-----------------------------------------------------------------*/
2190 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
2194 if (!IS_AST_SYM_VALUE (aexpr))
2196 if (!IS_AST_LIT_VALUE (cnst))
2201 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
2202 AST_SYMBOL (aexpr)->rname, op,
2203 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
2206 val->etype = getSpec (val->type);
2210 /*-----------------------------------------------------------------*/
2211 /* valForCastAggr - will return value for a cast of an aggregate */
2212 /* with no constant */
2213 /*-----------------------------------------------------------------*/
2215 valForCastArr (ast * aexpr, sym_link * type)
2219 if (!IS_AST_SYM_VALUE (aexpr))
2224 SNPRINTF (val->name, sizeof(val->name), "(%s)",
2225 AST_SYMBOL (aexpr)->rname);
2228 val->etype = getSpec (val->type);