1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeAssign (operand *, operand *, int);
49 static operand *geniCodeArray (operand *, operand *,int);
50 static operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
54 void setOClass (sym_link * ptr, sym_link * spec);
55 static operand *geniCodeCast (sym_link *, operand *, bool);
57 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
58 /* forward definition of ic print functions */
59 PRINTFUNC (picGetValueAtAddr);
60 PRINTFUNC (picSetValueAtAddr);
61 PRINTFUNC (picAddrOf);
62 PRINTFUNC (picGeneric);
63 PRINTFUNC (picGenericOne);
65 PRINTFUNC (picAssign);
69 PRINTFUNC (picJumpTable);
70 PRINTFUNC (picInline);
71 PRINTFUNC (picReceive);
72 PRINTFUNC (picDummyRead);
73 PRINTFUNC (picCritical);
74 PRINTFUNC (picEndCritical);
76 iCodeTable codeTable[] =
78 {'!', "not", picGenericOne, NULL},
79 {'~', "~", picGenericOne, NULL},
80 {RRC, "rrc", picGenericOne, NULL},
81 {RLC, "rlc", picGenericOne, NULL},
82 {GETHBIT, "ghbit", picGenericOne, NULL},
83 {UNARYMINUS, "-", picGenericOne, NULL},
84 {IPUSH, "push", picGenericOne, NULL},
85 {IPOP, "pop", picGenericOne, NULL},
86 {CALL, "call", picGenericOne, NULL},
87 {PCALL, "pcall", picGenericOne, NULL},
88 {FUNCTION, "proc", picGenericOne, NULL},
89 {ENDFUNCTION, "eproc", picGenericOne, NULL},
90 {RETURN, "ret", picGenericOne, NULL},
91 {'+', "+", picGeneric, NULL},
92 {'-', "-", picGeneric, NULL},
93 {'*', "*", picGeneric, NULL},
94 {'/', "/", picGeneric, NULL},
95 {'%', "%", picGeneric, NULL},
96 {'>', ">", picGeneric, NULL},
97 {'<', "<", picGeneric, NULL},
98 {LE_OP, "<=", picGeneric, NULL},
99 {GE_OP, ">=", picGeneric, NULL},
100 {EQ_OP, "==", picGeneric, NULL},
101 {NE_OP, "!=", picGeneric, NULL},
102 {AND_OP, "&&", picGeneric, NULL},
103 {OR_OP, "||", picGeneric, NULL},
104 {'^', "^", picGeneric, NULL},
105 {'|', "|", picGeneric, NULL},
106 {BITWISEAND, "&", picGeneric, NULL},
107 {LEFT_OP, "<<", picGeneric, NULL},
108 {RIGHT_OP, ">>", picGeneric, NULL},
109 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110 {ADDRESS_OF, "&", picAddrOf, NULL},
111 {CAST, "<>", picCast, NULL},
112 {'=', ":=", picAssign, NULL},
113 {LABEL, "", picLabel, NULL},
114 {GOTO, "", picGoto, NULL},
115 {JUMPTABLE, "jtab", picJumpTable, NULL},
116 {IFX, "if", picIfx, NULL},
117 {INLINEASM, "", picInline, NULL},
118 {RECEIVE, "recv", picReceive, NULL},
119 {SEND, "send", picGenericOne, NULL},
120 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
121 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
122 {CRITICAL, "critical_start", picCritical, NULL},
123 {ENDCRITICAL, "critical_end", picEndCritical, NULL}
126 /*-----------------------------------------------------------------*/
127 /* checkConstantRange: check a constant against the type */
128 /*-----------------------------------------------------------------*/
131 /* pedantic=0: allmost anything is allowed as long as the absolute
132 value is within the bit range of the type, and -1 is treated as
133 0xf..f for unsigned types (e.g. in assign)
134 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
135 pedantic>1: "char c=200" is not allowed (evaluates to -56)
138 void checkConstantRange(sym_link *ltype, value *val, char *msg,
145 max = pow ((double)2.0, (double)bitsForType(ltype));
147 if (IS_LONG(val->type)) {
148 if (IS_UNSIGNED(val->type)) {
149 v=SPEC_CVAL(val->type).v_ulong;
151 v=SPEC_CVAL(val->type).v_long;
154 if (IS_UNSIGNED(val->type)) {
155 v=SPEC_CVAL(val->type).v_uint;
157 v=SPEC_CVAL(val->type).v_int;
163 // this could be a good idea
164 if (options.pedantic)
168 if (IS_FLOAT(ltype)) {
173 if (!IS_UNSIGNED(val->type) && v<0) {
175 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
181 // if very pedantic: "char c=200" is not allowed
182 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
183 max = max/2 + negative;
190 #if 0 // temporary disabled, leaving the warning as a reminder
192 SNPRINTF (message, sizeof(message), "for %s %s in %s",
193 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
194 nounName(ltype), msg);
195 werror (W_CONST_RANGE, message);
203 /*-----------------------------------------------------------------*/
204 /* operandName - returns the name of the operand */
205 /*-----------------------------------------------------------------*/
207 printOperand (operand * op, FILE * file)
224 opetype = getSpec (operandType (op));
225 if (IS_FLOAT (opetype))
226 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
228 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
229 printTypeChain (operandType (op), file);
236 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
237 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
239 OP_LIVEFROM (op), OP_LIVETO (op),
240 OP_SYMBOL (op)->stack,
241 op->isaddr, OP_SYMBOL (op)->isreqv,
242 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
243 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
247 printTypeChain (operandType (op), file);
248 if (SPIL_LOC (op) && IS_ITEMP (op))
249 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
254 /* if assigned to registers */
255 if (OP_SYMBOL (op)->nRegs)
257 if (OP_SYMBOL (op)->isspilt)
259 if (!OP_SYMBOL (op)->remat)
260 if (OP_SYMBOL (op)->usl.spillLoc)
261 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
262 OP_SYMBOL (op)->usl.spillLoc->rname :
263 OP_SYMBOL (op)->usl.spillLoc->name));
265 fprintf (file, "[err]");
267 fprintf (file, "[remat]");
273 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
274 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
279 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
280 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
281 /* if assigned to registers */
282 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
286 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
287 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
288 OP_SYMBOL (op)->regs[i]->name :
297 printTypeChain (op->operand.typeOperand, file);
303 fprintf (file, "\n");
308 /*-----------------------------------------------------------------*/
309 /* print functions */
310 /*-----------------------------------------------------------------*/
311 PRINTFUNC (picGetValueAtAddr)
314 printOperand (IC_RESULT (ic), of);
317 printOperand (IC_LEFT (ic), of);
323 PRINTFUNC (picSetValueAtAddr)
327 printOperand (IC_LEFT (ic), of);
328 fprintf (of, "] = ");
329 printOperand (IC_RIGHT (ic), of);
333 PRINTFUNC (picAddrOf)
336 printOperand (IC_RESULT (ic), of);
337 if (IS_ITEMP (IC_LEFT (ic)))
340 fprintf (of, " = &[");
341 printOperand (IC_LEFT (ic), of);
344 if (IS_ITEMP (IC_LEFT (ic)))
345 fprintf (of, " offsetAdd ");
348 printOperand (IC_RIGHT (ic), of);
350 if (IS_ITEMP (IC_LEFT (ic)))
356 PRINTFUNC (picJumpTable)
361 fprintf (of, "%s\t", s);
362 printOperand (IC_JTCOND (ic), of);
364 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
365 sym = setNextItem (IC_JTLABELS (ic)))
366 fprintf (of, "\t\t\t%s\n", sym->name);
369 PRINTFUNC (picGeneric)
372 printOperand (IC_RESULT (ic), of);
374 printOperand (IC_LEFT (ic), of);
375 fprintf (of, " %s ", s);
376 printOperand (IC_RIGHT (ic), of);
380 PRINTFUNC (picGenericOne)
385 printOperand (IC_RESULT (ic), of);
391 fprintf (of, "%s ", s);
392 printOperand (IC_LEFT (ic), of);
395 if (!IC_RESULT (ic) && !IC_LEFT (ic))
398 if (ic->op == SEND || ic->op == RECEIVE) {
399 fprintf(of,"{argreg = %d}",ic->argreg);
407 printOperand (IC_RESULT (ic), of);
409 printOperand (IC_LEFT (ic), of);
410 printOperand (IC_RIGHT (ic), of);
415 PRINTFUNC (picAssign)
419 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
422 printOperand (IC_RESULT (ic), of);
424 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
427 fprintf (of, " %s ", s);
428 printOperand (IC_RIGHT (ic), of);
435 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
441 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
448 printOperand (IC_COND (ic), of);
451 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
454 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
456 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
460 PRINTFUNC (picInline)
462 fprintf (of, "%s", IC_INLINE (ic));
465 PRINTFUNC (picReceive)
467 printOperand (IC_RESULT (ic), of);
468 fprintf (of, " = %s ", s);
469 printOperand (IC_LEFT (ic), of);
473 PRINTFUNC (picDummyRead)
476 fprintf (of, "%s ", s);
477 printOperand (IC_RIGHT (ic), of);
481 PRINTFUNC (picCritical)
485 printOperand (IC_RESULT (ic), of);
487 fprintf (of, "(stack)");
488 fprintf (of, " = %s ", s);
492 PRINTFUNC (picEndCritical)
495 fprintf (of, "%s = ", s);
497 printOperand (IC_RIGHT (ic), of);
499 fprintf (of, "(stack)");
503 /*-----------------------------------------------------------------*/
504 /* piCode - prints one iCode */
505 /*-----------------------------------------------------------------*/
507 piCode (void *item, FILE * of)
515 icTab = getTableEntry (ic->op);
516 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
517 ic->filename, ic->lineno,
518 ic->seq, ic->key, ic->depth, ic->supportRtn);
519 icTab->iCodePrint (of, ic, icTab->printName);
525 printiCChain(ic,stdout);
527 /*-----------------------------------------------------------------*/
528 /* printiCChain - prints intermediate code for humans */
529 /*-----------------------------------------------------------------*/
531 printiCChain (iCode * icChain, FILE * of)
538 for (loop = icChain; loop; loop = loop->next)
540 if ((icTab = getTableEntry (loop->op)))
542 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
543 loop->filename, loop->lineno,
544 loop->seq, loop->key, loop->depth, loop->supportRtn);
546 icTab->iCodePrint (of, loop, icTab->printName);
552 /*-----------------------------------------------------------------*/
553 /* newOperand - allocate, init & return a new iCode */
554 /*-----------------------------------------------------------------*/
560 op = Safe_alloc ( sizeof (operand));
566 /*-----------------------------------------------------------------*/
567 /* newiCode - create and return a new iCode entry initialised */
568 /*-----------------------------------------------------------------*/
570 newiCode (int op, operand * left, operand * right)
574 ic = Safe_alloc ( sizeof (iCode));
576 ic->seqPoint = seqPoint;
578 ic->filename = filename;
580 ic->level = scopeLevel;
582 ic->key = iCodeKey++;
584 IC_RIGHT (ic) = right;
589 /*-----------------------------------------------------------------*/
590 /* newiCode for conditional statements */
591 /*-----------------------------------------------------------------*/
593 newiCodeCondition (operand * condition,
599 if (IS_VOID(operandType(condition))) {
600 werror(E_VOID_VALUE_USED);
603 ic = newiCode (IFX, NULL, NULL);
604 IC_COND (ic) = condition;
605 IC_TRUE (ic) = trueLabel;
606 IC_FALSE (ic) = falseLabel;
610 /*-----------------------------------------------------------------*/
611 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
612 /*-----------------------------------------------------------------*/
614 newiCodeLabelGoto (int op, symbol * label)
618 ic = newiCode (op, NULL, NULL);
622 IC_RIGHT (ic) = NULL;
623 IC_RESULT (ic) = NULL;
627 /*-----------------------------------------------------------------*/
628 /* newiTemp - allocate & return a newItemp Variable */
629 /*-----------------------------------------------------------------*/
637 SNPRINTF (buffer, sizeof(buffer), "%s", s);
641 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
644 itmp = newSymbol (buffer, 1);
645 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
651 /*-----------------------------------------------------------------*/
652 /* newiTempLabel - creates a temp variable label */
653 /*-----------------------------------------------------------------*/
655 newiTempLabel (char *s)
659 /* check if this alredy exists */
660 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
665 itmplbl = newSymbol (s, 1);
669 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
670 itmplbl = newSymbol (buffer, 1);
675 itmplbl->key = labelKey++;
676 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
680 /*-----------------------------------------------------------------*/
681 /* newiTempPreheaderLabel - creates a new preheader label */
682 /*-----------------------------------------------------------------*/
684 newiTempPreheaderLabel ()
688 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
689 itmplbl = newSymbol (buffer, 1);
693 itmplbl->key = labelKey++;
694 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
699 /*-----------------------------------------------------------------*/
700 /* initiCode - initialises some iCode related stuff */
701 /*-----------------------------------------------------------------*/
708 /*-----------------------------------------------------------------*/
709 /* copyiCode - make a copy of the iCode given */
710 /*-----------------------------------------------------------------*/
712 copyiCode (iCode * ic)
714 iCode *nic = newiCode (ic->op, NULL, NULL);
716 nic->lineno = ic->lineno;
717 nic->filename = ic->filename;
718 nic->block = ic->block;
719 nic->level = ic->level;
720 nic->parmBytes = ic->parmBytes;
722 /* deal with the special cases first */
726 IC_COND (nic) = operandFromOperand (IC_COND (ic));
727 IC_TRUE (nic) = IC_TRUE (ic);
728 IC_FALSE (nic) = IC_FALSE (ic);
732 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
733 IC_JTLABELS (nic) = IC_JTLABELS (ic);
738 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
739 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
743 IC_INLINE (nic) = IC_INLINE (ic);
747 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
751 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
752 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
753 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
759 /*-----------------------------------------------------------------*/
760 /* getTableEntry - gets the table entry for the given operator */
761 /*-----------------------------------------------------------------*/
763 getTableEntry (int oper)
767 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
768 if (oper == codeTable[i].icode)
769 return &codeTable[i];
774 /*-----------------------------------------------------------------*/
775 /* newiTempOperand - new intermediate temp operand */
776 /*-----------------------------------------------------------------*/
778 newiTempOperand (sym_link * type, char throwType)
781 operand *op = newOperand ();
785 itmp = newiTemp (NULL);
787 etype = getSpec (type);
789 if (IS_LITERAL (etype))
792 /* copy the type information */
794 itmp->etype = getSpec (itmp->type = (throwType ? type :
795 copyLinkChain (type)));
796 if (IS_LITERAL (itmp->etype))
798 SPEC_SCLS (itmp->etype) = S_REGISTER;
799 SPEC_OCLS (itmp->etype) = reg;
802 op->operand.symOperand = itmp;
803 op->key = itmp->key = ++operandKey;
807 /*-----------------------------------------------------------------*/
808 /* operandType - returns the type chain for an operand */
809 /*-----------------------------------------------------------------*/
811 operandType (operand * op)
813 /* depending on type of operand */
818 return op->operand.valOperand->type;
821 return op->operand.symOperand->type;
824 return op->operand.typeOperand;
826 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
827 " operand type not known ");
828 assert (0); /* should never come here */
829 /* Just to keep the compiler happy */
830 return (sym_link *) 0;
834 /*-----------------------------------------------------------------*/
835 /* isParamterToCall - will return 1 if op is a parameter to args */
836 /*-----------------------------------------------------------------*/
838 isParameterToCall (value * args, operand * op)
842 wassert (IS_SYMOP(op));
847 isSymbolEqual (op->operand.symOperand, tval->sym))
854 /*-----------------------------------------------------------------*/
855 /* isOperandGlobal - return 1 if operand is a global variable */
856 /*-----------------------------------------------------------------*/
858 isOperandGlobal (operand * op)
867 (op->operand.symOperand->level == 0 ||
868 IS_STATIC (op->operand.symOperand->etype) ||
869 IS_EXTERN (op->operand.symOperand->etype))
876 /*-----------------------------------------------------------------*/
877 /* isOperandVolatile - return 1 if the operand is volatile */
878 /*-----------------------------------------------------------------*/
880 isOperandVolatile (operand * op, bool chkTemp)
885 if (IS_ITEMP (op) && !chkTemp)
888 opetype = getSpec (optype = operandType (op));
890 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
893 if (IS_VOLATILE (opetype))
898 /*-----------------------------------------------------------------*/
899 /* isOperandLiteral - returns 1 if an operand contains a literal */
900 /*-----------------------------------------------------------------*/
902 isOperandLiteral (operand * op)
909 opetype = getSpec (operandType (op));
911 if (IS_LITERAL (opetype))
917 /*-----------------------------------------------------------------*/
918 /* isOperandInFarSpace - will return true if operand is in farSpace */
919 /*-----------------------------------------------------------------*/
921 isOperandInFarSpace (operand * op)
931 if (!IS_TRUE_SYMOP (op))
934 etype = SPIL_LOC (op)->etype;
940 etype = getSpec (operandType (op));
942 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
945 /*------------------------------------------------------------------*/
946 /* isOperandInDirSpace - will return true if operand is in dirSpace */
947 /*------------------------------------------------------------------*/
949 isOperandInDirSpace (operand * op)
959 if (!IS_TRUE_SYMOP (op))
962 etype = SPIL_LOC (op)->etype;
968 etype = getSpec (operandType (op));
970 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
973 /*--------------------------------------------------------------------*/
974 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
975 /*--------------------------------------------------------------------*/
977 isOperandInCodeSpace (operand * op)
987 etype = getSpec (operandType (op));
989 if (!IS_TRUE_SYMOP (op))
992 etype = SPIL_LOC (op)->etype;
998 etype = getSpec (operandType (op));
1000 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1003 /*-----------------------------------------------------------------*/
1004 /* isOperandOnStack - will return true if operand is on stack */
1005 /*-----------------------------------------------------------------*/
1007 isOperandOnStack (operand * op)
1017 etype = getSpec (operandType (op));
1018 if (IN_STACK (etype) ||
1019 OP_SYMBOL(op)->onStack ||
1020 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1026 /*-----------------------------------------------------------------*/
1027 /* isOclsExpensive - will return true if accesses to an output */
1028 /* storage class are expensive */
1029 /*-----------------------------------------------------------------*/
1031 isOclsExpensive (struct memmap *oclass)
1033 if (port->oclsExpense)
1034 return port->oclsExpense (oclass) > 0;
1036 /* In the absence of port specific guidance, assume only */
1037 /* farspace is expensive. */
1038 return IN_FARSPACE (oclass);
1041 /*-----------------------------------------------------------------*/
1042 /* operandLitValue - literal value of an operand */
1043 /*-----------------------------------------------------------------*/
1045 operandLitValue (operand * op)
1047 assert (isOperandLiteral (op));
1049 return floatFromVal (op->operand.valOperand);
1052 /*-----------------------------------------------------------------*/
1053 /* getBuiltInParms - returns parameters to a builtin functions */
1054 /*-----------------------------------------------------------------*/
1055 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1060 /* builtin functions uses only SEND for parameters */
1061 while (ic->op != CALL) {
1062 assert(ic->op == SEND && ic->builtinSEND);
1063 ic->generated = 1; /* mark the icode as generated */
1064 parms[*pcount] = IC_LEFT(ic);
1070 /* make sure this is a builtin function call */
1071 assert(IS_SYMOP(IC_LEFT(ic)));
1072 ftype = operandType(IC_LEFT(ic));
1073 assert(IFFUNC_ISBUILTIN(ftype));
1077 /*-----------------------------------------------------------------*/
1078 /* operandOperation - performs operations on operands */
1079 /*-----------------------------------------------------------------*/
1081 operandOperation (operand * left, operand * right,
1082 int op, sym_link * type)
1084 sym_link *let , *ret=NULL;
1085 operand *retval = (operand *) 0;
1087 assert (isOperandLiteral (left));
1088 let = getSpec(operandType(left));
1090 assert (isOperandLiteral (right));
1091 ret = getSpec(operandType(right));
1097 retval = operandFromValue (valCastLiteral (type,
1098 operandLitValue (left) +
1099 operandLitValue (right)));
1102 retval = operandFromValue (valCastLiteral (type,
1103 operandLitValue (left) -
1104 operandLitValue (right)));
1108 retval = operandFromValue (valCastLiteral (type,
1109 operandLitValue (left) *
1110 operandLitValue (right)));
1111 This could be all we've to do, but with gcc we've to take care about
1112 overflows. Two examples:
1113 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1114 significant bits are lost (52 in fraction, 63 bits would be
1115 necessary to keep full precision).
1116 If the resulting double value is greater than ULONG_MAX (resp.
1117 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1120 /* if it is not a specifier then we can assume that */
1121 /* it will be an unsigned long */
1122 if (IS_INT (type) ||
1125 /* long is handled here, because it can overflow with double */
1126 if (IS_LONG (type) ||
1128 /* signed and unsigned mul are the same, as long as the precision
1129 of the result isn't bigger than the precision of the operands. */
1130 retval = operandFromValue (valCastLiteral (type,
1131 (TYPE_UDWORD) operandLitValue (left) *
1132 (TYPE_UDWORD) operandLitValue (right)));
1133 else if (IS_UNSIGNED (type)) /* unsigned int */
1135 /* unsigned int is handled here in order to detect overflow */
1136 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1137 (TYPE_UWORD) operandLitValue (right);
1139 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1140 if (ul != (TYPE_UWORD) ul)
1143 else /* signed int */
1145 /* signed int is handled here in order to detect overflow */
1146 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1147 (TYPE_WORD) operandLitValue (right);
1149 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1150 if (l != (TYPE_WORD) l)
1155 /* all others go here: */
1156 retval = operandFromValue (valCastLiteral (type,
1157 operandLitValue (left) *
1158 operandLitValue (right)));
1161 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1163 werror (E_DIVIDE_BY_ZERO);
1169 if (IS_UNSIGNED (type))
1171 SPEC_USIGN (let) = 1;
1172 SPEC_USIGN (ret) = 1;
1173 retval = operandFromValue (valCastLiteral (type,
1174 (TYPE_UDWORD) operandLitValue (left) /
1175 (TYPE_UDWORD) operandLitValue (right)));
1179 retval = operandFromValue (valCastLiteral (type,
1180 operandLitValue (left) /
1181 operandLitValue (right)));
1186 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1188 werror (E_DIVIDE_BY_ZERO);
1193 if (IS_UNSIGNED (type))
1194 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1195 (TYPE_UDWORD) operandLitValue (right));
1197 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1198 (TYPE_DWORD) operandLitValue (right));
1202 /* The number of left shifts is always unsigned. Signed doesn't make
1203 sense here. Shifting by a negative number is impossible. */
1204 retval = operandFromValue (valCastLiteral (type,
1205 ((TYPE_UDWORD) operandLitValue (left) <<
1206 (TYPE_UDWORD) operandLitValue (right))));
1209 /* The number of right shifts is always unsigned. Signed doesn't make
1210 sense here. Shifting by a negative number is impossible. */
1211 if (IS_UNSIGNED(let))
1212 /* unsigned: logic shift right */
1213 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1214 (TYPE_UDWORD) operandLitValue (right));
1216 /* signed: arithmetic shift right */
1217 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1218 (TYPE_UDWORD) operandLitValue (right));
1221 if (IS_FLOAT (let) ||
1224 retval = operandFromLit (operandLitValue (left) ==
1225 operandLitValue (right));
1229 /* this op doesn't care about signedness */
1232 l = (TYPE_UDWORD) operandLitValue (left);
1233 r = (TYPE_UDWORD) operandLitValue (right);
1234 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1235 neccessary to strip them to 16 bit.
1236 Literals are reduced to their cheapest type, therefore left and
1237 right might have different types. It's neccessary to find a
1238 common type: int (used for char too) or long */
1239 if (!IS_LONG (let) &&
1245 retval = operandFromLit (l == r);
1249 retval = operandFromLit (operandLitValue (left) <
1250 operandLitValue (right));
1253 retval = operandFromLit (operandLitValue (left) <=
1254 operandLitValue (right));
1257 retval = operandFromLit (operandLitValue (left) !=
1258 operandLitValue (right));
1261 retval = operandFromLit (operandLitValue (left) >
1262 operandLitValue (right));
1265 retval = operandFromLit (operandLitValue (left) >=
1266 operandLitValue (right));
1269 retval = operandFromValue (valCastLiteral (type,
1270 (TYPE_UDWORD)operandLitValue(left) &
1271 (TYPE_UDWORD)operandLitValue(right)));
1274 retval = operandFromValue (valCastLiteral (type,
1275 (TYPE_UDWORD)operandLitValue(left) |
1276 (TYPE_UDWORD)operandLitValue(right)));
1279 retval = operandFromValue (valCastLiteral (type,
1280 (TYPE_UDWORD)operandLitValue(left) ^
1281 (TYPE_UDWORD)operandLitValue(right)));
1284 retval = operandFromLit (operandLitValue (left) &&
1285 operandLitValue (right));
1288 retval = operandFromLit (operandLitValue (left) ||
1289 operandLitValue (right));
1293 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1295 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1301 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1303 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1309 retval = operandFromValue (valCastLiteral (type,
1310 -1 * operandLitValue (left)));
1314 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1318 retval = operandFromLit (!operandLitValue (left));
1322 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1323 " operandOperation invalid operator ");
1331 /*-----------------------------------------------------------------*/
1332 /* isOperandEqual - compares two operand & return 1 if they r = */
1333 /*-----------------------------------------------------------------*/
1335 isOperandEqual (operand * left, operand * right)
1337 /* if the pointers are equal then they are equal */
1341 /* if either of them null then false */
1342 if (!left || !right)
1345 if (left->type != right->type)
1348 if (IS_SYMOP (left) && IS_SYMOP (right))
1349 return left->key == right->key;
1351 /* if types are the same */
1355 return isSymbolEqual (left->operand.symOperand,
1356 right->operand.symOperand);
1358 return (floatFromVal (left->operand.valOperand) ==
1359 floatFromVal (right->operand.valOperand));
1361 if (compareType (left->operand.typeOperand,
1362 right->operand.typeOperand) == 1)
1369 /*-------------------------------------------------------------------*/
1370 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1371 /*-------------------------------------------------------------------*/
1373 isiCodeEqual (iCode * left, iCode * right)
1375 /* if the same pointer */
1379 /* if either of them null */
1380 if (!left || !right)
1383 /* if operand are the same */
1384 if (left->op == right->op)
1387 /* compare all the elements depending on type */
1388 if (left->op != IFX)
1390 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1392 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1398 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1400 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1402 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1411 /*-----------------------------------------------------------------*/
1412 /* newiTempFromOp - create a temp Operand with same attributes */
1413 /*-----------------------------------------------------------------*/
1415 newiTempFromOp (operand * op)
1425 nop = newiTempOperand (operandType (op), TRUE);
1426 nop->isaddr = op->isaddr;
1427 nop->isvolatile = op->isvolatile;
1428 nop->isGlobal = op->isGlobal;
1429 nop->isLiteral = op->isLiteral;
1430 nop->usesDefs = op->usesDefs;
1431 nop->isParm = op->isParm;
1435 /*-----------------------------------------------------------------*/
1436 /* operand from operand - creates an operand holder for the type */
1437 /*-----------------------------------------------------------------*/
1439 operandFromOperand (operand * op)
1445 nop = newOperand ();
1446 nop->type = op->type;
1447 nop->isaddr = op->isaddr;
1449 nop->isvolatile = op->isvolatile;
1450 nop->isGlobal = op->isGlobal;
1451 nop->isLiteral = op->isLiteral;
1452 nop->usesDefs = op->usesDefs;
1453 nop->isParm = op->isParm;
1458 nop->operand.symOperand = op->operand.symOperand;
1461 nop->operand.valOperand = op->operand.valOperand;
1464 nop->operand.typeOperand = op->operand.typeOperand;
1471 /*-----------------------------------------------------------------*/
1472 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1473 /*-----------------------------------------------------------------*/
1475 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1477 operand *nop = operandFromOperand (op);
1479 if (nop->type == SYMBOL)
1481 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1482 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1488 /*-----------------------------------------------------------------*/
1489 /* operandFromSymbol - creates an operand from a symbol */
1490 /*-----------------------------------------------------------------*/
1492 operandFromSymbol (symbol * sym)
1497 /* if the symbol's type is a literal */
1498 /* then it is an enumerator type */
1499 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1500 return operandFromValue (valFromType (sym->etype));
1503 sym->key = ++operandKey;
1505 /* if this an implicit variable, means struct/union */
1506 /* member so just return it */
1507 if (sym->implicit || IS_FUNC (sym->type))
1511 op->operand.symOperand = sym;
1513 op->isvolatile = isOperandVolatile (op, TRUE);
1514 op->isGlobal = isOperandGlobal (op);
1518 /* under the following conditions create a
1519 register equivalent for a local symbol */
1520 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1521 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1523 (!(options.model == MODEL_FLAT24)) ) &&
1524 options.stackAuto == 0)
1527 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1528 !IS_FUNC (sym->type) && /* not a function */
1529 !sym->_isparm && /* not a parameter */
1530 sym->level && /* is a local variable */
1531 !sym->addrtaken && /* whose address has not been taken */
1532 !sym->reqv && /* does not already have a reg equivalence */
1533 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1534 !IS_STATIC (sym->etype) && /* and not declared static */
1535 !sym->islbl && /* not a label */
1536 ok && /* farspace check */
1537 !IS_BITVAR (sym->etype) /* not a bit variable */
1541 /* we will use it after all optimizations
1542 and before liveRange calculation */
1543 sym->reqv = newiTempOperand (sym->type, 0);
1544 sym->reqv->key = sym->key;
1545 OP_SYMBOL (sym->reqv)->prereqv = sym;
1546 OP_SYMBOL (sym->reqv)->key = sym->key;
1547 OP_SYMBOL (sym->reqv)->isreqv = 1;
1548 OP_SYMBOL (sym->reqv)->islocal = 1;
1549 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1550 SPIL_LOC (sym->reqv) = sym;
1553 if (!IS_AGGREGATE (sym->type))
1557 op->operand.symOperand = sym;
1560 op->isvolatile = isOperandVolatile (op, TRUE);
1561 op->isGlobal = isOperandGlobal (op);
1562 op->isPtr = IS_PTR (operandType (op));
1563 op->isParm = sym->_isparm;
1568 /* itemp = &[_symbol] */
1570 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1571 IC_LEFT (ic)->type = SYMBOL;
1572 IC_LEFT (ic)->operand.symOperand = sym;
1573 IC_LEFT (ic)->key = sym->key;
1574 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1575 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1576 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1579 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1580 if (IS_ARRAY (sym->type))
1582 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1583 IC_RESULT (ic)->isaddr = 0;
1586 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1590 return IC_RESULT (ic);
1593 /*-----------------------------------------------------------------*/
1594 /* operandFromValue - creates an operand from value */
1595 /*-----------------------------------------------------------------*/
1597 operandFromValue (value * val)
1601 /* if this is a symbol then do the symbol thing */
1603 return operandFromSymbol (val->sym);
1605 /* this is not a symbol */
1608 op->operand.valOperand = val;
1609 op->isLiteral = isOperandLiteral (op);
1613 /*-----------------------------------------------------------------*/
1614 /* operandFromLink - operand from typeChain */
1615 /*-----------------------------------------------------------------*/
1617 operandFromLink (sym_link * type)
1621 /* operand from sym_link */
1627 op->operand.typeOperand = copyLinkChain (type);
1631 /*-----------------------------------------------------------------*/
1632 /* operandFromLit - makes an operand from a literal value */
1633 /*-----------------------------------------------------------------*/
1635 operandFromLit (double i)
1637 return operandFromValue (valueFromLit (i));
1640 /*-----------------------------------------------------------------*/
1641 /* operandFromAst - creates an operand from an ast */
1642 /*-----------------------------------------------------------------*/
1644 operandFromAst (ast * tree,int lvl)
1650 /* depending on type do */
1654 return ast2iCode (tree,lvl+1);
1658 return operandFromValue (tree->opval.val);
1662 return operandFromLink (tree->opval.lnk);
1669 /* Just to keep the compiler happy */
1670 return (operand *) 0;
1673 /*-----------------------------------------------------------------*/
1674 /* setOperandType - sets the operand's type to the given type */
1675 /*-----------------------------------------------------------------*/
1677 setOperandType (operand * op, sym_link * type)
1679 /* depending on the type of operand */
1684 op->operand.valOperand->etype =
1685 getSpec (op->operand.valOperand->type =
1686 copyLinkChain (type));
1690 if (op->operand.symOperand->isitmp)
1691 op->operand.symOperand->etype =
1692 getSpec (op->operand.symOperand->type =
1693 copyLinkChain (type));
1695 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1696 "attempt to modify type of source");
1700 op->operand.typeOperand = copyLinkChain (type);
1706 /*-----------------------------------------------------------------*/
1707 /* Get size in byte of ptr need to access an array */
1708 /*-----------------------------------------------------------------*/
1710 getArraySizePtr (operand * op)
1712 sym_link *ltype = operandType(op);
1716 int size = getSize(ltype);
1717 return(IS_GENPTR(ltype)?(size-1):size);
1722 sym_link *letype = getSpec(ltype);
1723 switch (PTR_TYPE (SPEC_OCLS (letype)))
1735 return (GPTRSIZE-1);
1744 /*-----------------------------------------------------------------*/
1745 /* perform "usual unary conversions" */
1746 /*-----------------------------------------------------------------*/
1749 usualUnaryConversions (operand * op)
1751 if (IS_INTEGRAL (operandType (op)))
1753 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1756 return geniCodeCast (INTTYPE, op, TRUE);
1763 /*-----------------------------------------------------------------*/
1764 /* perform "usual binary conversions" */
1765 /*-----------------------------------------------------------------*/
1768 usualBinaryConversions (operand ** op1, operand ** op2,
1769 RESULT_TYPE resultType, char op)
1772 sym_link *rtype = operandType (*op2);
1773 sym_link *ltype = operandType (*op1);
1775 #define OLDONEBYTEOPS 1
1777 #ifdef OLDONEBYTEOPS
1778 bool oldOneByteOps = FALSE;
1779 static bool saidHello = FALSE;
1781 if (strcmp (port->target, "pic14") == 0)
1782 oldOneByteOps = TRUE;
1783 if (getenv ("SDCC_NEWONEBYTEOPS"))
1787 fprintf (stderr, "Override: oldOneByteOps = FALSE\n");
1790 oldOneByteOps = FALSE;
1792 else if (getenv ("SDCC_OLDONEBYTEOPS"))
1796 fprintf (stderr, "Override: oldOneByteOps = TRUE\n");
1799 oldOneByteOps = TRUE;
1804 && ( (IS_CHAR (getSpec (ltype)) && !IS_UNSIGNED (getSpec (ltype)))
1805 || (IS_CHAR (getSpec (rtype)) && !IS_UNSIGNED (getSpec (rtype)))))
1806 /* one or two signed char operands: promote to int */
1807 resultType = RESULT_TYPE_INT;
1810 ctype = computeType (ltype, rtype, resultType, op);
1812 #ifdef OLDONEBYTEOPS
1817 && IS_CHAR (getSpec (ltype)) && IS_UNSIGNED (getSpec (ltype))
1818 && IS_CHAR (getSpec (rtype)) && IS_UNSIGNED (getSpec (rtype)))
1820 /* two unsigned char operands and Mult: no promotion */
1823 *op1 = geniCodeCast (ctype, *op1, TRUE);
1824 *op2 = geniCodeCast (ctype, *op2, TRUE);
1836 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1838 /* one byte operations: keep signedness for code generator */
1846 *op1 = geniCodeCast (ctype, *op1, TRUE);
1847 *op2 = geniCodeCast (ctype, *op2, TRUE);
1852 /*-----------------------------------------------------------------*/
1853 /* geniCodeValueAtAddress - generate intermeditate code for value */
1855 /*-----------------------------------------------------------------*/
1857 geniCodeRValue (operand * op, bool force)
1860 sym_link *type = operandType (op);
1861 sym_link *etype = getSpec (type);
1863 /* if this is an array & already */
1864 /* an address then return this */
1865 if (IS_AGGREGATE (type) ||
1866 (IS_PTR (type) && !force && !op->isaddr))
1867 return operandFromOperand (op);
1869 /* if this is not an address then must be */
1870 /* rvalue already so return this one */
1874 /* if this is not a temp symbol then */
1875 if (!IS_ITEMP (op) &&
1877 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1879 op = operandFromOperand (op);
1884 if (IS_SPEC (type) &&
1885 IS_TRUE_SYMOP (op) &&
1886 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1887 (options.model == MODEL_FLAT24) ))
1889 op = operandFromOperand (op);
1894 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1895 if (IS_PTR (type) && op->isaddr && force)
1898 type = copyLinkChain (type);
1900 IC_RESULT (ic) = newiTempOperand (type, 1);
1901 IC_RESULT (ic)->isaddr = 0;
1903 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1907 return IC_RESULT (ic);
1910 /*-----------------------------------------------------------------*/
1911 /* geniCodeCast - changes the value from one type to another */
1912 /*-----------------------------------------------------------------*/
1914 geniCodeCast (sym_link * type, operand * op, bool implicit)
1918 sym_link *opetype = getSpec (optype = operandType (op));
1922 /* one of them has size zero then error */
1923 if (IS_VOID (optype))
1925 werror (E_CAST_ZERO);
1929 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1931 geniCodeArray2Ptr (op);
1935 /* if the operand is already the desired type then do nothing */
1936 if (compareType (type, optype) == 1)
1939 /* if this is a literal then just change the type & return */
1940 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1942 return operandFromValue (valCastLiteral (type,
1943 operandLitValue (op)));
1946 /* if casting to/from pointers, do some checking */
1947 if (IS_PTR(type)) { // to a pointer
1948 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1949 if (IS_INTEGRAL(optype)) {
1950 // maybe this is NULL, than it's ok.
1951 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1952 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1953 // no way to set the storage
1954 if (IS_LITERAL(optype)) {
1955 werror(E_LITERAL_GENERIC);
1958 werror(E_NONPTR2_GENPTR);
1961 } else if (implicit) {
1962 werror(W_INTEGRAL2PTR_NOCAST);
1967 // shouldn't do that with float, array or structure unless to void
1968 if (!IS_VOID(getSpec(type)) &&
1969 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1970 werror(E_INCOMPAT_TYPES);
1974 } else { // from a pointer to a pointer
1975 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1976 // if not a pointer to a function
1977 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1978 if (implicit) { // if not to generic, they have to match
1979 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1980 werror(E_INCOMPAT_PTYPES);
1987 } else { // to a non pointer
1988 if (IS_PTR(optype)) { // from a pointer
1989 if (implicit) { // sneaky
1990 if (IS_INTEGRAL(type)) {
1991 werror(W_PTR2INTEGRAL_NOCAST);
1993 } else { // shouldn't do that with float, array or structure
1994 werror(E_INCOMPAT_TYPES);
2001 printFromToType (optype, type);
2004 /* if they are the same size create an assignment */
2006 /* This seems very dangerous to me, since there are several */
2007 /* optimizations (for example, gcse) that don't notice the */
2008 /* cast hidden in this assignement and may simplify an */
2009 /* iCode to use the original (uncasted) operand. */
2010 /* Unfortunately, other things break when this cast is */
2011 /* made explicit. Need to fix this someday. */
2012 /* -- EEP, 2004/01/21 */
2013 if (getSize (type) == getSize (optype) &&
2014 !IS_BITFIELD (type) &&
2016 !IS_FLOAT (optype) &&
2017 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2018 (!IS_SPEC (type) && !IS_SPEC (optype))))
2020 ic = newiCode ('=', NULL, op);
2021 IC_RESULT (ic) = newiTempOperand (type, 0);
2022 SPIL_LOC (IC_RESULT (ic)) =
2023 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2024 IC_RESULT (ic)->isaddr = 0;
2028 ic = newiCode (CAST, operandFromLink (type),
2029 geniCodeRValue (op, FALSE));
2031 IC_RESULT (ic) = newiTempOperand (type, 0);
2034 /* preserve the storage class & output class */
2035 /* of the original variable */
2036 restype = getSpec (operandType (IC_RESULT (ic)));
2037 if (!IS_LITERAL(opetype))
2038 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2039 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2042 return IC_RESULT (ic);
2045 /*-----------------------------------------------------------------*/
2046 /* geniCodeLabel - will create a Label */
2047 /*-----------------------------------------------------------------*/
2049 geniCodeLabel (symbol * label)
2053 ic = newiCodeLabelGoto (LABEL, label);
2057 /*-----------------------------------------------------------------*/
2058 /* geniCodeGoto - will create a Goto */
2059 /*-----------------------------------------------------------------*/
2061 geniCodeGoto (symbol * label)
2065 ic = newiCodeLabelGoto (GOTO, label);
2069 /*-----------------------------------------------------------------*/
2070 /* geniCodeMultiply - gen intermediate code for multiplication */
2071 /*-----------------------------------------------------------------*/
2073 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2080 /* if they are both literal then we know the result */
2081 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2082 return operandFromValue (valMult (left->operand.valOperand,
2083 right->operand.valOperand));
2085 if (IS_LITERAL(retype)) {
2086 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2089 resType = usualBinaryConversions (&left, &right, resultType, '*');
2091 rtype = operandType (right);
2092 retype = getSpec (rtype);
2093 ltype = operandType (left);
2094 letype = getSpec (ltype);
2097 /* if the right is a literal & power of 2 */
2098 /* then make it a left shift */
2099 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2100 efficient in most cases than 2 bytes result = 2 bytes << literal
2101 if port has 1 byte muldiv */
2102 if (p2 && !IS_FLOAT (letype)
2103 && !((resultType != RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2104 && (port->support.muldiv == 1))
2105 && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
2106 && strcmp (port->target, "pic16") != 0)
2108 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2110 /* LEFT_OP need same size for left and result, */
2111 left = geniCodeCast (resType, left, TRUE);
2112 ltype = operandType (left);
2114 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2118 ic = newiCode ('*', left, right); /* normal multiplication */
2119 /* if the size left or right > 1 then support routine */
2120 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2124 IC_RESULT (ic) = newiTempOperand (resType, 1);
2127 return IC_RESULT (ic);
2130 /*-----------------------------------------------------------------*/
2131 /* geniCodeDivision - gen intermediate code for division */
2132 /*-----------------------------------------------------------------*/
2134 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2139 sym_link *rtype = operandType (right);
2140 sym_link *retype = getSpec (rtype);
2141 sym_link *ltype = operandType (left);
2142 sym_link *letype = getSpec (ltype);
2144 resType = usualBinaryConversions (&left, &right, resultType, '/');
2146 /* if the right is a literal & power of 2
2147 and left is unsigned then make it a
2149 if (IS_LITERAL (retype) &&
2150 !IS_FLOAT (letype) &&
2151 IS_UNSIGNED(letype) &&
2152 (p2 = powof2 ((TYPE_UDWORD)
2153 floatFromVal (right->operand.valOperand)))) {
2154 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2158 ic = newiCode ('/', left, right); /* normal division */
2159 /* if the size left or right > 1 then support routine */
2160 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2163 IC_RESULT (ic) = newiTempOperand (resType, 0);
2166 return IC_RESULT (ic);
2168 /*-----------------------------------------------------------------*/
2169 /* geniCodeModulus - gen intermediate code for modulus */
2170 /*-----------------------------------------------------------------*/
2172 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2178 /* if they are both literal then we know the result */
2179 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2180 return operandFromValue (valMod (left->operand.valOperand,
2181 right->operand.valOperand));
2183 resType = usualBinaryConversions (&left, &right, resultType, '%');
2185 /* now they are the same size */
2186 ic = newiCode ('%', left, right);
2188 /* if the size left or right > 1 then support routine */
2189 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2191 IC_RESULT (ic) = newiTempOperand (resType, 0);
2194 return IC_RESULT (ic);
2197 /*-----------------------------------------------------------------*/
2198 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2199 /*-----------------------------------------------------------------*/
2201 geniCodePtrPtrSubtract (operand * left, operand * right)
2207 /* if they are both literals then */
2208 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2210 result = operandFromValue (valMinus (left->operand.valOperand,
2211 right->operand.valOperand));
2215 ic = newiCode ('-', left, right);
2217 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2221 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2225 // should we really do this? is this ANSI?
2226 return geniCodeDivision (result,
2227 operandFromLit (getSize (ltype->next)),
2231 /*-----------------------------------------------------------------*/
2232 /* geniCodeSubtract - generates code for subtraction */
2233 /*-----------------------------------------------------------------*/
2235 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2242 /* if they both pointers then */
2243 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2244 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2245 return geniCodePtrPtrSubtract (left, right);
2247 /* if they are both literal then we know the result */
2248 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2249 && left->isLiteral && right->isLiteral)
2250 return operandFromValue (valMinus (left->operand.valOperand,
2251 right->operand.valOperand));
2253 /* if left is an array or pointer */
2254 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2256 isarray = left->isaddr;
2257 right = geniCodeMultiply (right,
2258 operandFromLit (getSize (ltype->next)),
2259 (getArraySizePtr(left) >= INTSIZE) ?
2262 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2265 { /* make them the same size */
2266 resType = usualBinaryConversions (&left, &right, resultType, '-');
2269 ic = newiCode ('-', left, right);
2271 IC_RESULT (ic) = newiTempOperand (resType, 1);
2272 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2274 /* if left or right is a float */
2275 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2279 return IC_RESULT (ic);
2282 /*-----------------------------------------------------------------*/
2283 /* geniCodeAdd - generates iCode for addition */
2284 /*-----------------------------------------------------------------*/
2286 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2295 /* if the right side is LITERAL zero */
2296 /* return the left side */
2297 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2300 /* if left is literal zero return right */
2301 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2304 /* if left is a pointer then size */
2305 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2307 isarray = left->isaddr;
2308 // there is no need to multiply with 1
2309 if (getSize (ltype->next) != 1)
2311 size = operandFromLit (getSize (ltype->next));
2312 SPEC_USIGN (getSpec (operandType (size))) = 1;
2313 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2314 right = geniCodeMultiply (right,
2316 (getArraySizePtr(left) >= INTSIZE) ?
2319 /* Even if right is a 'unsigned char',
2320 the result will be a 'signed int' due to the promotion rules.
2321 It doesn't make sense when accessing arrays, so let's fix it here: */
2323 SPEC_USIGN (getSpec (operandType (right))) = 1;
2325 resType = copyLinkChain (ltype);
2328 { // make them the same size
2329 resType = usualBinaryConversions (&left, &right, resultType, '+');
2332 /* if they are both literals then we know */
2333 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2334 && left->isLiteral && right->isLiteral)
2335 return operandFromValue (valPlus (valFromType (ltype),
2336 valFromType (rtype)));
2338 ic = newiCode ('+', left, right);
2340 IC_RESULT (ic) = newiTempOperand (resType, 1);
2341 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2343 /* if left or right is a float then support
2345 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2350 return IC_RESULT (ic);
2354 /*-----------------------------------------------------------------*/
2355 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2356 /*-----------------------------------------------------------------*/
2358 aggrToPtr (sym_link * type, bool force)
2363 if (IS_PTR (type) && !force)
2366 etype = getSpec (type);
2367 ptype = newLink (DECLARATOR);
2371 /* set the pointer depending on the storage class */
2372 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2376 /*-----------------------------------------------------------------*/
2377 /* geniCodeArray2Ptr - array to pointer */
2378 /*-----------------------------------------------------------------*/
2380 geniCodeArray2Ptr (operand * op)
2382 sym_link *optype = operandType (op);
2383 sym_link *opetype = getSpec (optype);
2385 /* set the pointer depending on the storage class */
2386 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2393 /*-----------------------------------------------------------------*/
2394 /* geniCodeArray - array access */
2395 /*-----------------------------------------------------------------*/
2397 geniCodeArray (operand * left, operand * right, int lvl)
2401 sym_link *ltype = operandType (left);
2406 if (IS_PTR (ltype->next) && left->isaddr)
2408 left = geniCodeRValue (left, FALSE);
2411 return geniCodeDerefPtr (geniCodeAdd (left,
2413 (getArraySizePtr(left) >= INTSIZE) ?
2419 size = operandFromLit (getSize (ltype->next));
2420 SPEC_USIGN (getSpec (operandType (size))) = 1;
2421 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2422 right = geniCodeMultiply (right,
2424 (getArraySizePtr(left) >= INTSIZE) ?
2427 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2428 It doesn't make sense when accessing arrays, so let's fix it here: */
2430 SPEC_USIGN (getSpec (operandType (right))) = 1;
2431 /* we can check for limits here */
2432 /* already done in SDCCast.c
2433 if (isOperandLiteral (right) &&
2436 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2438 werror (W_IDX_OUT_OF_BOUNDS,
2439 (int) operandLitValue (right) / getSize (ltype->next),
2444 ic = newiCode ('+', left, right);
2446 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2447 !IS_AGGREGATE (ltype->next) &&
2448 !IS_PTR (ltype->next))
2449 ? ltype : ltype->next), 0);
2451 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2454 return IC_RESULT (ic);
2457 /*-----------------------------------------------------------------*/
2458 /* geniCodeStruct - generates intermediate code for structures */
2459 /*-----------------------------------------------------------------*/
2461 geniCodeStruct (operand * left, operand * right, bool islval)
2464 sym_link *type = operandType (left);
2465 sym_link *etype = getSpec (type);
2467 symbol *element = getStructElement (SPEC_STRUCT (etype),
2468 right->operand.symOperand);
2470 wassert(IS_SYMOP(right));
2472 /* add the offset */
2473 ic = newiCode ('+', left, operandFromLit (element->offset));
2475 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2477 /* preserve the storage & output class of the struct */
2478 /* as well as the volatile attribute */
2479 retype = getSpec (operandType (IC_RESULT (ic)));
2480 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2481 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2482 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2483 SPEC_CONST (retype) |= SPEC_CONST (etype);
2485 if (IS_PTR (element->type))
2486 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2488 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2491 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2494 /*-----------------------------------------------------------------*/
2495 /* geniCodePostInc - generate int code for Post increment */
2496 /*-----------------------------------------------------------------*/
2498 geniCodePostInc (operand * op)
2502 sym_link *optype = operandType (op);
2504 operand *rv = (IS_ITEMP (op) ?
2505 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2507 sym_link *rvtype = operandType (rv);
2510 /* if this is not an address we have trouble */
2513 werror (E_LVALUE_REQUIRED, "++");
2517 rOp = newiTempOperand (rvtype, 0);
2518 OP_SYMBOL(rOp)->noSpilLoc = 1;
2521 OP_SYMBOL(rv)->noSpilLoc = 1;
2523 geniCodeAssign (rOp, rv, 0);
2525 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2526 if (IS_FLOAT (rvtype))
2527 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2529 ic = newiCode ('+', rv, operandFromLit (size));
2531 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2534 geniCodeAssign (op, result, 0);
2540 /*-----------------------------------------------------------------*/
2541 /* geniCodePreInc - generate code for preIncrement */
2542 /*-----------------------------------------------------------------*/
2544 geniCodePreInc (operand * op, bool lvalue)
2547 sym_link *optype = operandType (op);
2548 operand *rop = (IS_ITEMP (op) ?
2549 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2551 sym_link *roptype = operandType (rop);
2557 werror (E_LVALUE_REQUIRED, "++");
2562 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2563 if (IS_FLOAT (roptype))
2564 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2566 ic = newiCode ('+', rop, operandFromLit (size));
2567 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2570 (void) geniCodeAssign (op, result, 0);
2571 if (lvalue || IS_TRUE_SYMOP (op))
2577 /*-----------------------------------------------------------------*/
2578 /* geniCodePostDec - generates code for Post decrement */
2579 /*-----------------------------------------------------------------*/
2581 geniCodePostDec (operand * op)
2585 sym_link *optype = operandType (op);
2587 operand *rv = (IS_ITEMP (op) ?
2588 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2590 sym_link *rvtype = operandType (rv);
2593 /* if this is not an address we have trouble */
2596 werror (E_LVALUE_REQUIRED, "--");
2600 rOp = newiTempOperand (rvtype, 0);
2601 OP_SYMBOL(rOp)->noSpilLoc = 1;
2604 OP_SYMBOL(rv)->noSpilLoc = 1;
2606 geniCodeAssign (rOp, rv, 0);
2608 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2609 if (IS_FLOAT (rvtype))
2610 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2612 ic = newiCode ('-', rv, operandFromLit (size));
2614 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2617 geniCodeAssign (op, result, 0);
2623 /*-----------------------------------------------------------------*/
2624 /* geniCodePreDec - generate code for pre decrement */
2625 /*-----------------------------------------------------------------*/
2627 geniCodePreDec (operand * op, bool lvalue)
2630 sym_link *optype = operandType (op);
2631 operand *rop = (IS_ITEMP (op) ?
2632 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2634 sym_link *roptype = operandType (rop);
2640 werror (E_LVALUE_REQUIRED, "--");
2645 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2646 if (IS_FLOAT (roptype))
2647 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2649 ic = newiCode ('-', rop, operandFromLit (size));
2650 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2653 (void) geniCodeAssign (op, result, 0);
2654 if (lvalue || IS_TRUE_SYMOP (op))
2661 /*-----------------------------------------------------------------*/
2662 /* geniCodeBitwise - gen int code for bitWise operators */
2663 /*-----------------------------------------------------------------*/
2665 geniCodeBitwise (operand * left, operand * right,
2666 int oper, sym_link * resType)
2670 left = geniCodeCast (resType, left, TRUE);
2671 right = geniCodeCast (resType, right, TRUE);
2673 ic = newiCode (oper, left, right);
2674 IC_RESULT (ic) = newiTempOperand (resType, 0);
2677 return IC_RESULT (ic);
2680 /*-----------------------------------------------------------------*/
2681 /* geniCodeAddressOf - gens icode for '&' address of operator */
2682 /*-----------------------------------------------------------------*/
2684 geniCodeAddressOf (operand * op)
2688 sym_link *optype = operandType (op);
2689 sym_link *opetype = getSpec (optype);
2691 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2693 op = operandFromOperand (op);
2698 /* lvalue check already done in decorateType */
2699 /* this must be a lvalue */
2700 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2701 /* werror (E_LVALUE_REQUIRED,"&"); */
2705 p = newLink (DECLARATOR);
2707 /* set the pointer depending on the storage class */
2708 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2710 p->next = copyLinkChain (optype);
2712 /* if already a temp */
2715 setOperandType (op, p);
2720 /* other wise make this of the type coming in */
2721 ic = newiCode (ADDRESS_OF, op, NULL);
2722 IC_RESULT (ic) = newiTempOperand (p, 1);
2723 IC_RESULT (ic)->isaddr = 0;
2725 return IC_RESULT (ic);
2727 /*-----------------------------------------------------------------*/
2728 /* setOClass - sets the output class depending on the pointer type */
2729 /*-----------------------------------------------------------------*/
2731 setOClass (sym_link * ptr, sym_link * spec)
2733 switch (DCL_TYPE (ptr))
2736 SPEC_OCLS (spec) = data;
2740 SPEC_OCLS (spec) = generic;
2744 SPEC_OCLS (spec) = xdata;
2748 SPEC_OCLS (spec) = code;
2752 SPEC_OCLS (spec) = idata;
2756 SPEC_OCLS (spec) = xstack;
2760 SPEC_OCLS (spec) = eeprom;
2769 /*-----------------------------------------------------------------*/
2770 /* geniCodeDerefPtr - dereference pointer with '*' */
2771 /*-----------------------------------------------------------------*/
2773 geniCodeDerefPtr (operand * op,int lvl)
2775 sym_link *rtype, *retype;
2776 sym_link *optype = operandType (op);
2778 // if this is an array then array access
2779 if (IS_ARRAY (optype)) {
2780 // don't worry, this will be optimized out later
2781 return geniCodeArray (op, operandFromLit (0), lvl);
2784 // just in case someone screws up
2785 wassert (IS_PTR (optype));
2787 if (IS_TRUE_SYMOP (op))
2790 op = geniCodeRValue (op, TRUE);
2793 /* now get rid of the pointer part */
2794 if (isLvaluereq(lvl) && IS_ITEMP (op))
2796 retype = getSpec (rtype = copyLinkChain (optype));
2800 retype = getSpec (rtype = copyLinkChain (optype->next));
2801 /* outputclass needs 2b updated */
2802 setOClass (optype, retype);
2805 op->isGptr = IS_GENPTR (optype);
2807 op->isaddr = (IS_PTR (rtype) ||
2808 IS_STRUCT (rtype) ||
2813 if (!isLvaluereq(lvl))
2814 op = geniCodeRValue (op, TRUE);
2816 setOperandType (op, rtype);
2821 /*-----------------------------------------------------------------*/
2822 /* geniCodeUnaryMinus - does a unary minus of the operand */
2823 /*-----------------------------------------------------------------*/
2825 geniCodeUnaryMinus (operand * op)
2828 sym_link *optype = operandType (op);
2830 if (IS_LITERAL (optype))
2831 return operandFromLit (-floatFromVal (op->operand.valOperand));
2833 ic = newiCode (UNARYMINUS, op, NULL);
2834 IC_RESULT (ic) = newiTempOperand (optype, 0);
2836 return IC_RESULT (ic);
2839 /*-----------------------------------------------------------------*/
2840 /* geniCodeLeftShift - gen i code for left shift */
2841 /*-----------------------------------------------------------------*/
2843 geniCodeLeftShift (operand * left, operand * right)
2847 ic = newiCode (LEFT_OP, left, right);
2848 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2850 return IC_RESULT (ic);
2853 /*-----------------------------------------------------------------*/
2854 /* geniCodeRightShift - gen i code for right shift */
2855 /*-----------------------------------------------------------------*/
2857 geniCodeRightShift (operand * left, operand * right)
2861 ic = newiCode (RIGHT_OP, left, right);
2862 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2864 return IC_RESULT (ic);
2867 /*-----------------------------------------------------------------*/
2868 /* geniCodeLogic- logic code */
2869 /*-----------------------------------------------------------------*/
2871 geniCodeLogic (operand * left, operand * right, int op)
2875 sym_link *rtype = operandType (right);
2876 sym_link *ltype = operandType (left);
2878 /* left is integral type and right is literal then
2879 check if the literal value is within bounds */
2880 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2882 checkConstantRange(ltype,
2883 OP_VALUE(right), "compare operation", 1);
2886 /* if one operand is a pointer and the other is a literal generic void pointer,
2887 change the type of the literal generic void pointer to match the other pointer */
2888 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2889 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2891 /* find left's definition */
2892 ic = (iCode *) setFirstItem (iCodeChain);
2895 if (((ic->op == CAST) || (ic->op == '='))
2896 && isOperandEqual(left, IC_RESULT (ic)))
2899 ic = setNextItem (iCodeChain);
2901 /* if casting literal to generic pointer, then cast to rtype instead */
2902 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2904 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2905 ltype = operandType(left);
2908 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2909 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2911 /* find right's definition */
2912 ic = (iCode *) setFirstItem (iCodeChain);
2915 if (((ic->op == CAST) || (ic->op == '='))
2916 && isOperandEqual(right, IC_RESULT (ic)))
2919 ic = setNextItem (iCodeChain);
2921 /* if casting literal to generic pointer, then cast to rtype instead */
2922 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2924 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2925 rtype = operandType(right);
2929 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, ' ');
2931 ic = newiCode (op, left, right);
2932 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2934 /* if comparing float
2935 and not a '==' || '!=' || '&&' || '||' (these
2937 if (IS_FLOAT(ctype) &&
2945 return IC_RESULT (ic);
2948 /*-----------------------------------------------------------------*/
2949 /* geniCodeUnary - for a a generic unary operation */
2950 /*-----------------------------------------------------------------*/
2952 geniCodeUnary (operand * op, int oper)
2954 iCode *ic = newiCode (oper, op, NULL);
2956 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2958 return IC_RESULT (ic);
2961 /*-----------------------------------------------------------------*/
2962 /* geniCodeConditional - geniCode for '?' ':' operation */
2963 /*-----------------------------------------------------------------*/
2965 geniCodeConditional (ast * tree,int lvl)
2968 symbol *falseLabel = newiTempLabel (NULL);
2969 symbol *exitLabel = newiTempLabel (NULL);
2970 operand *cond = ast2iCode (tree->left,lvl+1);
2971 operand *true, *false, *result;
2973 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2977 true = ast2iCode (tree->right->left,lvl+1);
2979 /* move the value to a new Operand */
2980 result = newiTempOperand (tree->right->ftype, 0);
2981 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2983 /* generate an unconditional goto */
2984 geniCodeGoto (exitLabel);
2986 /* now for the right side */
2987 geniCodeLabel (falseLabel);
2989 false = ast2iCode (tree->right->right,lvl+1);
2990 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2992 /* create the exit label */
2993 geniCodeLabel (exitLabel);
2998 /*-----------------------------------------------------------------*/
2999 /* geniCodeAssign - generate code for assignment */
3000 /*-----------------------------------------------------------------*/
3002 geniCodeAssign (operand * left, operand * right, int nosupdate)
3005 sym_link *ltype = operandType (left);
3006 sym_link *rtype = operandType (right);
3008 if (!left->isaddr && !IS_ITEMP (left))
3010 werror (E_LVALUE_REQUIRED, "assignment");
3014 /* left is integral type and right is literal then
3015 check if the literal value is within bounds */
3016 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3018 checkConstantRange(ltype,
3019 OP_VALUE(right), "= operation", 0);
3022 /* if the left & right type don't exactly match */
3023 /* if pointer set then make sure the check is
3024 done with the type & not the pointer */
3025 /* then cast rights type to left */
3027 /* first check the type for pointer assignement */
3028 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3029 compareType (ltype, rtype) <= 0)
3031 if (compareType (ltype->next, rtype) < 0)
3032 right = geniCodeCast (ltype->next, right, TRUE);
3034 else if (compareType (ltype, rtype) < 0)
3035 right = geniCodeCast (ltype, right, TRUE);
3037 /* If left is a true symbol & ! volatile
3038 create an assignment to temporary for
3039 the right & then assign this temporary
3040 to the symbol. This is SSA (static single
3041 assignment). Isn't it simple and folks have
3042 published mountains of paper on it */
3043 if (IS_TRUE_SYMOP (left) &&
3044 !isOperandVolatile (left, FALSE) &&
3045 isOperandGlobal (left))
3049 if (IS_TRUE_SYMOP (right))
3050 sym = OP_SYMBOL (right);
3051 ic = newiCode ('=', NULL, right);
3052 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3053 SPIL_LOC (right) = sym;
3057 ic = newiCode ('=', NULL, right);
3058 IC_RESULT (ic) = left;
3061 /* if left isgptr flag is set then support
3062 routine will be required */
3066 ic->nosupdate = nosupdate;
3070 /*-----------------------------------------------------------------*/
3071 /* geniCodeDummyRead - generate code for dummy read */
3072 /*-----------------------------------------------------------------*/
3074 geniCodeDummyRead (operand * op)
3077 sym_link *type = operandType (op);
3079 if (!IS_VOLATILE(type))
3082 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3088 /*-----------------------------------------------------------------*/
3089 /* geniCodeSEParms - generate code for side effecting fcalls */
3090 /*-----------------------------------------------------------------*/
3092 geniCodeSEParms (ast * parms,int lvl)
3097 if (parms->type == EX_OP && parms->opval.op == PARAM)
3099 geniCodeSEParms (parms->left,lvl);
3100 geniCodeSEParms (parms->right,lvl);
3104 /* hack don't like this but too lazy to think of
3106 if (IS_ADDRESS_OF_OP (parms))
3107 parms->left->lvalue = 1;
3109 if (IS_CAST_OP (parms) &&
3110 IS_PTR (parms->ftype) &&
3111 IS_ADDRESS_OF_OP (parms->right))
3112 parms->right->left->lvalue = 1;
3114 parms->opval.oprnd =
3115 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3117 parms->type = EX_OPERAND;
3118 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3119 SPEC_ARGREG(parms->ftype);
3122 /*-----------------------------------------------------------------*/
3123 /* geniCodeParms - generates parameters */
3124 /*-----------------------------------------------------------------*/
3126 geniCodeParms (ast * parms, value *argVals, int *stack,
3127 sym_link * ftype, int lvl)
3135 if (argVals==NULL) {
3137 argVals = FUNC_ARGS (ftype);
3140 /* if this is a param node then do the left & right */
3141 if (parms->type == EX_OP && parms->opval.op == PARAM)
3143 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3144 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3148 /* get the parameter value */
3149 if (parms->type == EX_OPERAND)
3150 pval = parms->opval.oprnd;
3153 /* maybe this else should go away ?? */
3154 /* hack don't like this but too lazy to think of
3156 if (IS_ADDRESS_OF_OP (parms))
3157 parms->left->lvalue = 1;
3159 if (IS_CAST_OP (parms) &&
3160 IS_PTR (parms->ftype) &&
3161 IS_ADDRESS_OF_OP (parms->right))
3162 parms->right->left->lvalue = 1;
3164 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3167 /* if register parm then make it a send */
3168 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3169 IFFUNC_ISBUILTIN(ftype))
3171 ic = newiCode (SEND, pval, NULL);
3172 ic->argreg = SPEC_ARGREG(parms->etype);
3173 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3178 /* now decide whether to push or assign */
3179 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3183 operand *top = operandFromSymbol (argVals->sym);
3184 /* clear useDef and other bitVectors */
3185 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3186 geniCodeAssign (top, pval, 1);
3190 sym_link *p = operandType (pval);
3192 ic = newiCode (IPUSH, pval, NULL);
3194 /* update the stack adjustment */
3195 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3200 argVals=argVals->next;
3204 /*-----------------------------------------------------------------*/
3205 /* geniCodeCall - generates temp code for calling */
3206 /*-----------------------------------------------------------------*/
3208 geniCodeCall (operand * left, ast * parms,int lvl)
3212 sym_link *type, *etype;
3216 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3217 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3218 werror (E_FUNCTION_EXPECTED);
3219 return operandFromValue(valueFromLit(0));
3222 /* take care of parameters with side-effecting
3223 function calls in them, this is required to take care
3224 of overlaying function parameters */
3225 geniCodeSEParms (parms,lvl);
3227 ftype = operandType (left);
3228 if (IS_CODEPTR (ftype))
3229 ftype = ftype->next;
3231 /* first the parameters */
3232 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3234 /* now call : if symbol then pcall */
3235 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3236 ic = newiCode (PCALL, left, NULL);
3238 ic = newiCode (CALL, left, NULL);
3241 type = copyLinkChain (ftype->next);
3242 etype = getSpec (type);
3243 SPEC_EXTR (etype) = 0;
3244 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3248 /* stack adjustment after call */
3249 ic->parmBytes = stack;
3254 /*-----------------------------------------------------------------*/
3255 /* geniCodeReceive - generate intermediate code for "receive" */
3256 /*-----------------------------------------------------------------*/
3258 geniCodeReceive (value * args)
3260 /* for all arguments that are passed in registers */
3264 if (IS_REGPARM (args->etype))
3266 operand *opr = operandFromValue (args);
3268 symbol *sym = OP_SYMBOL (opr);
3271 /* we will use it after all optimizations
3272 and before liveRange calculation */
3273 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3276 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3277 options.stackAuto == 0 &&
3278 (!(options.model == MODEL_FLAT24)) )
3283 opl = newiTempOperand (args->type, 0);
3285 sym->reqv->key = sym->key;
3286 OP_SYMBOL (sym->reqv)->key = sym->key;
3287 OP_SYMBOL (sym->reqv)->isreqv = 1;
3288 OP_SYMBOL (sym->reqv)->islocal = 0;
3289 SPIL_LOC (sym->reqv) = sym;
3293 ic = newiCode (RECEIVE, NULL, NULL);
3294 ic->argreg = SPEC_ARGREG(args->etype);
3296 currFunc->recvSize = getSize (sym->type);
3299 IC_RESULT (ic) = opr;
3307 /*-----------------------------------------------------------------*/
3308 /* geniCodeFunctionBody - create the function body */
3309 /*-----------------------------------------------------------------*/
3311 geniCodeFunctionBody (ast * tree,int lvl)
3318 /* reset the auto generation */
3324 func = ast2iCode (tree->left,lvl+1);
3325 fetype = getSpec (operandType (func));
3327 savelineno = lineno;
3328 lineno = OP_SYMBOL (func)->lineDef;
3329 /* create an entry label */
3330 geniCodeLabel (entryLabel);
3331 lineno = savelineno;
3333 /* create a proc icode */
3334 ic = newiCode (FUNCTION, func, NULL);
3335 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3339 /* for all parameters that are passed
3340 on registers add a "receive" */
3341 geniCodeReceive (tree->values.args);
3343 /* generate code for the body */
3344 ast2iCode (tree->right,lvl+1);
3346 /* create a label for return */
3347 geniCodeLabel (returnLabel);
3349 /* now generate the end proc */
3350 ic = newiCode (ENDFUNCTION, func, NULL);
3355 /*-----------------------------------------------------------------*/
3356 /* geniCodeReturn - gen icode for 'return' statement */
3357 /*-----------------------------------------------------------------*/
3359 geniCodeReturn (operand * op)
3363 /* if the operand is present force an rvalue */
3365 op = geniCodeRValue (op, FALSE);
3367 ic = newiCode (RETURN, op, NULL);
3371 /*-----------------------------------------------------------------*/
3372 /* geniCodeIfx - generates code for extended if statement */
3373 /*-----------------------------------------------------------------*/
3375 geniCodeIfx (ast * tree,int lvl)
3378 operand *condition = ast2iCode (tree->left,lvl+1);
3381 /* if condition is null then exit */
3385 condition = geniCodeRValue (condition, FALSE);
3387 cetype = getSpec (operandType (condition));
3388 /* if the condition is a literal */
3389 if (IS_LITERAL (cetype))
3391 if (floatFromVal (condition->operand.valOperand))
3393 if (tree->trueLabel)
3394 geniCodeGoto (tree->trueLabel);
3400 if (tree->falseLabel)
3401 geniCodeGoto (tree->falseLabel);
3408 if (tree->trueLabel)
3410 ic = newiCodeCondition (condition,
3415 if (tree->falseLabel)
3416 geniCodeGoto (tree->falseLabel);
3420 ic = newiCodeCondition (condition,
3427 ast2iCode (tree->right,lvl+1);
3430 /*-----------------------------------------------------------------*/
3431 /* geniCodeJumpTable - tries to create a jump table for switch */
3432 /*-----------------------------------------------------------------*/
3434 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3436 int min = 0, max = 0, t, cnt = 0;
3442 int needRangeCheck = !optimize.noJTabBoundary
3443 || tree->values.switchVals.swDefault;
3445 if (!tree || !caseVals)
3448 /* the criteria for creating a jump table is */
3449 /* all integer numbers between the maximum & minimum must */
3450 /* be present , the maximum value should not exceed 255 */
3451 min = max = (int) floatFromVal (vch = caseVals);
3452 SNPRINTF (buffer, sizeof(buffer),
3454 tree->values.switchVals.swNum,
3456 addSet (&labels, newiTempLabel (buffer));
3458 /* if there is only one case value then no need */
3459 if (!(vch = vch->next))
3464 if (((t = (int) floatFromVal (vch)) - max) != 1)
3466 SNPRINTF (buffer, sizeof(buffer),
3468 tree->values.switchVals.swNum,
3470 addSet (&labels, newiTempLabel (buffer));
3476 /* if the number of case statements <= 2 then */
3477 /* it is not economical to create the jump table */
3478 /* since two compares are needed for boundary conditions */
3479 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3482 if (tree->values.switchVals.swDefault)
3484 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3488 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3492 falseLabel = newiTempLabel (buffer);
3494 /* so we can create a jumptable */
3495 /* first we rule out the boundary conditions */
3496 /* if only optimization says so */
3499 sym_link *cetype = getSpec (operandType (cond));
3500 /* no need to check the lower bound if
3501 the condition is unsigned & minimum value is zero */
3502 if (!(min == 0 && IS_UNSIGNED (cetype)))
3504 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3505 ic = newiCodeCondition (boundary, falseLabel, NULL);
3509 /* now for upper bounds */
3510 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3511 ic = newiCodeCondition (boundary, falseLabel, NULL);
3515 /* if the min is not zero then we no make it zero */
3518 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3519 if (!IS_LITERAL(getSpec(operandType(cond))))
3520 setOperandType (cond, UCHARTYPE);
3523 /* now create the jumptable */
3524 ic = newiCode (JUMPTABLE, NULL, NULL);
3525 IC_JTCOND (ic) = cond;
3526 IC_JTLABELS (ic) = labels;
3531 /*-----------------------------------------------------------------*/
3532 /* geniCodeSwitch - changes a switch to a if statement */
3533 /*-----------------------------------------------------------------*/
3535 geniCodeSwitch (ast * tree,int lvl)
3538 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3539 value *caseVals = tree->values.switchVals.swVals;
3540 symbol *trueLabel, *falseLabel;
3542 /* If the condition is a literal, then just jump to the */
3543 /* appropriate case label. */
3544 if (IS_LITERAL(getSpec(operandType(cond))))
3546 int switchVal, caseVal;
3548 switchVal = (int) floatFromVal (cond->operand.valOperand);
3551 caseVal = (int) floatFromVal (caseVals);
3552 if (caseVal == switchVal)
3554 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3555 tree->values.switchVals.swNum, caseVal);
3556 trueLabel = newiTempLabel (buffer);
3557 geniCodeGoto (trueLabel);
3560 caseVals = caseVals->next;
3562 goto defaultOrBreak;
3565 /* if we can make this a jump table */
3566 if (geniCodeJumpTable (cond, caseVals, tree))
3567 goto jumpTable; /* no need for the comparison */
3569 /* for the cases defined do */
3573 operand *compare = geniCodeLogic (cond,
3574 operandFromValue (caseVals),
3577 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3578 tree->values.switchVals.swNum,
3579 (int) floatFromVal (caseVals));
3580 trueLabel = newiTempLabel (buffer);
3582 ic = newiCodeCondition (compare, trueLabel, NULL);
3584 caseVals = caseVals->next;
3589 /* if default is present then goto break else break */
3590 if (tree->values.switchVals.swDefault)
3592 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3596 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3599 falseLabel = newiTempLabel (buffer);
3600 geniCodeGoto (falseLabel);
3603 ast2iCode (tree->right,lvl+1);
3606 /*-----------------------------------------------------------------*/
3607 /* geniCodeInline - intermediate code for inline assembler */
3608 /*-----------------------------------------------------------------*/
3610 geniCodeInline (ast * tree)
3614 ic = newiCode (INLINEASM, NULL, NULL);
3615 IC_INLINE (ic) = tree->values.inlineasm;
3619 /*-----------------------------------------------------------------*/
3620 /* geniCodeArrayInit - intermediate code for array initializer */
3621 /*-----------------------------------------------------------------*/
3623 geniCodeArrayInit (ast * tree, operand *array)
3627 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3628 ic = newiCode (ARRAYINIT, array, NULL);
3629 IC_ARRAYILIST (ic) = tree->values.constlist;
3631 operand *left=newOperand(), *right=newOperand();
3632 left->type=right->type=SYMBOL;
3633 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3634 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3635 ic = newiCode (ARRAYINIT, left, right);
3640 /*-----------------------------------------------------------------*/
3641 /* geniCodeCritical - intermediate code for a critical statement */
3642 /*-----------------------------------------------------------------*/
3644 geniCodeCritical (ast *tree, int lvl)
3649 /* If op is NULL, the original interrupt state will saved on */
3650 /* the stack. Otherwise, it will be saved in op. */
3652 /* Generate a save of the current interrupt state & disabled */
3653 ic = newiCode (CRITICAL, NULL, NULL);
3654 IC_RESULT (ic) = op;
3657 /* Generate the critical code sequence */
3658 if (tree->left && tree->left->type == EX_VALUE)
3659 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3661 ast2iCode (tree->left,lvl+1);
3663 /* Generate a restore of the original interrupt state */
3664 ic = newiCode (ENDCRITICAL, NULL, op);
3668 /*-----------------------------------------------------------------*/
3669 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3670 /* particular case. Ie : assigning or dereferencing array or ptr */
3671 /*-----------------------------------------------------------------*/
3672 set * lvaluereqSet = NULL;
3673 typedef struct lvalItem
3680 /*-----------------------------------------------------------------*/
3681 /* addLvaluereq - add a flag for lvalreq for current ast level */
3682 /*-----------------------------------------------------------------*/
3683 void addLvaluereq(int lvl)
3685 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3688 addSetHead(&lvaluereqSet,lpItem);
3691 /*-----------------------------------------------------------------*/
3692 /* delLvaluereq - del a flag for lvalreq for current ast level */
3693 /*-----------------------------------------------------------------*/
3697 lpItem = getSet(&lvaluereqSet);
3698 if(lpItem) Safe_free(lpItem);
3700 /*-----------------------------------------------------------------*/
3701 /* clearLvaluereq - clear lvalreq flag */
3702 /*-----------------------------------------------------------------*/
3703 void clearLvaluereq()
3706 lpItem = peekSet(lvaluereqSet);
3707 if(lpItem) lpItem->req = 0;
3709 /*-----------------------------------------------------------------*/
3710 /* getLvaluereq - get the last lvalreq level */
3711 /*-----------------------------------------------------------------*/
3712 int getLvaluereqLvl()
3715 lpItem = peekSet(lvaluereqSet);
3716 if(lpItem) return lpItem->lvl;
3719 /*-----------------------------------------------------------------*/
3720 /* isLvaluereq - is lvalreq valid for this level ? */
3721 /*-----------------------------------------------------------------*/
3722 int isLvaluereq(int lvl)
3725 lpItem = peekSet(lvaluereqSet);
3726 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3730 /*-----------------------------------------------------------------*/
3731 /* ast2iCode - creates an icodeList from an ast */
3732 /*-----------------------------------------------------------------*/
3734 ast2iCode (ast * tree,int lvl)
3736 operand *left = NULL;
3737 operand *right = NULL;
3741 /* set the global variables for filename & line number */
3743 filename = tree->filename;
3745 lineno = tree->lineno;
3747 block = tree->block;
3749 scopeLevel = tree->level;
3751 seqPoint = tree->seqPoint;
3753 if (tree->type == EX_VALUE)
3754 return operandFromValue (tree->opval.val);
3756 if (tree->type == EX_LINK)
3757 return operandFromLink (tree->opval.lnk);
3759 /* if we find a nullop */
3760 if (tree->type == EX_OP &&
3761 (tree->opval.op == NULLOP ||
3762 tree->opval.op == BLOCK))
3764 if (tree->left && tree->left->type == EX_VALUE)
3765 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3767 ast2iCode (tree->left,lvl+1);
3768 if (tree->right && tree->right->type == EX_VALUE)
3769 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3771 ast2iCode (tree->right,lvl+1);
3775 /* special cases for not evaluating */
3776 if (tree->opval.op != ':' &&
3777 tree->opval.op != '?' &&
3778 tree->opval.op != CALL &&
3779 tree->opval.op != IFX &&
3780 tree->opval.op != LABEL &&
3781 tree->opval.op != GOTO &&
3782 tree->opval.op != SWITCH &&
3783 tree->opval.op != FUNCTION &&
3784 tree->opval.op != INLINEASM &&
3785 tree->opval.op != CRITICAL)
3788 if (IS_ASSIGN_OP (tree->opval.op) ||
3789 IS_DEREF_OP (tree) ||
3790 (tree->opval.op == '&' && !tree->right) ||
3791 tree->opval.op == PTR_OP)
3794 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3795 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3798 left = operandFromAst (tree->left,lvl);
3800 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3801 left = geniCodeRValue (left, TRUE);
3805 left = operandFromAst (tree->left,lvl);
3807 if (tree->opval.op == INC_OP ||
3808 tree->opval.op == DEC_OP)
3811 right = operandFromAst (tree->right,lvl);
3816 right = operandFromAst (tree->right,lvl);
3820 /* now depending on the type of operand */
3821 /* this will be a biggy */
3822 switch (tree->opval.op)
3825 case '[': /* array operation */
3827 //sym_link *ltype = operandType (left);
3828 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3829 left = geniCodeRValue (left, FALSE);
3830 right = geniCodeRValue (right, TRUE);
3833 return geniCodeArray (left, right,lvl);
3835 case '.': /* structure dereference */
3836 if (IS_PTR (operandType (left)))
3837 left = geniCodeRValue (left, TRUE);
3839 left = geniCodeRValue (left, FALSE);
3841 return geniCodeStruct (left, right, tree->lvalue);
3843 case PTR_OP: /* structure pointer dereference */
3846 pType = operandType (left);
3847 left = geniCodeRValue (left, TRUE);
3849 setOClass (pType, getSpec (operandType (left)));
3852 return geniCodeStruct (left, right, tree->lvalue);
3854 case INC_OP: /* increment operator */
3856 return geniCodePostInc (left);
3858 return geniCodePreInc (right, tree->lvalue);
3860 case DEC_OP: /* decrement operator */
3862 return geniCodePostDec (left);
3864 return geniCodePreDec (right, tree->lvalue);
3866 case '&': /* bitwise and or address of operator */
3868 { /* this is a bitwise operator */
3869 left = geniCodeRValue (left, FALSE);
3870 right = geniCodeRValue (right, FALSE);
3871 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3874 return geniCodeAddressOf (left);
3876 case '|': /* bitwise or & xor */
3878 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3879 geniCodeRValue (right, FALSE),
3884 return geniCodeDivision (geniCodeRValue (left, FALSE),
3885 geniCodeRValue (right, FALSE),
3886 getResultTypeFromType (tree->ftype));
3889 return geniCodeModulus (geniCodeRValue (left, FALSE),
3890 geniCodeRValue (right, FALSE),
3891 getResultTypeFromType (tree->ftype));
3894 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3895 geniCodeRValue (right, FALSE),
3896 getResultTypeFromType (tree->ftype));
3898 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3902 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3903 geniCodeRValue (right, FALSE),
3904 getResultTypeFromType (tree->ftype));
3906 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3910 return geniCodeAdd (geniCodeRValue (left, FALSE),
3911 geniCodeRValue (right, FALSE),
3912 getResultTypeFromType (tree->ftype),
3915 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3918 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3919 geniCodeRValue (right, FALSE));
3922 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3923 geniCodeRValue (right, FALSE));
3925 #if 0 // this indeed needs a second thought
3929 // let's keep this simple: get the rvalue we need
3930 op=geniCodeRValue (right, FALSE);
3931 // now cast it to whatever we want
3932 op=geniCodeCast (operandType(left), op, FALSE);
3933 // if this is going to be used as an lvalue, make it so
3939 #else // bug #604575, is it a bug ????
3940 return geniCodeCast (operandType (left),
3941 geniCodeRValue (right, FALSE), FALSE);
3948 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3953 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3954 setOperandType (op, UCHARTYPE);
3965 /* different compilers (even different gccs) evaluate
3966 the two calls in a different order. to get the same
3967 result on all machines we've to specify a clear sequence.
3968 return geniCodeLogic (geniCodeRValue (left, FALSE),
3969 geniCodeRValue (right, FALSE),
3973 operand *leftOp, *rightOp;
3975 rightOp = geniCodeRValue (right, FALSE);
3976 leftOp = geniCodeRValue (left , FALSE);
3978 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3981 return geniCodeConditional (tree,lvl);
3984 return operandFromLit (getSize (tree->right->ftype));
3988 sym_link *rtype = operandType (right);
3989 sym_link *ltype = operandType (left);
3990 if (IS_PTR (rtype) && IS_ITEMP (right)
3991 && right->isaddr && compareType (rtype->next, ltype) == 1)
3992 right = geniCodeRValue (right, TRUE);
3994 right = geniCodeRValue (right, FALSE);
3996 geniCodeAssign (left, right, 0);
4001 geniCodeAssign (left,
4002 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4004 geniCodeRValue (right, FALSE), FALSE),
4005 getResultTypeFromType (tree->ftype));
4009 geniCodeAssign (left,
4010 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4012 geniCodeRValue (right, FALSE),
4013 getResultTypeFromType (tree->ftype)),
4017 geniCodeAssign (left,
4018 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4020 geniCodeRValue (right, FALSE),
4021 getResultTypeFromType (tree->ftype)),
4025 sym_link *rtype = operandType (right);
4026 sym_link *ltype = operandType (left);
4027 if (IS_PTR (rtype) && IS_ITEMP (right)
4028 && right->isaddr && compareType (rtype->next, ltype) == 1)
4029 right = geniCodeRValue (right, TRUE);
4031 right = geniCodeRValue (right, FALSE);
4034 return geniCodeAssign (left,
4035 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4038 getResultTypeFromType (tree->ftype),
4044 sym_link *rtype = operandType (right);
4045 sym_link *ltype = operandType (left);
4046 if (IS_PTR (rtype) && IS_ITEMP (right)
4047 && right->isaddr && compareType (rtype->next, ltype) == 1)
4049 right = geniCodeRValue (right, TRUE);
4053 right = geniCodeRValue (right, FALSE);
4056 geniCodeAssign (left,
4057 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4060 getResultTypeFromType (tree->ftype)),
4065 geniCodeAssign (left,
4066 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4068 geniCodeRValue (right, FALSE)), 0);
4071 geniCodeAssign (left,
4072 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4074 geniCodeRValue (right, FALSE)), 0);
4077 geniCodeAssign (left,
4078 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4080 geniCodeRValue (right, FALSE),
4082 operandType (left)), 0);
4085 geniCodeAssign (left,
4086 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4088 geniCodeRValue (right, FALSE),
4090 operandType (left)), 0);
4093 geniCodeAssign (left,
4094 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4096 geniCodeRValue (right, FALSE),
4098 operandType (left)), 0);
4100 return geniCodeRValue (right, FALSE);
4103 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4106 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4107 return ast2iCode (tree->right,lvl+1);
4110 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4111 return ast2iCode (tree->right,lvl+1);
4114 geniCodeFunctionBody (tree,lvl);
4118 geniCodeReturn (right);
4122 geniCodeIfx (tree,lvl);
4126 geniCodeSwitch (tree,lvl);
4130 geniCodeInline (tree);
4134 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4138 geniCodeCritical (tree, lvl);
4144 /*-----------------------------------------------------------------*/
4145 /* reverseICChain - gets from the list and creates a linkedlist */
4146 /*-----------------------------------------------------------------*/
4153 while ((loop = getSet (&iCodeChain)))
4165 /*-----------------------------------------------------------------*/
4166 /* iCodeFromAst - given an ast will convert it to iCode */
4167 /*-----------------------------------------------------------------*/
4169 iCodeFromAst (ast * tree)
4171 returnLabel = newiTempLabel ("_return");
4172 entryLabel = newiTempLabel ("_entry");
4174 return reverseiCChain ();
4177 static const char *opTypeToStr(OPTYPE op)
4181 case SYMBOL: return "symbol";
4182 case VALUE: return "value";
4183 case TYPE: return "type";
4185 return "undefined type";
4189 operand *validateOpType(operand *op,
4196 if (op && op->type == type)
4201 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4202 " expected %s, got %s\n",
4203 macro, args, file, line,
4204 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4206 return op; // never reached, makes compiler happy.